Pipefmt
Align
Input
Output
0 columns0 rowsNo table
--

GFM pipe table syntax reference

Pipefmt formats markdown pipe tables in the browser with correct CJK width handling. The reference below enumerates the pipe-table dialects that exist in markdown today, the alignment marker syntax that GFM defines, cell-escape rules, the Unicode East Asian Width property the formatter depends on, and the common malformations that cause silent breakage in editors.

Pipe table dialects compared

Five markdown specs define some form of pipe table. They disagree on whether outer pipes are required, what counts as a valid separator, and how multi-line cells behave.

DialectOuter pipesSeparator rowAlignment markersMulti-line cellsNotes
CommonMarkNot in core specN/AN/AN/APipe tables are an extension, not part of core CommonMark
GitHub Flavored Markdown (GFM)Optional per rowRequired, three dashes minimum:---, :---:, ---:Not supportedThe de-facto web standard; Pipefmt targets this dialect
Markdown Extra (PHP)Optional, must be consistentRequired, three dashes minimum:---, :---:, ---:Not supportedFirst spec to add pipe tables (2004)
MultiMarkdownOptionalRequired:---, :---:, ---: plus + for sortableSupported via line continuation \Adds caption row syntax [Caption]
Pandoc pipe_tablesRequired outer pipesRequired:---, :---:, ---:Not supportedPandoc supports four other table syntaxes alongside pipe_tables

Pipefmt's parser follows the GFM dialect. The markdown-table npm package,prettier-plugin-markdown, GitHub's renderer, and most static site generators do the same.

GFM pipe-table syntax rules

A GFM pipe table is three things in order: a header row, a separator row, and zero or more body rows. The header and separator must have the same column count. Body rows can be shorter (missing cells become empty) or longer (extra cells are dropped).

RuleRequired?Example
At least one pipe per rowYesName | Age
Separator row immediately after headerYes| --- | --- |
Separator cell has at least three dashesYes--- minimum; ---- and more are also valid
Outer pipes match between rowsNoMixing is legal but visually ugly
Cell whitespace is trimmedYes| Alice | renders the same as | Alice |
Pipes inside cells escaped with backslashYesa \| b renders as a | b
Empty cells permittedYes| | | | is a valid row of three empty cells
Header content can be emptyYesRenders as a header row with blank cells
Blank line ends the tableYesA blank line after a body row stops parsing
Tables can sit directly under proseYesNo blank line required above the header

Alignment marker reference

The separator row's per-column markers are the only way GFM expresses column alignment. There is no other syntax for it.

MarkerAlignmentHTML outputVisual cue
:---Left<td align="left">Colon at the left end
---:Right<td align="right">Colon at the right end
:---:Center<td align="center">Colons at both ends
---Default (renderer decides)<td>No colons

Edge cases the GFM grammar accepts or rejects:

VariantTreated asNotes
:--:CenterTwo-dash version is legal
:-:CenterSingle-dash version is legal
: ---InvalidSeparator row fails to parse (space after colon)
--- :InvalidSeparator row fails to parse (space before colon)
:::InvalidMust contain at least one dash
:--Left, but renderer-specificGFM is lenient; some renderers reject
Mixed within column (:--- header, ---: body)Header winsOnly the separator row matters

When Pipefmt's Align option is set to Auto, the formatter inspects every non-empty value in each column. Columns whose values all parse as numbers (integer or decimal, optional leading sign) get ---: (right). All others get :--- (left). Explicit markers in the input always take precedence.

Cell escaping and special characters

CharacterInside a cellOutput
\| (escaped pipe)LegalRenders as |
\\ (escaped backslash)LegalRenders as \
<br>Legal in GFMRenders as a line break
Literal newlineIllegal in pipe tablesStops the table
Backtick code spansLegalPipes inside backticks do not need escaping
HTML entities (&amp;)LegalRendered by the host renderer, not Pipefmt
Trailing whitespaceStrippedPipefmt removes it during tokenization
Leading whitespaceStrippedSame as trailing
Asterisks, underscoresLegalInline emphasis is applied by the renderer

Unicode East Asian Width property

The formatter's CJK-aware alignment depends on Unicode Technical Report #11 (East Asian Width). Every code point in the Unicode database carries one of six width categories. Pipefmt walks each grapheme cluster with Intl.Segmenter and looks up the category for the base code point of each cluster.

CategoryCodeMonospace columnsExamples
NarrowNa1ASCII letters, digits, punctuation
WideW2CJK Unified Ideographs, Japanese Kanji, Korean Hangul
FullwidthF2Fullwidth Latin letters (, ), CJK symbols
HalfwidthH1Halfwidth Katakana (, ), halfwidth Hangul
NeutralN1Most non-East-Asian scripts (Cyrillic, Devanagari, Arabic)
AmbiguousA1 in Latin context, 2 in CJKGreek letters, box-drawing characters, some math symbols

Pipefmt treats Ambiguous as 1 column. This matches the string-width package defaults and produces correct output when CJK and Latin content share a column. The cost is that pure-CJK documents using Greek letters or box-drawing characters as wide content will under-pad those cells; this trade-off is the same in every East Asian Width implementation.

Common CJK character blocks

The Wide and Fullwidth categories cover several specific Unicode blocks. Knowing the block helps when a cell contains characters that look CJK but measure as 1 column (for example, halfwidth Katakana).

BlockRangeWidth categoryNotes
CJK Unified IdeographsU+4E00–U+9FFFWMost modern Chinese, Japanese Kanji, Korean Hanja
HiraganaU+3040–U+309FWJapanese phonetic syllabary
KatakanaU+30A0–U+30FFWJapanese phonetic syllabary
Hangul SyllablesU+AC00–U+D7AFWKorean composed syllables
CJK Symbols and PunctuationU+3000–U+303FW, , , , ideographic space
Halfwidth KatakanaU+FF65–U+FF9FH1 column despite being Japanese
Fullwidth ASCIIU+FF01–U+FF5EF is fullwidth, A is narrow
CJK Compatibility IdeographsU+F900–U+FAFFWLegacy duplicate characters
CJK Extension AU+3400–U+4DBFWLess common ideographs
CJK Extension BU+20000–U+2A6DFWRare ideographs, supplementary plane

Monospace fonts with full CJK metrics

Even with correctly padded output, a font that lacks CJK glyph metrics will render the table crooked in the editor. These fonts ship with proper 2-column CJK glyphs by default.

FontLicenseCJK coverageSource
Noto Sans Mono CJKOFLFull (SC, TC, JP, KR)Google Fonts
Source Han Code JPOFLJapanese, with English ligaturesAdobe
Sarasa MonoOFLFull (SC, TC, JP, KR)Iosevka derivative
JetBrains Mono + Noto CJK fallbackOFLEnglish primary, CJK via font-stack fallbackConfigure editor font stack
Plemol JPOFLJapaneseHybrid of IBM Plex Mono and IBM Plex Sans JP
CicaOFLJapaneseHack + Rounded M+

Older Consolas builds (pre-2019) lack CJK metrics and will render wide characters as 1 column even when the source content is padded for 2. The editor font setting, not Pipefmt's output, is the cause.

Common-failure patterns

A symptom-cause-fix lookup for the malformations Pipefmt sees most often.

SymptomCauseFix
Table shows as plain text in the rendered outputMissing or malformed separator rowAdd a separator row with at least three dashes per column
Columns misaligned in editor despite Pipefmt runningProportional font or missing CJK metrics in the editor fontSwitch to a font from the table above
Trailing cells appear in the wrong columnUnescaped pipe inside a cellEscape literal pipes with \|
Separator markers ignored by the rendererSpace between colon and dashesRemove spaces; markers must be contiguous :---
Header row renders as a body rowBlank line between header and separatorRemove the blank line
Output has an extra empty columnTrailing pipe creates an empty columnEither remove the trailing pipe everywhere or turn Outer Pipes on
Some rows missing cellsBody row has fewer pipes than headerAdd empty cells | | to pad to the header column count
Multi-line content collapsesNewline inside a cellReplace with <br> (GFM-supported) or restructure the row
Numbers right-align in some renderers but not othersBare --- separator and Align is Auto in PipefmtSet explicit ---: markers to force right alignment everywhere
Cell padding looks off in a CJK columnEditor font lacks CJK metrics, or Ambiguous-category content presentTry a CJK-capable monospace font; confirm content is not Greek or box-drawing

Related concepts

  • CommonMark spec: the base markdown grammar; pipe tables are a GFM extension layered on top
  • Unicode TR #11: the authoritative East Asian Width specification that defines the six width categories
  • string-width npm package: the implementation Pipefmt's measurement is calibrated against
  • Intl.Segmenter: browser API for grapheme cluster iteration used in the width pass
  • Pandoc table syntaxes: pandoc supports four table forms alongside pipe_tables; only pipe_tables overlaps with GFM
  • prettier-plugin-markdown: the prettier plugin that formats markdown tables in source files