@gram-lang/format
Canonical code formatter for .gram files, used by both the gram format CLI command and the VS Code extension / Language Server. It unifies 13 formatting rules into a single deterministic pass.
formatGram
typescript
function formatGram(source: string, options?: FormatterOptions): stringFormats a .gram source string according to Gram's 13 canonical formatting rules.
typescript
import { formatGram } from '@gram-lang/format';
const formatted = formatGram(`
---
title: 'Crepes'
---
## Batter
Mix @flour{200g} and @milk{200ml}.
`);FormatterOptions
typescript
interface FormatterOptions {
tabSize?: number; // Number of spaces per tab level (default: 2)
insertSpaces?: boolean; // Use spaces instead of tabs (default: true)
}Formatting Rules
formatGram applies 13 deterministic formatting rules:
- Frontmatter: Preserves frontmatter delimiters (
---) and cleans up leading/trailing whitespace around metadata. - Section Headings: Ensures a single space after
##section titles (e.g.## Section). - Step Indexing: Formats numbered step prefixes cleanly (
1. Step text). - Action Blocks: Formats step action prefixes (
[Mix] ...). - Ingredient Tokens: Normalizes
@ingredient{qty}spacing and bracket syntax. - Cookware Tokens: Normalizes
#cookware{qty}spacing and bracket syntax. - Timer Tokens: Normalizes
~timer{duration}and passive~_timer{duration}spacing. - Temperature Tokens: Normalizes
^temp{value}syntax. - Intermediate Declarations & References: Normalizes
->&doughdeclarations and&doughreferences. - Composite Syntax: Normalizes
<@parentcomposite ingredient syntax. - Decimal Quantities: Normalizes numeric decimal quantities (e.g. trimming trailing zeros like
1.50->1.5). - Comment Formatting: Ensures clean spacing after comment sigils (
// comment). - Whitespace Cleanup: Trims trailing whitespace per line and ensures a single trailing newline.
FormatterChanges
Returns structured metrics on formatting edits made (useful for editor extensions and reporting):
typescript
interface FormatterChanges {
formatted: string;
hasChanges: boolean;
rulesApplied: string[];
}