Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

spec: Auto generate HTML section elements #8

Closed
MurakamiShinyu opened this issue Jan 26, 2020 · 19 comments
Closed

spec: Auto generate HTML section elements #8

MurakamiShinyu opened this issue Jan 26, 2020 · 19 comments
Assignees
Labels
spec Spec related thing
Projects
Milestone

Comments

@MurakamiShinyu
Copy link
Member

MurakamiShinyu commented Jan 26, 2020

HTML headings <h1> .. <h6> create implicit sections. However, using explicit <section> elements has an advantage that allows entire sections to be treated differently in CSS.

Goals

It will be useful if implicit sections created by headings in markdown are converted to explicit <section> elements.

Prior Art

Pandoc Option: --section-divs

Wrap sections in <section> tags, and attach identifiers to the enclosing <section> rather than the heading itself.

Example:

# Chapter 1
...

## Section 1-1
...

### Subsection 1-1-1
...

### Subsection 1-1-2
...

## Section 1-2
...

# Chapter 2
...

is converted to the following HTML by pandoc -t html5 --section-divs:

<section id="chapter-1" class="level1">
<h1>Chapter 1</h1>
<p></p>
<section id="section-1-1" class="level2">
<h2>Section 1-1</h2>
<p></p>
<section id="subsection-1-1-1" class="level3">
<h3>Subsection 1-1-1</h3>
<p></p>
</section>
<section id="subsection-1-1-2" class="level3">
<h3>Subsection 1-1-2</h3>
<p></p>
</section>
</section>
<section id="section-1-2" class="level2">
<h2>Section 1-2</h2>
<p></p>
</section>
</section>
<section id="chapter-2" class="level1">
<h1>Chapter 2</h1>
<p></p>
</section>

Discussion

The conversion with Pandoc Option: --section-divs may have the following issues:

  • The level 1 heading maybe should not be wrapped with <section> because this is usually the top level heading of <body>.
  • Headings maybe should not be wrapped with <section> when already wrapped in a section element (with HTML blocks or Fenced blocks) that has same or deeper level of the heading, or when placed in HTML elements other than sectioning elements article, aside, nav, or section.

Update (2021-01-13): It may need further consideration, but at this point I think it's best to make it compatible with Pandoc's --section-divs feature.

@MurakamiShinyu MurakamiShinyu added the spec Spec related thing label Jan 26, 2020
@MurakamiShinyu
Copy link
Member Author

Generated <section> with attributes

Example:

### Tips {#tips .tips role="doc-tip"}
...

is converted to the following HTML by pandoc -t html5 --section-divs:

<section id="tips" class="level3 tips" role="doc-tip">
<h3 class="tips" role="doc-tip">Tips</h3>
<p></p>
</section>

We can see from this result:

  • The id attribute is moved to the <section> tag.
  • The class is copied and added to the class attribute of the <section> tag, where the class leveln is generated by default.
  • Other attributes are copied to <section> tag.

@tk0miya
Copy link

tk0miya commented Jan 28, 2020

The original markdown does not defines the order of headings. So many markdown processors accept document which starts with Lv6 heading. It seems this proposal expects high leveled heading wraps lower one, right? If so, we should define the order of headings as a rule.

@uetchy
Copy link
Member

uetchy commented Jan 29, 2020

@tk0miya Can you elaborate on this and provide some specific example? I'm interested in your concerns.

@tk0miya
Copy link

tk0miya commented Jan 29, 2020

For example, this example starts with lv6 heading. My interest is this is valid or invalid and what HTML is converted from this VFM markup if valid.

###### Heading 6

# Heading 1

@uetchy uetchy added this to To do in Spec Feb 12, 2020
@skoji
Copy link
Sponsor Member

skoji commented Jun 17, 2020

How about this ?

###### Heading 6
# Heading 1

converts to:

<section id="heading-6" class="level6">
<h6>Heading 6</h6>
</section>
<section id="heading-1" class="level1">
<h1>Heading 1</h1>
</section>

( I think this is good enough, but I may have missed something)

@tk0miya
Copy link

tk0miya commented Jun 17, 2020

Thank you for the comment. It means the low leveled section can stand independently without higher section. Reasonable.

BTW, I noticed the section tags have its id attribute generated from its heading title. Is there any rules for generation? If it is a part of spec, we need to define the rule for it too (for example, 1) make title small-case 2) replace all spaces into hyphens 3)...). My interest is how to generate ID if they are duplicated. We usually gives the same title in the different section.

@uetchy
Copy link
Member

uetchy commented Jun 26, 2020

id in the headings are the same as GitHub style id, which is defined in here, which is needed for references.

@uetchy
Copy link
Member

uetchy commented Jun 26, 2020

Does <section> really need id? I think it's a bit repetitious since its very first heading already has the same id.

@uetchy uetchy moved this from To do to In progress in Spec Jun 26, 2020
@uetchy uetchy added this to the v1 milestone Jul 1, 2020
@uetchy uetchy added this to In progress in v1 Jul 1, 2020
@uetchy uetchy moved this from In progress to To do in v1 Jul 1, 2020
@uetchy uetchy removed this from the v1 milestone Jul 1, 2020
@uetchy uetchy moved this from To do to In progress in v1 Jul 2, 2020
@uetchy uetchy moved this from Waiting for the implementation to Review in progress in Spec Jul 2, 2020
@uetchy uetchy removed the help wanted label Jul 2, 2020
@MurakamiShinyu
Copy link
Member Author

現状の vfm と Pandoc --section-divs の動作の比較評価

vfm での section 要素の自動生成機能は、Prior Artである Pandoc Option: --section-divs と互換性があるとよさそうです。

Pandoc と現状の vfm (1.0.0-alpha.15) の動作で、次のような違いがあります:

  • Pandoc では section 要素に class 属性 "level1" 〜 "level6" が出力される
    • これがあると CSS でレベルごとの section のスタイルを指定しやすいので、vfm にもほしい
  • Pandoc では属性の指定がある見出し(例 # Heading1 {#id1 .class1 key1=value1})で id は section 要素に、それ以外の属性は section 要素と h1-h6 要素の両方に出力される
    • 現状の vfm ではどの属性も section 要素だけに出力される。Pandoc 同様に h1-h6 要素にも出力されるほうがよいだろう
  • Pandoc では blockquote 内の見出し(例 > # Heading)では section は作られない
    • blockquote の内容は本文とは違うものなので、sectionによる構造化の対象にはしないということだろう
  • Pandoc では fenced block(例 ::: Warning)内に最初にあるのが見出し(#…)の場合、fenced block で div 要素ではなく section 要素が作られて、見出しがその最初の子要素になる。ただし、fenced block に、見出しの id 属性(見出しのテキストから自動生成されるものでも)とは別の id 属性が指定されている場合には、div 要素が作られてその中に section 要素が作られる。
    • 現状の vfm では fenced block に直接見出しをつけることができず、見出しのために不要な section 要素が作られてしまう。

以下、これらの違いを示すサンプル:

属性が指定された見出し要素のテスト

$ cat test1.md
# Heading1
Aaaa.

## Heading2 {.class2}
Bbbb.

### Heading3 {#id3 .class3 data-key3=value3}
Cccc.

## Heading2
Dddd.
$ pandoc --section-divs test1.md | prettier --parser=html
<section id="heading1" class="level1">
  <h1>Heading1</h1>
  <p>Aaaa.</p>
  <section id="heading2" class="level2 class2">
    <h2 class="class2">Heading2</h2>
    <p>Bbbb.</p>
    <section id="id3" class="level3 class3" data-key3="value3">
      <h3 class="class3" data-key3="value3">Heading3</h3>
      <p>Cccc.</p>
    </section>
  </section>
  <section id="heading2-1" class="level2">
    <h2>Heading2</h2>
    <p>Dddd.</p>
  </section>
</section>
$ vfm --partial test1.md | prettier --parser=html
<section id="heading1">
  <h1>Heading1</h1>
  <p>Aaaa.</p>
  <section class="class2" id="heading2">
    <h2>Heading2</h2>
    <p>Bbbb.</p>
    <section id="id3" class="class3" data-key3="value3">
      <h3>Heading3</h3>
      <p>Cccc.</p>
    </section>
  </section>
  <section id="heading2-1">
    <h2>Heading2</h2>
    <p>Dddd.</p>
  </section>
</section>

この結果から分かることのまとめ:

  • pandoc の結果では section タグの class 属性に levelN が出力されている。
  • pandoc の結果では id 以外の見出しに指定された属性は section タグと hN タグの両方に出力されている。
  • vfm の結果では hN タグに属性が何も出力されていない。

Blockquote および Fenced block 内の見出し要素のテスト

注:現状の vfm (1.0.0-alpha.15) では Fenced block への任意の属性の指定(例 ::: {#id7 .class7 data-key7=value7})は未サポートだが、class属性は ::: のあとに記述することで指定できるのでこのテストではそれを使う。

$ cat test2.md
# Heading1

> ## Block Quote {#id2 .class2 data-key2=value2}
> Aaaa.
>
> ### Heading3 {.class3 data-key3=value3}
> Bbbb.

Cccc.

::: class4
## Fenced Block {.class5 data-key5=value5}
Dddd.

### Heading6 {.class6 data-key6=value6}
Eeee.
:::

Ffff.
$ pandoc --section-divs test2.md | prettier --parser=html
<section id="heading1" class="level1">
  <h1>Heading1</h1>
  <blockquote>
    <h2 id="id2" class="class2" data-key2="value2">Block Quote</h2>
    <p>Aaaa.</p>
    <h3 id="heading3" class="class3" data-key3="value3">Heading3</h3>
    <p>Bbbb.</p>
  </blockquote>
  <p>Cccc.</p>
  <section id="fenced-block" class="level2 class5 class4" data-key5="value5">
    <h2 class="class5" data-key5="value5">Fenced Block</h2>
    <p>Dddd.</p>
    <section id="heading6" class="level3 class6" data-key6="value6">
      <h3 class="class6" data-key6="value6">Heading6</h3>
      <p>Eeee.</p>
    </section>
  </section>
  <p>Ffff.</p>
</section>
$ vfm --partial test2.md | prettier --parser=html
<section id="heading1">
  <h1>Heading1</h1>
  <blockquote>
    <section id="id2" class="class2" data-key2="value2">
      <h2>Block Quote</h2>
      <p>Aaaa.</p>
      <section class="class3" data-key3="value3" id="heading3">
        <h3>Heading3</h3>
        <p>Bbbb.</p>
      </section>
    </section>
  </blockquote>
  <p>Cccc.</p>
  <div class="class4">
    <section class="class5" data-key5="value5" id="fenced-block">
      <h2>Fenced Block</h2>
      <p>Dddd.</p>
      <section class="class6" data-key6="value6" id="heading6">
        <h3>Heading6</h3>
        <p>Eeee.</p>
      </section>
    </section>
  </div>
  <p>Ffff.</p>
</section>

この結果から分かることのまとめ:

  • pandoc の結果では blockquote 内には section が作られていない。
    • vfmでは blockquote 内でも section が作られている。
  • pandoc の結果では、見出しが最初にある fenced block で div 要素ではなく section 要素が作られて、その最初の子要素が見出し要素(h2) になっている。見出しに指定された属性は section タグと h2 タグの両方に出力されている。
    • vfmでは div 要素が作られて、その中に section 要素が作られている。

なお、次のテストは参考として、 fenced block に class 以外の属性の指定をしたもの。vfm はこの形式が未サポートなので fenced block として処理されない。
pandocの結果では fenced block に id 属性が指定されている場合には、div 要素が作られてその中に section 要素が作られることが分かる。

$ cat test3.md
::: {.class4 data-key4=value4}
## Fenced Block {.class5 data-key5=value5}
Dddd.

### Heading6 {.class6 data-key6=value6}
Eeee.
:::

::: {#id7 .class7 data-key7=value7}
## Fenced Block {.class8 data-key9=value9}
Ffff.

### Heading10
Gggg.
:::
$ pandoc --section-divs test3.md | prettier --parser=html
<section
  id="fenced-block"
  class="level2 class5 class4"
  data-key5="value5"
  data-key4="value4"
>
  <h2 class="class5" data-key5="value5">Fenced Block</h2>
  <p>Dddd.</p>
  <section id="heading6" class="level3 class6" data-key6="value6">
    <h3 class="class6" data-key6="value6">Heading6</h3>
    <p>Eeee.</p>
  </section>
</section>
<div id="id7" class="class7" data-key7="value7">
  <section id="fenced-block-1" class="level2 class8" data-key9="value9">
    <h2 class="class8" data-key9="value9">Fenced Block</h2>
    <p>Ffff.</p>
    <section id="heading10" class="level3">
      <h3>Heading10</h3>
      <p>Gggg.</p>
    </section>
  </section>
</div>
$ vfm --partial test3.md | prettier --parser=html
<p>
  ::: {.class4 data-key4=value4}<br />
  ## Fenced Block {.class5 data-key5=value5}<br />
  Dddd.
</p>
<section class="class6" data-key6="value6" id="heading6">
  <h3>Heading6</h3>
  <p>
    Eeee.<br />
    :::
  </p>
  <p>
    ::: {#id7 .class7 data-key7=value7}<br />
    ## Fenced Block {.class8 data-key9=value9}<br />
    Ffff.
  </p>
</section>
<section id="heading10">
  <h3>Heading10</h3>
  <p>
    Gggg.<br />
    :::
  </p>
</section>

@akabekobeko
Copy link
Member

@MurakamiShinyu

現状の vfm と Pandoc --section-divs の動作の比較評価

について v1.0 対応とするか v2.0 へ見送るかの意見をお願いします。

@akabekobeko akabekobeko added this to the v1.0.0 milestone Apr 3, 2021
@MurakamiShinyu
Copy link
Member Author

について v1.0 対応とするか v2.0 へ見送るかの意見をお願いします。

v2へ見送りましょう。

@akabekobeko akabekobeko removed this from In progress in v1 Apr 3, 2021
@akabekobeko akabekobeko modified the milestones: v1.0.0, v2.0.0 Apr 3, 2021
@akabekobeko
Copy link
Member

コメントありがとうございます。v2.0 へ送ります。

@MurakamiShinyu
Copy link
Member Author

@akabekobeko

すみません、「v2へ見送りましょう。」と書いたものの、次の、属性については pandoc と同様にできればうれしいです。

Pandoc では属性の指定がある見出し(例 # Heading1 {#id1 .class1 key1=value1})で id は section 要素に、それ以外の属性は section 要素と h1-h6 要素の両方に出力される

というのは、figureについては img の属性が img と figure の両方の出力されるようになった(#47)ので、section と見出し要素についても同様になっているのが整合性があることと、あとからこの動作仕様を変えると、現在の動作を前提に作られたスタイルシートでは問題が起きる可能性があるので、できれば今のうちに変更をしたほうがよいと思うためです。簡単な変更ですむのであればですが。

@akabekobeko akabekobeko modified the milestones: v2.0.0, v1.0.0 Apr 4, 2021
@akabekobeko
Copy link
Member

あとからこの動作仕様を変えると、現在の動作を前提に作られたスタイルシートでは問題が起きる可能性があるので、できれば今のうちに変更をしたほうがよいと思うためです。簡単な変更ですむのであればですが。

は確かにそうですね。検討します。というわけで一旦 Milestone を v1.0 にしておきます。

@akabekobeko
Copy link
Member

村上さんの要望のうち

  1. Pandoc では section 要素に class 属性 "level1" 〜 "level6" が出力される
    • これがあると CSS でレベルごとの section のスタイルを指定しやすいので、vfm にもほしい
  2. Pandoc では属性の指定がある見出し(例 # Heading1 {#id1 .class1 key1=value1})で id は section 要素に、それ以外の属性は section 要素と h1-h6 要素の両方に出力される
    • 現状の vfm ではどの属性も section 要素だけに出力される。Pandoc 同様に h1-h6 要素にも出力されるほうがよいだろう
  3. Pandoc では blockquote 内の見出し(例 > # Heading)では section は作られない
    • blockquote の内容は本文とは違うものなので、sectionによる構造化の対象にはしないということだろう
  4. Pandoc では fenced block(例 ::: Warning)内に最初にあるのが見出し(#…)の場合、fenced block で div 要素ではなく section 要素が作られて、見出しがその最初の子要素になる。ただし、fenced block に、見出しの id 属性(見出しのテキストから自動生成されるものでも)とは別の id 属性が指定されている場合には、div 要素が作られてその中に section 要素が作られる。
    • 現状の vfm では fenced block に直接見出しをつけることができず、見出しのために不要な section 要素が作られてしまう。

1 を #90 で対応。VFM 1.0-alpha.20 にて反映予定。残件を継続検討する。

@akabekobeko
Copy link
Member

akabekobeko commented Apr 29, 2021

続けて 2 を #91 で対応。この PR では # Heading {hidden} を指定した際、従来は style="display none"" を出力していたのを村上さんの提案により hidden 属性への変更も実施した。

VFM 1.0-alpha.20 にて反映予定。残件を継続検討する。

@akabekobeko
Copy link
Member

akabekobeko commented Apr 30, 2021

#92 で 3 に対応。あわせてここまでの変更を反映した VFM 1.0-alpha.20 をリリース。

#92 対応の際に気付いたのだが村上さんが #91 でコミットしてくれた内容は文字列を "" で括っているのだけど VFM の .prettierrc"singleQuote": true を設定しているため、私の環境で Pretteir が処理された結果 '' に変更された。

Vivliostyle 本体としては「Pretteir を利用するがデフォルト設定を採用」だったので VFM も踏襲するべきだろうか。なお Pretteir 標準はたまに変更されることがある。例えば trailingComma は後から標準有効になって個人プロジェクトで無効化した覚えがある。よって GitHub Actions などで push 時に強制するとかしないと部分的にチグハグとなりそうだ。

@akabekobeko
Copy link
Member

akabekobeko commented May 2, 2021

4 以外を反映した VFM 1.0.0-alpha.20 をリリース。

@akabekobeko
Copy link
Member

@MurakamiShinyu
本件は VFM 1.0.0-alpha.20 以降で対応されます。ご確認のうえ問題なければ Issue を close してください。

Spec automation moved this from Under testing (pre-release) to Stable May 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
spec Spec related thing
Projects
No open projects
Spec
  
Stable
Development

No branches or pull requests

5 participants