以前、Markdown内の数値をロケールごとの形式へ変換する「markdown-it-digit」を作りました。ただし、npmパッケージを公開しただけでは、Visual Studio CodeのMarkdownプレビューへ自動的に反映されません。
そこで、markdown-it-digit をVS Code標準のMarkdownプレビューから使えるようにする拡張機能「Markdown Digit」を開発しました。
この記事では、既存のmarkdown-itプラグインをVS Codeへ組み込む方法、拡張機能としてのテスト、初回公開に向けた配布内容の整理、GitHub Actionsによる自動公開、そして実際の公開処理で遭遇した認証エラーについてまとめます。
markdown-it-digitとは?
「markdown-it-digit」とは、Markdown内の数値をロケールごとの形式へ変換するmarkdown-itプラグインです。
$1234567${en} のような専用記法を使うことで、英語式の3桁区切りやインド式の桁区切り、日本語・中国語・韓国語・台湾向けの万進法表記へ変換できます。
markdown-it-digitの詳細については、以下の記事で詳しく紹介しています。

Markdownのソースを変えずに数値を読みやすくする
Markdown Digitが扱う記法は、元になった「markdown-it-digit」と同じです。
$1234567${en}この記法をMarkdownプレビューで表示すると、次のように変換されます。
1,234,567変換するのはレンダリング後のプレビューだけです。エディター内のMarkdownソースは書き換えません。また、通常の数値や未対応のロケール、コードブロック、インラインコード、URLなどは変換対象にしません。

対応する形式はen、in、jp、cn、kr、twの6種類です。英語式やインド式の桁区切りに加えて、日本語・中国語・韓国語・台湾向けの万進法表記を利用できます。
VS CodeのMarkdown拡張APIへ接続する
実装の中心は、とても小さなactivate関数です。
const markdownItDigit = require('markdown-it-digit');
function activate() {
return {
extendMarkdownIt(markdownIt) {
return markdownIt.use(markdownItDigit);
},
};
}package.jsonでmarkdown.markdownItPluginsを有効にすると、VS CodeのMarkdown機能からmarkdown-itインスタンスを受け取れます。そのインスタンスへmarkdown-it-digitを登録して返すだけで、標準プレビューのレンダリングに数値変換を加えられます。
独自のプレビュー画面やコマンドを作るのではなく、VS Codeが提供する拡張ポイントへ既存プラグインを接続する設計にしました。そのため、拡張機能側には数値解析やロケール変換のロジックを重複して持たせていません。
拡張機能として4つの動作を確認する
実装が短くても、VS Codeとの接続部分が正しく動くかは別に確認する必要があります。テストでは次の4点を検証しました。
activateがMarkdown拡張APIを公開すること- 渡された
markdown-itインスタンスを拡張して返すこと - 6種類すべてのロケールを正しく変換できること
- 通常の数値や無効な記法を変更しないこと
テストは@vscode/test-cliと@vscode/test-electronを使い、実際のVS Code拡張ホスト上で実行します。npm testの前にはESLintも実行する構成にし、最終確認ではLintと4件のテストがすべて成功しました。
初回公開に必要な情報を揃える
機能が動くだけではMarketplaceへ公開できません。1.0.0の準備では、manifestと利用者向け文書をまとめて整備しました。
- バージョンを
1.0.0へ更新 - Marketplaceのpublisher IDを登録
- PNGアイコンを
images/icon.pngとして登録 - 英語版と日本語版のREADMEを整備
- 対応ロケール、記法、変換されない領域を文書化
- CHANGELOGへ1.0.0の変更内容を追加
READMEでは「エディターのソースは変更しない」「コマンドや設定項目は持たない」という拡張機能の範囲も明記しました。できることだけでなく、しないことも書くことで、導入後の動作を想像しやすくしています。
開発途中には、manifestのnameとdisplayNameがどちらもリポジトリ名のvscode-markdown-digitになっているミスも見つかりました。リポジトリ名と拡張機能名を区別し、識別名をmarkdown-digit、利用者に表示する名前をMarkdown Digitへ修正しました。
VSIXへ不要な開発ファイルを含めない
vsce lsを使うと、生成されるVSIXに何が入るかを公開前に確認できます。
今回は.vscodeignoreを調整し、テスト、エディター設定、GitHub Actions、エージェント用の管理ファイルなどを配布対象から除外しました。最終的な対象は、日英README、manifest、LICENSE、実装、CHANGELOG、アイコン、実行時依存に絞っています。
拡張機能はインストール後に必要なものだけを配布し、開発やプロジェクト管理のためのファイルはリポジトリ側に残す方針です。
タグのpushから2つのMarketplaceへ公開する
公開作業は、v*形式のタグをpushするとGitHub Actionsが起動するようにしました。workflowでは次の順序で処理します。
- リポジトリをcheckoutする
npm ciでlockfileどおりに依存関係をインストールする- タグと
package.jsonのバージョンが一致するか確認する - Linux上で仮想ディスプレイを使ってテストする
- VSIXを生成する
- Visual Studio Marketplaceへ公開する
- Open VSXへ公開する
GitHub Actionsのリポジトリ権限はcontents: readに限定し、処理が停止し続けないよう15分のタイムアウトも設定しました。公開CLIはdevDependenciesとlockfileでバージョンを固定し、workflowからは--no-installを付けてローカル版だけを使います。
一度はCLIをnpx <package>形式へ変更し、公開前テストも外しました。しかし、固定したCLIを確実に使用できることと、公開直前にも動作を検証できることを優先し、この変更は打ち消しコミットで元に戻しました。共有済みの履歴を書き換えず、変更を取り消した経緯もGit上に残しています。
公開時にPATの認証エラーが発生した
実際にタグから公開workflowを動かしたところ、Visual Studio Marketplaceへの公開で認証エラーが発生しました。
The Personal Access Token verification has failed.
TF400813: The user is not authorized to access this resource.直前にはLinuxの資格情報ストアを開けないという警告も出ていましたが、処理を止めた原因はそちらではありません。Marketplaceへ渡したPATの認証または権限が問題でした。
認証情報を登録し直し、workflowを再実行できる状態まで整理しました。なお、Azure DevOpsのグローバルPATには廃止予定があるため、今後は長期間有効なSecretを置かず、Microsoft Entra IDのフェデレーション認証へ移行することも検討します。
開発を振り返って
Markdown Digitの拡張機能側のコードは小さくまとまりました。複雑な数値処理を「markdown-it-digit」へ集約し、VS Code側はMarkdownプレビューとの接続だけを担当させたためです。
一方で、初回公開では実装以外の確認が多くありました。manifestの名称、publisher、アイコン、日英README、VSIXの内容、タグとバージョンの一致、2つの公開先の認証など、どれか1つ欠けても公開作業は完了しません。
特に、拡張機能のコードが正しく動くことと、Marketplaceへ安全に公開できることは別の課題でした。公開前テスト、固定したCLI、最小権限、配布ファイルの確認をworkflowへ組み込んだことで、次回以降も同じ手順を再現できる形にしています。
今回の開発によって、markdown-it-digitの数値表記をVS Code標準のMarkdownプレビューから利用するための土台が整いました。
