Quick Start: Fixing Markdown Files#
Now that you are familiar with Quick Start: Scanning Markdown Files, the previous page in our Quick Start guide series that showed how to find Rule Failures, let's move on to fixing some of those reported Rule Failures.
If you have not read the scanning Quick Start guide yet, we recommend visiting it first so the examples in this page make sense.
On the previous page, you learned how to use PyMarkdown to scan files and report Rule Failures. On this page, you will use PyMarkdown to fix some of those Rule Failures automatically, using Rule Plugins that support the autofix capability.
Important: Any fixing performed by PyMarkdown in fix mode is purely mechanical. It is designed not to change the meaning of your content.
A Rule Plugin can only offer the autofix capability if the change:
- adjusts formatting, not the wording or meaning, and
- is completely unambiguous.
For example, removing extra spaces after a # in a heading is safe, but rewriting
a heading from "Overview" to "Introduction" is not.
Once you know how to scan for Rule Failures, letting PyMarkdown fix the ones that support the autofix capability is the obvious next step. It helps you reduce or eliminate Rule Failures more quickly, and the process is easy to automate in scripts.
What You Will Learn#
Quick Start Guide Single Line Summary This page leverages your knowledge on scanning with PyMarkdown to explain how PyMarkdown's fix mode works to automatically correct Rule Failures.
On this page, you will:
- run your first
fixcommand with PyMarkdown - identify which Rule Plugins currently support the autofix capability
- work through a complete
fixexample on a single file:- scan the file
- fix the file
- interpret what was fixed, what was not fixed, and why
- apply the
fixcommand to multiple files or directories
Prerequisites#
The following sections assume that you have already installed PyMarkdown
and can run basic commands from a terminal (for example, changing directories and
running pymarkdown). The fix mode commands also build on what you learned about
the scan mode commands described on the Quick Start: Scanning Markdown Files
page.
If any of that feels unfamiliar, use the links above to walk through those pages first, then return here when you are ready to try fixing files.
Get Help for the fix Command#
Just like the help command for scan mode, the fix command with the --help
option prints help text for the command-line options and arguments available in
fix mode.
sh
pymarkdown fix --help
sh
pipenv run pymarkdown fix --help
Fix Mode Commands#
The fix mode commands automatically fix any Rule Failures for Rule Plugins that support the autofix capability. They:
- use the same options and arguments as scan mode commands
- differ only in the subcommand name:
scanvsfix
In practice, you can take any scan command and replace scan with fix. For example,
the following command applies available fixes to the file sample.md:
sh
pymarkdown fix sample.md
sh
pipenv run pymarkdown fix sample.md
and this command applies fixes to all files in any directories named docs under
the current directory:
sh
pymarkdown fix **/docs
sh
pipenv run pymarkdown fix **/docs
Aside from the fact that commands starting with scan run in scan mode and
commands starting with fix run in fix mode, the scan mode and fix
mode commands are otherwise identical.
Rule Plugins With Autofix#
When you run pymarkdown scan, you'll see Rule IDs like MD019 or MD025 in the
output. Some of those Rule Plugins support the autofix capability and can be
fixed automatically;
others cannot.
For quick reference, these are the built-in Rule Plugins that currently support the autofix capability in the latest release. It is presented here so those users following along with these examples in their own directories can understand what Rule Failures they should expect to get fixed.
NOTE: Don't memorize this list — use it as a reference. For this Quick Start guide, you only need to know that some Rule Plugins in your scan output can be fixed automatically. The full list is also available in our User Guide for easy reference.
| Rule ID & Link | Human-Readable Identifier | Short Description |
|---|---|---|
| MD001 | heading-increment, header-increment |
Heading levels should only increment by one level at a time. |
| MD004 | ul-style |
Inconsistent Unordered List Start style. |
| MD005 | list-indent |
Inconsistent indentation for list items at the same level. |
| MD007 | ul-indent |
Unordered list indentation. |
| MD009 | no-trailing-spaces |
Trailing spaces. |
| MD010 | no-hard-tabs |
Hard tabs. |
| MD013 | line-length |
Line length. |
| MD019 | no-multiple-space-atx |
Multiple spaces are present after hash character on Atx Heading. |
| MD021 | no-multiple-space-closed-atx |
Multiple spaces are present inside hash characters on Atx Closed Heading. |
| MD023 | heading-start-left,header-start-left |
Headings must start at the beginning of the line. |
| MD027 | no-multiple-space-blockquote |
Multiple spaces after blockquote symbol. |
| MD029 | ol-prefix |
Ordered list item prefix. |
| MD030 | list-marker-space |
Spaces after list markers. |
| MD035 | hr-style |
Horizontal rule style. |
| MD037 | no-space-in-emphasis |
Spaces inside emphasis markers. |
| MD038 | no-space-in-code |
Spaces inside code span elements. |
| MD039 | no-space-in-links |
Spaces inside link text. |
| MD044 | proper-names |
Proper names should have the correct capitalization. |
| MD046 | code-block-style |
Code block style. |
| MD047 | single-trailing-newline |
Each file should end with a single newline character. |
| MD048 | code-fence-style |
Code fence style should be consistent throughout the document. |
This list may evolve as new Rule Plugins are added or existing Rule Plugins gain
or lose autofix
support. For each Rule Plugin, the first column links to the Rule Plugin's
Fix Description in
the documentation, the second column lists human-readable identifiers, and the third
column gives a short description.
Fix a Single File#
Now that you have seen how to run pymarkdown fix and which Rule Plugins support
the autofix capability,
let's walk through a complete example on a single file.
Create a File to Scan#
For this example, open a console and change to a directory where you
have permission to create files. In this example, we
will refer to that directory as /home/myself. Then start the editor of your choice
in that directory and create a file named sample.md whose contents are two headings:
```Markdown
Heading 1#
Another Heading 1#
```
NOTE: Make sure sample.md ends with a blank line so your scan results match
the example in this Quick Start guide.
NOTE: In Markdown, a line that starts with 1 to 6 # characters, followed
by one or more spaces and then text, is called an ATX Heading. Both headings in
sample.md are ATX headings of this form. In this example, we will use the term
"heading" specifically to refer to this type of heading. For more background, you
can later refer to the Markdown Guide's headings
documentation.
Scan the File#
After following those directions, go to the console and type the following command to scan the file:
sh
pymarkdown scan sample.md
sh
pipenv run pymarkdown scan sample.md
When you run the above scan command, the output should show two specific Rule Failures
(MD019 and MD025). If your file does not end with a blank line, you may also
see
Rule Plugin MD047, which checks for a single trailing newline at the end of the
file.
If MD047 appears, add a blank line at the end of sample.md, save, and run the
scan again.
sh
/home/myself/sample.md:3:1: MD019: Multiple spaces are present after hash character on Atx Heading. (no-multiple-space-atx)
/home/myself/sample.md:3:1: MD025: Multiple top-level headings in the same document (single-title,single-h1)
This matches what we expect. Line 3 has a heading with multiple spaces after the
# character, which triggers Rule Plugin MD019 (extra spaces after # in an
ATX heading).
The same heading is also a level‑1 heading in a document that already has a level‑1
heading on line 1, which triggers Rule Plugin MD025.
Fixing the File#
After verifying that your scan results match the output specified above, go back to your console and type the following command to fix the same file:
sh
pymarkdown fix sample.md
sh
pipenv run pymarkdown fix sample.md
After running that command, you should see output similar to:
bash
Fixed: /home/myself/sample.md
and if you open the sample.md file, you will notice the change to the
heading on line 3:
```Markdown
Heading 1#
Another Heading 1#
```
To see which Rule Failures remain, run the scan command from the Scan the File
section again. The returned output should validate that the Rule Failure for MD019
was fixed.
sh
/home/myself/sample.md:3:1: MD025: Multiple top-level headings in the same document (single-title,single-h1)
What Was Fixed?#
Because Rule Plugin MD019 supports the autofix capability,
it can reduce
the spaces between the # character and the next character on line 3 to a single
space. In Markdown, this type of heading allows one or more spaces after the #,
so PyMarkdown can safely collapse multiple spaces into one without changing the
meaning of the heading.
What Was Not Fixed?#
The situation for Rule Plugin MD025 is different. As described in that Rule Plugin's Fix Description, changing the level of the heading on line 3 is too ambiguous for PyMarkdown to fix automatically, because it cannot tell which level you intended.
Consider the following questions:
- Did the author intend the heading on line 1 or the heading on line 3 to be the "real" level 1 heading?
- If line 1 is the intended level 1 heading, should line 3 be changed to a level 2 heading instead?
- What if this file were longer and had more headings after line 3? Should all of those headings be promoted by one level, or should they be left alone?
Because there are so many possible interpretations, PyMarkdown cannot safely choose
a single "correct" fix. As a result, resolving the violation of Rule MD025 on
line 3 is something you must do manually in your editor by choosing the appropriate
heading level. A simple approach is:
- pick a single
#heading as the main document title - change any additional
#headings to##(or deeper) to reflect the structure you want
You can take this above approach with any of the unfixed Rule Failures to whittle away at the list of manual fixes you need to apply.
Fix Multiple Files or Directories#
The example above used a single file, sample.md. In real projects, you'll usually
want to fix many files at once. Since fix and scan share the same options, you
can reuse the same command patterns from the scanning Quick Start guide.
Earlier, in the Scan Glob Paths section, you saw
that **/docs means "all docs directories under the current directory".
To apply any available fixes with the same pattern, first scan:
sh
pymarkdown scan **/docs
sh
pipenv run pymarkdown scan **/docs
Review the reported Rule Failures, then run:
sh
pymarkdown fix **/docs
sh
pipenv run pymarkdown fix **/docs
to apply fixes for any Rule Plugins that support the autofix capability to all matching files.
Where to Go From Here#
If you followed along with the examples on your own files, you have:
- run
pymarkdown scanand thenpymarkdown fixon an individual file - learned that calling patterns learned for the
scancommand work with thefixcommand
Depending on what you want to do next, choose one of:
Next, in the Quick Start guide series:
- Use Quick Start: Managing Rule Plugins to learn how to turn specific Rule Plugins on or off
If you want to skip ahead, you can go to the following page:
- Use Quick Start: Enabling PyMarkdown Extensions to learn how to add extra features via extensions
If you need some review:
- Select Quick Start: Introduction for an overview of all Quick Start documents
- Select Quick Start: Scanning Markdown Files for a refresher on how to scan files for Rule Failures