- Overview - Back to language guide index
- Attributes - Key-value pairs for element configuration and metadata
- Style Guide - Best practices and conventions
Elements
Elements are the building blocks of .chalk documents. Understanding the different types of elements and how they’re defined is essential for working with .chalk.
Table of Contents
- Element Classification
- Standard-Syntax Elements
- Custom-Syntax Elements
- Inline Elements
- Meta-Elements
- Headers
- Containers
Element Classification
.chalk elements can be categorized in two ways:
By Syntax Type
| Syntax Type | Pattern | Example |
|---|---|---|
| Standard-Syntax | identifier{...}[...](...) |
article{content}(author: John) |
| Custom-Syntax | Non-standard patterns | # Heading, Plain paragraph |
By Definition Source
| Definition Source | Description | Examples |
|---|---|---|
| Library-Defined | Explicitly defined in your .chalk library with specific rules | article, sidebar, callout |
| Primitive | Built-in elements automatically available | paragraph, h1-h6, list |
How They Combine
| Library-Defined | Primitive | |
|---|---|---|
| Standard-Syntax | ✅ Most custom elementsarticle{...}, callout{...} |
❌ Not applicable |
| Custom-Syntax | ✅ Possible (advanced) Custom parsers in library |
✅ All primitives# Heading, paragraph |
Key Points:
- Primitives are always custom-syntax elements (markdown-like)
- Library-defined elements are typically standard-syntax, but can use custom-syntax with advanced parsers
- Standard-syntax elements are always library-defined
- Custom-syntax elements can be either primitive or library-defined
Standard-Syntax Elements
Standard-syntax elements use the identifier{...}[...](...) pattern and must be defined in your library.
Identifier Rules
Element identifiers must follow these rules:
- Must start with a letter (a-z, A-Z) or underscore (_)
- Can contain letters, numbers (0-9), underscores (_), hyphens (-), and periods (.)
- Cannot end with a period
- Cannot start with a number or period
Valid identifiers:
- ✅
article,blog_post,my-element - ✅
ui.button,component.card.fancy(periods for namespacing) - ✅
section1.part2,my_component.sub-item
Invalid identifiers:
- ❌
123element(starts with number) - ❌
.element(starts with period) - ❌
element.(ends with period) - ❌
my@element(contains invalid character)
Element Structure
All standard-syntax elements follow this general pattern:
identifier{
body content
}[
detail content
](
attributes
)
- Body content: Main content of the element
- Detail content: Optional secondary/sidebar content
- Attributes: Configuration parameters (see Attributes Guide)
Body content and detail content can contain other elements, including nested standard-syntax elements. Each element’s library definition specifies which content areas it supports as well as what elements are allowed in the body and detail sections.
Having two different sections (body and detail) allows for more complex layouts and content structures. For example, an article element might use the body for the main text and the detail section for related links or author information that is styled differently.
Examples:
blog-post{
...
}(author: John Doe; published: 2024-01-01)
chart{
...
}[
...
](
attr1: value1
attr2: value2
)
square(size: 10)
ui.button{Click me}
component.card.fancy{Main content}[Sidebar](color: blue)
Custom-Syntax Elements
Custom-syntax elements use non-standard patterns that don’t follow the identifier{...}[...](...) format.
Primitive Custom-Syntax Elements
The most common custom-syntax elements are the primitives built into .chalk:
# Heading 1
## Heading 2
### Heading 3
This is a paragraph.
- Unordered list item
- Another item
1. Ordered list item
2. Another numbered item
Primitive elements are automatically recognised and don’t need to be defined in your library, though they must still be explicitly allowed in content policies. See the Primitives Reference for complete details.
Library-Defined Custom-Syntax Elements (Advanced)
Libraries can define custom-syntax elements using specialised parsers, though this is uncommon and requires advanced implementation. Most library-defined elements use standard-syntax.
Inline Elements
Inline elements work within text content (paragraphs, headings, list items) to provide formatting and semantic markup. They use either full syntax or shorthand notation.
Full Syntax
The full inline element syntax is:
!identifier{body}(attributes)
Components:
!- Prefix indicating an inline elementidentifier- The element identifier (follows same rules as standard elements){body}- Optional body content (can contain nested inline elements)(attributes)- Optional attributes
Identifier rules: Same as standard-syntax elements (can contain periods for namespacing)
Constraint: Inline elements must be on a single line (cannot contain newlines).
Examples:
!bold{This is bold text}
!highlight{highlighted text}(color: yellow)
!abbr{HTML}(title: HyperText Markup Language)
!icon(name: star; size: 16)
!icon.star(size: 16)
!ui.component.badge{New}
Shorthand Syntax
Inline elements can have shorthand notation for convenience. A few primitive inline elements have markdown-style shorthand:
This paragraph has **bold**, *italic*, `code`, and $\LaTeX$ formatting.
Libraries can define custom shorthand for their inline elements:
This is ===highlighted=== text.
Nesting
Inline elements can be nested within each other:
This is **bold with *italic* inside** text.
This is ***bold and italic*** combined.
Escaping Inline Delimiters
You can use a backslash (\) to escape delimiter characters and prevent them from being parsed as inline elements. This is useful when you need to write literal delimiter characters in your content.
Basic escaping:
\$x\$→$x$(literal text, not LaTeX)\*not italic\*→*not italic*(literal text, not italic)\**not bold**→**not bold**(literal text, not bold)\`not code\`→`not code`(literal text, not code)\!→!(literal exclamation mark)
Escaping the backslash:
\\→\(literal backslash)\\$x$→\+ LaTeX element (backslash followed by inline element)
Partial escaping:
When you escape the opening delimiter of a pattern, the pattern is not recognized, so subsequent delimiters can still form valid elements:
Price is \$5 and formula is $x$
This produces: literal text “Price is $5 and formula is “ + LaTeX element “x”.
Inside full syntax:
!bold{Price: \$5.00} // Bold text containing "$5.00"
!code{\{x: 1\}} // Code text containing "{x: 1}"
Custom shorthand delimiters:
For library-defined shorthand delimiters (like ==highlight==), escape the first character:
\==not highlighted== // Literal "=" + "=not highlighted=="
Common use cases:
- Currency amounts:
Items cost \$10, \$20, and \$30 - Code examples:
Use \backticks` in code` - Mathematical expressions:
Set x = \$5 then solve $x + y = 10$ - Literal punctuation:
Use \*asterisks\* or \*\*double asterisks\*\*
Custom Inline Elements
Libraries can define custom inline elements beyond the primitives. These are used with full syntax:
This has !highlight{important text}(color: pink).
The !abbr{API}(title: Application Programming Interface) uses REST.
Use !icon(name: star; size: 16) for ratings.
Some custom inline elements may have shorthand syntax defined by the library:
This is ===highlighted text===.
Examples
Basic formatting:
This paragraph has **bold**, *italic*, and `code` formatting.
With attributes:
Use !icon(name: star; size: 16) for ratings.
Mixed with text:
The !abbr{HTML}(title: HyperText Markup Language) specification defines web markup.
Nested formatting:
This is **bold with *italic* inside** and ***combined***.
Meta-Elements
Meta-elements start with @ and control document processing. Meta-element identifiers follow the same naming rules as standard elements (can contain periods for namespacing).
@const(name: John Doe; version: 1.0)
@const(config.database.host: localhost)
@include(src: header.part.chalk)
Meta-elements cannot be defined or customised in libraries.
Constants
Define reusable values with optional period-based namespacing:
@const(name: John Doe; version: 1.0)
@const(app.config.port: 8080)
@const(ui.color.primary: blue)
Constants can be referenced using {{identifier}}:
Welcome, {{name}}!
Server running on port {{app.config.port}}
signature(version: {{version}}; color: {{ui.color.primary}})
Until final compilation, constants are all treated as strings. Once compiled, they will be converted to their appropriate types based on context.
When the same constant is defined multiple times, the last definition wins. Input constants (passed via compile options) always take priority over source definitions.
Inclusions
Include external .part.chalk .chalk element files:
@include(src: header.part.chalk)
@include(src: footer.part.chalk)
Headers
Header attributes provide metadata about the document.
Document headers use *(..attributes..) syntax:
*(
title: My Document
author: John Doe
date: 2024-01-01
)
See more in the Attributes Guide
Containers
Containers are anonymous elements that group content to apply attributes to multiple elements at once:
{
# Container content
More content here
box{
Jack is in a box.
}
}(
colour: red
)
In the above example, the colour: red attribute applies to all elements within the container, including the heading 1, paragraph, and the box element. If any inner elements also define a colour attribute, that will override the container’s attribute for that specific element. Additionally, if any element within the container does not support the colour attribute, that attribute will simply be ignored for that element without causing an error.