PyMarkdown Linter
PyMarkdown is a comprehensive Markdown linter that scans files against a robust set of rules to identify potential problems and style issues. It adheres to both GitHub Flavored Markdown and CommonMark specifications, offering both 'scan' mode to detect issues and 'fix' mode to automatically correct certain violations. The project maintains an active and consistent release schedule, typically delivering updates every 1-2 months, with a strong focus on enhancing documentation and continuous improvement.
Warnings
- breaking The minimum required Python version was updated from 3.9 to 3.10 in version 0.9.34. [cite: v0.9.34 release notes, 4] Earlier Python versions are no longer supported.
- gotcha In version 0.9.31, support for JSON5 (allowing comments in JSON configuration files) was enabled by default. [cite: v0.9.31 release notes, 2] If you have existing JSON configuration files that previously relied on comments being ignored or handled differently, this change could alter parsing behavior.
- gotcha When using the `--alternate-extensions` command-line argument, the specified extensions completely *replace* the default `.md` extension set. If you wish to lint `.md` files along with other extensions, you must explicitly include `.md` in the list (e.g., `--alternate-extensions=.md,.mdown`).
- gotcha Starting with version 0.9.30, new `disable` and `enable` pragma commands were introduced for document-wide rule control. [cite: v0.9.30 release notes, 8] While older `disable-next-line` and `disable-num-lines` commands still function, migrating to the new commands might be necessary for consistent and comprehensive rule management, especially for blanket disabling/enabling.
- gotcha PyMarkdown merges configuration from three sources: built-in defaults, configuration files, and command-line overrides. Later sources (e.g., command line) always override earlier ones. Incorrectly assuming the precedence order can lead to unexpected linting behavior.
Install
-
pip install pymarkdownlnt
Imports
- PyMarkdownApi
from pymarkdown.api import PyMarkdownApi
Quickstart
import os
from pymarkdown.api import PyMarkdownApi
# Create a dummy Markdown file for scanning
markdown_content = """
# Heading 1
This is some text.
* Item 1
* Item 2
This is some more text with extra spaces.
"""
file_path = "example.md"
with open(file_path, "w") as f:
f.write(markdown_content)
# Initialize the API
api = PyMarkdownApi()
# Scan the file
scan_results = api.scan_path(file_path)
print(f"Scanning: {file_path}")
if scan_results.pragma_errors or scan_results.scan_failures:
print("Found issues:")
for failure in scan_results.scan_failures:
print(f" {failure.log_file}: Line {failure.line_number}, Col {failure.column_number}: {failure.rule_id} - {failure.rule_name} ({failure.rule_description})")
else:
print("No issues found.")
# Optionally, fix the file (if fixable rules triggered)
# fix_results = api.fix_path(file_path)
# if fix_results.result_file_was_changed:
# print(f"File '{file_path}' was fixed.")
# with open(file_path, 'r') as f:
# print('Fixed content:\n' + f.read())
# else:
# print(f"File '{file_path}' did not require fixing.")
os.remove(file_path)