- Overview - Back to API reference index
- Library Reference - Creating and managing .chalk libraries
- Compiler Reference - Using the .chalk compiler programmatically
- Custom Parsers - Creating custom parsers and parser priority
- Type Reference - Complete TypeScript type definitions
- Troubleshooting - Common issues and solutions
Primitives Reference
Primitives are the built-in elements and attribute types provided by dotchalk. They form the foundation of the .chalk markup language and are automatically available in every library.
Primitive Elements are markdown-like elements (paragraphs, headings) that are automatically parsed from .chalk source files. They don’t require explicit syntax—just write markdown-like text and these elements are recognised.
Primitive Attribute Types are the basic data types used for element attributes. When defining library elements, you specify which primitive types each attribute accepts.
Table of Contents
Primitive Elements
The following elements are automatically recognised and parsed from markdown-like syntax in .chalk documents:
| Element | Syntax | Description | Attributes | Body Policy |
|---|---|---|---|---|
paragraph |
Plain text (not starting with #) |
Basic text block | None | literal |
h1 |
# text |
Top-level heading | None | literal |
h2 |
## text |
Second-level heading | None | literal |
h3 |
### text |
Third-level heading | None | literal |
h4 |
#### text |
Fourth-level heading | None | literal |
h5 |
##### text |
Fifth-level heading | None | literal |
h6 |
###### text |
Sixth-level heading | None | literal |
list |
- item or 1. item |
List of items (unordered or ordered) | ordered: boolean |
literal |
Notes on Primitive Elements
- Automatic Parsing: These elements don’t require .chalk element syntax—they’re detected from markdown-like formatting
- Body Policy: All primitive elements use
literalbody policy, meaning their content is preserved as-is - Inline Formatting: Body content supports inline markdown (bold, italic, code, links, LaTeX)
- No Detail Sections: Primitive elements don’t support detail sections
- Library Integration: Primitives are available in every library by default
- Content Policy Required: Primitive elements must be explicitly allowed in content policies to appear in element bodies or details. For example, to allow paragraphs and headings in an element’s body, use
bodyPolicy: ["paragraph", "h1", "h2"]orbodyPolicy: "all"
List Element
The list element parses markdown-like list syntax and compiles to an array of formatted list items:
Unordered lists use - prefix (not *):
- First item
- Second item with **bold** text
- Third item with *italic* text
Ordered lists use number prefixes:
1. First item
2. Second item with `code`
3. Third item with [link](url)
Compiled output structure:
{
instance_id: 'elem_...',
identifier: 'list',
body: [
[{ type: 'text', content: 'First item' }],
[{ type: 'text', content: 'Second item with ' }, { type: 'bold', content: [{ type: 'text', content: 'bold' }] }, { type: 'text', content: ' text' }],
[{ type: 'text', content: 'Third item with ' }, { type: 'italic', content: [{ type: 'text', content: 'italic' }] }, { type: 'text', content: ' text' }]
],
detail: null,
attributes: [{ identifier: 'ordered', value: false }]
}
- The
bodyis an array of list items, where each item is an array of inline formatting elements (same as paragraphs) - The
orderedattribute istruefor numbered lists andfalsefor bullet lists - Consecutive list items of the same type are grouped into a single list element
- Mixing ordered and unordered items creates separate list elements
Primitive Inline Elements
The following inline elements are built into dotchalk and automatically available in all libraries:
| Element | Full Syntax | Shorthand | Description | Body Policy |
|---|---|---|---|---|
bold |
!bold{text} |
**text** |
Bold text formatting | inline('all') |
italic |
!italic{text} |
*text* |
Italic text formatting | inline('all') |
code |
!code{text} |
`text` |
Inline code formatting | inline(null) |
latex |
!latex{expression} |
$expression$ |
LaTeX mathematical notation | inline(null) |
Notes on Primitive Inline Elements
- Dual Syntax: Can use either full syntax (
!bold{text}) or shorthand (**text**) - No Attributes: Primitive inline elements don’t accept attributes, but can be added with library overrides
- Nesting:
boldanditalicallow nested inline elements;codeandlatexdo not, per their body policies
Usage Examples
This paragraph has **bold** and *italic* text.
You can use full syntax: !bold{important} or !italic{emphasis}.
Inline code: `const x = 5;` or !code{const x = 5;}
Math formulas: $E = mc^2$ or !latex{E = mc^2}
Nesting works: **bold with *italic* inside**
Escaping Delimiter Characters
You can escape delimiter characters to prevent them from being parsed as inline elements:
| Element | Escaped | Result | Example |
|---|---|---|---|
| bold | \*\*text\*\* |
**text** |
\*\*not bold\*\* |
| italic | \*text\* |
*text* |
\*not italic\* |
code |
\`text\` |
`text` |
\`not code\` |
| $latex$ | \$text\$ |
$text$ |
\$not latex\$ |
Common use cases:
// Currency amounts
Price: \$5.99
// Code snippets with backticks
Use \`npm install\` to install packages.
// Math-like expressions without parsing
The equation \$x = 5\$ is simple.
// Escaping the backslash itself
Escape with \\ to get a literal backslash.
Example Usage
*(title: My Document)
# Welcome
This is a paragraph with **bold** and *italic* text.
## Section Heading
Another paragraph here.
- First list item
- Second list item with **formatting**
- Third list item
### Subsection
1. Numbered item one
2. Numbered item two
3. Numbered item three
More content with `code` and $x^2$ maths.
Primitive Attribute Types
The following attribute types are built into dotchalk and can be used when defining custom elements:
| Type | Identifier | Parsed Result | Valid Input Examples | Invalid Input | Description |
|---|---|---|---|---|---|
| String | string |
string |
hello, Hello World, 123abc |
(all input valid) | Any text value |
| Number | number |
number |
42, 3.14, -10, 0.5 |
abc, 12x, 1.2.3 |
Numeric values (integer or decimal) |
| Integer | integer |
number |
42, -10, 0, 1000 |
3.14, 0.5, 12x |
Whole numbers only (no decimals) |
| Boolean | boolean |
boolean |
true, false, yes, no, 1, 0 |
maybe, 2, t |
True/false values |
| String List | string-list |
string[] |
a,b,c, one, two, three, x |
(all input valid) | Comma-separated strings |
| Number List | number-list |
number[] |
1,2,3, 1.5, 2.5, 3.5, 42 |
1,a,3, 1.2.3,4 |
Comma-separated numbers |
| Integer List | integer-list |
number[] |
1,2,3, -5, 0, 10, 100 |
1.5,2,3, 1,2x,3 |
Comma-separated integers |
| Formatted String | formatted-string |
{ raw: string, elements: any[] } |
**bold**, *italic*, $x^2$, [link](url) |
(all input valid) | String with inline markdown/LaTeX |
email |
string |
user@example.com, name.surname@domain.co.uk |
invalid, @example.com, user@ |
Valid email addresses | |
| Date | date |
{ year: number, month: number, day: number } |
2024-12-25, 2024-01-01, 1999-12-31 |
25/12/2024, 2024-13-01, invalid |
Date in YYYY-MM-DD format |
| URL | url |
string |
https://example.com, /path/to/file, ./relative |
not a url, ht!tp://bad |
Absolute or relative URLs |
| RGB Colour | rgb |
{ red: number, green: number, blue: number } |
#f00, #ff0000, rgb(255, 0, 0) |
red, #gggggg, rgb(300,0,0) |
Hex or RGB colour values |
Type Details
String
- Purpose: General-purpose text values
- Validation: None—all input is accepted
- Processing: Trims whitespace from start and end
- Use Cases: Names, titles, descriptions, URLs, identifiers
Number
- Purpose: Numeric values for calculations or measurements
- Validation: Must be parseable as a valid number
- Processing: Converts to JavaScript
numbertype - Use Cases: Dimensions, counts, percentages, indices, IDs
Integer
- Purpose: Whole number values without decimal places
- Validation: Must be a valid integer (no decimal point or non-numeric characters)
- Processing: Converts to JavaScript
numbertype (integer) - Use Cases: Counts, indices, IDs, quantities, ages, rankings
Boolean
- Purpose: True/false flags and toggles
- Validation: Must match recognised boolean values
- Accepted Values:
- True:
true,yes,1 - False:
false,no,0
- True:
- Case Insensitive:
TRUE,True,YESall work - Shorthand Syntax:
- Boolean attributes can be written as just the identifier (without
: value) to representtrueenabledis equivalent toenabled: truevisibleis equivalent tovisible: true
- Negation: Prefix with
!to representfalse!enabledis equivalent toenabled: false!visibleis equivalent tovisible: false
- Boolean attributes can be written as just the identifier (without
- Use Cases: Feature flags, visibility toggles, state indicators
Examples:
// Explicit boolean values
element{ content }(visible: true; enabled: false)
// Shorthand: identifier means true
element{ content }(visible; enabled)
// Negation: !identifier means false
element{ content }(!visible; !enabled)
// Mixed syntax
element{ content }(visible; !enabled; active: true)
String List
- Purpose: Multiple text values in a single attribute
- Validation: None—all input is accepted
- Processing: Splits on commas, trims each item, filters empty strings
- Use Cases: Tags, categories, CSS classes, file paths, author lists
Number List
- Purpose: Multiple numeric values in a single attribute
- Validation: Each comma-separated item must be a valid number
- Processing: Splits on commas, parses each as number
- Use Cases: Coordinates, dimensions, data points, version numbers
Integer List
- Purpose: Multiple integer values in a single attribute
- Validation: Each comma-separated item must be a valid integer (no decimals)
- Processing: Splits on commas, parses each as integer
- Use Cases: Indices, counts, rankings, discrete data points, version components
Formatted String
- Purpose: Rich text with inline formatting
- Validation: None—all input is accepted
- Processing: Parses markdown-like and LaTeX syntax
- Supported Formatting:
- Bold:
**text** - Italic:
*text* - Code:
`text` - Links:
[text](url) - Inline LaTeX:
$equation$
- Bold:
- Use Cases: Descriptions with formatting, rich labels, tooltips
- Purpose: Email address validation
- Validation: Must match basic email format (
user@domain.tld) - Processing: Trims whitespace and validates structure
- Use Cases: Contact information, author emails, notification addresses
Date
- Purpose: Date values without time information
- Validation: Must be valid date in YYYY-MM-DD format
- Processing: Validates the date is real (e.g., rejects 2024-13-01) and returns structured object
- Format: ISO 8601 date format (YYYY-MM-DD)
- Parsed Result: Object with
year,month, anddayas integers - Use Cases: Publication dates, deadlines, event dates, timestamps
Example:
// Input: "2024-12-25"
// Output: { year: 2024, month: 12, day: 25 }
URL
- Purpose: Web addresses and file paths
- Validation: Must be absolute URL (with protocol) or relative path
- Accepted Formats:
- Absolute:
https://example.com,http://site.com/path - Relative:
/path/to/file,./relative/path,../parent/path
- Absolute:
- Use Cases: Links, references, image sources, external resources
RGB Colour
- Purpose: Colour values for styling
- Validation: Must match hex or RGB format with valid values
- Accepted Formats:
- 3-digit hex:
#RGB(e.g.,#f00for red) - 6-digit hex:
#RRGGBB(e.g.,#ff0000for red) - RGB function:
rgb(r, g, b)where r, g, b are 0-255
- 3-digit hex:
- Processing: Converts all formats to structured RGB object with integer values (0-255)
- Parsed Result: Object with
red,green, andblueas integers - Use Cases: Text colours, background colours, border colours, theme values
Examples:
// Input: "#f00" (3-digit hex)
// Output: { red: 255, green: 0, blue: 0 }
// Input: "#abc" (3-digit hex)
// Output: { red: 170, green: 187, blue: 204 }
// Input: "#ff5733" (6-digit hex)
// Output: { red: 255, green: 87, blue: 51 }
// Input: "rgb(100, 200, 50)"
// Output: { red: 100, green: 200, blue: 50 }
Using Primitives
In Element Definitions
When defining elements, specify primitive types for attributes:
import chalk from '@jackhgns/dotchalk';
const lib = chalk.library({
document: { class: 'mylib', body: 'all' }
});
lib.element('callout', {
body: 'literal',
attributes: {
type: { type: 'string', required: true },
visible: { type: 'boolean', default: true },
tags: { type: 'string-list' }
}
});
// Using structured types
lib.element('event', {
body: 'literal',
attributes: {
date: { type: 'date', required: true }, // Returns { year, month, day }
colour: { type: 'rgb' }, // Returns { red, green, blue }
link: { type: 'url' } // Returns string
}
});
Accessing structured attribute values:
// After compilation, structured types are available as objects
const result = chalk.compile(`
event{Conference 2025}(
date: 2025-06-15
colour: #3498db
)
`, lib);
// The compiled attribute values:
// date = { year: 2025, month: 6, day: 15 }
// colour = { red: 52, green: 152, blue: 219 }
Markdown-like Content
Primitive elements are automatically parsed from markdown-like syntax in documents and within elements that allow them:
# This becomes an h1 element
This becomes a paragraph element.
## This becomes an h2 element
Another paragraph here.
Important: Primitive elements only appear where the content policy allows them. For example:
// This element allows primitive elements in its body
lib.element('section', {
body: ['paragraph', 'h1', 'h2', 'h3'], // Explicitly allow primitives
attributes: {}
});
// This element does NOT allow primitive elements
lib.element('callout', {
body: 'literal', // No parsing, raw text only
attributes: {}
});
Type Validation
The compiler validates attribute values against their primitive types:
// Valid - basic types
const result = chalk.compile(`
callout{Content}(type: warning; visible: true; tags: urgent,important)
`, lib);
// Valid - structured types
const result = chalk.compile(`
event{Annual Meeting}(
date: 2025-06-15
colour: #ff5733
link: https://example.com/event
)
`, lib);
// Compiled attributes:
// date = { year: 2025, month: 6, day: 15 }
// colour = { red: 255, green: 87, blue: 51 }
// link = "https://example.com/event"
// Invalid - will produce errors
const result = chalk.compile(`
event{Bad Event}(
date: 25/06/2025 // Error: Invalid date format. Use YYYY-MM-DD
colour: red // Error: Invalid colour format. Use #RGB, #RRGGBB, or rgb(r, g, b)
visible: maybe // Error: Boolean value must be true/false, yes/no, or 1/0
)
`, lib);