pymdtools

Contents:

  • pymdtools
  • Package API
  • Common Utilities
  • File Tools
  • Markdown Instructions
  • Markdown Link Management
    • Supported Links
    • Link Records
    • Common Usage
    • Choosing A Rewrite Function
    • Public API
      • Link
        • Link.label
        • Link.name
        • Link.title
        • Link.url
      • get_domain_name()
      • is_external_link()
      • markdown_code_ranges()
      • merge_ranges()
      • move_base_path_in_md_text()
      • position_in_ranges()
      • search_link_in_md_file()
      • search_link_in_md_text()
      • search_link_in_md_text_json()
      • sub_string_link_by_ref_md()
      • sub_string_link_md()
      • sub_string_name_by_ref_md()
      • update_link_from_old_link()
      • update_link_in_md_text()
      • update_links_from_old_link()
      • update_links_in_md_text()
  • Markdown File Wrapper
  • Markdown To PDF
  • Mistune Integration
  • Markdownify Integration
  • Markdown Normalization
  • Translation Helpers
  • Release process
  • License
pymdtools
  • Markdown Link Management
  • View page source

Markdown Link Management

pymdtools.mdcommon provides utilities for inspecting and rewriting links inside Markdown documents. It is meant for workflows that update a set of Markdown files together: collecting link targets, moving relative paths, renaming labels, replacing obsolete targets, or normalizing references after a documentation tree has been reorganized.

The module works on Markdown text and leaves file discovery, encoding, backups, and writes to higher-level helpers such as pymdtools.common and pymdtools.filetools. This keeps link transformations easy to test before the updated content is written back to disk.

Supported Links

The parser handles the two Markdown link forms used by the project:

  • inline links, such as [label](target "title");

  • reference-style links, such as [label][id] with a matching [id]: target "title" definition.

External links are detected separately so that bulk path updates can skip URLs such as https://example.org or mailto:contact@example.org.

Link Records

Links are exchanged as small dictionaries. This representation makes it simple to serialize, compare, transform, and feed discovered links back into rewrite functions.

Common keys are:

  • name stores the visible link label;

  • url stores the link target;

  • title stores the optional Markdown title;

  • line stores the one-based line number for discovered links;

  • id_link is used for reference-style links;

  • name_to_replace can be provided when replacing a label with another one.

Common Usage

Extract links from Markdown text:

from pymdtools.mdcommon import search_link_in_md_text

links = search_link_in_md_text('[Docs](docs/index.md "Documentation")')

Replace one link by label:

from pymdtools.mdcommon import update_links_in_md_text

updated = update_links_in_md_text(
    "[old](old.md)",
    {"name_to_replace": "old", "name": "new", "url": "new.md"},
)

Move relative link targets under a new base path while leaving external links unchanged:

from pymdtools.mdcommon import move_base_path_in_md_text

updated = move_base_path_in_md_text("[Guide](guide.md)", "docs")

Apply a transformation to a Markdown tree:

from pathlib import Path

from pymdtools.common import get_file_content, set_file_content
from pymdtools.mdcommon import move_base_path_in_md_text

for md_file in Path("docs").rglob("*.md"):
    original = get_file_content(md_file)
    updated = move_base_path_in_md_text(original, "archive")
    if updated != original:
        set_file_content(md_file, updated)

Choosing A Rewrite Function

Use update_link_in_md_text when the visible label is the stable identifier. Use update_link_from_old_link when both the previous label and previous target must match before replacing a link. Use update_links_from_old_link to apply several old/new replacements in sequence.

Use move_base_path_in_md_text for documentation moves where every relative target in one Markdown document needs to be prefixed with the same base path.

Public API

Markdown link management helpers.

pymdtools.mdcommon provides tools to inspect and rewrite links inside Markdown documents. It is designed for workflows that modify a set of Markdown files together, for example after moving documentation folders, renaming pages, or replacing obsolete link targets.

Links are represented as dictionaries with keys such as name, url, title, line, id_link and name_to_replace. This small data model is easy to serialize, compare, transform, and feed back into rewrite functions.

The helpers operate on Markdown text and avoid mutating caller-provided link dictionaries. File-oriented helpers delegate path validation and text loading to pymdtools.common.

class pymdtools.mdcommon.Link

Bases: dict[str, str | int | None]

Dictionary-compatible link object.

The class stores the same fields returned by link extraction helpers while exposing convenience properties for name, label, url and title. Assigning None removes the underlying key.

property label: str | None

Alias for name.

property name: str | None

Return the link label, stored under the name key.

property title: str | None

Return the optional link title.

property url: str | None

Return the link target URL.

pymdtools.mdcommon.get_domain_name(url: str) → str

Return the domain part of an external URL.

Non-external URLs are returned unchanged. mailto URLs return their path, which is the email address.

Parameters:

url – URL or Markdown link target to inspect.

Returns:

Domain name for external HTTP(S) URLs, email address for mailto URLs, or the original value for local links.

pymdtools.mdcommon.is_external_link(url: str) → bool

Return whether url is an external link.

http and https URLs require both a scheme and a network location. Other schemes, such as mailto, are considered external when their scheme is present. Invalid URLs return False.

Parameters:

url – URL or Markdown link target to classify.

Returns:

True when the target is considered external, otherwise False.

pymdtools.mdcommon.markdown_code_ranges(text: str) → list[tuple[int, int]]

Locate fenced, indented, and inline Markdown code regions.

pymdtools.mdcommon.merge_ranges(ranges: Sequence[tuple[int, int]]) → list[tuple[int, int]]

Return sorted, overlapping character ranges as disjoint ranges.

pymdtools.mdcommon.move_base_path_in_md_text(text_md: str, mv_base_path: str | PathLike[str] | Path) → str

Prefix relative Markdown links with mv_base_path.

External URLs are left unchanged. The generated Markdown URLs use POSIX separators, even on Windows.

Parameters:
  • text_md – Markdown text to update.

  • mv_base_path – Base path to prepend to relative link targets.

Returns:

Updated Markdown text.

Raises:

TypeError – If extracted link records do not contain string URLs.

pymdtools.mdcommon.position_in_ranges(index: int, ranges: Sequence[tuple[int, int]]) → bool

Return whether index belongs to one of the sorted ranges.

pymdtools.mdcommon.search_link_in_md_file(filename: str | PathLike[str] | Path, filename_ext: str = '.md', encoding: str | None = 'utf-8', previous_links: Sequence[Mapping[str, str | int | None]] | None = None) → list[dict[str, str | int | None]]

Extract Markdown links from a file.

The file is validated with pymdtools.common.check_file() before being read with pymdtools.common.get_file_content().

Parameters:
  • filename – Markdown file to inspect.

  • filename_ext – Expected file extension, including the leading dot.

  • encoding – Encoding used to read the file. None triggers automatic detection in pymdtools.common.

  • previous_links – Optional existing links to prepend to the result.

Returns:

A list of link records extracted from the file.

Raises:
  • RuntimeError – Propagated from file validation helpers.

  • OSError – Propagated from file reading helpers.

pymdtools.mdcommon.search_link_in_md_text(text: str, previous_links: Sequence[Mapping[str, str | int | None]] | None = None) → list[dict[str, str | int | None]]

Extract Markdown links from text.

Both inline links, such as [label](target "title"), and reference links, such as [label][id] plus [id]: target "title", are returned. The returned records contain name, url, title and line.

previous_links is copied before new entries are appended.

Parameters:
  • text – Markdown text to inspect.

  • previous_links – Optional existing links to prepend to the result.

Returns:

A list of link records in discovery order. Each extracted record contains name, url, title and line when available.

pymdtools.mdcommon.search_link_in_md_text_json(text_md: str) → str

Return links found in Markdown text as formatted JSON.

Parameters:

text_md – Markdown text to inspect.

Returns:

A deterministic, pretty-printed JSON string describing extracted links.

pymdtools.mdcommon.sub_string_link_by_ref_md(unused_dummy: object, link: Mapping[str, str | int | None]) → str

Build a Markdown reference definition from a link mapping.

Parameters:
  • unused_dummy – Kept for compatibility with re.sub callbacks.

  • link – Mapping containing url, optional id_link and optional title.

Returns:

Markdown reference definition line.

Raises:

TypeError – If required fields are missing or are not strings.

pymdtools.mdcommon.sub_string_link_md(unused_dummy: object, link: Mapping[str, str | int | None]) → str

Build an inline Markdown link string from a link mapping.

Parameters:
  • unused_dummy – Kept for compatibility with re.sub callbacks.

  • link – Mapping containing name, url and optional title.

Returns:

Markdown inline link string.

Raises:

TypeError – If required fields are missing or are not strings.

pymdtools.mdcommon.sub_string_name_by_ref_md(unused_dummy: object, link: Mapping[str, str | int | None]) → str

Build the visible part of a Markdown reference-style link.

Parameters:
  • unused_dummy – Kept for compatibility with re.sub callbacks.

  • link – Mapping containing name and id_link.

Returns:

Markdown reference-style link label.

Raises:

TypeError – If required fields are missing or are not strings.

pymdtools.mdcommon.update_link_from_old_link(text_md: str, old_link: Mapping[str, str | int | None], new_link: Mapping[str, str | int | None]) → str

Replace a link identified by its previous label and URL.

This is stricter than update_link_in_md_text(): both the old label and old URL must match before an inline link is replaced.

Parameters:
  • text_md – Markdown text to update.

  • old_link – Mapping describing the existing link. Requires name and url.

  • new_link – Mapping describing the replacement link.

Returns:

Updated Markdown text.

Raises:

TypeError – If required fields are missing or are not strings.

pymdtools.mdcommon.update_link_in_md_text(text_md: str, name: str, new_link: Mapping[str, str | int | None]) → str

Replace links identified by their visible label.

Inline links and reference-style links are both supported. new_link is copied internally, so the caller-provided mapping is not modified.

Parameters:
  • text_md – Markdown text to update.

  • name – Existing visible link label to replace.

  • new_link – Mapping containing at least name and url. title is optional.

Returns:

Updated Markdown text.

Raises:

TypeError – If required fields in new_link are missing or are not strings.

pymdtools.mdcommon.update_links_from_old_link(text_md: str, links_couple: Sequence[tuple[Mapping[str, str | int | None], Mapping[str, str | int | None]]]) → str

Apply several (old_link, new_link) replacements to Markdown text.

Parameters:
  • text_md – Markdown text to update.

  • links_couple – Sequence of (old_link, new_link) pairs.

Returns:

Updated Markdown text after all replacements have been applied in order.

Raises:

TypeError – If any replacement mapping misses required string fields.

pymdtools.mdcommon.update_links_in_md_text(text_md: str, links: Mapping[str, str | int | None] | Sequence[Mapping[str, str | int | None]]) → str

Replace one or more links in Markdown text.

A single link mapping or a sequence of link mappings is accepted. When name_to_replace is provided, it is used as the search key and name is used as the replacement label.

Parameters:
  • text_md – Markdown text to update.

  • links – One link mapping or a sequence of mappings describing the new link values.

Returns:

Updated Markdown text.

Raises:

TypeError – If required link fields are missing or are not strings.

Previous Next

© Copyright Copyright 2018, Florent Tournois.

Built with Sphinx using a theme provided by Read the Docs.