1

VSCode拡張機能作った

76
0
$$$$

作りました

作りました.

記事公開先はどっちかというとQiitaとかZennのほうが適切かもしれませんがMathlogの拡張なんでMathlogでUpします.

修正記録

9/24 一部フォーマット仕様を修正. 追記9/24 を確認

Mathlog for VSCode 拡張仕様

Mathlogの記事をVisual Studio Codeで書くための非公式拡張です.記事本文の意味を変えない整形,Mathlog本体に寄せたローカルプレビュー,入力時の色分けと診断を提供します.

インストール

Visual Studio Marketplace

Mat-tom-ja.mathlog-vscode-extension

GitHub

mathlog-vscode-extension-releases

対応バージョン

VSCode 1.136.0以降.
Linux,Windowsで簡易動作確認済.

使い方

  1. .mathlogmdファイルを作成または開きます.
  2. Mathlog: Open Previewでプレビューを開きます.編集は既定200ms後に反映され,エディタとプレビューはスクロール同期します.
  3. Shift+Alt+F(Format Document)で本文を整形します.(LinuxはCtrl+Shift+I)
  4. プレビューの配色はMathlog: Select Preview Themeでeditor・light・darkから選べます.

Format Document Format Document

Mathlog preview Mathlog preview

ファイル形式

専用拡張子として.mathlogmd , .mathlogmacros という2つの独自ファイル拡張子を用意しています.(.mathlogmdは.txt,.mdでも利用可能)

  • .mathlogmd : 記事本体
  • .mathlogmacros : texマクロを記載するファイル. tex標準拡張機能との衝突回避のために.texではなく独自拡張子として実装しています.本文は数式として整形し,定義コマンド・マクロ・引数・コメントをテーマの色で着色します(プレビューは対象外).

参考文献には.bibを利用します.

対応する記事構造

分類例フォーマットプレビュー
TeX$ $
$$ $$
空白・括弧・折り返しを整えるMathJaxでSVGへ描画
形式ブロック&&&def title〜&&&内部(contents)をフォーマット本文をMarkdownとして整形
Markdown見出し#
箇条書き-
tab揃えなどを行うmarkdown-itでHTMLへ変換
HTML<span>
<div>
タグと属性を保持一部属性限定で描画
アノテーション<!-- mathlog-format: ... -->
% mathlog-format: ...
拡張機能を制御する独自構文
(コメントアウト)
本文に出さない

使用技術

実行時の依存は,Node.js上で動くJavaScriptライブラリに限定する.

動作層ライブラリ用途
実行時prettier・@prettier/syncMarkdownと表の整形
実行時markdown-itプレビューのMarkdown変換
実行時mathjax数式のSVG描画(外部CDNは使わない)
実行時refaアノテーション正規表現のまとめ
開発時@vscode/test-cli・@vscode/test-electronVSCode統合テスト
開発時playwrightブラウザ試験と公式表示の取得
開発時vscode-textmate・vscode-oniguruma文法スコープの確認
開発時pngjs・pixelmatch・parse5画像比較とDOM正規化
開発時PaddleOCROCR評価(Pythonの外部ツール)
開発時mocha単体テストの実行
開発時eslint静的検査

拡張本体への同梱は,動作層が実行時であるものに限る.開発時のものは配布物に含まれない.
拡張本体はTypeScriptで実装し,実行時はVSCode API以外の外部サービスへ接続しない.

フォーマット仕様

記事本文の意味を変えないことを優先し,判断できない箇所は変更しない.

  • 本文には表示目的の物理改行を追加しない.Mathlogでは物理改行がそのまま改行になるため,折り返しはエディタの右端に任せる.
  • 数式は80文字を目安に折り返し,TeXコマンドを途中で分割しない.可視の括弧・角括弧・波括弧・カンマと中置記号の前後の空白を1つに統一する.
  • 長い数式は括弧の展開を優先する.align・eqnarray・arrayは&の列と行末の\\を揃える.
  • 全角ASCII・全角記号・全角空白は対応する半角へ置換する(インラインコードとコードブロックの内容は保持.,と.は対象外).
  • mathlog-format:アノテーションで,範囲ごとに改行の禁止(no-break)・空白の削除(no-whitespace)・整形からの保護(no-format)を指定できる.

行長の上限,小スコープの閾値,全角置換の範囲は設定(mathlog.formatting.*)で変更できる.

ハイライト仕様

TextMate文法で構文を識別し,色はVSCodeのテーマが決めます.既定テーマが色を持たない表の区切り・水平線・宣言ラベルには,拡張が薄いグレーを与えます.

構文色の出どころ無効化設定
見出しテーマ-
数式(インライン・表示・LaTeX環境)テーマ-
形式ブロックの境界と種類テーマ-
コメント(HTMLコメント・数式内の%)テーマ-
リンクテーマ(リンク色)links
画像テーマlinks
箇条書きテーマlists
引用テーマquotes
表の区切り既定色(薄いグレー)tables
水平線既定色(薄いグレー)horizontalRules
宣言ラベル[label]既定色(薄いグレー)labels
参照[[label]]テーマ(リンク色)labels
HTML<span>
<div>
html
コード(フェンス・インライン・タブ字下げ)テーマcode

無効化はmathlog.highlighting.disabledDecorationsへカテゴリ名を入れて行います.mathlog.highlighting.insideFormalBlocksをfalseにすると,形式ブロック本文の装飾(箇条書き・引用・表・水平線・ラベル・リンク・HTML・コード)をまとめて無効化できます.

文字装飾(**太字**など)はエディタでは既定で無色で,プレビューでは反映します.

プレビュー仕様

Mathlog: Open PreviewでWebviewを開く.編集から既定200ms後に本文を再変換し,MathJaxの描画中に変更が続いた場合は最新の1件だけを描画する.mathlog.preview.updateDelayは0〜2000msで変更可能.
Markdownはmarkdown-itで変換し,形式ブロック,ラベル参照,Mathlog固有の箇条書き,表,引用,限定的なHTMLを処理する.HTMLはspanとdivのclass,data-*,styleのcolorだけを許可し,それ以外はエスケープする.<br>は改行として許可する.
MathJaxは同梱の3.2系tex-svgを使う.\\tag,\\label,\\ref,\\eqrefは同じプレビュー内で解決するが,\\tagのない式には自動連番を付けない.形式ブロック番号と数式番号は連動しない.
プレビューの配色はeditor,light,darkから選択.エディタとプレビューは元の行番号とブロック単位の位置を使って双方向にスクロール同期する.
XyJax,TikZ,Mathlog独自マクロのうち未登録のものは対象外.解析に失敗した数式はMathJaxのエラー表示として描画し,原稿は変更しない.

診断とリソース

診断は純粋な解析結果をVSCodeのProblemsパネルへ変換する.

診断条件重大度
未定義ラベル[[label]]の参照先が,見出し・形式ブロック・数式のラベル,参考文献キーのどれにもないWarning
未定義マクロ\nameが,同梱MathJaxのコマンド・登録済みコマンド・マクロファイル・本文中の定義のどれにもないWarning
未定義参考文献キー\cite{key}のkeyが参考文献ファイルにないWarning
未閉鎖構文コードフェンス・形式ブロック・数式・LaTeX環境がファイル末尾までに閉じられていないWarning
不正なアノテーションmathlog-format:の正規表現がコンパイルできないError

ワークスペース共通のマクロは既定.mathlog-macros,参考文献は既定.mathlog-bibliography.bibから読み込む.mathlog.resources.macrosとmathlog.resources.bibliographyで複数パスを指定でき,存在しないファイルは無視する.記事ごとの追加は次のHTMLコメントで宣言する.

      <!-- mathlog-macros: macros.mathlogmacros -->
<!-- mathlog-bibliography: references.bib -->
    

マクロは\\newcommand,\\renewcommand,\\defを解析し,補完・診断・プレビューへ渡す.プレビューを開いた後に追加したマクロは反映されるが,削除した定義はプレビューを開き直すまで残る.

テスト仕様

テストは以下の観点で実施.

区分確認内容CI実行
単体フォーマッタ(記事とマクロファイル),スコープとセマンティックトークン,テーマ整合,診断,補完,プレビューのHTML生成とマスク計算有
統合VSCode API,コマンド,診断の表示,プレビューの起動有
ブラウザWebviewを実ブラウザで描画し,レイアウト・更新・MathJaxマクロを確認無
ゴールデン保存済みの公式PNG・正規化DOMとローカル描画の比較無
フォーマッタ評価352件の整形結果を公式表示と比較し,OCRと画像差で評価無
描画保持350件について,整形の前後でMathlogの描画が変わらないことを確認無
ツール単体取得・比較ツール自身のテスト有

評価基準

プレビューなど画像判定が関与するテストケースに対してはpriorityScoreを設定し,2以下をOK判定としています.
priorityScoreは複数の判定項目に異なる点数を付与し,その合計値です.
例えばOCRでの文字列比較には4点の重みをつけ,非一致である場合判定NG.(TOLERATED例外有)
PASSまたはTOLERATEDをOK判定としています.

判定点数扱い
PASS0一致
TOLERATED1〜2画像判定NGのみ,仕様上NG許容など
NG3以上修正対象

評価結果

区分件数OKTOLERATEDNG
単体381381-0
統合1515-0
ブラウザ1818-0
ツール単体5252-0
ゴールデン1111-0
フォーマッタ評価352340120
描画保持350334151

描画保持のNG 1件は\begin{align}に対して\end{array}が書かれた箇所を,仕様どおり\end{align}まで数式として整形するために描画がわずかに動く既知のケースで,許容としております.機械的にTOLERATED判定を追加するのも悩ましい描画の穴をついたテストケースのため,意図的にNG判定を残しています.
また本結果はベースライン完成時点での集計結果であり,実際のリリースバージョンでNG判定が発生している可能性があることについてご了承ください.これは画像系のテスト項目全件実施に3時間程度かかってしまうので評価頻度を妥協しているためです.

設定

設定既定内容
mathlog.formatting.additionalInfixSymbols[]中置記号として扱う記号を追加する
mathlog.formatting.mathBracketOpeningStyle"nextLine"長い数式を展開するときの開始括弧の位置
mathlog.formatting.mathLineLimit80数式の折り返しの目安
mathlog.formatting.mathSmallScopePointLimit10括弧展開の対象から外す小スコープの閾値
mathlog.formatting.fullWidthNormalization各グループtrue全角類似文字の置換(グループ単位で無効化できる)
mathlog.formatting.characterReplacements[]追加の文字置換(例: 、→,)
mathlog.preview.colorTheme"editor"プレビューの配色(editor・light・dark)
mathlog.preview.updateDelay200編集からプレビュー更新までの待ち時間(ms)
mathlog.highlighting.disabledDecorations[]色付けをやめるカテゴリ
mathlog.highlighting.insideFormalBlockstrue形式ブロック本文の装飾を色付けする
mathlog.resources.macros[".mathlog-macros"]読み込むマクロファイル
mathlog.resources.bibliography[".mathlog-bibliography.bib"]読み込む参考文献ファイル

既知の制限

  • Mathlog本体のXyJaxを同梱しないため,xy環境と\\xymatrixは描画しない.
  • HTML要素を組み合わせたレイアウトは再現しない.
  • エディタの色付けはVSCodeテーマに依存する.
  • Mathlogへの投稿・同期と記事の自動公開は行わない.貼り付けたあと,マクロと参考文献はブラウザ側で入力する必要がある.
  • 公式画像との差分はフォント,ブラウザ,スクロール領域の違いにより残る場合がある.

以上が本拡張機能の概要です.


制作背景

なぜ作ったか?

なかったから.VSCodeの拡張機能が.

拡張機能の価値

Mathlog公式の下書き機能でも問題はないのですが,以下の部分でVSCode上での執筆ができることの価値が有りました.

項目MathlogVSCode(+本拡張)
フォーマットなしあり
ハイライトなし色分けにより可読性向上
構文エラー数式の描画エラーより豊富に実装:未定義ラベル・マクロ・参考文献キー,
閉じ忘れ,不正なアノテーション
自動置換-,・.を,・.へ自動置換
(characterReplacementsで任意の置換も追加可)
バージョン管理-Git/GitHubが使える
校正-Copilot・Codexなどで添削できる
入力支援形式ブロック等GUIで挿入可能
$などの自動閉じetc.
左記に加えスニペット使用可能
オフライン不可(変更を保存できない)可(MathJax同梱,外部CDNへ接続しない)
gitでローカルコミット可能
画像都度アップロードするため管理がしにくいフォルダにまとめておくことで管理しやすい

逆に,VSCode上で作業することでブラウザへのアップロードの手間が増えるので完全な上位互換では有りません.トレードオフは発生します.
とはいえGit/GitHubでのバージョン管理,フォーマット,更にはAIに添削をさせることができるという点で,本拡張機能の開発の価値は大いにあると判断しました.

免責事項について

拡張機能の説明に記載しておきましたのでご一読のうえ利用ください.
Mat-tom-ja.mathlog-vscode-extension

その他

自分用に作ったやつなので更新改善のペースはかなり遅いと思われます.
CICDも完璧に作り込めてるとまでは言えないので定期更新の仕組み組んでるとかそういう感じでもないです.
ただ明確な不具合やもっとこうしたらいいんじゃない?等あったらコメント歓迎です.
本来単にMathlogの記事をつらつら書いてたんですが,「やってらんねぇ〜〜〜!」と正直なってしまい,作りました笑.本来やりたかったMathlogの執筆作業に戻りたいと思います.


9/24追記

箇条書きと数式の組み合わせに関するフォーマット仕様を修正しました.

文章の後ろで始めた長い数式を複数行へ展開するとき,開始の$だけがタブ字下げされた行へ落としていました.Mathlogは箇条書き項目内のタブ字下げされた$だけの行を数式として読まないため,プレビューの数式と本文がズレます.

リリース直前に意図して入れた変更だったのですがフォーマット前後で描画を崩してしまう誤った修正だったため,取り消しました.

入力例:

      
- 補題 $a_{1} + a_{2} + \cdots + a_{10} = b_{1} + b_{2} + \cdots + b_{10} + c_{1} + c_{2} + \cdots + c_{10}$ が成り立つ.

    

公式の描画 公式の描画

修正前フォーマット仕様:

      
- 補題

    $

    a_{1} + a_{2} + \cdots + a_{10} = b_{1} + b_{2} + \cdots + b_{10} + c_{1} +

        c_{2} + \cdots + c_{10}

    $ が成り立つ.

    

公式の描画 公式の描画

修正後フォーマット仕様:

      
- 補題 $

    a_{1} + a_{2} + \cdots + a_{10} = b_{1} + b_{2} + \cdots + b_{10} + c_{1} +

        c_{2} + \cdots + c_{10}

    $ が成り立つ.

    

公式の描画 公式の描画

1つの項目に数式が2つある場合も同じで,2つ目の$も直前の本文と同じ行へ残します.修正後の出力は再整形しても変化しません.

あと雛形作りました.とても簡素な作りですがもし使いたい方がいれば.
https://github.com/Mat-tom-ja/mathlog-template

投稿日:16日前
更新日:14日前
数学の力で現場を変える アルゴリズムエンジニア募集 - Mathlog served by OptHub

この記事を高評価した人

高評価したユーザはいません

この記事に送られたバッジ

バッジはありません。

投稿者

Mattom
Mattom
1
139
趣味レベルで数学の勉強、やり直そうと思って始めました。

コメント

他の人のコメント

コメントはありません。
読み込み中...
読み込み中