記法の拡張
@cosense-toolbox/parser/extensions から拡張用の型と既製の拡張を読み込めます。拡張を使わない場合、このサブパスを import する必要はありません。拡張の種類
InlineConstruct は行の任意の位置から始まる記法を追加します。BracketRule は [...] の中身の解釈を追加します。Extension はそれらをまとめ、parse に渡す単位です。記法を追加する
拡張関数は記法が成立しない位置で
null を返します。成立した場合はノードと消費した文字数を返します。位置情報はパーサーが付けます。
TypeScriptimport { parse } from "@cosense-toolbox/parser"import type { Extension, InlineConstruct } from "@cosense-toolbox/parser/extensions"const mention: InlineConstruct = (source, index) => { if (source[index] !== "@") return null const match = source.slice(index + 1).match(/^[A-Za-z0-9_-]+/) if (!match) return null return { node: { type: "internalLink", label: `@${match[0]}`, target: match[0] }, length: match[0].length + 1, }}const mentions: Extension = { constructs: [mention] }parse("メモ\n@qaynam に確認する", { extensions: [mentions] })拡張は既定のルールより先に試されます。既定の記法と同じ形を受け取る拡張を追加すると、その解釈を上書きできます。
テーブルセルの記法
テーブルセルでは既定でリンク記法だけを解析します。
tableCellNotation() を extensions に加えると、装飾などを含めてセル内の記法を解析できます。特定のノードだけをセルに残すには、拡張の
keepInTableCell で判定します。セル内の文字列を <br> に置き換える描画拡張 tableCellLineBreaks() は HTML への変換 を参照してください。独自の埋め込み
Cosense Web が埋め込まないサービスも、
BracketRule から独自の provider の embed ノードを返せば埋め込みとして扱えます。Apple Music、Instagram、地図を OpenStreetMap にする例は メディアと埋め込み にあります。独自ノード型
既存のノード型に当てはまらない記法は、
InlineNodeMap を declaration merging で拡張します。独自の type が走査や描画の型にも反映されます。
TypeScriptimport type { Position } from "@cosense-toolbox/parser"declare module "@cosense-toolbox/parser" { interface InlineNodeMap { mention: { type: "mention"; user: string; position: Position } }}描画時は
toHtml の handlers にそのノード型を追加します。独自ノードを追加したのにハンドラーがない場合、子ノードがあればその内容が出力されます。AST を検証する
@cosense-toolbox/parser/schema の decodePage は、Worker や postMessage など外部から受け取った値が Page の形かを検証します。通常の parse は必ず AST を返すため、外部データを扱う場合に使います。
TypeScriptimport { decodePage } from "@cosense-toolbox/parser/schema"import { Either } from "effect"const result = decodePage(JSON.parse(input))if (Either.isRight(result)) { const page = result.right}不具合や記法の不足を見つけた場合は GitHub の Issue で報告できます。