Markdown から読む
ChatGPT の回答や README のような Markdown を、Cosense のページに貼れる記法のテキストや、Cosense の AST にします。
TypeScriptimport { markdownToCosenseText } from "@cosense-toolbox/markdown"markdownToCosenseText("## 予定\n\n- **会議**の資料を作る")// → "\n[**** 予定]\n [* 会議]の資料を作る"@cosense-toolbox/markdown
Markdown の文字列から読むなら、
@cosense-toolbox/markdown を使います。読み方は remark と同じです (CommonMark と GFM、$...$ の数式)。markdownToCosenseText(markdown, options?) → Cosense のページに貼れる記法のテキスト。1 行目はタイトルparseFromMarkdown(markdown, options?) → Cosense の AST。parse の結果と同じ型なので、HTML への変換 や AST のヘルパー にそのまま渡せます
TypeScript// ### の見出しを [** ] にするmarkdownToCosenseText(markdown, { extensions: [{ decoration: (output, node) => (node.sizeLevel === 2 ? output.replace("***", "**") : output) }],})Markdown との変換は、
@cosense-toolbox/parser とは別のパッケージにしています。Markdown を読む部品 (micromark) は大きいので、parser を使うだけの人に入らないようにするためです。fromMdast
fromMdast は、mdast (Markdown の AST) を Cosense の AST にします。markdownToCosenseText と parseFromMarkdown も中でこれを使っていて、記法の対応はここで決まります。remark を使っているアプリなら、手元の mdast をそのまま渡せます。
TypeScriptimport { toCosenseText } from "@cosense-toolbox/parser/compile"import { fromMdast } from "@cosense-toolbox/markdown"toCosenseText(fromMdast(mdast))記法の対応
## 見出し → [**** 見出し]。# が 1 つ増えるごとに大きさが 1 段下がり、##### 以降は [* ]箇条書き → 字下げ。入れ子は深い字下げ
番号付きの箇条書き → 番号を残した字下げ (
1. )タスク (
- [ ] - [x]) → ☐ ☑ の印を付けた字下げ**太字** *斜体* ~~打ち消し~~ → [* ] [/ ] [- ]。ちょうど重なった装飾は [*/ ] のように記号をまとめますインラインコード → そのまま。コードの中の改行は空白にして 1 行に収めます
[ラベル](URL) → [ラベル URL]。http でない URL (相対パスやアンカー) は、Cosense ではリンクにならないので文字だけ画像 →
[画像の URL]。リンク付きの画像は [リンク先 画像の URL]フェンス →
code:言語名。言語名の後ろにファイル名があればファイル名、どちらも無ければ code:text表 →
table:table。セルの中の装飾も読みます引用 →
> の行$数式$ $$数式$$ → [$ 数式] (下の「数式」)区切り線 → 空行
Cosense の装飾は入れ子にできないので、装飾の中の装飾は記号を外します (装飾の中のリンクは残します)。装飾と見出しの中のインラインコードも、Cosense は装飾の中のバッククォートをコードとして読まないので、バッククォートを外した文字にします。
ブロックの間は Cosense の書きかたに合わせます。段落どうしの間は空行にし、見出しのすぐ後と、箇条書きの前には空行を挟みません。ただし、コードブロックと表のすぐ後に、それより深い字下げの行 (箇条書きなど) が来るときは空行で区切ります。Cosense ではコードブロックと表が、後ろに続く深い字下げの行を自分の中身として読むからです。引用や項目の中で終わったコードブロックでも同じです。
Markdown の文字は、Markdown のとおり文字のノードになります。
[ページ] や #タグ を Cosense のリンクとして読み直すことはしません。ただし、Cosense の記法には逃がし (エスケープ) が無いので、toCosenseText で書き出したテキストを Cosense に貼ると、Cosense はそれをリンクやタグとして読みます。タイトル
Markdown の先頭が
# の見出しなら、それがページのタイトル (1 行目) になります。先頭が見出しでなければ、タイトルは空になります。2 つ目からの # の見出しは [***** ] になります。数式
数式は CommonMark にも GFM にも無い拡張です。
@cosense-toolbox/markdown は、広く使われている pandoc の決まりに合わせ、次のどれかに当てはまる $...$ を数式にせず、文字のまま残します。開く
$ のすぐ後が空白閉じる
$ のすぐ前が空白閉じる
$ のすぐ後が数字そのため、
$x^2$ は [$ x^2] になり、$5と$10 や $5 と $10 は文字のまま残ります。$$...$$ は値段と紛れないので、いつも数式にします。$ を一切数式として読まないときは、math: false を渡します。$ も $$ も文字のまま残ります。
TypeScriptmarkdownToCosenseText("$x^2$", { math: false }) // → "\n$x^2$"位置情報
ノードの
position は、元になった Markdown のノードの位置を指します。段落の中の改行で分けた行のように、1 つの Markdown のノードから複数のノードを作ったときは、どれも同じ位置を持ちます。空行や箇条書きの番号のように Markdown に無いノードは、隣のノードの始まりに幅 0 で置きます。