
2025/12/23 19:28
**組み込みシンタックスハイライト機能付きフォント(2024)**
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
## Summary この記事では、COLRテーブルとコンテキスト別代替(contextual alternates)を利用して、OpenTypeフォントに直接構文ハイライト機能を埋め込む方法を紹介しています。これにより、コードスニペットはJavaScriptやCSSテーマなしでレンダリングできます。 改変された Monaspace Krypton フォント(`FontWithASyntaxHighlighter-Regular.woff2`)には、キーワード文字を色付きバリアントへ置き換えるチェーン置換(ALT_SUBS)によるカラ―グリフとルックアップテーブルが含まれています。コメントは有限状態機械(finite‑state‑machine)スタイルのルックアップで処理され、CSS/HTML の関数やタグは「ユニバーサル」ルックアップ(`CssParamCalt`)を使って最大25文字までの名前と `(` を一致させる代替グリフクラスでハイライトされます。 フォントには niutech によって追加された 2 つのカラーテーマ(Night Owl と Light Owl)が含まれています。テーマを切り替えるには、glyphs ファイルを編集し `fontmake` で再構築する必要があります。 使用方法は簡単です。フォントを読み込むために次の CSS を追加します。 ```css @font-face { font-family:'FontWithASyntaxHighlighter'; src:url('/FontWithASyntaxHighlighter-Regular.woff2') format('woff2'); } code{font-family:"FontWithASyntaxHighlighter",monospace;}
これにより
<pre>、<code>、<textarea>、および <input> 要素で動作し、高速レンダリングとクリーンな HTML を提供し、約 94 % のブラウザ互換性を実現します。
メリット: JavaScript 不要、CSS オーバーライドによるテーマ変更が可能、幅広いブラウザでの互換性。
デメリット: OpenType 対応環境に限定され、フォント編集が必要、基本的なパターンマッチング(正規表現非対応)、複数行ハイライト不可、手動改行でコメント/文字列ルールが崩れる。
この技術はすでに Holograph、@celine/celine、Shaders art、Mdit、構文ハイライト付き textarea コンポーネント、および OpenType TEX ハイライターなどのプロジェクトで使用されています。将来的には harfbuzz‑wasm を用いた実際のパーサーにルックアップ規則を置き換えることで現在の制限を解消できる可能性があります。
Monaspace のソースは SIL v1.1 ライセンス下で配布され、コード例は MIT ライセンスです。小型 sandbox ウェブコンポーネントは GitHub (
https://github.com/hlotvonen/tinybox) で公開されています。
本文
手書きウェブサイトでの構文ハイライト
問題点
フレームワークやジェネレーター、DOM 操作スクリプトを使わずにウェブサイトを手書きする場合、最も難しい部分は コードスニペットの構文ハイライト です。
典型的な解決策としては Prism や highlight.js のような JavaScript ライブラリがあり、これらはコードを走査して
<span> タグに CSS クラスを付与します。しかし、その分余計な複雑さとボリュームが増えてしまいます。
アイデア:フォントベースの構文ハイライト
JavaScript でマークアップを注入する代わりに、色付き文字列を カスタムフォント に埋め込む方法です。
- COLR テーブル – 各文字ごとに色付きグリフを作成。
- コンテキストオルタネート (calt) – 文字列(例:キーワード)をその色付きバージョンで置き換え。
結果として
<pre><code> 内はプレーンテキストのままで、JS は不要。ハイライトできるフォントだけが必要です。
動作原理
| 機能 | 目的 |
|---|---|
| COLR テーブル | 各グリフの複数色バージョンを保持。 |
| コンテキストオルタネート | 周囲文字に応じてグリフを置換(例: → )。 |
キーワード if のハイライト例
sub i' f by i.alt2; sub i.alt2 f' by f.alt2;
キーワード代替テーブル
ALT_SUBS で各文字を色付き対応に置換。個別キーワード(例:console, function)はこのテーブルから構築されます。
より複雑なシンタックスへの対処
| 構文 | アプローチ |
|---|---|
| CSS/HTML タグと属性 | 「長い未知長」ルールを使用:許可された文字クラスを最長名まで繰り返し、トリガー(例 )で終了。 |
| コメント/文字列 | 開始デリミタから閉じデリミタまでの範囲を色付けする有限状態機械風ルックアップ。 |
利点
- JavaScript 不要 – 純粋な CSS + フォントで実現。
- 高速レンダリング – テキストエンジンが処理。
- マークアップがクリーン –
内に<pre><code>
を挿入せず。<span> - テーマ変更容易 –
で色を上書き(約 94 % のブラウザ対応)。@override-colors - OpenType 対応環境ならどこでも動作 – InDesign、Web、さらには
/<textarea>
まで。<input> - 軽量 – ライブラリファイルは不要。
欠点
| 制限 | 詳細 |
|---|---|
| フォント編集が必要 | 新しい言語やスタイルを追加する場合、フォントを再構築。 |
| OpenType サポート必須 | PowerPoint など一部プログラムは COLR/calt を非対応。 |
| パターンマッチング制限 | 正規表現は使えず、単純なコンテキストルールのみ。 |
| 複数行トークン | 長いコメントや文字列が改行で途切れるとハイライトが崩れる。 |
| 完全解析不可 | エッジケースでは正しく色付けされない可能性あり。 |
テーマのカスタマイズ
(112〜120 行)でパレット値を変更。FontWithASyntaxHighlighter.glyphs
で再構築。fontmake- CSS で色を上書き:
@override-colors { --colr-0: #ff8c00; /* 例 */ }
代替ビルトインテーマ
GitHub ページに Night Owl と Light Owl のテーマが用意されています。
フォントの使用方法
<link rel="preload" href="/FontWithASyntaxHighlighter-Regular.woff2" as="font" type="font/woff2" crossorigin> <style> @font-face { font-family: 'FontWithASyntaxHighlighter'; src: url('/FontWithASyntaxHighlighter-Regular.woff2') format('woff2'); } code { font-family: "FontWithASyntaxHighlighter", monospace; } </style>
これで
<pre><code> ブロックが自動的にハイライト表示されます。
フォントを利用したプロジェクト
- Holograph(ビジュアルコーディングツール)
- @celine/celine(リアクティブ HTML ノートブック)
- 純 CSS で作るシェーダーアート
- Mdit(Markdown プレビュー)
- Tinybox ウェブコンポーネント(ハイライト付き textarea)
今後の展望
- Harfbuzz‑wasm:実際のパーサを用いて完全な正確性を目指す。
- より強力な状態機械:複数行トークンを堅牢に処理。
ライセンスとリソース
| アイテム | ライセンス |
|---|---|
| オリジナル MonaSpace フォント | SIL Open Font License v1.1 |
| コード例 / Tinybox コンポーネント | MIT |
- GitHub に UFO、Glyphs ソースファイルを公開
でフォントビルドfontmake- OpenType Cookbook と機能ファイル仕様
お問い合わせ・フィードバック
E‑mail: hlotvonen@gmail.com
Mastodon: @hlotvonen
フォントを使ったアイデア、改善提案、あるいはプロジェクトでの利用例があればぜひご連絡ください!