Repository navigation
Conversation
|
Have you measured perf on running span gamut on each header? Plus this would break any existing hrefs if they were recompiled with this code |
|
Perf: the span gamut doesn't run an extra time.
Existing hrefs: ids stay the same for plain headers and for emphasis, code spans and entities ( If that's a concern, the new behaviour could sit behind a |
|
@Crozzers Tell me more on your backwards compat concern. You're worried that someone who previously rendered header IDs and then put them online and shared links would have invalid links if they went and re-rendered this and published the page again? |
This fixes #192.
With the
header-idsextra, a markdown header's id is slugified from the raw markdown source. Link URLs, image paths and emphasis markers therefore end up in the id:# [Inline link](https://github.com)inline-linkhttpsgithubcominline-link# [Reference link][ref]reference-linkrefreference-link#  Imagelogologopng-imageimage# <span>Inline</span> HTMLspaninlinespan-htmlinline-html# __Strong__ and _em___strong__-and-_em_strong-and-em_h_subnow runs the span gamut first and builds the id from the rendered header, andheader_id_from_textstrips tags before slugifying. Its docstring already says it receives the header's HTML content, and the mixed-mode HTML headers (_h_tag_sub) already pass HTML, so both paths now treat tags the same way. The safe mode handling from #739 is kept: HTML spans are unhashed (to their sanitized form) before the id is built, so the existingheader_ids_safe_mode*cases are unchanged. In escape mode the escaped tags are visible text, so they still count towards the id there (hello-bworldb).A footnote reference in a header is still a placeholder at this point (numbers are assigned after the block gamut), so the placeholder is dropped from the id text. Without that, the placeholder ended up in the
idattribute and_do_footnote_markerlater failed with aValueError. Footnoted headers keep the id they had before (# Header with a footnote[^1]->header-with-a-footnote1).Behaviour changes worth knowing about:
_/__emphasis, so existing anchors to such headers move. Headers without inline markup keep their ids. Over the 289.textinputs undertest/(rendered withheader-ids,footnotes,tables,fenced-code-blocks), only the new cases and the safe mode inputs changed id, and the safe mode inputs only change when rendered without safe mode.# <sometext>) has no visible text, so it now gets the same fallback id as other headers with no word characters (-1), instead ofsometext.header_id_from_textnow receive the rendered header HTML for markdown headers rather than the markdown source.Tests: two new tm-cases,
header_ids_issue192(the headers above, plus a code span that keeps its underscores) andheader_ids_footnote_ref(footnote refs in headers, which covers theValueErrorabove). Withlib/markdown2.pyreverted to master both new cases fail on the ids; the rest of the suite passes either way.The suite was run:
make testoneequivalent (cd test && python test.py -- -knownfailure, 298 tests) andpython test/test_redos.py(10 tests) on Python 3.12 and 3.9 with pygments, wavedrom, latex2mathml and emoji installed, all passing.pycodestyle --diffon the change reports only the two existing E128 lines of theheader_id_from_textsignature. Not run: the other Python versions and the Windows and Linux jobs in the CI matrix.