cmark-gfm
cmark-gfm copied to clipboard
ID's are not generated on header elements
I noticed a peculiarity in that headers are not generated on H elements.
# My Title
should evaluate to <h1 id="my-title">My Title</h1>
Instead it evaluates to <h1>My Title</h1>
.
This makes internal links not possible, which is a rather large issue since MD is often used for documentation.
https://github.com/jch/html-pipeline/blob/master/lib/html/pipeline/toc_filter.rb
Here is a ruby example of the implementation I believe.
text = node.text
id = ascii_downcase(text)
id.gsub!(PUNCTUATION_REGEXP, '') # remove punctuation
id.tr!(' ', '-') # replace spaces with dash
uniq = headers[id] > 0 ? "-#{headers[id]}" : ''
headers[id] += 1
if header_content = node.children.first
result[:toc] << %(<li><a href="##{id}#{uniq}">#{EscapeUtils.escape_html(text)}</a></li>\n)
header_content.add_previous_sibling(%(<a id="#{id}#{uniq}" class="anchor" href="##{id}#{uniq}" aria-hidden="true">#{anchor_icon}</a>))
end
For a real-world example of this issue, see: https://pypi.org/project/norgatedata/
Explicitly adding HTML links with ids after headers is one way of working around all this. The following creates a fully linked readme that will also work on other platforms (such as PyPI for the above comment):
Contents:<a id="contents"></a> [Section Header](#section-header)
# Section Header [`↩`](#contents) <a id="section-header"></a>
See any of my projects for an example of how it functions.
Generating header IDs is a crucial feature, in my opinion. Doing how @andrewtavis suggested is feasible as a temporary solution to adopt only when it is fundamental to have a reference to the header; nevertheless, writing that much markup only to get what can easily be automated seems very cumbersome and useless.