vivliostyle / vfm

⬇️ Open and extendable Markdown syntax and toolchain.
https://vivliostyle.github.io/vfm/#/vfm
Other
71 stars 12 forks source link

Generated HTML should be human readable #48

Closed MurakamiShinyu closed 3 years ago

MurakamiShinyu commented 3 years ago

Issue Details

vfmで生成されるHTMLファイルは、ほとんど改行が含まれず、大きな文書でも body 要素内がほとんど1行になってしまい、そのままではHTMLファイルの内容を確認することがしずらい。

Expected Behavior

ブロック要素の開始タグの前と終了タグのあとなどに改行があること。

Actual Behavior

次のmarkdownに対して:

# Heading 1 

AAA  

## Heading 2

BBB

### Heading 3

CCC

vfmの出力結果:

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<section id="heading-1"><h1>Heading 1</h1><p>AAA</p><section id="heading-2"><h2>Heading 2</h2><p>BBB</p><section id="heading-3"><h3>Heading 3</h3><p>CCC</p></section></section></section>
</body>
</html>

(body要素内が1行になっている)

akabekobeko commented 3 years ago

VFM は devDependenciesprettier を持ちます。これは開発用コードを整形するためのものですが HTML にも対応しているので dependencies へ移し、例えば VFM に usePrettier オプションが指定されたら prettier で処理する手があります。

akabekobeko commented 3 years ago

自前で処理するよりもは prettier のほうが安全でしょう。整形設定に悩みますが、標準にするか prettier オプションも VFM 経由で指定する、などの方法があります。prettier オプションを露出させると将来の禍根になりそうなので私としては標準設定にしておくほうがよいと考えています。

MurakamiShinyu commented 3 years ago

prettierの標準設定では、長い行をスペースのところで改行して折り返しますが、日本語のテキストでは文中のスペースがないので、HTMLタグの途中(<ruby> タグの <ruby> との間など)で改行することになります。その結果は見やすくないし、HTMLタグの検索などもしにくいものになってしまうので、あまりよくないと思います。

たとえば https://github.com/vivliostyle/vivliostyle_doc/blob/gh-pages/samples/gon/index.html を prettier で整形すると次のようになります:

    <p>
      これは、私が小さいときに、村の<ruby
        ><rb>茂平</rb><rp>(</rp><rt>もへい</rt><rp>)</rp></ruby
      >というおじいさんからきいたお話です。
    </p>

    <p>
      むかしは、私たちの村のちかくの、中山というところに小さなお城があって、中山さまというおとのさまが、おられたそうです。
    </p>

    <p>
      その中山から、少しはなれた山の中に、「ごん狐」という狐がいました。ごんは、一人ぼっちの小狐で、<em
        class="sesame_dot"
        >しだ</em
      >の一ぱいしげった森の中に穴をほって住んでいました。そして、夜でも昼でも、あたりの村へ出てきて、いたずらばかりしました。はたけへ入って芋をほりちらしたり、菜種<em
        class="sesame_dot"
        >がら</em
      >の、ほしてあるのへ火をつけたり、<ruby
        ><rb>百姓家</rb><rp>(</rp><rt>ひゃくしょうや</rt><rp>)</rp></ruby
      >の裏手につるしてあるとんがらしをむしりとって、いったり、いろんなことをしました。
    </p>

    <p>
      <ruby><rb>或</rb><rp>(</rp><rt>ある</rt><rp>)</rp></ruby
      >秋のことでした。二、三日雨がふりつづいたその間、ごんは、外へも出られなくて穴の中にしゃがんでいました。
    </p>

Prettierでの整形を使わなくても、Markdown上で改行されているところはHTML上で改行されるようにするというだけでもだいぶよいと思います(自動インデントはされませんが)。それならばpre以外のHTML要素に対してもCSSの white-space プロパティで空白文字の扱いを制御できるメリットがあります。(自動インデント整形をするとそれができなくなるデメリットがある)

akabekobeko commented 3 years ago

HAST になった時点で元の Markdown における改行は個別の要素に分散される。HTML 文字列化は rehype-stringify が担当しているので、ここかその後で処理する必要がある。という理由から Prettier を提案したのだが、HAST として整形できないものかと調べたら以下があった。

rehype-stringify の後に rehype-format を指定する。これのデフォルト設定で目的は果たせそう。

akabekobeko commented 3 years ago

補足。rehype 系なら HAST なので remark の互換を気にせず利用できるはず。

akabekobeko commented 3 years ago

手元で rehype-format を試したら想定通りインデントされることがわかった。Prettier の既定だと 80 文字で自動改行されるが、それもない。

VFM の stringify でこれが処理されるようにして長く複数段落に渡る文字列を指定すると

const actual = stringify('あああああああああああああああああああああああああ いいいいいいいいいいいいいいいいいいいいいい ううううううううううううううううううううううううう えええええええええええええええええええええええええ おおおおおおおおおおおおおおおおおおおおおおお\n\nかきくけこ\n\nさしすせそ');

変数 actual へ返される値は以下となった。

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
  </head>
  <body>
    <p>あああああああああああああああああああああああああ いいいいいいいいいいいいいいいいいいいいいい ううううううううううううううううううううううううう えええええええええええええええええええええええええ おおおおおおおおおおおおおおおおおおおおおおお</p>
    <p>かきくけこ</p>
    <p>さしすせそ</p>
  </body>
</html>

ユニット テストの期待値 HTML、または容量削減の観点 (稀だとは思われる) から未フォーマットの HTML が欲しくなるかもしれない。実際、常に処理するとユニット テストの大半を書き換える必要がある。そのため新たに

というオプションを追加することにした。これらが明示的に指定されると未フォーマットの HTML を得られる。

akabekobeko commented 3 years ago

新オプションを README.md へ記載しようとして気づいたのだが HTML の DOCTYPE

となっている。VFM は XML/XHTML ではなく HTML を返すため小文字でもよいのだと思われる。ただしドキュメントと実際の値が異なるのはよくないので小文字に直すべきか?

@MurakamiShinyu 方針について相談です。↑のようにドキュメント README.md を直すほうがよいでしょうか?

akabekobeko commented 3 years ago

すみません #70 として本 issue 対応を PR したので、返答はそちらへお願いします。PR 側に議題として DOCTYPE の話をコメントしておきました。

MurakamiShinyu commented 3 years ago

READMEの doctype を実装に合わせて小文字にしたのでOKだと思います。 https://github.com/rehypejs/rehype-document#readme を見ても小文字で <!doctype html> になっていて、rehype ではそれが標準のようですし。

akabekobeko commented 3 years ago

承知しました。

akabekobeko commented 3 years ago

本件を対応して 1.0.0-alpha.17 としてリリースしました。問題なければ close してください。