repomatic.markdown module¶

Prepare externally-sourced markdown for a pull request or issue body.

sanitize_markdown_mentions() neutralizes @mentions, #issue refs and GitHub URLs, and demote_markdown_headings() pushes the embedded content’s headings below the embedding document’s own sections. Both shield fenced code blocks, so a # comment or an @decorator in a sample survives.

A leaf module with no project-internal imports, so any module can import it without the risk of an import cycle.

repomatic.markdown.sanitize_markdown_mentions(text)[source]¶

Neutralize @mentions, #issue refs, and GitHub URLs in markdown.

Prevents GitHub from auto-linking mentions and issue references in externally-sourced markdown (upstream release notes, third-party tool output) that would cause notification spam or accidental issue closure.

Uses a placeholder extraction approach: fenced code blocks and inline code spans are temporarily replaced with unique placeholders before sanitization, then restored afterward. This avoids the fragile “sanitize then restore” pattern that caused bugs in both Dependabot (2019 code-fence regression, dependabot/dependabot-core#1421) and Renovate (ongoing restoration pass edge cases, renovatebot/renovate#8823, renovatebot/renovate#2554).

Inserts a Unicode zero-width space (U+200B) after @ and # to break GitHub’s mention and issue parsers without affecting visual rendering. Rewrites github.com URLs to redirect.github.com to prevent backlink cross-references on upstream issues.

Parameters:

text (str) – Raw markdown text from an external source.

Return type:

str

Returns:

Sanitized markdown safe for embedding in a GitHub PR or issue body.

Note

Only call this on externally-sourced content (upstream release notes, third-party tool output). Do not call on content authored by the repository owner where mentions are intentional.

repomatic.markdown.demote_markdown_headings(text, floor)[source]¶

Demote ATX headings so the shallowest one lands at level floor.

Externally-sourced markdown (upstream release notes) carries its own # and ## headings, which GitHub renders at full size even inside a <details> block, so they compete with the embedding document’s section hierarchy. All headings are shifted deeper by the uniform offset that puts the shallowest at floor, preserving the body’s internal structure; levels past ###### (h6, markdown’s deepest) are clamped. Headings already at or below floor are left alone: this function never promotes.

Fenced code blocks are shielded with the same placeholder extraction as sanitize_markdown_mentions(), so # comments in shell samples survive. Only ATX headings are rewritten: setext headings (underlined with === or ---), rare in release notes, pass through unchanged.

Parameters:
  • text (str) – Raw markdown text from an external source.

  • floor (int) – Target level (1-6) for the shallowest heading.

Return type:

str

Returns:

Markdown with headings demoted.