Skip to content

Preserve queries and fragments when rewriting Markdown file links - #746

Open
pabszero wants to merge 10 commits into
trentm:masterfrom
pabszero:fix-markdown-link-suffixes
Open

pabszero wants to merge 10 commits into
trentm:masterfrom
pabszero:fix-markdown-link-suffixes

Conversation

@pabszero

@pabszero pabszero commented Oct 19, 2026 •

Copy link
Copy Markdown

With markdown-file-links, [guide](guide.md#install) keeps pointing to Markdown instead of HTML, while [part](guide.html#part.md) changes the fragment incorrectly. Check only the path before ? or #, then preserve the suffix exactly, including empty delimiters. Apply the same conversion to reference-link targets, including documents with reference links and no inline .md link.

Fixture cases cover 34 inline/reference URL combinations, link_defs=False, and unchanged inline images. Reference definitions are reassigned only when their path ends in .md. The changelog documents the fix.

Validation on Windows CPython 3.13.5:

  • The three regression fixtures fail against original upstream e69bbdf and pass with the fix.
  • Official selected suite: cd test && python test.py -- -knownfailure — 298 passed, with optional dependencies installed and the harness’s version-specific Pygments exclusions.
  • ReDoS suite: 10 passed.
  • Independent fixture-output and URL-assignment controls passed; git diff --check passed, with no PEP8 diagnostics on added Python lines. Existing whole-file diagnostics remain.

Other Python versions and operating systems were not run locally for this revision. OpenAI Codex assisted with investigation, implementation, tests and this description.

@Crozzers Crozzers left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changelog also needs updating

Comment thread README.md Outdated
including an operator cell such as ```` ``|`` ````. A pipe immediately after the
closing delimiter separates the next cell.

The `markdown-file-links` extra converts `.md` file links to `.html`, preserving

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really needed here in the readme. It clogs it up and begs the question "why is this extra so important? Why not add the other 20 extras right here".
This should go in dedicated a wiki page for the extra, if one doesn't already exist

Comment thread test/test_markdown2.py Outdated

def test_markdown_file_links_query_and_fragment(self):
cases = (
("guide.md", "guide.html"),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should go in a testcase file in tests/tm-cases/, same format as the others.

Usually stuff is only put here if it's difficult to express in those test files, or so large it's impractical to commit in a file

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Plus if I make this test fail an assertion on purpose I get this error, rather than anything useful. This is an issue with the test harness rather than your changes specifically, but another reason to put it in tm-cases, which doesn't have that issue

Traceback (most recent call last):
  File "/mnt/nas/Python/python-markdown2/test/test.py", line 54, in <module>
    retval = testlib.harness(testdir_from_ns=testdir_from_ns,
                             default_tags=default_tags)
  File "/mnt/nas/Python/python-markdown2/test/testlib.py", line 703, in harness
    result = test(testdir_from_ns, tags, setup_func=setup_func)
  File "/mnt/nas/Python/python-markdown2/test/testlib.py", line 396, in test
    result = runner.run(suite)
  File "/mnt/nas/Python/python-markdown2/test/testlib.py", line 539, in run
    result.printSummary()
    ~~~~~~~~~~~~~~~~~~~^^
  File "/mnt/nas/Python/python-markdown2/test/testlib.py", line 506, in printSummary
    self.printErrorList('FAIL', self.failures)
    ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
  File "/mnt/nas/Python/python-markdown2/test/testlib.py", line 512, in printErrorList
    % (flavour, self.getDescription(test)))
                ~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/mnt/nas/Python/python-markdown2/test/testlib.py", line 472, in getDescription
    if test._testlib_explicit_tags_:
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: '_SubTest' object has no attribute '_testlib_explicit_tags_'

Comment thread lib/markdown2.py Outdated
for key, url in self.md.urls.items():
if url.endswith('.md'):
self.md.urls[key] = url.removesuffix('.md') + '.html'
self.md.urls[key] = self._convert_url(url)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If previously self.md.urls was only mutated if the link was deemed valid (endswith('.md')), then shouldn't this do a similar check to L3949?

Saves us potentially polluting the dict with random extra URLs?

@pabszero

Copy link
Copy Markdown
Author

Addressed the review in 1300a57: removed the README addition, moved the URL matrix into test/tm-cases (including reference-only links, link_defs=False, and the image compatibility control), and added the CHANGES entry. The reference-definition loop now assigns only when the path before the query/fragment ends in .md. The test harness is unchanged.

The official selected suite passes (298 tests), as do all 10 ReDoS cases. The three regression fixtures fail on the original source and pass with the fix; independent output and assignment controls also pass. The published tree matches the locally tested tree, and the PR description reflects the revision. OpenAI Codex assistance is disclosed there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants