【VSCode】コードをHTMLやPDFに変換する拡張機能

2/17/2024

拡張機能

t f B! P L

今回は、Visual Studio Codeで書いたソースコードをハイライトされた状態で、HTML、PDFおよび画像に変換し、エクスポートできる拡張機能を作ったので、その紹介をさせていただきます。

概要

私は、見ての通りウェブサイトを運営しているため、書いたソースコードを記事に記載することが多々あります。

今までは、prism.jsやhighlight.jsなどのシンタックスハイライトを行うライブラリを使って、ソースコードを記載していましたが、あくまでシンタックスハイライトのみであり、Semantic Highlight(良い日本語がないため英語で記載)を行うことができません。

そこで、VSCode上のソースコードをそのままHTMLやPDFに変換し、出力できる拡張機能を作成しました。

Note

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(選択可)

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

コードを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の拡張機能を作ってみてください。

ここまでお読みいただき、ありがとうございました。