Guide
Em dashes in Markdown: keep the source ASCII
Keep Markdown source predictable when an editor, plugin, or static site generator turns ASCII hyphen runs into U+2013 or U+2014 during editing or rendering.
By Kris Vinters · Published · 4 minute read
Find which layer changes the dashes
Markdown itself does not require smart punctuation. A separate typography pass can convert -- to U+2013 and --- to U+2014. Python-Markdown calls its extension SmartyPants; other editors and site generators expose similar smart-punctuation or typographic-symbol options.
The conversion can happen while you type, when Markdown becomes HTML, or in a later template filter. Those stages produce different diffs: an editor changes the source file, while a renderer can leave the source ASCII and place the Unicode character only in generated output.
Code fences and inline code are normally excluded by Markdown-aware typography extensions, but editor autocorrect and pipeline order can act before the Markdown parser. Front matter is usually consumed before body rendering, yet a whole-file formatter can still rewrite quoted values. Test the exact stack that writes your file.
Write and keep an ASCII-only source
Turn off smart punctuation in the editor that saves the source. Then turn off the dash substitution in the Markdown extension or generator if the generated HTML must also remain ASCII. Search the settings UI for smart punctuation, SmartyPants, smart dashes, or typographic symbols because the option name belongs to the implementation, not to Markdown.
Keep -- and --- as ASCII sequences in prose when that is your chosen source convention. In code blocks, front matter, shell examples, and identifiers, use the exact ASCII syntax the target language expects. Review both the source diff and the built output so you know which stage made a change.
If a formatter must stay on, scope it to prose or configure exclusions for code, front matter, generated files, and fixtures. A repository check for non-ASCII source can catch accidental substitutions, but it must allow the languages and fixtures your project intentionally contains.
For text that already contains Unicode dashes, paste the prose into Ghostchars, open Advanced, and select "Plain-text punctuation". That option converts U+2013 and U+2014 to ASCII hyphens. It also converts other typographic punctuation, so review the findings and do not run an entire source file through it without checking syntax-sensitive regions.
This is character normalization, not a statement about authorship. The cleaner changes selected punctuation. The prose report measures patterns such as dash rate and returns measurements, not a verdict.
Keep code blocks, front matter, and diffs stable
Add one small regression sample to the project: prose with -- and ---, an inline-code span, a fenced code block, and a front-matter value. Build it with the same command as production and compare the source and output. This catches a renderer change without claiming every Markdown stack behaves alike.
When a diff shows a dash change, inspect the raw file before editing. If the source is still ASCII, the renderer made the typographic output. If the Unicode codepoint is already in the source, check editor autocorrect, format-on-save, paste transforms, and pre-commit formatters.
Markdown dash questions
Does Markdown convert two or three hyphens by itself?
No universal Markdown rule requires it. A smart-punctuation extension, editor, theme, or generator can add the conversion. Check the implementation and its configuration.
Will smart punctuation change code blocks?
Markdown-aware extensions generally exclude code spans and code blocks, but an editor or whole-file formatter can run before parsing. Keep a build fixture and verify your actual pipeline.
Can the published page use U+2014 while the source stays ASCII?
Yes. A renderer can leave --- in the source and emit U+2014 only in HTML. If both source and output must stay ASCII, turn off that rendering pass as well as editor substitutions.
Continue with all practical guides to hidden characters and the limits of cleaning.