連番を振る remark プラグイン
図表番号を記述するのに使いたい。
カウンターと定義・参照
以下のような場合を考える。
詳しくは「図 1」を参照してください。
![ここに図 1 があるとする](/images/slug/fig1.png)
*図 1*
![ここに図 2 があるとする](/images/slug/fig2.png)
*図 2*
「図 2」を「図 1」と比較すると。
以下のような記述はどうか?
-
:num[value-name]{define}
- 変数の定義と参照、初期値はdefine
が使われた回数 -
:num[value-name]
- 変数の参照、定義の前に使ってもよい
詳しくは「:num[array-some]」を参照してください。
![ここに図 1 があるとする](/images/slug/fig1.png)
*図 :num[array-some]{define}*
![ここに図 2 があるとする](/images/slug/fig2.png)
*図 :num[array-every]{define}*
「図 :num[array-every]」を「図 :num[array-some]」と比較すると。
毎回変数名を考えるのも大変。
単純なカウンターとして以下の記述は?
-
:num[value-name]{reset}
- 変数の定義(参照はしない = tree から削除)、初期値は0
-
:num[value-name]{up}
- 変数の値をカウントアップして参照
:num[fig](reset}
![ここに図 1 があるとする](/images/slug/fig1.png)
*図 :num[fig]{up}*
![ここに図 2 があるとする](/images/slug/fig2.png)
*図 :num[fig]{up}*
変数の値が動的に変更されると以下の「定義の前に使ってもよい」をどう扱うかが問題になる。
:num[value-name]
- 変数の参照、定義の前に使ってもよい
最終的に確定した値を使うでもよいのだが、ちょっとわかりにくいか?
:num[fig](reset}
![ここに図 1 があるとする](/images/slug/fig1.png)
*図 :num[fig]{up}*
![ここに図 2 があるとする](/images/slug/fig2.png)
*図 :num[fig]{up}*
「図 :num[fig]」を参照してください。 <- これは「図 3」になる。
![ここに図 3 があるとする](/images/slug/fig3.png)
*図 :num[fig]{up}*
どちらの記述に軸足を置くか(よく使うのはどちらか)による。
単純なカウンター方式をよく使うのならば定義前の参照は許可せずに :num[value-name]{lazy}
を使うとスッキリしそうだが、これも最終的な値になるのでわかりくいか。
ここまで書いておいてなんだが構文的にラベル(コンテンツ)を変数名にしてもよいのか?
:num{name="fig"}
が正しそうだが記述が煩雑かな。
その代わりに :num[図. ${fig}]{name="fig"}
的なこともできそうだが。
それはそれで処理を作るのが大変そう。
簡単に試作してみた。
- ラベル(コンテンツ)は使わない
-
value-name
はname
属性で設定 - カウント中の値を参照する場合は
:num{value="fig" look}
のようにする
という感じに落ち着きそう。
実際に入力してみた感じでは極端にやりにくいということはなかったが、「ここはdefine
だっけ?」と考え込んでしまうこともあった。
あと、存在しない変数を指定した場合はエラーメッセージを出した方がよいのか?
エラーメッセージを Markdown へ挿入するようにした。
エラーメッセージの表示
スクリプトに組み込んで動かした場合、remark-cli もしくは textlint のエラーにもしたくなる(ターミナル上にもメッセージを表示させたい)。
この辺は後で対応かな。
作った。
しばらく試してみた結果。
- 参照と定義の場合
- 章などで連番(define のカウンター)をリセットしたくなる
- 図と表などで連番の系統をわけたくなる
- カウンターの場合
- 章などでカウンターをリセットしたくなる
対応としては以下のような感じか。
define をリセットさせる定義の案。以下のように記述すると heading
で depth:2
のノードでリセットする。
:::num{reset}
## :num
:::
連番の系統は変数名を .
で区切る(1階層のみ)。
:num{name="fig.some" define}
:num{name="tbl.area" define}
カウンターをリセットさせる定義の案。define とほぼ同じ。変数chapter
を定義し heading
で depth:2
のノードでリセットする。
:::num{reset}
## :num{name="chapter"}
:::
「定義と参照」と「カウンター」が混在しているのは不自然になってきた気がする。
プラグインをわけるかも。
define のカウンターはクラスを作ってリセットなどの制御をできるようにした。
カウンターは自動カウントを付けるかも。
:::num{increment}
## :num{name="chapter"}
:::
だいたい動くようになった。カウンターは remark-counter にわけた。
変数を参照するときに記述が長い。
name
属性ではなく id
属性にするとショートカットが使える。
Shortcuts are available for
id=
({#readme}
for{id=readme}
) and
class
({.big}
for{class=big}
).
今回の場合だとこうなる。
-
:num{name="foo"}
これが -
:num{#foo}
こうなる
記述は短縮できてよいのだが、参照する側(n 個)にも同一 id
が振られるのが違和感ある。
定義と参照で記述を非対称にすると違和感減るか?
-
:num{#foo define}
- 定義は属性としてid
を指定 -
:num[#foo]
または:num[foo]
- 参照はラベルの中からfoo
を参照
変数の定義(reset
のブロック)を毎回記述するのは非効率。
使いたいのは大体同じ。
:::num{reset}
# :num
## :num
:::
:::cnt{reset}
:cnt{name="chapter"}
:cnt{name="fig"}
:cnt{name="chart"}
:cnt{name="tbl"}
:::
:::cnt{increment}
# :cnt{name="chapter"}
## :cnt{name="chapter"}
:::
テンプレート設定的なもの指定できるようにしたい。
- ファイルを用意しておいて
cat
で対象の.md
ファイルに連結してしまう
プラグイン側の対応は必要ないがcat
で連結できるタイミングがあるとも限らない - プラグインのオプションでマークダウンの文字列をわたす
わたされた文字列を別途パースし変数の定義など更新する必要がある - プラグインのオプションで普通に指定する
リセットの設定などは指定する項目が多い(マークダウンで書いていたものをオブジェクトで表現することになる)
あとで考える。
カウンターの機能はやはりマージした。
変数名の指定はid
を使うようにした。
- カウンターの定義 -
:num{#var reset}
- 割り当ての定義 -
:num{#var}
- 参照するとき -
:num[var]
定義時の define
をなくしたので少し簡潔になった。
テンプレートは options で渡すようにした(連結用の.md
を外部に持つのは面倒)。
実行準備ができた状態です(図 :num[sec]-:num[fig.ready])。
以下のようになります(図 :num[sec]-:num[fig.result])。
のように毎回 "図 :num[sec]-" を記述するのは手間がかかりすぎる。
以下のような書式指定機能が欲しくなる。
:::num{format assign}
:num[図 :nnum[sec]-:num]{series=fig}
:::
書式機能もつけてみた。
:::num{format assign}
:num[図 :num[sec]-:num]{series=fig}
:num[写真 :num[sec]-:num]{series=photo}
:num[グラフ :num[sec]-:num]{series=chart}
:num[グラフ :num[sec]-:num]{series=grapgh}
:num[図式 :num[sec]-:num]{series=diagram}
:num[フロー :num[sec]-:num]{series=flow}
:num[表 :num[sec]-:num]{series=tbl}
:::
テンプレートなどで上記のように記述しておくと :num[fig-result]
が 図 1-1
のようになる。
以下のような感じにできたので、とりあえずはこの辺までかな。
編集
プレビュー
アコーディオンの記述 :::details タイトル
が remark-directive
で \:::details タイトル
にエスケープされる。
タイトル
部分が :::name[label]{attributes}
の構文とあわないことから通常のテキストとして処理されるために発生している。
(:::message
は ContainerDirective
として処理される)
これは対応が難しい。
暫定的に sed -e 's/^\\:::/:::/'
で行頭の \:::
を置き換えで対応かな。
ずるずる引っ張ってしまったが、一区切りということで記事にした。
現時点で考えている機能追加の案。
定義と参照で異なる書式。表のラベル(キャプション)風な表示で使えそうかなと。
この辺は CSS が使える環境ならそちらに任せるかな?
:num[▼ 表 :num[sec]-:num]{series=tbl bind=define}
:num[表 :num[sec]-:num]{series=tbl bind=refer}
複数の変数をまとめて参照する機能と書式。
(図 4-2、図 4-3) という表示はちょっと長いので対応したい。
書式の定義
:num[図 :num[sec]-:num]{series=fig join=","}
参照時の記述では ,
区切りで複数の変数を指定。
結果は以下の通り(:num[fig-foo,fig-bar])
変換結果。
結果は以下の通り(図 4-2,3)
オートリセットなどのトリガーを式で指定。
とくに困っているわけではないのだが、現行の記述だと柔軟性がないので。
案としては以下のような感じ。
- 式(jsonpathが利用できないか考えている)をトリガーとしてわたす
- 式は
unist-util-visit-parents
から渡されるparents
+node
の配列とマッチするかを検証 - マッチしたらリセット処理発動
カウンターの初期値を外部から挿入。
これも現状ではとくに困っていないのだが、Zenn 本のように章でファイルがわかれている場合用。
以下のようにすると環境変数などから値を設定など。
# 〇〇について
:num{#chapter reset="$CHAPTER"}
という感じでいまのところこのは 4 つかな。
- 定義と参照で異なる書式
- 複数の変数をまとめて参照する機能と書式
- オートリセットなどのトリガーを式で指定
- カウンターの初期値を外部から挿入
とりあえず、ここでクローズ。