Should not output "null" for empty value of frontmatter properties
MurakamiShinyu opened this issue · 11 comments
Issue Details
Frontmatter にキーだけ書いて値が空の場合、HTMLでその値が出力されるところに "null" という文字列が出力される。
文字列 "null" は、HTMLにおいて特別な意味がないただの文字列であり、例えば <title>null</title>
では "null" というタイトルということになってしまうので適切ではない。
例:
---
lang:
title:
author:
link:
- rel:
href:
---
↓
<!doctype html>
<html lang="null">
<head>
<meta charset="utf-8">
<title>null</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="author" content="null">
<link rel="null" href="null">
</head>
<body></body>
</html>
- VFM version
- 1.0.0-alpha.24
Expected Behavior
文字列 "null" ではなく、空文字列になるべきだろう。上記の例なら次の出力になってほしい:
<!doctype html>
<html lang="">
<head>
<meta charset="utf-8">
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="author" content="">
<link rel="" href="">
</head>
<body></body>
</html>
js-yaml の解析は Key だけある場合に null となるようです。これを判定することは可能です。ただしこの状態を空文字として出力すべきでしょうか?
例えば現在 id
や lang
などのルートにある値を空文字にすると評価部分が if (value)
のようになっているため、空文字も偽となって書き込みをスキップします。
空文字として書き込む仕様にするなら全ての値について振る舞いを決める必要があります。null
が書き込まれること自体はバグですが、単に空文字として扱うだけでは修正にならないと考えています。
空文字を許容する値については、それを仕様として明示する必要があります。それを持って判定部も単に if (value)
とするのではなく空文字も許容するように修正することとなるでしょう。
src/plugins/document.ts
の処理をお読みいただけると私の意図がわかりやすいと思います。
手元で空文字変換して lang
や id
などオプショナルかつ直値になるもののテストを書いていてこの問題に気づきました。直値ではなく Array
になるもの (link
など) はその先で空文字をはじいていないため、結果として許容されることになります。
Markdownで原稿を作るプロジェクトによって、Markdownの雛形として、
---
lang:
title:
author:
hoge:
---
のように、値を空にしておいたものを使って、必要に応じてその値を埋める、というような使い方をすると思います。
その場合、値が空のままではエラーになるというのでは使いにくいので、空の値は空文字列 "" と同じ扱いでよいかと考えたのですが、むしろ該当する属性や要素を出力しないというのが、適切かもしれないですね。
補足。js-yaml の変換結果を試したところ
key:
=null
key: ""
=""
key: "value"
="value"
でした。明示的に空文字を指定するための ""
と暗黙的な空の値を区別する必要があるか?という話です。
むしろ該当する属性や要素を出力しないというのが、適切かもしれないですね。
はい。明示的な空文字を指定する方法がある以上、null
の場合は読み込み時点で「評価しない = 未定義」とするほうがよさそうです。
ちなみに現時点だと「値なし = null
」は
metadata[key] = `${data[key]}`;
のようにしているためエラーにならず、本 issue のように "null"
となっています。これを未定義として扱うなら代入部分で判定してはじくように変更します。
すみません↑に補足です。明示的に空文字を指定された場合、つまり key: ""
をはじくか否かも決める必要があります。
key
自体が未定義 ...出力なしkey:
...現状は"null"
扱いで出力、本 issue で指摘されているとおりバグkey: ""
...現状はlang
やid
などルートかつオプショナルな値だけ未出力、link
など階層化されるものは出力
となっています。これをそれぞれどのようにするか。
HTML仕様で Boolean attributes https://html.spec.whatwg.org/#boolean-attributes は、属性の名前だけ指定しても =""
を指定しても同じで true という意味になります。そのような属性を指定するのに key: ""
が指定できることは必要です。これを key:
だけの指定でも同じ意味にしても、自然な感じはします。
それもありますね。key
を指定している時点で値がなくても出力を期待しているともとれるので。
ここまでの議論を踏まえ、当初案の発展形で
key:
もkey: ""
として扱うlang
やid
が null (これは 1 により書き込み側からは""
に見える) または空文字でも""
として出力する
とするのはどうでしょうか?
ではそのようにします。ドキュメントにも記載予定です。
#112 にて対応、それを反映した 1.0.0-alpha.25 をリリースしたので本件は close します。