- Overview - Back to API reference index
- Library Reference - Creating and managing .chalk libraries
- 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
Compiler Reference
The dotchalk compiler transforms .chalk source code into structured JSON documents. This reference covers the two main compilation functions.
Installation & Importing
ESM (ECMAScript Modules)
// Default import (namespace)
import chalk from '@jackhgns/dotchalk';
chalk.compile(source, library);
chalk.library();
// Named imports
import { compile, compileFile, library, validateLibrary } from '@jackhgns/dotchalk';
// Type imports
import type { Library, Document, Element, Attribute, CompileResult } from '@jackhgns/dotchalk';
CommonJS
const chalk = require('@jackhgns/dotchalk');
chalk.compile(source, library);
chalk.library();
Both import styles provide identical functionality. ESM is recommended for new projects as it enables tree-shaking and static analysis.
Table of Contents
- compile - Compile .chalk source strings
- In-Memory File Resolution - Using in-memory files with @include
- compileFile - Compile .chalk files with @include support
- CompileResult - Return type for compilation functions
- Constants - Injecting constants at compile time
compile
Compiles .chalk source code into a structured document.
Important: The compile function automatically validates the library before compilation. If the library is invalid, compilation will fail immediately with a validation error. This ensures that only well-formed libraries can be used for compilation.
Signature:
chalk.compile(
source: string,
library: Library,
documentClass?: string,
inputConstants?: Record<string, any>,
files?: FileMap
): CompileResult
Parameters:
source(string) - The .chalk source code to compilelibrary(Library) - Library containing document and element definitionsdocumentClass(string, optional) - Document class name to use for compilationinputConstants(Record<string, any>, optional) - Constants to inject (converted to strings)files(FileMap, optional) - In-memory file map for@includeresolution (see In-Memory File Resolution)
Returns: CompileResult with compiled document or error
Example:
import chalk from '@jackhgns/dotchalk';
const source = `
*(title: Hello World; author: John Doe)
This is a **paragraph** with formatting.
`;
const result = chalk.compile(source, myLibrary);
if (result.ok) {
console.log('Document:', result.data);
console.log('Class:', result.data.class);
console.log('Header:', result.data.header);
console.log('Body:', result.data.body);
} else {
console.error('Compilation failed:', result.error);
}
With Document Class:
// Compile as a tutorial document
const result = chalk.compile(source, myLibrary, 'tutorial');
// Compile as an article document
const result = chalk.compile(source, myLibrary, 'article');
With Input Constants:
const result = chalk.compile(source, myLibrary, undefined, {
version: '1.0.0',
author: 'Jane Smith',
buildDate: new Date().toISOString()
});
// Constants can be used in the source as {{version}}, {{author}}, {{buildDate}}
In-Memory File Resolution
The compile function supports resolving @include directives from in-memory file maps instead of the filesystem. This is useful for:
- Testing: Compile documents without creating temporary files
- Browser environments: Avoid filesystem access in web applications
- Bundler integration: Include
.part.chalkfiles in bundles as strings - Dynamic content: Generate includes programmatically
Signature:
chalk.compile(
source: string,
library: Library,
documentClass?: string,
inputConstants?: Record<string, any>,
files?: Record<string, string> // FileMap
): CompileResult
Example: Basic In-Memory Include
const result = chalk.compile(
'@include(src: header.part.chalk)',
myLibrary,
undefined,
undefined,
{
'header.part.chalk': 'para{Welcome to my article}'
}
);
if (result.ok) {
console.log('Included header:', result.data.body[0].body);
}
Example: Nested In-Memory Includes
const result = chalk.compile(
'@include(src: components/main.part.chalk)',
myLibrary,
undefined,
undefined,
{
'components/main.part.chalk': '@include(src: header.part.chalk)\n\nMain content',
'components/header.part.chalk': 'para{Site Header}'
}
);
Example: Mixed Filesystem and In-Memory
When using compile() with a files map, includes are resolved first from the map, then fall back to the filesystem if not found:
// Files in the map are used; others are read from disk
const result = chalk.compile(
'@include(src: header.part.chalk)\n@include(src: footer.part.chalk)',
myLibrary,
undefined,
undefined,
{
'header.part.chalk': 'para{In-memory header}'
// footer.part.chalk will be read from disk if it exists
}
);
Important Notes:
- Path resolution: Paths are resolved relative to the current working directory (same as filesystem resolution)
- Nested includes: When an in-memory file includes another file, the path is resolved relative to the including file’s directory
- Filesystem fallback: If a file is not in the map, the compiler will attempt to read it from disk
- Only for
compile(): Thefilesparameter is only available oncompile(), notcompileFile(). UsecompileFile()for filesystem-based compilation
compileFile
Compiles a .chalk file and all its dependencies referenced via @include metaelements.
Important: Like compile, the compileFile function automatically validates the library before compilation. If the library is invalid, compilation will fail immediately with a validation error.
This function:
- Validates the library definition
- Resolves the main file path
- Builds a dependency graph of all
@includereferences - Compiles files in dependency order (dependencies first)
- Returns the compiled main document
Signature:
chalk.compileFile(
mainFile: string,
baseDir: string,
library: Library,
documentClass?: string,
inputConstants?: Record<string, any>
): CompileResult
Parameters:
mainFile(string) - Path to the main .chalk file (relative to baseDir or absolute)baseDir(string) - Base directory for resolving relative file pathslibrary(Library) - Library containing document and element definitionsdocumentClass(string, optional) - Document class name to use for compilationinputConstants(Record<string, any>) - Optional constants to inject
Returns: CompileResult with compiled document or error
Example:
import chalk from '@jackhgns/dotchalk';
import path from 'path';
const result = chalk.compileFile(
'article.chalk',
__dirname,
myLibrary
);
if (result.ok) {
console.log('Compiled document:', result.data);
} else {
console.error('Compilation failed:', result.error);
}
With Document Class:
// Compile as a tutorial
const result = chalk.compileFile(
'guide.chalk',
__dirname,
myLibrary,
'tutorial'
);
With Input Constants:
const result = chalk.compileFile(
'article.chalk',
path.join(__dirname, 'content'),
myLibrary,
undefined,
{
version: '2.0.0',
buildDate: new Date().toISOString()
}
);
File Structure Example:
project/
├── content/
│ ├── main.chalk # Uses @include(src: header.part.chalk)
│ ├── header.part.chalk # Reusable header content
│ └── footer.part.chalk # Reusable footer content
└── compile.js
main.chalk:
*(title: My Article; author: Jane Doe)
@include(src: header.part.chalk)
This is the main content.
@include(src: footer.part.chalk)
Important Notes:
- File extensions are required. The
@includedirective will not auto-add.part.chalkor.chalkextensions. You must explicitly specify the full filename including extension (e.g.,@include(src: header.part.chalk)). - Paths are resolved relative to the file containing the
@includedirective, not the main file. - Circular includes (A includes B which includes A) are detected and will result in an error.
CompileResult
The return type for compilation functions, providing either a successful result or an error.
For complete type definitions, see the Type Reference page.
Type Definition:
type CompileResult =
| { ok: true; data: ChalkDocument }
| { ok: false; error: string };
Handling Results:
const result = chalk.compile(source, library);
if (result.ok) {
// Success - access result.data
const document = result.data;
console.log('Document class:', document.class);
console.log('Header attributes:', document.header);
console.log('Body elements:', document.body);
} else {
// Failure - access result.error
console.error('Error:', result.error);
}
For the complete ChalkDocument structure, see Type Reference - ChalkDocument.
Constants
Both compile and compileFile support injecting constants at compile time via the inputConstants parameter.
How Constants Work
- Definition: Constants can be defined in source using
@const(key: value)or injected viainputConstants - Reference: Use
{{key}}syntax to reference constants in your source - Scope: Input constants are document-scoped and available throughout the entire document
- Conversion: All input constant values are converted to strings
Multi-word Constant Keys
Constant identifiers can contain spaces:
const result = chalk.compile(source, library, {
'app version': '1.0.0',
'build date': '2025-12-19',
'is production': true
});
In source:
*(title: My App)
Version: {{app version}}
Built: {{build date}}
Production: {{is production}}
Combining Source and Input Constants
// Input constants
const result = chalk.compile(`
@const(author: John Doe)
@const(title: {{app name}} Documentation)
*(title: {{title}}; author: {{author}})
Welcome to {{app name}} version {{version}}.
`, library, {
'app name': 'MyApp',
'version': '2.0.0'
});
Error Handling
Undefined Constants:
const result = chalk.compile(`
{{undefined constant}}
`, library);
// result.ok === false
// result.error === "Undefined constants: undefined constant. Constants must be declared..."
Invalid Constant Keys:
const result = chalk.compile(`
@const(invalid!key: value)
`, library);
// result.ok === false
// result.error === "Invalid constant key format..."
Complete Examples
Basic Compilation
import chalk from '@jackhgns/dotchalk';
// Create a library
const library = chalk.library({
document: {
class: 'article',
body: 'all',
attributes: {
title: { type: 'string', required: true },
author: { type: 'string', required: true }
}
}
});
// Compile source
const source = `
*(title: Getting Started; author: Jane Doe)
# Introduction
This is a **simple** article with *formatting*.
# Conclusion
That's all!
`;
const result = chalk.compile(source, library);
if (result.ok) {
console.log(JSON.stringify(result.data, null, 2));
}
File Compilation with Includes
compile.js:
import chalk from '@jackhgns/dotchalk';
import path from 'path';
const library = chalk.library({
document: {
class: 'documentation',
body: 'all',
attributes: {
title: { type: 'string', required: true },
version: { type: 'string', required: true }
}
}
});
const result = chalk.compileFile(
'docs/main.chalk',
__dirname,
library,
{ version: '1.0.0' }
);
if (result.ok) {
console.log('Compiled:', result.data.class);
} else {
console.error('Error:', result.error);
}
docs/main.chalk:
*(title: API Documentation; version: {{version}})
@include(intro.part.chalk)
# API Reference
Content here...
@include(footer.part.chalk)
Error Handling Pattern
function compileAndHandle(source, library) {
const result = chalk.compile(source, library);
if (!result.ok) {
// Log error
console.error('Compilation Error:', result.error);
// Return default or throw
throw new Error(`Failed to compile: ${result.error}`);
}
// Process successful result
return processDocument(result.data);
}
Validation Pattern
function validateAndCompile(source, library) {
const result = chalk.compile(source, library);
if (!result.ok) {
return {
valid: false,
errors: [result.error]
};
}
// Additional validation
const doc = result.data;
const errors = [];
if (!doc.header.title) {
errors.push('Document missing title');
}
if (doc.body.length === 0) {
errors.push('Document has no content');
}
return {
valid: errors.length === 0,
errors,
document: doc
};
}
Best Practices
1. Check Results
Always check the ok property before accessing data:
// Good
const result = chalk.compile(source, library);
if (result.ok) {
process(result.data);
}
// Avoid
const result = chalk.compile(source, library);
process(result.data); // May be undefined if compilation failed
2. Use Absolute Paths for compileFile
// Good
const result = chalk.compileFile(
'article.chalk',
path.join(__dirname, 'content'),
library
);
// Avoid
const result = chalk.compileFile(
'article.chalk',
'./content', // Relative to cwd, not script location
library
);
3. Provide Meaningful Input Constants
// Good - descriptive keys
const constants = {
'app version': packageJson.version,
'build timestamp': new Date().toISOString(),
'environment': process.env.NODE_ENV
};
// Avoid - cryptic keys
const constants = {
v: '1.0',
t: Date.now(),
e: 'prod'
};
4. Handle Errors Gracefully
function safeCompile(source, library) {
try {
const result = chalk.compile(source, library);
if (!result.ok) {
logger.error('Compilation failed:', result.error);
return null;
}
return result.data;
} catch (err) {
logger.error('Unexpected error:', err);
return null;
}
}