今回は、Visual Studio Codeで書いたソースコードをハイライトされた状態で、HTML、PDFおよび画像に変換し、エクスポートできる拡張機能を作ったので、その紹介をさせていただきます。
概要
私は、見ての通りウェブサイトを運営しているため、書いたソースコードを記事に記載することが多々あります。
今までは、prism.jsやhighlight.jsなどのシンタックスハイライトを行うライブラリを使って、ソースコードを記載していましたが、あくまでシンタックスハイライトのみであり、Semantic Highlight(良い日本語がないため英語で記載)を行うことができません。
そこで、VSCode上のソースコードをそのままHTMLやPDFに変換し、出力できる拡張機能を作成しました。
Syntax Highlight(シンタックスハイライト)とは、プログラムのソースコードを色分けして表示することで、プログラムの構造を視覚的に理解しやすくするための技術です。
しかしながら、あくまで正規表現を使って特定の文字列を色分けするだけであり、Semantic Highlightのように、ソースコードの本質を理解して色分けすることはできません。
Semantic Highlightは、プログラムのソースコードを解析し、変数や関数などの意味を理解して色分けする技術であり、VSCodeでは、言語サーバープロトコル(LSP)を用いて、コードに関する追加の情報を提供し、単純なシンタックスハイライトを超えた機能を実現しています。
機能
この拡張機能には、以下の機能があります。
- エディタ上のソースコードをHTMLに変換し、出力する機能
- エディタ上のソースコードをPDFに変換し、出力する機能
- エディタ上のソースコードを画像に変換し、出力する機能
インストール
VSCodeの拡張機能タブから、CodeToHTML
と検索し、インストールしてください。
または、Visual Studio Marketplaceからインストールすることもできます。
ソースコードは、GitHubにて公開しています。
使い方
今回は以下のソースコードを変換してみます。
class Person {
constructor(name = "Anonymous") {
this.name = name;
}
introduce() {
console.log(`Hello, my name is ${this.name}`);
}
}
const person = new Person();
person.introduce(); // Hello, my name is Anonymous
- 変換したいソースコードを開きます。
Ctrl + Shift + P
を押しコマンドパレットを開きます。- コマンドパレットに
CodeToHTML
と入力し、[CodeToHTML] Code to HTML
を選択します。 - Webviewが開き、HTMLコードが表示されます。
コードをHTMLに変換する
デフォルトでCode To HTML
が選択されているため、お好みで設定を変更して、Download
を選択すると、HTMLファイルがダウンロードされます。
Copy
でクリップボードにコピーすることもできます。
それぞれの設定は以下の通りです。
- Structure: ソースコードの構造を変更します。
- html > body > div
- htmlおよびbodyタグに囲われたdivベースの構造 (改行はbrタグ)
- html > body > pre
- htmlおよびbodyタグに囲われたpreベースの構造
- html > body > pre > code
- htmlおよびbodyタグに囲われたpre > codeベースの構造
- div
- divタグのみで囲まれた構造 (改行はbrタグ)
- pre
- preタグのみで囲まれた構造
- pre > code
- pre > codeタグのみで囲まれた構造
- Text Wrap: ソースコードの折り返しを変更します。
- None
- 折り返しなし
- Normal
- 通常の折り返し(折り返しが先頭から始まる)
- Smart
- インデントに合わせた折り返し(その行の先頭に空白がある場合、折り返しにも空白が入る)
- Max Length: 折り返しする最大文字数を変更します。
html > body > div
の変換結果は以下の通りです。
エクスポートされたHTML(選択可)
コードをPDFに変換する
Code To PDF
を選択し、Download
を選択すると、PDFファイルがダウンロードされます。
それぞれの設定は以下の通りです。
- Font(.ttf): フォントを変更します。
- Text Wrap: ソースコードの折り返しを変更します。(詳しくはHTMLの説明を参照)
- Max Length: 折り返しする最大文字数を変更します。(詳しくはHTMLの説明を参照)
フォントについてですが、デフォルトでは、courier
が選択されていますが、日本語が出力できません。
そのため、英語と日本語の両方を出力できるフォントを選択してください。
FontForgeなどのツールを使って、VSCode標準のフォントであるConsolas
と日本語フォントを組み合わせたフォントを作成することもできますし、元から英語と日本語の両方を出力できるプログラミング向けのフォント(例えばPlemolJPなど)を使うこともできます。
コードを画像に変換する
Code To Image
を選択し、Download
を選択すると、画像ファイルがダウンロードされます。
それぞれの設定は以下の通りです。
- Image Type: 画像の形式を変更します。
- png
- jpeg
- svg
- Text Wrap: ソースコードの折り返しを変更します。(詳しくはHTMLの説明を参照)
- Max Length: 折り返しする最大文字数を変更します。(詳しくはHTMLの説明を参照)
まとめ
今回は、VSCodeのエディタ上のソースコードをHTMLやPDFに変換し、出力することができる拡張機能について紹介しました。
制作の経緯と動作原理についても記載しましたので、もしご興味があれば、ご覧いただければ幸いです。
制作の経緯
初期の案では、VSCodeのエディタ上のトークン化されたソースコードから、それぞれのトークンの色を取得し、HTMLに変換することを考えていました。
しかし、VSCodeのAPIには、トークン化されたソースコードを取得するためのAPIがなく、トークンの色を取得するためのAPIもありませんでした。(GitHubのVSCodeのリポジトリにこの件に関連するIssueが色々立ってました)
例えば、Developer: Inspect Editor Tokens and Scopes
というコマンドがあります。
このコマンドを実行すると、GUI上にそのトークンのTextMateおよびSemantic Highlightの情報が表示されますが、これを取得するためのAPIは無さそうでした。
仕方がないので、自分でトークン化し、色を取得するためのプログラムを実装することにしたのですが、残念ながら、トークン化しTextMateのルールに従って色を取得するまではできたものの、結局シンタックスハイライトのみしか行えなく、Semantic Highlightはできませんでした。
参考: https://github.com/microsoft/vscode-textmate
ちなみに、余談ですが、これをブラウザ上でも動かせるmonaco-textmateというライブラリを見つけました。
これを使って、ブラウザ上でSyntax Highlightを任意で行うことができるようなので、prism.jsやhighlight.jsの代わりに使えるライブラリを作ろうかなと一瞬考えましたが、めんどくさいので、誰か作ってくれないかなと思っています。
その後、言語サーバープロトコルの勉強を始めようかと思っていたのですが、さすがに私には難しすぎたので、あきらめようかと思っていたところ、 VSCodeにハイライトされた状態のソースコードをリッチテキスト形式でクリップボードにコピーするコマンドがあるとこに気がつきました。
参考: https://stackoverflow.com/questions/35660927/how-to-copy-formatted-code-to-clipboard-in-vs-code
しかし、これがまた厄介で、存在するのはクリップボード上のリッチテキストなので、rtfファイルからHTMLに変換するライブラリが使えず、なかなかうまくいきませんでした。
無理かと思いつつ、Stack
Overflowを眺めていると、なんとDataTransfer.getData()
およびDataTransfer.setData()
にて、text/plain
だけでなく、text/html
を指定することで、クリップボード上のリッチテキストをHTMLに変換することができるという情報を得ました。
Mozillaのリファレンスにも記載がなかったため、半信半疑でしたが、実際に試してみると、rtfのデータをHTMLに変換することができ、これにより、VSCodeのエディタ上のソースコードをHTMLに変換することができるようになりました。
あとは、なんやかんやで、HTMLをPDFや画像に変換するライブラリを使い(うまく動かなかったのでHTMLのパースの処理は書くことになりましたが)、拡張機能が完成しました。
いろいろ躓くところがありましたが、ひとまず完成してよかったです。
余談ですが、VSCodeの拡張機能の公開は、ブラウザの拡張機能の公開よりもはるかに簡単で、公開するための審査もないため、誰でも簡単に公開することができます。
なので、もし興味があれば、ぜひVSCodeの拡張機能を作ってみてください。
ここまでお読みいただき、ありがとうございました。