- Library Reference - Creating and managing .chalk libraries
- Compiler Reference - Using the .chalk compiler programmatically
- Custom Parsers - Creating custom parsers and parser priority
- Primitives Reference - Built-in data types and elements in .chalk
- Type Reference - Complete TypeScript type definitions
- Troubleshooting - Common issues and solutions
API Reference
Complete reference for the .chalk API, including library creation, compiler usage, custom parsers, type definitions, and built-in primitives.
Table of Contents
Installation & Setup
This package is published on GitHub Packages. To install, you must add the following to your .npmrc:
@jackhgns:registry=https://npm.pkg.github.com
Then install with:
npm install @jackhgns/dotchalk
Note: The package is not available on npmjs.com. You must use the
.npmrcconfiguration above.
System Requirements
Node.js Version
- Minimum: Node.js 16.0.0 or higher
- Recommended: Node.js 18.0.0 or higher
- Latest: Node.js 20.x (fully tested)
TypeScript (Optional)
If you’re using TypeScript in your project:
- Minimum: TypeScript 4.5.0 or higher
- Recommended: TypeScript 5.0.0 or higher
The Compiled Object
When you compile a .chalk document using the compiler, you receive a Result<ChalkDocument, string> that contains either the compiled document object or an error message. The compiled object has a well-defined structure that represents your document’s content in a programmatic format.
ChalkDocument Structure
A compiled document has the following structure (see Type Reference - ChalkDocument for complete details):
interface ChalkDocument {
instance_id: string; // Unique identifier for this document instance
class: string; // The document type/class name
header: Record<string, any>; // Document-level attributes (from headers)
body: DocumentContent; // Array of elements or structured content
}
Example Compiled Output
Given a simple .chalk document:
*(title: My Document; author: John Doe)
# Introduction
note{This is an important note.}
The compiled object would look like:
{
instance_id: "doc_1766629364403001",
class: "article",
header: {
title: "My Document",
author: "John Doe"
},
body: [
{
instance_id: "elem_1766629364412002",
identifier: "h1",
body: [
{
type: "text",
content: "Introduction"
}
],
detail: null,
attributes: []
},
{
instance_id: "elem_1766629364412003",
identifier: "note",
body: "This is an important note.",
detail: null,
attributes: []
}
]
}
ChalkElement Structure
Each element in the body array follows this structure (see Type Reference - ChalkElement for complete details):
interface ChalkElement {
instance_id: string; // Unique identifier for this element
identifier: string; // Element type (e.g., "h1", "note", "paragraph")
body: ElementContent; // Primary content (can be string, array, or nested elements)
detail: ElementContent; // Secondary/detail content (optional)
attributes: ChalkAttribute[]; // Array of attributes with names and values
}
Element Content Types
The body and detail fields can contain different types of content:
- String: Plain text content (for
literalbody policy) - Array of content blocks: Structured content with
typeandcontentfields (for formatted text) - ChalkElement[]: Array of nested elements (for
elementsorallbody policy) - null: No content (for
emptybody policy)
Attributes
Element attributes are represented as (see Type Reference - ChalkAttribute for complete details):
interface ChalkAttribute {
instance_id: string; // Unique identifier for this attribute
identifier: string; // Attribute name
value: any; // Parsed value (type depends on definition)
}
For example, an element with attributes:
note{Important content here}(priority: high)
Would compile to:
{
instance_id: "elem_1766629364413006",
identifier: "note",
body: "Important content here",
detail: null,
attributes: [
{
instance_id: "attr_1766629364413005",
identifier: "priority",
value: "high"
}
]
}
Nested Elements
Elements can contain other elements, creating a tree structure:
section{
# Welcome
callout{Important information here}
}(
id: intro
)
Compiles to:
{
instance_id: "elem_1766629364414011",
identifier: "section",
body: [
{
instance_id: "elem_1766629364413008",
identifier: "h1",
body: [
{
type: "text",
content: "Welcome"
}
],
detail: null,
attributes: []
},
{
instance_id: "elem_1766629364414009",
identifier: "callout",
body: "Important information here",
detail: null,
attributes: []
}
],
detail: null,
attributes: [
{
instance_id: "attr_1766629364414010",
identifier: "id",
value: "intro"
}
]
}
Inline Elements in Compiled Output
Inline elements within text content (paragraphs, headings, etc.) are compiled as structured objects in the body array alongside text nodes:
Source:
This paragraph has **bold** and !highlight{important}(color: yellow) text.
Compiled:
{
instance_id: "elem_001",
identifier: "paragraph",
body: [
{ type: "text", content: "This paragraph has " },
{
instance_id: "elem_002",
identifier: "bold",
body: [{ type: "text", content: "bold" }],
detail: null,
attributes: []
},
{ type: "text", content: " and " },
{
instance_id: "elem_003",
identifier: "highlight",
body: [{ type: "text", content: "important" }],
detail: null,
attributes: [{ identifier: "color", value: "yellow" }]
},
{ type: "text", content: " text." }
],
detail: null,
attributes: []
}
Key points:
- Text nodes have
type: 'text'andcontent: string - Inline elements are full
ChalkElementobjects withidentifier,body, etc. - Inline elements can nest within each other in their
bodyarrays - The
detailfield is alwaysnullfor inline elements
Working with the Compiled Object
Once you have a compiled document, you can:
- Access document metadata: Use
headerfor document-level attributes - Iterate through elements: Loop through the
bodyarray to process each element - Query by element type: Filter elements by their
identifierproperty - Traverse nested structures: Recursively process
bodycontent when it contains nested elements - Transform to other formats: Convert to HTML, Markdown, JSON, or custom output formats
React Example
import React from 'react';
import chalk from '@jackhgns/dotchalk';
function renderDoc({ source, library }) {
const result = chalk.compile(source, library);
if (!result.ok) {
return <div>Error: {result.error}</div>;
}
const doc = result.data;
return (
<article>
<h1>{doc.header.title}</h1>
{doc.body.map(element => {
switch (element.identifier) {
case 'paragraph':
return <p key={element.instance_id}>{element.body}</p>;
case 'note':
return (
<div key={element.instance_id} className="note">
{element.body}
</div>
);
default:
return null;
}
})}
</article>
);
}
Basic Usage Example
import chalk from '@jackhgns/dotchalk';
const result = chalk.compile(chalkSource, library);
if (result.ok) {
const doc = result.data;
// Access document metadata
console.log(`Title: ${doc.header.title}`);
// Find all h1 elements
const headers = doc.body.filter(
elem => elem.identifier === 'h1'
);
// Process each element
doc.body.forEach(element => {
console.log(`Element: ${element.identifier}`);
});
}
For more details on compilation, see the Compiler Reference.
Core API Functions
The dotchalk API provides four main functions:
chalk.library()- Creates a new library for defining document schemas and element types. See Library Reference.chalk.compile(source, library)- Compiles .chalk source code into a structured document. See Compiler Reference.chalk.compileFile(mainFile, baseDir, library)- Compiles .chalk files with @include support. See Compiler Reference.chalk.validateLibrary(library)- Validates a library definition for correctness. See Compiler Reference.
These functions work together to provide a complete workflow from library definition to document compilation.