GFM vs CommonMark vs Pandoc Markdown: Syntax Compared
Know which Markdown features travel safely
Markdown looks like one language until the same file renders differently on GitHub, Hugo, Obsidian, or Pandoc. And the problem is not that Markdown is unreliable.
It is that “Markdown” describes a family of related syntaxes, parsers, and platform features rather than a single universal document format. CommonMark defines a precise portable core, GitHub Flavored Markdown adds features useful for software collaboration, and Pandoc Markdown expands the language into a serious document-authoring format.

Choosing between them depends on where the document must render. A README file, a Hugo blog post, and an academic paper each have different requirements. This comparison is part of the broader documentation tooling picture and covers the formal dialects, platform-specific extensions, and practical portability rules so you can pick the right syntax for your target environment. For a quick syntax reference, the Markdown cheatsheet covers the essential formatting elements.
Markdown Is Not One Language
The original Markdown syntax was intentionally small and loosely specified. That made it easy to read and implement, but different parsers began interpreting ambiguous input differently.
CommonMark was created to define consistent parsing rules for the fundamental Markdown structures. GitHub Flavored Markdown, usually called GFM, builds on that foundation with several widely used extensions.
Pandoc Markdown takes a different approach. Instead of remaining a small web-oriented syntax, it adds document features such as citations, metadata, footnotes, definition lists, attributes, and mathematical notation.
A simplified relationship looks like this:
This hierarchy is useful, but it is not exact inheritance in every implementation. Each renderer can enable, disable, or add syntax independently.
The Short Answer
Use CommonMark-compatible syntax when portability matters most.
Use GFM when writing README files, pull requests, issue templates, and technical documentation intended primarily for GitHub-compatible platforms.
Use Pandoc Markdown when the source document must become PDF, DOCX, EPUB, LaTeX, slides, or an academic paper with citations and metadata.
For a Hugo technical blog, use the CommonMark core plus the Goldmark extensions that your site explicitly enables. Do not assume every feature visible on GitHub will work merely because Hugo is described as GFM-compatible.
Opinionated take: if you only remember one rule for a Hugo technical blog, treat CommonMark plus GFM-style tables and task lists as the default, and treat everything else — footnotes, math, callouts, header attributes — as an explicit, tested extension rather than an assumed default. That single habit prevents most of the portability failures described below.
CommonMark: The Portable Core
CommonMark is a formal specification for the basic Markdown language. Its main contribution is not a large collection of features, but consistent parsing.
It defines how parsers should interpret:
- Paragraphs
- ATX and Setext headings
- Block quotes
- Ordered and unordered lists
- Fenced and indented code blocks
- Emphasis and strong emphasis
- Links and images
- Reference-style links
- Inline code
- Thematic breaks
- Raw HTML blocks
- Hard and soft line breaks
A CommonMark document can still behave differently at the presentation layer. CSS, syntax highlighting, heading anchors, HTML sanitization, and link policies are outside the core parsing rules.
CommonMark should therefore be treated as a reliable structural baseline, not a promise that every renderer will produce an identical page.
A Portable CommonMark Example
# Service Deployment
The service exposes a small HTTP API.
## Requirements
- Linux
- Docker
- 8 GB of memory
## Start the service
```bash
docker compose up -d
```
See the [configuration guide](configuration.md) for details.
This type of document works across almost every modern Markdown environment. It uses headings, paragraphs, lists, fenced code, and ordinary links without relying on dialect-specific extensions.
GitHub Flavored Markdown: CommonMark for Software Projects
GitHub Flavored Markdown is a formal dialect based on CommonMark. It preserves the CommonMark parsing model and adds features commonly needed in repository documentation and collaboration.
The formal GFM specification adds:
- Pipe tables
- Task list items
- Strikethrough
- Extended autolinks
- Restrictions around some raw HTML tags
These extensions are now so common that many users think they are part of standard Markdown. They are not part of the CommonMark core.
GFM Tables
| Backend | Best use |
|---|---|
| Ollama | Local experiments |
| vLLM | Shared inference |
| SGLang | Structured workloads |
A strict CommonMark parser is allowed to treat this as ordinary paragraph text. A GFM-compatible parser recognizes it as a table. For a deeper look at table syntax and alignment options, see Tables in Markdown.
GFM Task Lists
- [x] Install Docker
- [x] Download the model
- [ ] Add monitoring
Task list syntax is useful in issues, pull requests, and project documentation. Outside a supporting renderer, it may appear as an ordinary list containing literal square brackets.
GFM Strikethrough
Use the ~~old endpoint~~ new endpoint.
Strikethrough is widely supported, but it is still an extension rather than portable CommonMark syntax.
GFM Autolinks
GFM recognizes more URL-like and email-like text without requiring angle brackets or explicit link syntax.
Visit https://example.com/docs for details.
In strict CommonMark, explicit autolinks use angle brackets:
<https://example.com/docs>
The explicit form is safer when a document must travel through unknown Markdown processors.
GitHub.com Supports More Than Formal GFM
A frequent source of confusion is the assumption that every Markdown feature visible on GitHub belongs to the GFM specification.
It does not.
GitHub.com adds platform-level processing and features around the GFM parser. Depending on the context, GitHub can support:
- Mathematical expressions
- Mermaid diagrams
- Alerts
- Issue and pull request references
- User and team mentions
- Commit references
- Emoji shortcodes
- Collapsible HTML sections
- Color previews
- Repository-relative links
- Automatic heading anchors
Some of these features are syntax extensions. Others are post-processing behavior or integrations with GitHub data.
This distinction matters because another renderer may accurately claim GFM compatibility without implementing GitHub’s math renderer, Mermaid integration, issue references, or alert styling.
GitHub Mermaid Diagrams
GitHub renders a fenced code block marked mermaid as a diagram:
```mermaid
flowchart LR
A[Markdown] --> B[Rendered diagram]
```
A generic GFM renderer may display the same block as highlighted source code. The Markdown remains valid, but the enhanced rendering is platform-specific. For a practical introduction to Mermaid syntax, see the Mermaid Diagrams Quickstart.
GitHub Mathematical Expressions
GitHub supports inline and block mathematical expressions using dollar delimiters and additional escaping forms.
The cache size is approximately $2nlhd$ bytes.
$$
C = 2nlhd
$$
Math is not part of formal GFM. Moving this content to another renderer requires a compatible math extension such as KaTeX, MathJax, or Pandoc math support.
GitHub Alerts
GitHub supports alert-style block quotes such as:
> [!WARNING]
> Changing this setting clears the cache.
On GitHub, this can appear as a styled warning. On a plain CommonMark renderer, it usually appears as an ordinary block quote containing [!WARNING].
That fallback is readable, which makes GitHub alerts less dangerous than extensions that disappear completely. They are still not portable presentation elements.
Pandoc Markdown: Markdown as a Document Language
Pandoc Markdown is designed for document conversion rather than one particular website. It uses Markdown as the source syntax for producing HTML, PDF, DOCX, EPUB, LaTeX, presentations, and other formats.
Its default Markdown reader includes a large extension set. Important capabilities include:
- YAML metadata blocks
- Footnotes
- Citations
- Multiple table formats
- Definition lists
- Mathematical notation
- Header identifiers and attributes
- Code block attributes
- Fenced divisions
- Bracketed spans
- Superscript and subscript
- Strikeout
- Line blocks
- Numbered example lists
- Raw LaTeX
- Raw HTML
- Automatic section numbering
- Bibliography processing
Pandoc Markdown is much more expressive than CommonMark or formal GFM. That expressiveness makes it powerful for publishing, but less safe as an interchange format.
Pandoc Footnotes
Markdown has several incompatible dialects.[^dialects]
[^dialects]: CommonMark, GFM, and Pandoc Markdown are three
important examples.
Footnote syntax is supported by many modern tools, but it is not part of CommonMark or formal GFM.
GitHub currently renders footnotes in several content contexts, but that is a GitHub platform feature rather than a formal GFM guarantee. A renderer claiming only CommonMark or GFM compatibility may not support them.
Pandoc Citations
PagedAttention improves KV cache memory management
[@kwon2023pagedattention].
With a bibliography file and citation style, Pandoc can resolve this into a formatted academic citation and bibliography.
pandoc article.md \
--citeproc \
--bibliography references.bib \
--csl ieee.csl \
-o article.pdf
The citation syntax remains readable in an unsupported renderer, but it will not become a formatted reference without Pandoc or another compatible citation processor. Pandoc’s reader-side flexibility also underpins conversion workflows in the other direction — see converting Word documents to Markdown for a practical example of using Pandoc’s extended dialect as an intermediate format.
Pandoc Definition Lists
CommonMark
: A precise specification for core Markdown.
GFM
: A CommonMark-based dialect with software-oriented extensions.
Pandoc Markdown
: An extended authoring format for document conversion.
Definition lists are useful in manuals, glossaries, and technical books. They normally degrade poorly in renderers that do not support them because the colon lines remain visible as plain text.
Pandoc Header Attributes
## Cache Configuration {#cache-config .deployment}
Pandoc interprets the braces as an explicit identifier and class list. Many other Markdown renderers show the attribute text directly in the heading.
This is one of the clearest examples of useful syntax that should not be placed in a document expected to render everywhere.
Pandoc Fenced Divisions
::: warning
Changing this option restarts the server.
Pandoc converts this into a structural division with a class. Templates, CSS, filters, or output writers can decide how that structure should appear.
Most CommonMark and GFM renderers do not recognize the fence. They display the colons and content as ordinary text.
CommonMark vs GFM vs Pandoc Markdown
The following matrix describes the formal dialects, not every feature added by GitHub.com, Hugo, Obsidian, GitLab, or another platform.
| Feature | CommonMark | Formal GFM | Pandoc Markdown |
|---|---|---|---|
| Headings | Yes | Yes | Yes |
| Emphasis | Yes | Yes | Yes |
| Links and images | Yes | Yes | Yes |
| Block quotes | Yes | Yes | Yes |
| Ordered and unordered lists | Yes | Yes | Yes |
| Fenced code blocks | Yes | Yes | Yes |
| Raw HTML syntax | Yes | Restricted in some contexts | Yes |
| Pipe tables | No | Yes | Yes |
| Task lists | No | Yes | Yes |
| Strikethrough | No | Yes | Yes |
| Extended autolinks | No | Yes | Configurable |
| Footnotes | No | No | Yes |
| Citations | No | No | Yes |
| YAML metadata | No | No | Yes |
| Definition lists | No | No | Yes |
| Mathematical notation | No | No | Yes |
| Header attributes | No | No | Yes |
| Fenced divisions | No | No | Yes |
| Raw LaTeX | No | No | Yes |
| Bibliography processing | No | No | Yes |
The word “No” does not mean a platform can never support the feature. It means the feature is not guaranteed by that dialect’s formal specification.
Which Syntax Works on GitHub?
For README files, issues, pull requests, discussions, and wikis, GFM is the natural baseline.
You can generally use:
- CommonMark syntax
- Tables
- Task lists
- Strikethrough
- Extended autolinks
- Syntax-highlighted code fences
- GitHub-specific references
- GitHub-supported math
- GitHub-supported diagrams
- GitHub alerts
- Footnotes where supported by the content surface
The portability risk begins when GitHub performs additional rendering beyond formal GFM. Mermaid diagrams, mathematical notation, issue references, and alert presentation may not survive outside GitHub.
For repository files that are also published elsewhere, test the source in the second renderer rather than treating GitHub preview as authoritative.
Which Syntax Works in Hugo?
Hugo uses Goldmark as its default Markdown renderer. Goldmark conforms to CommonMark and provides extensions compatible with important parts of GFM.
In a typical Hugo configuration, the following work well:
- CommonMark structure
- Fenced code blocks
- Pipe tables
- Strikethrough
- Task lists
- Automatic heading IDs
- Syntax highlighting
- Footnotes when the extension is enabled
- Definition lists when enabled
- Typographic substitutions when enabled
Hugo also adds features outside Markdown through:
- Front matter
- Shortcodes
- Render hooks
- Page resources
- Internal reference functions
- Template processing
- Site configuration
These Hugo features do not travel with the Markdown file. For a practical example of Hugo deployment, see Deploy Hugo to AWS S3.
Hugo Front Matter Is Not Markdown Content
A Hugo page commonly starts with YAML, TOML, or JSON metadata:
---
title: "Markdown Compatibility"
description: "Compare Markdown dialects and renderers."
date: 2026-07-31
tags:
- Markdown
- documentation
---
Pandoc can also recognize YAML metadata blocks, but it interprets fields according to its own templates and writers. GitHub normally displays the block as a YAML-like section or treats it as repository metadata only in specific systems.
The same syntax can therefore be recognized in more than one tool without having the same semantics.
Raw HTML in Hugo
Goldmark does not render potentially unsafe raw HTML by default in a standard Hugo configuration.
A block such as:
<div class="notice">
Restart the service after changing this value.
</div>
may be omitted unless raw HTML rendering is enabled or the content is implemented through a shortcode or render hook.
For a controlled technical blog, enabling raw HTML can be reasonable. It still makes the source less portable and should be a deliberate site-level decision.
Mermaid in Hugo
A fenced mermaid block is still just a code block unless the Hugo theme, render hook, shortcode, or JavaScript pipeline transforms it into a diagram.
GitHub and Hugo may therefore accept identical Mermaid source while using completely different rendering mechanisms.
Which Syntax Works in Pandoc?
Pandoc can read several Markdown dialects explicitly:
pandoc --from=markdown input.md
pandoc --from=commonmark input.md
pandoc --from=gfm input.md
pandoc --from=commonmark_x input.md
This is one of Pandoc’s most useful portability features. The operator can tell Pandoc which dialect the source claims to use instead of relying on a vague .md file extension.
Pandoc also lets you enable or disable individual extensions:
pandoc \
--from=markdown-footnotes-pipe_tables \
input.md \
-o output.html
Or start from a narrower format and add one feature:
pandoc \
--from=commonmark+footnotes \
input.md \
-o output.html
You can inspect available extensions with:
pandoc --list-extensions=markdown
pandoc --list-extensions=commonmark
pandoc --list-extensions=gfm
This extension model is powerful, but it means “Pandoc Markdown” is not always one fixed configuration. Build commands and defaults files are part of the document specification.
Which Syntax Works in Obsidian?
Obsidian stores notes as Markdown files, but its authoring model includes several application-specific features.
Common examples include:
- Wiki links
- Embedded notes
- Embedded files
- Callouts
- Block references
- Tags
- Properties
- Highlighting
- Comments
- Dataview queries from plugins
- Application-specific URI links
A wiki link such as:
[[Markdown Compatibility]]
is meaningful inside an Obsidian vault. GitHub, CommonMark, and a default Pandoc reader normally display it as literal bracketed text.
An embed is even more application-specific:
![[compatibility-table]]
The referenced content is not present in the file itself. Exporting or publishing the note therefore requires an expansion step that resolves the embed.
Obsidian is a good example of why storage in .md files does not guarantee Markdown portability. For a practical look at Obsidian as a knowledge management tool, see Obsidian for Personal Knowledge Management.
Which Syntax Works in GitLab?
GitLab Flavored Markdown uses CommonMark as its core and includes GFM features such as tables and task lists. It then adds GitLab-specific behavior including cross-references, mathematical notation, diagrams, and other collaboration features.
A README written in conservative GFM usually moves between GitHub and GitLab without major damage.
Platform integrations do not travel as reliably. Issue references, user mentions, diagrams, math handling, and special block syntax can behave differently even when the basic Markdown remains readable.
Platform Support Matrix
This matrix describes common default behavior. Themes, plugins, extensions, and configuration can change individual cells.
| Feature | GitHub | Hugo Goldmark | Pandoc | Obsidian | GitLab |
|---|---|---|---|---|---|
| CommonMark core | Yes | Yes | Yes | Mostly | Yes |
| Pipe tables | Yes | Yes | Yes | Yes | Yes |
| Task lists | Yes | Yes | Yes | Yes | Yes |
| Strikethrough | Yes | Yes | Yes | Yes | Yes |
| Footnotes | Yes | Configurable | Yes | Yes | Yes |
| YAML metadata | Context-dependent | Front matter | Yes | Properties | Context-dependent |
| Math | Yes | Requires setup | Yes | Yes | Yes |
| Mermaid | Yes | Requires setup | Output-dependent | Yes | Yes |
| Citations | No native bibliography | Requires tooling | Yes | Plugin-dependent | No native bibliography |
| Definition lists | No | Configurable | Yes | Limited | Limited |
| Header attributes | Limited | Renderer-dependent | Yes | Limited | Limited |
| Wiki links | No | No by default | No by default | Yes | Wiki-dependent |
| Callouts or alerts | GitHub syntax | Theme or shortcode | Template-dependent | Obsidian syntax | GitLab syntax |
| Raw HTML | Sanitized or restricted | Disabled by default | Yes | Context-dependent | Sanitized or restricted |
“Yes” still does not guarantee identical HTML or visual presentation. It means the environment recognizes the general feature.
Syntax That Is Usually Safe Everywhere
The safest portable subset includes:
- ATX headings using
# - Ordinary paragraphs
- Blank lines between blocks
-for unordered lists1.for ordered lists- Fenced code blocks using backticks
- Inline code using backticks
- Emphasis using
*text* - Strong emphasis using
**text** - Ordinary links
- Ordinary images
- Block quotes
- Thematic breaks
- Explicit angle-bracket autolinks
An intentionally conservative document might look like this:
# Deployment Guide
This guide explains how to deploy the service.
## Requirements
- Docker
- Linux
- A supported GPU
## Configuration
Create a file named `compose.yaml`.
```yaml
services:
application:
image: example/application:1.0
```
For more information, see the [configuration reference](config.md).
> Back up existing data before upgrading.
This syntax travels well because it does not depend on tables, footnotes, attributes, callouts, or platform processing.
Syntax That Commonly Breaks
Portability problems tend to cluster around a small number of features.
Pipe Tables
Pipe tables are well supported by GFM-oriented tools, but not by strict CommonMark.
A table can degrade into unreadable text when passed through a parser that does not recognize it. For highly portable documents, consider short lists or semantic HTML generated during a build step.
Footnotes
Footnote syntax has become common, but it remains an extension.
Different tools may:
- Support only one footnote format
- Place footnotes differently
- Generate different identifiers
- Reject multi-paragraph footnotes
- Render the source literally
Use footnotes when the publishing pipeline is known. Avoid depending on them in README files that must render across arbitrary systems.
Heading IDs and Attributes
This Pandoc syntax is not portable:
## Installation {#installation .procedure}
Use an ordinary heading and let the renderer generate its own anchor when portability matters.
Also avoid hard-coding links to auto-generated heading IDs unless every target uses the same slugification rules.
Callouts and Alerts
GitHub, Obsidian, GitLab, MkDocs, Docusaurus, and Hugo themes can all support callout-like blocks, but they often use different syntax.
A portable fallback is an ordinary block quote:
> Warning: Back up the database before upgrading.
It is less visually impressive, but it preserves meaning everywhere.
Wiki Links
Wiki links are concise inside knowledge-management tools:
[[KV Cache]]
They are poor interchange syntax because the target path, file name, heading rules, and resolution behavior belong to the application.
Use standard Markdown links in content intended for publication:
[KV cache](kv-cache.md)
Raw HTML
Raw HTML is the usual escape hatch when Markdown cannot express a layout. It is also a common portability and security failure.
A renderer may:
- Remove the HTML
- Escape it
- Sanitize selected elements
- Allow blocks but not inline elements
- Refuse Markdown parsing inside HTML
- Pass it unchanged only in trusted mode
Use raw HTML only when the publishing target is controlled.
Mathematical Notation
Dollar-delimited math is popular but not universally interpreted.
The source:
The complexity is $O(n^2)$.
may become:
- Rendered mathematics
- Ordinary text with dollar signs
- Incorrect emphasis
- Input to a different math parser
Choose one math pipeline and test it in every target environment.
Mermaid and Other Diagram Blocks
A Mermaid code fence is syntactically safe because unsupported renderers normally display it as code.
The semantic result is still different. Readers may see a rendered architecture diagram on GitHub and raw Mermaid source in another environment.
This is graceful degradation, not true compatibility.
The Three Layers of Markdown Compatibility
It helps to separate compatibility into three layers.
Layer 1: Parsing Compatibility
Does the parser recognize the structure?
Examples include headings, tables, footnotes, and fenced divisions.
Layer 2: Transformation Compatibility
Does the platform apply additional processing?
Examples include:
- Rendering Mermaid
- Resolving citations
- Expanding wiki links
- Linking issue numbers
- Processing shortcodes
- Generating a table of contents
Layer 3: Presentation Compatibility
Does the result look and behave appropriately?
Examples include:
- Table styling
- Syntax highlighting
- Alert colors
- Heading anchors
- Responsive images
- Footnote placement
- Math fonts
Two platforms can parse identical syntax while producing substantially different presentation.
A Better Portability Model
Instead of asking whether a file is “valid Markdown,” ask four narrower questions:
- Which dialect is the source written in?
- Which parser reads it?
- Which extensions are enabled?
- Which platform transformations run afterward?
For example:
Dialect: CommonMark plus GFM tables
Parser: Goldmark
Extensions: tables, strikethrough, task lists, footnotes
Platform: Hugo
Additional processing: render hooks and Mermaid JavaScript
That description is much more useful than saying “the site uses Markdown.”
Choosing a Dialect by Use Case
README Files
Use GFM.
README files benefit from:
- Tables
- Task lists
- Fenced code
- Autolinks
- Strikethrough
- GitHub references
Avoid excessive dependence on GitHub-only features when the repository is mirrored to GitLab, rendered on a package registry, or included in generated documentation.
Hugo Technical Articles
Use CommonMark-compatible Markdown with a documented Goldmark extension set.
Tables, code fences, footnotes, and Mermaid can be reasonable because you control the build pipeline. Prefer Hugo shortcodes or render hooks over embedding large amounts of raw HTML.
Keep Hugo-specific syntax isolated and easy to find.
Academic Documents
Use Pandoc Markdown.
Citations, bibliography processing, footnotes, metadata, mathematical notation, cross-references, and conversion to PDF or DOCX justify the reduced portability.
Store the Pandoc command, defaults file, filters, bibliography, and templates beside the source. The source file alone does not fully describe the build.
Books and Long-Form Documentation
Pandoc Markdown is usually the strongest of the three options when multiple output formats matter.
Definition lists, citations, attributes, metadata, and structured transformations become more important as document complexity grows.
For web-only documentation hosted in a Git repository, GFM or a CommonMark-based documentation generator may remain simpler.
Notes and Personal Knowledge Bases
Use the native syntax of the selected notes application when application features provide real value.
Obsidian wiki links, embeds, and callouts are useful inside a vault. Treat export as a compilation process rather than assuming the raw files are already portable publications.
Shared Documentation Across Unknown Systems
Use a conservative CommonMark subset.
Avoid:
- Wiki links
- Platform alerts
- Header attributes
- Citations
- Raw HTML
- Custom containers
- Application embeds
- Shortcodes
Portability usually requires giving up convenience features.
Practical Rules for Portable Markdown
Start with CommonMark Structure
Use CommonMark for the document skeleton:
- Headings
- Paragraphs
- Lists
- Links
- Images
- Block quotes
- Code blocks
This ensures that the main meaning survives even when optional extensions fail.
Add GFM Features Deliberately
Tables and task lists are reasonable when all important targets support them.
Do not assume “most tools support GFM” without testing the exact target. Some claim GFM compatibility while enabling only selected extensions.
Isolate Platform Extensions
Keep platform-specific syntax in clearly identifiable blocks.
For example, centralize Hugo shortcodes, Pandoc citations, or Obsidian embeds rather than scattering them through every paragraph.
Isolation makes later conversion easier.
Prefer Graceful Degradation
A Mermaid block degrades into readable source code. A GitHub alert degrades into a block quote.
A wiki embed may degrade into an unexplained file name, while a Pandoc fenced division may expose punctuation around the content.
Choose extensions whose fallback remains understandable.
Do Not Depend on Auto-Generated Heading IDs
Heading anchor algorithms differ between GitHub, Hugo, Pandoc, and documentation generators.
For cross-document links, use renderer-supported explicit IDs only when the target pipeline is controlled. Otherwise, link to the document rather than a generated fragment.
Keep Build Configuration with the Content
Pandoc extensions, Hugo settings, plugins, filters, and JavaScript integrations determine how Markdown behaves.
Commit relevant configuration files with the source:
content/
article.md
pandoc.yaml
references.bib
config/
_default/
markup.yaml
layouts/
_default/
_markup/
A .md extension alone does not capture the publishing environment. For a structured approach to documenting these decisions, see Decision Records for AI-Driven Development.
Test Markdown Against Every Important Target
Visual preview in one editor is not enough. The editor may support a richer dialect than the production renderer.
For Pandoc, test explicit input formats:
pandoc --from=commonmark article.md -o commonmark.html
pandoc --from=gfm article.md -o gfm.html
pandoc --from=markdown article.md -o pandoc.html
Warnings and visible source punctuation reveal which features are dialect-specific.
For Hugo, build the production site:
hugo --gc --minify
Then inspect the generated HTML rather than relying only on an editor preview.
For repositories, view the committed file on the actual hosting platform. Local Markdown extensions in VS Code may not match GitHub or GitLab.
Troubleshooting Common Rendering Mismatches
When a file that worked on one platform breaks on another, the failure usually falls into one of a handful of repeatable patterns. The table below lists the symptom as you would actually see it, the most likely cause, and a concrete command or check to confirm and fix it.
| Symptom | Likely cause | Confirm and fix |
|---|---|---|
A pipe table renders as one long paragraph with visible | characters |
Renderer is strict CommonMark without a tables extension | Run pandoc --from=commonmark file.md -o test.html and inspect the output; either enable the tables extension or export with --from=gfm |
[^note] stays inline as literal text instead of becoming a superscript footnote marker |
The footnote Goldmark extension is not enabled | In Hugo, check for footnote under markup.goldmark.extensions in hugo.yaml, rebuild with hugo --gc --minify, and look for <sup> in the generated HTML |
A ```mermaid fence shows as plain grey source code instead of a diagram |
The platform performs no post-processing on the fenced block | GitHub renders it natively; Hugo needs a render hook, shortcode, or JS pipeline — check the built HTML for <pre><code class="language-mermaid"> versus an <svg> |
## Heading {#id} shows the literal curly braces in the rendered heading text |
Header attribute syntax is Pandoc-specific, not CommonMark or GFM | Remove the attribute syntax for portable output, or pre-convert with pandoc --from=markdown --to=gfm file.md -o out.md |
[[Note Name]] displays as literal double square brackets |
Wiki link syntax is application-specific to tools like Obsidian | Replace with a standard Markdown link, [Note Name](note-name.md), before exporting outside the vault |
[@kwon2023pagedattention] stays as plain bracketed text instead of a formatted citation |
No bibliography or citeproc pass was applied | Re-run with pandoc --citeproc --bibliography=refs.bib input.md -o output.pdf and confirm the CSL style is specified |
> [!WARNING] renders as an ordinary quoted paragraph instead of a styled alert |
Alert styling is a GitHub.com platform feature, not part of formal GFM | Expected outside GitHub; keep the wording readable as a plain block quote rather than depending on the color styling |
This is the fastest first pass before assuming a Markdown “bug” — most of these mismatches are a missing extension or a platform-only feature, not broken syntax. For code-fence-specific issues such as missing syntax highlighting or unsupported language identifiers, see the dedicated guide on Markdown code blocks.
Lint the Portable Subset
A Markdown linter cannot guarantee renderer compatibility, but it can remove avoidable ambiguity.
Useful rules include:
- Use consistent heading styles
- Add blank lines around lists and code blocks
- Use fenced rather than indented code
- Specify code fence languages
- Avoid skipped heading levels
- Use consistent list markers
- Avoid ambiguous emphasis around punctuation
- Keep line endings consistent
- Validate links and images
For multi-target publishing, add a build test for each important renderer rather than relying only on syntax linting.
Converting Between Dialects with Pandoc
Pandoc can normalize documents from one dialect to another:
pandoc \
--from=markdown \
--to=gfm \
article.md \
-o article-gfm.md
Or convert GFM into Pandoc Markdown:
pandoc \
--from=gfm \
--to=markdown \
README.md \
-o document.md
This is useful, but conversion is not guaranteed to preserve every feature.
Potential losses include:
- Platform-specific references
- Callout styling
- Complex tables
- Embedded application objects
- Custom attributes
- Raw HTML behavior
- Plugin syntax
- Diagram rendering
- Exact whitespace and formatting
Pandoc preserves document structure better than original source formatting. Treat conversion as a build step, not a reversible text formatter.
Recommended Strategy for Hugo Sites
For a Hugo technical blog, the most practical policy is:
- Use CommonMark for core prose and structure.
- Enable a small documented set of Goldmark extensions.
- Use GFM-style tables and task lists where they improve readability.
- Implement Mermaid through one consistent render hook or shortcode.
- Handle math through one documented KaTeX or MathJax pipeline.
- Use Hugo front matter only at the start of content files.
- Prefer render hooks and shortcodes over raw HTML.
- Keep source links as standard Markdown links where possible.
- Test migrated or externally sourced documents through Hugo.
- Document any syntax that will not render correctly on GitHub.
This approach accepts that Hugo content is not universally portable while keeping the portability boundary visible.
The worst approach is accidental dialect mixing: GitHub alerts, Obsidian embeds, Pandoc attributes, and Hugo shortcodes placed in the same document without a defined build pipeline.
Decision Table
| Use case | Recommended syntax | Reason |
|---|---|---|
| Portable plain-text document | CommonMark | Smallest reliable baseline |
| GitHub README | GFM | Tables, tasks, and repository workflows |
| GitHub issue template | GFM plus GitHub features | Platform is the intended target |
| Hugo blog post | CommonMark plus configured Goldmark extensions | Controlled publishing pipeline |
| Academic paper | Pandoc Markdown | Citations, math, metadata, PDF output |
| Multi-format book | Pandoc Markdown | Structured conversion to many outputs |
| Obsidian vault | Obsidian Markdown | Backlinks, embeds, and knowledge workflows |
| GitHub and GitLab mirror | Conservative GFM | Strong shared feature set |
| Unknown renderer | CommonMark subset | Lowest compatibility risk |
Conclusion
CommonMark, GitHub Flavored Markdown, and Pandoc Markdown are not competing versions of the same product. They solve different problems.
CommonMark provides a dependable parsing foundation. GFM adds practical features for software collaboration, while Pandoc Markdown turns Markdown into a rich source language for publishing and conversion.
The safest rule is simple: write the smallest dialect that satisfies the real destination. Use CommonMark when content must travel, GFM when GitHub-style collaboration is the target, and Pandoc Markdown when document structure and output formats matter more than universal rendering.
Markdown portability is not achieved by avoiding every extension. It is achieved by knowing which extensions are part of the source contract and testing them in every renderer that matters.