mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-06 17:34:25 +00:00
docs(formatter_markdown): follow updated DIVERGENCES policy (#26776)
Follows #26745 In Markdown, comment is also content, so put `<!-- -->` in the first line may break fixture's intent.
This commit is contained in:
1 parent
7717813ee7
commit
11ff089ea9
29 files changed
+178
-87
No files matched your search
@@ -63,8 +63,9 @@ Rules:
|
||||
- Every divergence has an entry in the owning layer's `DIVERGENCES.md` and a pin fixture
|
||||
- The owning layer decides the behavior: a language crate for single-language behavior, `apps/oxfmt` for embedding
|
||||
- The pin is a minimal fixture in the owner's `tests/fixtures/`, distilled from whatever exposed the divergence; a conformance file is never the pin, it stays a regression net
|
||||
- The fixture carries a one-line marker: which lines deviate + `see DIVERGENCES.md#<slug>`; the why lives in the entry
|
||||
- `DIVERGENCES.md#<slug>` is the one reference form everywhere (docs, source, fixtures); never a quoted or bare slug, never an upstream issue alone
|
||||
- The fixture points back at its entry: it is named after the slug, or carries a one-line `DIVERGENCES.md#<slug>` marker
|
||||
(a fixture pinning several entries, or a language where a comment is content); the why and the deviating lines live in the entry
|
||||
- `DIVERGENCES.md#<slug>` is the one reference form everywhere (docs, source, fixture markers); never a quoted or bare slug, never an upstream issue alone
|
||||
- Entry format, with OUR behavior as the spec
|
||||
- H2 slug: the stable anchor
|
||||
- `Why:` required; the reason keyword, its parenthetical, then upstream issues as bare references: `uniform-rule (same construct, same output: X; prettier/prettier#NNNN)`
|
||||
|
||||
@@ -68,18 +68,9 @@ node -e 'const p=require("./apps/oxfmt/node_modules/prettier");p.__debug.printTo
|
||||
|
||||
### Prettier conformance
|
||||
|
||||
At the current version (v3.9.6), these divergences have been confirmed and are intentional (see DIVERGENCES.md):
|
||||
Every failing file is accounted for by a DIVERGENCES.md entry's `Conformance:` line; there are no unclassified failures.
|
||||
|
||||
Conformance failures classified as divergences (16, all of them):
|
||||
|
||||
- `thematicBreak/simple.md` and `commonmark-test-suite/snippet: example-11.md`, `example-50.md` to `example-54.md` (`#leading-thematic-break`)
|
||||
- `commonmark-test-suite/snippet: example-2.md` (`#indented-code-tab`)
|
||||
- `link/encodedLink.md` (`#url-escaping`)
|
||||
- `gfm-test-suite/snippet: example-491.md` (`#single-tilde-strikethrough`)
|
||||
- `liquid/*.md` (`#liquid-flow-tags`)
|
||||
- `blockquote/notext-end.md` (`#line-shapes`)
|
||||
- `paragraph/cjk.md` (`#container-directive`)
|
||||
- `commonmark-test-suite/snippet: example-412.md` (`#stray-delimiters`)
|
||||
Pin fixtures are named after their entry's slug (a comment would be an HTML block and change the document).
|
||||
|
||||
### Fixture fingerprint
|
||||
|
||||
|
||||
@@ -5,7 +5,8 @@ Admission reasons and rules: see `crates/oxc_formatter_core/FORMATTER_POLICY.md`
|
||||
## leading-thematic-break
|
||||
|
||||
- Why: semantics (prettier/prettier#19839)
|
||||
- Pin: `tests/fixtures/markdown/thematic-break-first.md`
|
||||
- Pin: `tests/fixtures/markdown/leading-thematic-break.md`
|
||||
- Conformance: `markdown/thematicBreak/simple.md`, `markdown/commonmark-test-suite/snippet: example-11.md`, `example-50.md` to `example-54.md`
|
||||
|
||||
```markdown
|
||||
<!-- input -->
|
||||
@@ -37,7 +38,8 @@ Prettier `main` prints `***` since #19839; the pin (3.9.6) still prints `---`.
|
||||
## url-escaping
|
||||
|
||||
- Why: semantics (prettier/prettier#19482, prettier/prettier#19849, prettier/prettier#19891)
|
||||
- Pin: `tests/fixtures/markdown/link-url-special-chars.md`
|
||||
- Pin: `tests/fixtures/markdown/url-escaping.md`
|
||||
- Conformance: `markdown/link/encodedLink.md`
|
||||
|
||||
```markdown
|
||||
<!-- input -->
|
||||
@@ -59,6 +61,7 @@ Titles get the same `\&` treatment.
|
||||
|
||||
- Why: uniform-rule (same construct, same output: space-indented code block)
|
||||
- Pin: `tests/fixtures/markdown/indented-code-tab.md`
|
||||
- Conformance: `markdown/commonmark-test-suite/snippet: example-2.md`
|
||||
|
||||
````markdown
|
||||
<!-- input: two spaces, a tab -->
|
||||
@@ -79,7 +82,7 @@ so an indent written as spaces plus a tab becomes a fenced block.
|
||||
|
||||
## ignored-block-trailing-quote-line
|
||||
|
||||
- Why: uniform-rule (same construct, same output: the `proseWrap: preserve` layout)
|
||||
- Why: uniform-rule (same construct, same output: a blockquote's trailing blank `>` line under `proseWrap: preserve`)
|
||||
- Pin: `tests/fixtures/markdown/prose-wrap/ignored-block-trailing-quote-line.md`
|
||||
|
||||
```markdown
|
||||
@@ -110,7 +113,7 @@ Prettier drops it under `preserve` and `never` but prints a bare `>` under `alwa
|
||||
## list-indented-code-alignment
|
||||
|
||||
- Why: semantics (prettier/prettier#19644, prettier/prettier#19647, prettier/prettier#19990)
|
||||
- Pin: `tests/fixtures/markdown/tab-width-4/list-indented-code.md`, `tests/fixtures/markdown/tab-width-4/indented-code-block.md`
|
||||
- Pin: `tests/fixtures/markdown/tab-width-4/list-indented-code-alignment.md`
|
||||
|
||||
```markdown
|
||||
<!-- input, tabWidth 4 -->
|
||||
@@ -133,11 +136,12 @@ An indented code block inside a list item is printed at the item's content colum
|
||||
the code's content is exactly what follows that column, so any extra alignment becomes part of it on the next parse.
|
||||
The pin aligns it by the task checkbox (continuation lines drift by 4 per run, #19644);
|
||||
#19647 aligned it by the tab width instead, which shifted the content whenever `tabWidth` exceeded the marker width.
|
||||
Prettier `main` prints it as we do since #19990 (`indented-code-block.md` is its fixture); the pin (3.9.6) still differs.
|
||||
Prettier `main` prints it as we do since #19990 (the fixture's first four items are its fixture); the pin (3.9.6) still differs.
|
||||
|
||||
The same rule keeps the marker of an ordered list unpadded when an item starts with indented code
|
||||
(the content column is the marker plus one space, so any padding lands inside the code).
|
||||
Prettier pads it when the code starts at a tab stop in the source, which `>2. foo` does only because of the `>`:
|
||||
## ordered-marker-before-indented-code
|
||||
|
||||
- Why: semantics
|
||||
- Pin: `tests/fixtures/markdown/tab-width-4/ordered-marker-before-indented-code.md`
|
||||
|
||||
```markdown
|
||||
<!-- input -->
|
||||
@@ -150,8 +154,15 @@ Prettier pads it when the code starts at a tab stop in the source, which `>2.
|
||||
> 2. foo
|
||||
```
|
||||
|
||||
An HTML block after a task item's paragraph keeps the item's content column too
|
||||
(Prettier drops the alignment when the html starts at another column than the paragraph, which moves it out of the item):
|
||||
The marker of an ordered list stays unpadded when an item starts with indented code:
|
||||
the content column is the marker plus one space, so any padding lands inside the code
|
||||
(the rule of DIVERGENCES.md#list-indented-code-alignment, applied to the marker).
|
||||
Prettier pads it when the code starts at a tab stop in the source, which `>2. foo` does only because of the `>`.
|
||||
|
||||
## list-html-block-alignment
|
||||
|
||||
- Why: semantics
|
||||
- Pin: `tests/fixtures/markdown/tab-width-4/list-html-block-alignment.md`
|
||||
|
||||
```markdown
|
||||
<!-- input -->
|
||||
@@ -170,13 +181,39 @@ An HTML block after a task item's paragraph keeps the item's content column too
|
||||
<textarea>
|
||||
```
|
||||
|
||||
An HTML block closed by its container's end (`><script>a` then a list) carries that line ending as content;
|
||||
Prettier prints it, and inside a blockquote the block gains a `>` line on every pass. It is not printed.
|
||||
An HTML block after a task item's paragraph keeps the item's content column, as indented code does (DIVERGENCES.md#list-indented-code-alignment).
|
||||
Prettier drops the alignment when the html starts at another column than the paragraph (the checkbox counts for its printer, not for the parser), which moves the block out of the item.
|
||||
|
||||
## html-block-trailing-newline
|
||||
|
||||
- Why: invariant
|
||||
- Pin: `tests/fixtures/markdown/html-block-trailing-newline.md`
|
||||
|
||||
```markdown
|
||||
<!-- input -->
|
||||
- > <script>
|
||||
> a
|
||||
- b
|
||||
|
||||
<!-- ours -->
|
||||
- > <script>
|
||||
> a
|
||||
- b
|
||||
|
||||
<!-- prettier (one more `> ` line per pass) -->
|
||||
- > <script>
|
||||
> a
|
||||
>
|
||||
- b
|
||||
```
|
||||
|
||||
An HTML block closed by its container's end carries that line ending as content (micromark's `trailing_newline`); it is not printed.
|
||||
Prettier prints it as a blank line of the blockquote, and inside a list item that line is not a fixpoint: every pass adds another.
|
||||
|
||||
## list-marker-after-ignored-list
|
||||
|
||||
- Why: semantics
|
||||
- Pin: `tests/fixtures/markdown/oxfmt-ignore.md`
|
||||
- Pin: `tests/fixtures/markdown/list-marker-after-ignored-list.md`
|
||||
|
||||
```markdown
|
||||
<!-- input -->
|
||||
@@ -204,7 +241,8 @@ Prettier alternates from the marker it would have printed (`-`), prints `*` next
|
||||
## single-tilde-strikethrough
|
||||
|
||||
- Why: semantics (prettier/prettier#19739)
|
||||
- Pin: `tests/fixtures/markdown/single-tilde.md`
|
||||
- Pin: `tests/fixtures/markdown/single-tilde-strikethrough.md`
|
||||
- Conformance: `markdown/gfm-test-suite/snippet: example-491.md`
|
||||
|
||||
```markdown
|
||||
<!-- input -->
|
||||
@@ -224,7 +262,8 @@ Prettier `main` preserves it since #19739.
|
||||
## liquid-flow-tags
|
||||
|
||||
- Why: semantics (prettier/prettier#19724, prettier/prettier#19838)
|
||||
- Pin: `tests/fixtures/markdown/prose-wrap/liquid-flow.md`
|
||||
- Pin: `tests/fixtures/markdown/prose-wrap/liquid-flow-tags.md`
|
||||
- Conformance: `markdown/liquid/character-after-closing-tokens.md`, `markdown/liquid/example-1.md`, `markdown/liquid/example-2.md`
|
||||
|
||||
```markdown
|
||||
<!-- input -->
|
||||
@@ -260,6 +299,7 @@ Prettier `main` parses them as flow nodes since #19838.
|
||||
|
||||
- Why: semantics
|
||||
- Pin: `tests/fixtures/markdown/prose-wrap/container-directive.md`
|
||||
- Conformance: `markdown/paragraph/cjk.md`
|
||||
|
||||
```markdown
|
||||
<!-- input -->
|
||||
@@ -287,6 +327,7 @@ Prettier has no directive construct (#19662 would add micromark's grammar only),
|
||||
|
||||
- Why: semantics
|
||||
- Pin: `tests/fixtures/markdown/prose-wrap/line-shapes.md`
|
||||
- Conformance: `markdown/blockquote/notext-end.md`
|
||||
|
||||
```markdown
|
||||
<!-- input -->
|
||||
@@ -305,12 +346,11 @@ A paragraph line starting with `<<<` (VitePress snippet import), a component tag
|
||||
a stray `:::`, or `[!` as the first line of a blockquote (GitHub / Obsidian alert marker) keeps its line boundaries and is never re-wrapped (AGENTS.md "Dialects").
|
||||
Prettier joins and wraps them like any word: the alert above loses its marker line (GitHub needs `[!NOTE]` alone on it),
|
||||
a wrapped `<<<` line loses its `[title]`, and a component tag wrapped to column 0 opens an HTML block in MDX / VitePress.
|
||||
`blockquote/notext-end.md` is the conformance failure.
|
||||
|
||||
## wrapped-block-starts
|
||||
|
||||
- Why: semantics (prettier/prettier#13634, prettier/prettier#19112, prettier/prettier#19847)
|
||||
- Pin: `tests/fixtures/markdown/prose-wrap/wrap-block-starts.md`
|
||||
- Pin: `tests/fixtures/markdown/prose-wrap/wrapped-block-starts.md`
|
||||
|
||||
```markdown
|
||||
<!-- input, proseWrap always -->
|
||||
@@ -340,6 +380,7 @@ Prettier drops the break before `- item`, `# heading` and `> quote` itself.
|
||||
|
||||
- Why: semantics (prettier/prettier#6035, prettier/prettier#17303, prettier/prettier#17353)
|
||||
- Pin: `tests/fixtures/markdown/prose-wrap/stray-delimiters.md`
|
||||
- Conformance: `markdown/commonmark-test-suite/snippet: example-412.md`
|
||||
|
||||
```markdown
|
||||
<!-- input -->
|
||||
@@ -368,7 +409,7 @@ Found by `tests/invariants.rs`, the fuzzed `parse(format(x)) ≅ parse(x)` check
|
||||
## verbatim-inline-continuation
|
||||
|
||||
- Why: semantics (prettier/prettier#19116)
|
||||
- Pin: `tests/fixtures/markdown/list-multiline-inline.md`
|
||||
- Pin: `tests/fixtures/markdown/verbatim-inline-continuation.md`
|
||||
|
||||
```markdown
|
||||
<!-- input -->
|
||||
|
||||
@@ -130,7 +130,7 @@ fn double_gap(
|
||||
let prev_is_ignore = ignore_kind(previous, f) == Some(IgnoreKind::Next);
|
||||
let html_after_html = matches!((previous, node), (Block::HtmlBlock(_), Block::HtmlBlock(_)));
|
||||
// A type 7 HTML block can only follow a paragraph without a blank line as a lazy line of a container
|
||||
// (a micromark quirk, parser DIVERGENCES);
|
||||
// (a micromark quirk, oxc-markdown-parser DIVERGENCES.md);
|
||||
// printed with the container's prefix it needs the blank line to stay a block.
|
||||
// Prettier prints it adjacent, where it becomes paragraph text.
|
||||
let html_after_paragraph =
|
||||
|
||||
@@ -88,10 +88,10 @@ pub fn write_list<'a>(
|
||||
write!(f, text(prefix));
|
||||
|
||||
// A `[paragraph, html]` item whose html sits left of the content column is
|
||||
// micromark's lazy type 7 quirk (parser DIVERGENCES): the html stays where it was, unaligned.
|
||||
// micromark's lazy type 7 quirk (oxc-markdown-parser DIVERGENCES.md): the html stays where it was, unaligned.
|
||||
// (Prettier drops the alignment whenever the two columns differ,
|
||||
// which moves an html block indented past a task checkbox out of the item:
|
||||
// DIVERGENCES `list-indented-code-alignment`)
|
||||
// DIVERGENCES.md#list-html-block-alignment)
|
||||
let skip_align =
|
||||
item.children.len() == 2 && matches!(item.children[1], Block::HtmlBlock(_)) && {
|
||||
let source = f.context().source_text().as_str();
|
||||
@@ -137,7 +137,7 @@ fn write_list_item<'a>(
|
||||
let body = format_with(|f| block::write_block(child, &item.children, i, child_parent, f));
|
||||
// An indented code block's content is whatever follows the item's content column + 4:
|
||||
// any extra alignment lands inside the code on the next parse.
|
||||
// See DIVERGENCES `list-indented-code-alignment`.
|
||||
// See DIVERGENCES.md#list-indented-code-alignment and DIVERGENCES.md#list-html-block-alignment.
|
||||
// (Prettier's checkbox align before #19647, the same for prettier/prettier#19986)
|
||||
if is_indented_code(child) || matches!(child, Block::HtmlBlock(_)) {
|
||||
write!(f, body);
|
||||
@@ -234,7 +234,7 @@ fn is_aligned(list: &List<'_>, next: Option<&Block<'_>>, f: &MarkdownFormatter<'
|
||||
// An item starting with indented code has its content column fixed at the marker plus one space:
|
||||
// padding the marker would land inside the code (`>2. foo`,
|
||||
// where the code starts at a tab stop only because of the `>`).
|
||||
// See DIVERGENCES `list-indented-code-alignment`.
|
||||
// See DIVERGENCES.md#ordered-marker-before-indented-code.
|
||||
if list.children.iter().any(|item| item.children.first().is_some_and(is_indented_code)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ const CONFIG: ConformanceConfig = ConformanceConfig {
|
||||
"markdown/commonmark-test-suite/snippet: example-98.md",
|
||||
// Fenced blocks whose only difference is Prettier formatting the embedded language (js / ts / css / json / html / markdown).
|
||||
"markdown/blockquote/code.md",
|
||||
// Also the `always`-only trailing `>` line: DIVERGENCES.md `ignored-block-trailing-quote-line`.
|
||||
// Also the `always`-only trailing `>` line: DIVERGENCES.md#ignored-block-trailing-quote-line.
|
||||
"markdown/blockquote/ignore-code.md",
|
||||
"markdown/list/codeblock.md",
|
||||
"markdown/list/parser-regression/issue-11202.md",
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
- > <script>
|
||||
> a
|
||||
- b
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
---
|
||||
source: crates/oxc_formatter_markdown/tests/fixtures/mod.rs
|
||||
---
|
||||
==================== Input ====================
|
||||
- > <script>
|
||||
> a
|
||||
- b
|
||||
|
||||
==================== Output ====================
|
||||
------------------
|
||||
{ printWidth: 80 }
|
||||
------------------
|
||||
- > <script>
|
||||
> a
|
||||
- b
|
||||
|
||||
-------------------
|
||||
{ printWidth: 100 }
|
||||
-------------------
|
||||
- > <script>
|
||||
> a
|
||||
- b
|
||||
|
||||
===================== End =====================
|
||||
File renamed without changes.
File renamed without changes.
+4
@@ -0,0 +1,4 @@
|
||||
<!-- oxfmt-ignore -->
|
||||
* kept as written
|
||||
|
||||
- formatted
|
||||
Vendored
+27
@@ -0,0 +1,27 @@
|
||||
---
|
||||
source: crates/oxc_formatter_markdown/tests/fixtures/mod.rs
|
||||
---
|
||||
==================== Input ====================
|
||||
<!-- oxfmt-ignore -->
|
||||
* kept as written
|
||||
|
||||
- formatted
|
||||
|
||||
==================== Output ====================
|
||||
------------------
|
||||
{ printWidth: 80 }
|
||||
------------------
|
||||
<!-- oxfmt-ignore -->
|
||||
* kept as written
|
||||
|
||||
- formatted
|
||||
|
||||
-------------------
|
||||
{ printWidth: 100 }
|
||||
-------------------
|
||||
<!-- oxfmt-ignore -->
|
||||
* kept as written
|
||||
|
||||
- formatted
|
||||
|
||||
===================== End =====================
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+12
@@ -15,3 +15,15 @@
|
||||
- item with extra code indentation
|
||||
|
||||
indented code
|
||||
|
||||
- foo
|
||||
|
||||
bar
|
||||
|
||||
indented code in a bullet item
|
||||
second line
|
||||
|
||||
- [ ] task
|
||||
|
||||
indented code in a task item
|
||||
second line
|
||||
+36
@@ -20,6 +20,18 @@ source: crates/oxc_formatter_markdown/tests/fixtures/mod.rs
|
||||
|
||||
indented code
|
||||
|
||||
- foo
|
||||
|
||||
bar
|
||||
|
||||
indented code in a bullet item
|
||||
second line
|
||||
|
||||
- [ ] task
|
||||
|
||||
indented code in a task item
|
||||
second line
|
||||
|
||||
==================== Output ====================
|
||||
-------------------------------
|
||||
{ printWidth: 80, tabWidth: 4 }
|
||||
@@ -42,6 +54,18 @@ source: crates/oxc_formatter_markdown/tests/fixtures/mod.rs
|
||||
|
||||
indented code
|
||||
|
||||
- foo
|
||||
|
||||
bar
|
||||
|
||||
indented code in a bullet item
|
||||
second line
|
||||
|
||||
- [ ] task
|
||||
|
||||
indented code in a task item
|
||||
second line
|
||||
|
||||
--------------------------------
|
||||
{ printWidth: 100, tabWidth: 4 }
|
||||
--------------------------------
|
||||
@@ -63,4 +87,16 @@ source: crates/oxc_formatter_markdown/tests/fixtures/mod.rs
|
||||
|
||||
indented code
|
||||
|
||||
- foo
|
||||
|
||||
bar
|
||||
|
||||
indented code in a bullet item
|
||||
second line
|
||||
|
||||
- [ ] task
|
||||
|
||||
indented code in a task item
|
||||
second line
|
||||
|
||||
===================== End =====================
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
- foo
|
||||
|
||||
bar
|
||||
|
||||
indented code in a bullet item
|
||||
second line
|
||||
|
||||
- [ ] task
|
||||
|
||||
indented code in a task item
|
||||
second line
|
||||
|
||||
>2. ordered item starting with indented code
|
||||
> second line
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
>2. ordered item starting with indented code
|
||||
> second line
|
||||
-36
@@ -2,18 +2,6 @@
|
||||
source: crates/oxc_formatter_markdown/tests/fixtures/mod.rs
|
||||
---
|
||||
==================== Input ====================
|
||||
- foo
|
||||
|
||||
bar
|
||||
|
||||
indented code in a bullet item
|
||||
second line
|
||||
|
||||
- [ ] task
|
||||
|
||||
indented code in a task item
|
||||
second line
|
||||
|
||||
>2. ordered item starting with indented code
|
||||
> second line
|
||||
|
||||
@@ -21,36 +9,12 @@ source: crates/oxc_formatter_markdown/tests/fixtures/mod.rs
|
||||
-------------------------------
|
||||
{ printWidth: 80, tabWidth: 4 }
|
||||
-------------------------------
|
||||
- foo
|
||||
|
||||
bar
|
||||
|
||||
indented code in a bullet item
|
||||
second line
|
||||
|
||||
- [ ] task
|
||||
|
||||
indented code in a task item
|
||||
second line
|
||||
|
||||
> 2. ordered item starting with indented code
|
||||
> second line
|
||||
|
||||
--------------------------------
|
||||
{ printWidth: 100, tabWidth: 4 }
|
||||
--------------------------------
|
||||
- foo
|
||||
|
||||
bar
|
||||
|
||||
indented code in a bullet item
|
||||
second line
|
||||
|
||||
- [ ] task
|
||||
|
||||
indented code in a task item
|
||||
second line
|
||||
|
||||
> 2. ordered item starting with indented code
|
||||
> second line
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
Reference in new issue
Block a user