remark-siunit
v1.0.0
Published
LaTeX siunitx reimplemented as a remark-directive plugin for Astro: :si[value]{unit=...}, :num[value], :unit[...], and a ::si-scope container for local sisetup-style overrides.
Readme
remark-siunit
LaTeX の siunitx を Astro (remark-directive) 向けに再実装したプラグインです。 提示された全表(基本単位・固有名称を持つ組立単位・非SI単位・SI接頭辞・単位略語・2進接頭辞)を サポートしています。
設計方針:略語を全部書き出さない
Unit abbreviations 表には \kWh \GeV \uF など100個近い組み合わせがありますが、これを
1つずつハードコードするのではなく、「接頭辞」と「単位」を別々のテーブルとして持ち、
実行時に分解・合成する方式にしました(src/units-data.mjs の4テーブルのみが真のデータで、
src/parse-unit.mjs のresolveBareUnit()が任意の組み合わせを解決します)。
これにより:
- 表にある組み合わせ(
kWh,GeV,uF,kg,hPa...)はもちろん - 表にない組み合わせ(
Tmol,zJ,Yg...)も自動的に使える
という、実際のsiunitxの内部動作(\kilo\gramのように接頭辞と単位を独立に組み合わせる)
に近い挙動になっています。
kgの特例
SIの基本単位は「キログラム」ですが、接頭辞は歴史的経緯で「グラム」に付きます
(ミリグラムはmgであってmkgではない)。units-data.mjsではkilogram(基本単位、kg)と
gram(接頭辞を付けられる単位、g)を別エントリとして持たせることでこれを再現しています。
µ の入力しづらさ
micro接頭辞はSI記号としてはµですが、キーボードで打ちにくいためuもエイリアスとして
受け付けます(ug = µg、ul = µLなど、Unit abbreviationsの\ugスタイルに対応)。
ディレクティブ
| 構文 | LaTeX相当 | 説明 |
|---|---|---|
| :si[9.8]{unit="m/s^2"} | \SI{9.8}{\metre\per\second\squared} | 数値+単位 |
| :num[1234.5] | \num{1234.5} | 数値のみ(桁区切り等の書式のみ適用) |
| :unit[kg.m/s^2] | \si{\kilogram\metre\per\second\squared} | 単位のみ |
| :::si-scope{...} ... ::: | {\sisetup{...} ...} | ブロック内だけ設定を上書き |
単位文字列の文法
kg.m/s^2 -> kg·m·s⁻² (掛け算は "." または "*"、"/"以降は分母)
km/h -> km·h⁻¹
square.metre -> m² ( \square 相当のショートカット)
cubic.metre -> m³ ( \cubic 相当)
metre.per.second のような英語名の連結も可("per"は特別扱いしていないため
"/" で区切ってください: "metre/second")指数は明示的な^のみサポートします(m^2。\tothe{n}相当)。単位記号が数字で終わることは
ないため曖昧さはありませんが、\square/\cubic以外のASCIIショートカット(裸のm2)は
意図的にサポートしていません(誤読を避けるため)。
設定(\sisetup相当)
{
decimalMarker: '.', // 小数点記号
groupDigits: true, // 桁区切りの有無
groupMinDigits: 5, // これ未満の桁数は区切らない
groupSeparator: '\u2009', // 桁区切り文字(既定: 細いスペース)
perMode: 'power', // 'power' (m·s⁻¹) | 'symbol' (分母1項なら m/s)
unitSeparator: '\u00B7', // 複数単位の連結記号(既定: 中点 ·)
numberUnitSeparator: '\u202F', // 数値と単位の間(既定: 詰め気味のノーブレークスペース)
}- サイト全体の既定値:
astro.config.mjsに渡すconfigオブジェクト、またはsiunit.config.json(astro-integration.mjs経由)で設定します。 - ブロック単位の上書き:
:::si-scope{decimalMarker="," groupMinDigits="3"} ... :::のように、該当ブロック内だけ設定を変えられます(ネスト可、抜けると自動的に元に戻ります)。 - 個別呼び出しの上書き:
:num[1234.5]{decimalMarker=","}のように、ディレクティブ自体に 属性を付けても上書きできます。
acroterm/theoremとの違い:Pass 1 (事前スキャン) が不要
以前の会話で触れた通り、\sisetupのスコープはTeXのグルーピングの仕組みに乗っているだけで、
「まだ見ぬ後続ページの情報を先読みする」必要がある問題ではありません。そのため、このプラグインは
acroterm/theoremのような2パスビルドを行わず、単一パスの木の走査中に設定のスタックを
push/popするだけでsi-scopeを実現しています(src/plugin.mjsのwalk()参照)。
セットアップ
yarn add remark-siunit remark-directive unified unist-util-visit mdast-util-to-stringastro.config.mjs(example/astro.config.mjs参照):
import siunitIntegration from 'remark-siunit/astro-integration.mjs';
import siunitPlugin from 'remark-siunit/src/plugin.mjs';
const { integration, remarkPluginConfig } = siunitIntegration({ configPath: './siunit.config.json' });
export default defineConfig({
integrations: [integration],
markdown: { remarkPlugins: [[siunitPlugin, remarkPluginConfig]] },
});見た目の調整は example/siunit.css を参照してください(単位を直立体で表示するなど)。
既知の制約
- 指数は
^nの明示のみ対応(裸のm2は非対応)。 - 数値の不確かさ表記
1.234(5)は入力をそのまま末尾に付けるだけの簡易実装です。siunitxの 「不確かさの桁を最後のN桁に正確に対応させる」高度なアルゴリズムは実装していません。 \square/\cubicのみショートカット対応。\quartic等その他の冪修飾語はありません (^4のように明示してください)。- コンテナディレクティブは
:::(コロン3つ、名前の前後にスペースなし)が必須です。
テスト
node test-run.mjsBase units・Derived units・Non-SI units・SI prefixes・Unit abbreviations・Binary prefixes
の各表から抜粋したケースと、si-scopeのスコープ内外での設定切り替えを確認できます。
