vivliostyle / vfm

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

feat: disable attributes copy to parent #157

Closed akabekobeko closed 1 year ago

akabekobeko commented 1 year ago

refs #151

MurakamiShinyu commented 1 year ago
  • コピーで hidden 属性を独自に処理していたが、これは維持
    • これをなくすと # Heading {hidden} が処理されない
    • {} 記法の仕様かバグ対策と思われるので、互換性のため踏襲

hidden属性などHTMLのブール属性は hidden のように名前だけの指定あるいは hidden="" のように空文字列の値の指定あるいは hidden="hidden" という名前と値が同じ指定によって真の値を、その属性を指定しないことで偽の値を表すことになってます。vfmの属性記法でも同様であるべきだし、また、hiddenに限らずほかのブール属性でも同様であるべきです。

そこで hidden 以外のブール属性として autofocus 属性でテストしてみました。結果は、autofocus だけの指定も autofocus="" の指定も無視されてしまいます。autofocus=autofocus と指定すると autofocus が出力されます。

# Foo {autofocus}
↓
<h1 id="foo">Foo</h1>
# Foo {autofocus=""}
↓
<h1 id="foo">Foo</h1>
# Foo {autofocus=autofocus}
↓
<h1 autofocus id="foo">Foo</h1>

興味深いことに、HTML仕様でブール属性として定義されていない属性や未定義の属性については空の値でもその属性が出力されます。

# Foo {tabindex aaa bbb="" title="title"}
↓
<h1 tabindex="" aaa="" bbb="" title="title" id="foo">Foo</h1>

このテスト結果から、hidden 属性について特別に処理する必要があった理由は分かりました。hidden 属性以外についても同様に処理するとよいのでないかと思います。つまり、{ } 内の属性の記法が名前だけあるいは空の値の指定であるならば、その属性名を出力する。HTML構文では属性名だけなら空の値の指定 ="" が省略されていることになるので今まで bbb=""bbb="" が出力されたのが bbb だけの出力になっても問題ないと思います。

それから、見出し以外での { } 記法による属性は同じ扱いであるべきです。テストしたところ、見出し以外ではhidden属性が無視されてます:

[Foo](#foo){hidden}
↓
<p><a href="#foo">Foo</a></p>
MurakamiShinyu commented 1 year ago

section の深さにあわせて aria-labelledby 属性へ heading-N を設定するようにした

aria-labelledby 属性はラベルとなる要素の id を指定するものです。sectionにとってはその子要素である見出し要素がラベルになるので見出しの id をsectionのaria-labelledby 属性に設定します。

https://github.com/vivliostyle/vfm/issues/151#issuecomment-1264537214

このコメントに書いたHTMLの例、

<section class="level1" aria-labelledby="heading-1">
  <h1 class="one" id="heading-1">Heading 1</h1>
  <p>One.</p>
  <section class="level2" aria-labelledby="heading-2">
    <h2 class="two" id="heading-2">Heading 2</h2>
    <p>Two.</p>
  </section>
</section>

この例での aria-labelledby="heading-1"aria-labelledby="heading-2" はそれぞれ見出しの id="heading-1"id="heading-2" を参照するものです。それらは見出しの文字列「Heading 1」「Heading 2」から生成されるidです。「Foo」のような意味のない文字列のほうが例としてよかったですね。

MurakamiShinyu commented 1 year ago

このPRのタイトルは "feat: disable attributes copy to parent" なので、見出し(→section)だけでなく画像(→figure)についての変更も、このPRに入れるとよいと思います。

![Text](url) の形式の画像をfigure囲みに変換する仕様はPandocに準拠してますが、Pandocでは ![Text](url){attributes} で指定したattributesはimg要素に出力されるだけで、それをfigureにコピーするようにしたのはVFM独自の拡張でした。その属性コピーをやめる変更によって、Pandocと同様になるとよいです。

Pandocでの変換の例:

$ pandoc
![Text](image.png){#aaa .bbb width=250}
↓
<figure>
<img src="image.png" id="aaa" class="bbb" width="250" alt="Text" />
<figcaption aria-hidden="true">Text</figcaption>
</figure>
akabekobeko commented 1 year ago

ひとつの PR として対応する機能が多すぎるので分割したほうがよさそうです。

とします。平日は時間が取れなさそうなので来週末以降になります。

akabekobeko commented 1 year ago

@MurakamiShinyu 6396aa30c5eb485a357bcf15276ff8d0bb301d2e にて見出しの id 属性がある場合は <section>aria-labelledby 属性に値をコピーするようにしました。あわせてテストやドキュメントも最新の状態に更新しています。

レビューをお願いします。

MurakamiShinyu commented 1 year ago

動作確認しました。よいと思います。

ドキュメントの次のところ:

見出しに id 属性がある場合は、セクションの aria-labelledby 属性に値をコピーします

見出しには id が自動生成されるので常に id 属性があるのでないでしょうか? そうであれば、 「見出しの id 属性の値をセクションの aria-labelledby 属性にコピーします」 という説明のほうがよいと思います。

akabekobeko commented 1 year ago

@MurakamiShinyu fe85733c235df8b32f2b6a4aaa18fcebbfb78b2f にて id コピーの説明を修正しました。現在は見出しがどのような文字列であろうとも明示的に {} で指定しない限り、文字列をそのまま id にしています。そのため「常に」を入れるか迷ったのですが、この挙動が好ましくないという意見もありそうです。

よって、単に見出しの id をコピーするという説明としました。