mdformat Documentation

repository·master·Indexed 21 days ago

https://github.com/hukkin/mdformat

An opinionated, CommonMark-compliant Markdown formatter available as a Unix-style CLI tool and Python library. mdformat enforces consistent styling, including ATX headings and sorted link references, and is extensible via plugins for different Markdown flavors (such as GFM) and code block formatters. It supports configuration via .mdformat.toml, integration as a pre-commit hook, and provides a Python API for formatting text and files.

Tokens
8.7K
Snippets
30
Records
46
Agent score
73%

What's inside mdformat

  1. Overview of mdformat features and opinions

    master

    mdformat is a CommonMark compliant Markdown formatter. It enforces a consistent style across Markdown documents with the following opinions:

    • Indentation & Whitespace: Ensures consistent indentation and whitespace throughout the document.
    • Headings: Always uses ATX style headings (e.g., # Heading).
    • Link References: Moves all link references to the bottom of the document, sorted by label.
    • Code Blocks: Reformats indented code blocks into fenced code blocks.
    • Ordered Lists: Uses 1. as the ordered list marker whenever possible, including for non-initial list items.

    Note on Line Wrapping: By default, mdformat will not change word wrapping. This is intended to support Semantic Line Breaks.

  2. How mdformat formats thematic breaks and whitespace

    master

    Thematic breaks

    Formatted as a string of underscores exactly 70 characters wide.

    Whitespace rules

    • Converts line endings to a single newline character.
    • Strips leading and trailing whitespace from paragraphs.
    • Indents block quotes and list items consistently.
    • Separates blocks with a single empty line (except for 'tight lists', which use a single newline).
    • Ensures the document ends with a single newline character (unless the document is empty).
  3. How mdformat formats code blocks and spans

    master

    Code blocks

    Only fenced code blocks are allowed. If you use indented code blocks, mdformat will reformat them into fenced code blocks to support info strings.

    Code spans

    mdformat reduces code spans (backtick strings) to the minimum length required. It strips unnecessary whitespace from the front and back, unless the content itself contains backticks.

    Example of code span reduction:

    `Backtick string is reduced.`
    
    `Space is stripped from the front and back...`
    
    `` ...unless a "`" character is present. ``
  4. How mdformat formats bullet and ordered lists

    master

    Bullet lists

    mdformat uses - as the default bullet marker. To maintain distinction, it alternates between - and * markers for consecutive bullet lists.

    Ordered lists

    mdformat uses . as the default ordered list marker. To minimize diffs when items are added or removed, it uses a non-numbering style where every item starts with 1. or 1).

    Note: You can enable consecutive numbering via configuration.

    Example of non-numbering style:

    1. Item A
    1. Item B
    1. Item C
  5. How mdformat formats links

    master

    Redundant angle brackets surrounding a link destination are removed.

    Example:

    [Python](https://python.org)

    All link reference definitions are:

    1. Moved to the bottom of the document.
    2. Sorted by label.
    3. Cleaned of unused or duplicate references.
    Here's a link to [GitLab][dupe ref]
    
    [dupe ref]: https://gitlab.com
  6. Understand mdformat's formatting style and philosophy

    master

    mdformat follows a consistent formatting style designed to make writing, editing, and collaborating on Markdown documents as smooth as possible.

    Key principles include:

    • Minimizing Diffs: The style is optimized to reduce the number of lines changed in a version control diff (e.g., using non-numbering for ordered lists).
    • Content Preservation: mdformat only changes style, not content. It includes a safety check that errors if the Markdown AST (Abstract Syntax Tree) changes after formatting, ensuring the rendered HTML remains visually identical.
    • Consistency: It enforces specific syntax for headings, lists, and code blocks to ensure a uniform document structure.
  7. Develop a code formatter plugin

    master

    To create a plugin that formats code blocks (e.g., Python, JavaScript) within Markdown, you must define a formatter function with the following signature:

    Callable[[str, str], str]

    • Input 1: The unformatted code from the code block.
    • Input 2: The info string (the language identifier).
    • Return value: The formatted code as a string.

    Your plugin must be exposed via entry point distribution metadata using the group mdformat.codeformatter. The name of the entry point must match the language name used in Markdown info strings.

    # Example entry point configuration for setup.py
    import setuptools
    
    setuptools.setup(
        # other arguments here...
        entry_points={
            "mdformat.codeformatter": ["python = my_package.some_module:format_python"]
        }
    )
  8. Install mdformat

    master

    Install mdformat via your preferred Python package manager.

    Note: The formatting style produced by mdformat may change between versions. It is highly recommended to pin your mdformat dependency version to ensure consistent formatting across environments.

    # Example installation (refer to README for specific commands)
    pip install mdformat
  9. Configure mdformat using a .mdformat.toml file

    master

    You can configure mdformat behavior using a TOML file named .mdformat.toml.

    Resolution Logic:

    • The tool searches for the configuration file starting from the location of the file being formatted and moves up the file tree until a config file is found.
    • When formatting from standard input (stdin), resolution starts from the current working directory.
    • Precedence: Command line interface arguments always take precedence over settings in the .mdformat.toml file.
    # .mdformat.toml
    wrap = "keep"         # options: {"keep", "no", INTEGER}
    number = false        # options: {false, true}
    end_of_line = "lf"    # options: {"lf", "crlf", "keep"}
    validate = true       # options: {false, true}
    # extensions = [      # options: a list of enabled extensions (default: all installed are enabled)
    #     "gfm",
    #     "toc",
    # ]
    # codeformatters = [  # options: a list of enabled code formatter languages (default: all installed are enabled)
    #     "python",
    #     "json",
    # ]
  10. Use mdformat as a pre-commit hook

    master

    To automatically format Markdown files before every commit, add mdformat to your .pre-commit-config.yaml. You can also include plugins (like mdformat-gfm or mdformat-black) using the additional_dependencies key.

    - repo: https://github.com/hukkin/mdformat
      rev: 1.0.0  # Use the ref you want to point at
      hooks:
      - id: mdformat
        # Optionally add plugins
        additional_dependencies:
        - mdformat-gfm
        - mdformat-black
  11. Install mdformat

    master

    You can install mdformat using pipx. Depending on your requirements, you may need to inject additional plugins for specific Markdown flavors.

    To install with standard CommonMark support:

    pipx install mdformat

    To install with GitHub Flavored Markdown (GFM) support, you must inject the mdformat-gfm plugin after installing the core package:

    pipx install mdformat
    pipx inject mdformat mdformat-gfm