Wit

API reference

The public surface for embedders: only what each package's index.ts re-exports. The pipeline is scanCloseless → parse → loadExternalData → resolve → expand → render.

@witlang/parser

parse(source: string, file?: string, options?: ParseOptions): Document
ParseOptions { closeless?: Iterable<string> }   // body-less names from other files
format(source: string, opts?: FormatOptions): string
FormatOptions { indent: string; closeless?: Iterable<string> }   // indent '  '
lex(source: string, file?: string, extraNames?: Iterable<string>): Token[]
parserTokens(source: string, file?: string, closeless?: Iterable<string>): Token[]
closelessNames(tokens: Token[], extra?: Iterable<string>): Set<string>
splitArgs(raw: string, declared: readonly string[] | null, loc: Loc): Param[]
parseInlineFromText(...): Inline[]
tryParseRecordFromText(...) / tryParseCollectionFromText(...)
CORE_VOCAB_NAMES: readonly string[]    // the 52 core names
CORE_PARAMS: readonly string[]         // parameter names core nodes read
class WitError { code; loc; message }
  • closeless lists definitions without ::body:: that live in other files, so their uses parse without a close. Get it from scanCloseless in the runtime.
  • lex is the raw token stream; parserTokens is what the parser walks, after stray markers become prose.
  • splitArgs splits the text inside (…) against the declared names: a value runs to the next declared key:; null treats every identifier as a key.

Types: Document Block Inline AstNode Paragraph Comment NodeUse NodeDef HeaderParam DataDef Record Collection IfStatement EachStatement ScriptBlock ScriptCall ReferenceDirective Text Italic Bold Interpolation BodySlot DataValue StringValue NumberValue BooleanValue NullValue Condition ExistenceCondition ComparisonCondition Param AccessPath Loc HasLoc Token TokenKind NodeOpen ParenArgs. Shapes: data model, AST reference.

@witlang/runtime

scanCloseless(rootPath: string, rootSource: string, reader?: FileReader): Set<string>
resolve(doc: Document, options?: ResolveOptions): ResolvedDocument
ResolveOptions {
  rootPath?: string
  fileReader?: FileReader                        // (absPath) => string
  onMissingReference?: (path: string) => null | void
  closeless?: ReadonlySet<string>                // for parsing referenced files
  prepare?: (doc: Document) => Document          // run on each referenced file
}
expand(resolved: ResolvedDocument): ExpandedDocument
loadExternalData(doc: Document, source: DataSource): Document
DataSource = DataLoader | Record<string, unknown>
DataLoader = (req: DataLoadRequest) => unknown
DataLoadRequest { alias: string; args: Record<string, string>; loc: Loc }
toDataValue(value: unknown, loc: Loc): DataValue
class RuntimeError / ResolverError / ExpanderError { code; loc; message }
RuntimeErrorCode                                 // the code constants
CORE_VOCAB_NAMES / RESERVED_OPAQUE ('node')
isCoreVocabName(name) / isReservedNodeName(name)
  • resolve reads referenced files, merges +# entries and throws ResolverError. expand binds parameters, runs statements and scripts, and throws ExpanderError.
  • onMissingReference returning null skips a missing file instead of raising E_MISSING_REFERENCE_FILE.
  • prepare is how the CLI runs @load in referenced files: pass (d) => loadExternalData(d, source).
  • A plain { alias: value } object is the simplest DataSource; a missing alias is E_LOAD_FAILED.

Types: DataLoader DataLoadRequest DataSource ResolvedDocument ExpandedDocument ResolveOptions FileReader RuntimeErrorCodeName.

@witlang/render-html

renderHtml(doc: ExpandedDocument, options?: RenderHtmlOptions): string
RenderHtmlOptions {
  mode?: 'fragment' | 'document'   // default 'fragment'
  title?: string                   // default 'Wit document'
  lang?: string                    // default 'en'
  css?: string                     // default defaultThemeCss; '' = unstyled
}
escapeHtml(s: string): string
defaultThemeCss / rawThemeCss      // stylesheet strings

wit build uses document mode; --fragment uses fragment, --raw passes rawThemeCss.

@witlang/render-markdown

renderMarkdown(doc: ExpandedDocument): string

End-to-end

import { parse } from '@witlang/parser';
import { scanCloseless, loadExternalData, resolve, expand } from '@witlang/runtime';
import { renderHtml } from '@witlang/render-html';

const closeless = scanCloseless(path, source);
const doc = parse(source, path, { closeless });
const data = { sales: [{ region: 'West', total: 100 }] };
const loaded = loadExternalData(doc, data);
const prepare = (d) => loadExternalData(d, data);
const expanded = expand(resolve(loaded, { rootPath: path, closeless, prepare }));
const html = renderHtml(expanded, { mode: 'document' });

With @load sales load@ and @table(rows: @sales) in the source, that renders a one-row table.

See also

CLI · Data model · Errors · Embed Wit in an app.