@nextgensoftwares/folio-plugin-code
Syntax highlighting (headless, lazy grammars) and multi-language code groups. Guide: Code & syntax highlighting.
Plugin
| Export | Signature | Description |
|---|---|---|
codePlugin | (options?: CodePluginOptions) => CodePlugin | codeBlock/codeGroup renderers, the codeGroup node, commands, Mod-Alt-C, slash/toolbar items, toolbar slot pickers, a caret guard, DOCX exporters, wrapLayout and subscribeLayout |
type CodePluginOptions | palette, style, settings, header, preferred, display, languages, builtins, preload, palette, exportAll, picker, preferredPicker, groupLanguages, onError | |
type CodePlugin | FolioPlugin plus CodeApi | |
type CodeApi | state(), setState(patch), setPreferred(lang), setDisplay(d), languages(), resolve(id), label(id), registerLanguage(l), setHighlighter(h, options?), highlighter(), whenHighlighted(), loadLanguages(ids), highlight(code, lang), groupLanguages(), palette(), setPalette(p), style(), setStyle(patch), exportAll(), setExportAll(b), withAllVariants(fn), revealCaret, subscribe(fn) | |
CodeStore | class | view state plus generations (gen, groupGen, langGen) that tell layout what to re-measure; subscribeLayout, subscribe |
type CodeViewState, type GroupDisplay | { preferred: string | null; display: 'preferred' | 'all' } |
Highlighter
| Export | Description |
|---|---|
defineLanguage(spec) | compiles a LanguageSpec (ordered rules, word lists, identifier pattern, capitalizedTypes, calls, caseInsensitive) into a Language with tokenize(text) => Token[] |
PATTERNS | shared rules: slashComment, hashComment, blockComment, dqString, sqString, number, annotation |
Language, LanguageSpec, Rule, Token, TokenType | Token = { from, to, type, color?, italic? } in UTF-16 offsets of the block's text, sorted and disjoint (color = a highlighter theme's fixed colour) |
Highlighter, HighlighterOptions, HighlighterLanguage, ScopedToken, ScopeTheme | a pluggable highlighter: tokenize(code, lang) → ScopedToken[] (sync or Promise), optional languages, supports, canonical, theme; options { mode: 'fallback' | 'override', debounce, theme } (guide) |
resolveScope(scope, themes?), resolveTokens(spans, length, themes?) | scope → token type / colour (highlight.js, Prism, TextMate names, dotted prefixes); spans → sorted disjoint Token[] (inner spans win) |
staleTokens(recent, text), normalizeColor(css) | an earlier version's tokens re-based across one edit (placeholder while async answers are pending); #rgb/#rrggbbaa/rgb() → #rrggbb |
highlightJs(src, opts?), prism(src, opts?), shiki(src, { theme }) | adapters; src is the library instance or a lazy loader (no dependency on any of them) |
htmlSpans(html, prefix?), prismSpans(stream), shikiSpans(lines), lazySource, decodeEntities | building blocks for other adapters |
HljsLike, HighlightJsOptions | the part of highlight.js (v10+) highlightJs uses (highlight(code, { language, ignoreIllegals? }) → { value }, getLanguage, listLanguages); options { languages?, theme? } (languages for the menus, default every language of a directly passed instance) |
PrismLike, PrismOptions | the part of Prism prism uses (languages, tokenize(text, grammar)); options { languages?, loadLanguage?(lang, prism), theme? } (loadLanguage loads a grammar Prism doesn't have yet) |
ShikiLike, ShikiOptions | the part of a Shiki v1+ highlighter shiki uses (codeToTokensBase, getLoadedLanguages, loadLanguage); options { theme, languages? } (theme is one the highlighter has loaded, e.g. github-light) |
Source<T> | T | (() => Promise<T | { default: T }>): a library instance or a loader for it (() => import('highlight.js')); what the adapters take as src |
MaybePromise<T> | T | Promise<T>: what Highlighter.tokenize may return |
ResolvedScope | { type: TokenType | null; color?; italic? }: what resolveScope returns for a scope (a theme colour, a theme or built-in token type, or nothing) |
TokenedText | { text: string; tokens: readonly Token[] }: an earlier highlighter result, the recent entries of staleTokens |
LanguageRegistry, LanguageInfo | id/alias lookup with on-demand loading (get is sync and starts a load; load resolves) |
BUILTIN_LANGUAGES | the lazy built-ins: JavaScript, TypeScript, Python, Java, Rust, Go, C/C++, SQL, Bash, JSON, CSS, HTML |
LIGHT_PALETTE, DARK_PALETTE, CodePalette | token and box colours (document colours): tokens plus background, border, text, header, accent, gutter, lineHighlight(Bar), diffAdd(Text), diffRemove(Text) |
CODE_PRESETS, GITHUB, ONE, SOLARIZED, MONOCHROME, CodePreset | code themes with light and dark variants |
PaletteChoice, paletteKey(choice), hexLuminance(css) | auto / light / dark, a preset id ('one', 'solarized:dark') or a palette; its cache key; luminance used by auto |
paletteFor(choice, theme) | auto picks dark for a dark theme.code.background |
codeTokenMap(from?, to?) | light → dark token colours, for a colour theme's map |
Layout
| Export | Description |
|---|---|
measureHighlighted(node, ctx, env, header?) | measureCodeBlock with tokens, palette and style; cached per node |
measureCodeBlock(node, ctx, input), CodeMeasureInput, CodeStyle | the block layout: box, header, gutter, bands, wrapped lines, "(continued)" carry; CodeStyle = { tabWidth, wrapMarker, repeatHeader } |
advancesOf(text, font, measurer, space, tab), wrapLine(text, adv, width, hang), Segment | per-unit advances (tab stops) and pre-wrap breaking with hanging indents |
boxRects(width, height, radius, border, background, ends?) | the box as fills: rounded caps at real ends, square body (clean page cuts) |
headerFragments(spec, measurer), HeaderSpec, languageDot(name) | header fragments (dot, label/title or tabs, accent underline, divider) |
lineSet(spec), normalizeLines(spec) | "3-5,8" → line numbers; tidy a typed spec |
CODE_SCHEMA | codeBlock (language, title, lineNumbers, highlight, diff, wrapMarker) and codeGroup (active) |
colorizeFlow(flow, tokens, palette, measurer) | splits code-line text items at token boundaries; geometry unchanged |
tokensFor(lang, text) | memoized tokenization |
createCodeRenderer(env), createGroupRenderer(env) | the codeBlock / codeGroup BlockRenderers |
visibleVariants(langs, state, active?), variantLanguages(env, group), groupActive(env, group) | which variants a group shows (own choice → preference → first) |
headerInfo(fragment), withHeaderInfo(flow, info), CodeHeaderInfo, CodeHeaderRect | the data the header UI reads off the code-header rect (language, text, tab languages) |
withCodeRefresh(env, next) | the layout wrapper: re-identifies just the blocks a state change affects |
HighlightEnv, HeaderTabs, PaletteChoice | renderer environment and options |
Commands and UI
| Export | Description |
|---|---|
insertCodeBlock(language?) | paragraph → code block, or insert one after the block (Mod-Alt-C, code.insertBlock) |
insertCodeGroup(languages?) | a group with one empty variant per language (code.insertGroup) |
setCodeLanguage(language) | the language attr of the block at the caret (code.setLanguage) |
addCodeVariant(language), removeCodeVariant() | add a variant (wrapping a lone block in a group) / remove the one at the caret |
setCodeAttrs(pos, patch), CodeBlockAttrs | title, line numbers, highlighted lines, diff, ↪ of the block at pos (code.setAttrs) |
setGroupVariant(groupPos, index) | show that variant in that group (its active attr; a clicked tab); a caret in the group follows |
clearGroupVariants | clear every group's active ("apply to all") |
setCodeLanguageAt(pos, language) | the header chip: language of the block at pos; in a group the variant stays shown |
codeBlockAt(state) | the code block at the selection head and its group, if any |
caretGuard(env), visibleCaretPos(env, doc, pos, dir), revealCaret(env) | keep the caret out of hidden variants |
createLanguagePicker(api), createPreferredPicker(api), CodeSlotProps | the "toolbar" slot components |
createHeaderPainter(api, options?), CodeHeaderOptions | the rect:code-header painter: core bar + tablist, language chip, copy ({ chip?, copy?: 'always' | 'read' | false }) |
LanguageMenu, LanguageMenuProps, filterLanguages(list, query) | the chip's searchable list (combobox + listbox) and its matcher |
CodeRectPainter, CODE_RECT_PAINTERS | screen painters for the decoration rects (border, divider, band, bar, tab, dot) through the colour adapter's roles |
CopyButton, LanguageChip, LanguageChipProps, BlockOptions, BlockOptionsProps | copy with a check animation; the chip and its options panel |
DIFF_HELP | the help text of the options panel's Diff toggle: + lines get a green band, - lines a red band, the text itself unchanged |
createCodeSettings(api) | the "Code blocks" settings section (code theme, tab width, ↪, repeated headers) |
CODE_HEADER_CSS, injectHeaderCss() | the header UI styles, injected once |
Export
| Export | Description |
|---|---|
codeDocxExporters(env, exportAll) | { codeBlock, codeGroup } for exporters.docx (dynamic import('docx')) |
codeTable(docx, node, ctx, env, header), DocxHeader | a code block as a shaded one-column table: header row (title, language or tabs), line numbers as text, highlighted/diff lines shaded |
codeLineRuns(text, tokens, color), LineRun | coloured runs per source line (comments italic) |
expandTabs(runs, tab) | tabs in a line's LineRuns → spaces to the next stop (tab columns, counted across the runs), as the screen lays them out (Word's own tab stops differ) |
CodeDocxContext, CodeDocxExporter | the structural slice of DocxContext they use |
PDF needs nothing: token colours are on the layout's text items.