Closed akabekobeko closed 2 years ago
この値があると VFM の readMetadata
と組み合わせたプリプロセス的な処理に役立つ。例えば date
へ日時を定義しておき、それに基づいて記事一覧をソートするなど。
開発中の vivliostyle-sitegen では HTML テンプレートに EJS を採用している。このツールではプロパティーに基づく分岐やループも可能なので、この値を受け渡すことで Markdown 単位の柔軟なカスタマイズも可能。vivliostyle.org の記事、例えばブログのタグなどを vivliostyle-sitegen で実現するためにも必要な機能となる。
プロパティ名が tools
なら、その値はツール名がキーになっているのが自然な気がします。つまり、
---
tools:
vivliostyle-sitegen:
date: "20220119"
categories: ["Development"]
tags: ["Markdown", "Frontmatter"]
---
確かにそうですね。実際には複数ツールから同時にホストされるのは稀だとは思いますが、そのようにしておくと宣言そのものが自己言及的になる点も好ましいですね。
デメリットとしては階層が深くなること。しかし同一ツールで複数 Markdown を書くなら定形をコピペして書き換える運用が想定されるため、あまり気にしなくてもよさそうではあります。
プロパティー階層を単一にするなら...
tools
ではなく tool
や tool-data
のように単数形または曖昧なものにするtools-vivliostyle-sitegen
のようにする
tools-
を接頭辞とするプロパティーは <meta>
として処理せず、そのままデータ化するという感じですかね。
宣言のわかりやすさだと村上さん案がよさそう。
実際には複数ツールから同時にホストされるのは稀だとは思いますが
と書いたが、もし複数ツール間で共有したいという要望があっても満たせるし、単一ツール内でもバージョン処理に有用そう。例えば foobar
というツールについてメタデータの破壊的な変更があった場合、過去の foobar
をそのままに foobar-v2
を追加することで両バージョンへ同時に対応可能となる。
接頭辞案でも同様の対応は可能だが、プロパティー名の中に入れ子構造があるというのは直感的ではない。
もうひとつの考え:
現状のvfmで次のFrontmatterのとき、
---
date: "20220119"
categories: ["Development"]
tags: ["Markdown", "Frontmatter"]
---
次の出力になります:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="date" content="20220119">
<meta name="categories" content="Development">
<meta name="tags" content="Markdown,Frontmatter">
</head>
<body></body>
</html>
このようにmetaタグに出力されても、とくに困ることはないようにも思えます。
ツール側は、HTMLのmetaタグに出力されるのとは関係なしに、Frontmatterの情報を使うことができるでしょう。
値がobjectの場合(現状ではmetaタグには [object Object]
のように出力される)はmetaタグには出力しないほうがよさそう。
あるいは、ツールの側からvfmに、ツールが特別扱いするキーを指定できるようにして、そのキーはmetaタグに出力しないというのでもよいかも。
vivliostyle-sitegen としては当初、まさに meta をそのまま利用するつもりでした。しかし [object Object]
問題と Array がカンマ区切り文字列となることで、それをツール側で split しなければならないのが面倒で本件を提案してみました。レアケースですがカンマ区切りの要素にカンマが含まれる場合のエスケープも検討する必要があります (曲名や書籍名などをタグにすると意外に遭遇しそう)。
ただ meta としてそのまま処理する案も <meta>
としてメタデータ出力されることが逆にメリットとも言えそうで捨てがたいのですよね。
あるいは、ツールの側からvfmに、ツールが特別扱いするキーを指定できるようにして、そのキーはmetaタグに出力しないというのでもよいかも。
この方法もよいですね。ツールとしては自身の名前をそのまま除外指定して
---
vivliostyle-sitegen:
date: "20220119"
categories: ["Development"]
tags: ["Markdown", "Frontmatter"]
---
とするか、標準プロパティーと衝突しないのを前提として個別に除外指定して
---
date: "20220119"
categories: ["Development"]
tags: ["Markdown", "Frontmatter"]
---
ともできます。↑については他の Markdown 対応 SSG ツールから移行する際にもよさそうです。
もし
あるいは、ツールの側からvfmに、ツールが特別扱いするキーを指定できるようにして、そのキーはmetaタグに出力しないというのでもよいかも。
へ対応するとしたら用途的にツール (プログラム) 想定なので VFM としてのオプションではなく readMetadata
に限定したものとしたほうがエンド ユーザーを混乱させることもなくよさそう。
影響範囲やドキュメント整備などを考慮して、本件は村上さん案の「meta
として無視するキー指定」を採用することにした。
readMetadata
API に meta
処理から除外するキー名コレクションを指定可能として、それに該当するものが検出されたら remark-frontmatter
が処理した JavaScript のデータをそのまま維持する。VFM の処理は
metadata.ts
の readMetadata
で remark-frontmatter
の結果を HTML 出力用のデータ型に整形document.ts
の createHTML
とそのサブルーチンで 1 の値をキー毎に HTML 化となっている。1 で未知のキーは meta
として処理されるのを除外指定でスキップすればよい。2 では想定されるキーのみ処理されるため、未知側がどのようになっていても影響しない。
Metadata
に [key: string]: any;
を追加することで無視した任意の値をキーにより代入可能となる。ただしこの方法だと既知のプロパティー限定チェックが効かなくなってしまうため、
export type Metadata = {
// ...前略
excludes?: {
[key: string]: any;
}
}
として excludes
に除外したものをまとめることにした。readMetadata
で除外指定するための引数も同名で対応づけられる。
VFM v1.2.0 へ反映したので close します
Goals
Provides Frontmatter properties for third party tools.
VFM's Frontmatter processes undefined properties as meta tags. In this case, the value becomes a string and the type information is lost.
For example, in vivliostyle-sitegen, want to handle various types of data such as dates and tags in Markdown units. Therefore, I want to maintain non-string types.
The root property is a single property, and arbitrary structures can be defined within it. The property name is
tools
because we assume third-party tools.