Skip to content

Lists ​

Markers, looseness, the content-column model, continuation markers and block openers inside items.

Generated from resources/examples/edge-cases.md and resources/examples/core.md - edit the cases there, not here. Each case links the conformance fixture it produces.

An invisible fenced block is not a list paragraph ​

1 conformance fixture

A blank before a fenced percent block does not make the block a second paragraph. The opener, payload, and closer are classified as one block before list looseness is decided.

carve
- intro

   %%%
   hidden
   %%%
html
<ul>
  <li>intro</li>
</ul>

Lists ​

22 conformance fixtures

A marker is a list item only when followed by a space and content. A content-less marker — bare (-) or trailing whitespace only (- ) — is not a list; it stays paragraph text. The rule ignores trailing whitespace, so - and - behave the same (an editor stripping the space can't change the meaning). Carve is stricter than CommonMark, where a bare - is an empty item.

carve
-
not a list
html
<p>-
not a list</p>

The same holds for every marker that takes a separator space, not just bullets. A definition term needs content too, and here the trailing-whitespace half of the rule is what matters: :: and :: with two spaces after it must mean the same thing, or stripping whitespace on save would turn a paragraph into a definition list.

carve
::
html
<p>::</p>

An ordered list nests the same way — a child indented to the parent's content column (three spaces under 1. ) is a sub-list, even though an ordered marker does not interrupt a paragraph (§10).

carve
1. outer
   1. inner
html
<ol>
  <li>outer
    <ol>
      <li>inner</li>
    </ol>
  </li>
</ol>

An ordered child below the content column does not nest: an ordered marker does not interrupt a paragraph (§10), so it folds into the item as lazy text.

carve
1. outer
  1. inner
html
<ol>
  <li>outer
1. inner</li>
</ol>

After a blank line the same content-column rule applies: a continuation belongs to the item only if it reaches the item's content column (three columns under 1. ), exactly as without a blank. The blank line only decides whether the item is tight or loose; it never relaxes the column a block must reach. A block opener at the content column attaches and stays tight — unlike a second paragraph, a nested block does not loosen the list.

carve
1. one

   > q
html
<ol>
  <li>one
    <blockquote><p>q</p></blockquote>
  </li>
</ol>

Below the content column the line is outside the item body: the list ends and the block parses at document level. A two-column indent is not enough under an ordered marker whose content column is three — the same threshold the no-blank case uses.

carve
1. one

  > q
html
<ol>
  <li>one</li>
</ol>
<p>&gt; q</p>

Past the content column, a recognized opener uses its authored column as a temporary block base. Extra indentation is accepted inside list items and canonical output moves the opener back to the content column.

carve
1. one

    > q
html
<ol>
  <li>one
    <blockquote><p>q</p></blockquote>
  </li>
</ol>

A list marker does not interrupt an open paragraph — like an ordered marker, a bullet needs a blank line before it. An indented bullet after a prose line folds into the paragraph (lazy continuation).

carve
text
  - item
html
<p>text
- item</p>

With no preceding paragraph, an indented bullet simply opens a list whose base column is the indentation (Rule B).

carve
  - a
  - b
html
<ul>
  <li>a</li>
  <li>b</li>
</ul>

A blank line between items produces a loose list — each item wraps in a paragraph.

carve
- apples

- oranges
html
<ul>
  <li><p>apples</p></li>
  <li><p>oranges</p></li>
</ul>

A paragraph ends at a blank line — or at a line that begins an interrupting block. A continuation line that starts with >, a valid |…| table row, a heading #, a thematic break, or a fence with a closer interrupts the paragraph and starts that block, with no blank line required (the Markdown-like rule; §10). A list marker is the exception: neither a bullet (- / * ) nor an ordered marker (1., 1), a., …) interrupts — a list needs a blank line before it (symmetric, Djot-like). So a hard-wrapped prose line that happens to begin with a bullet stays prose; the bullet lines fold into the paragraph as lazy continuation.

carve
Die Frage ist x = 5
* 3 + 17 wahr.
html
<p>Die Frage ist x = 5
* 3 + 17 wahr.</p>

A heading under a prose line still interrupts it; a list — bullet or ordered — does not, so these fold into one paragraph.

carve
Liste:
- eins
- zwei
html
<p>Liste:
- eins
- zwei</p>

A blank line before the marker makes it a list, even with one item.

carve
Text hier

- nur eins
html
<p>Text hier</p>
<ul>
  <li>nur eins</li>
</ul>

A blockquote needs a blank line before it like any block; its caption line then attaches and the pair renders as a figure.

carve
Intro

> Stay hungry
^ Steve Jobs
html
<p>Intro</p>
<figure>
  <blockquote><p>Stay hungry</p></blockquote>
  <figcaption>Steve Jobs</figcaption>
</figure>

After a lazy continuation line, a marker at the content column resumes the same sub-list rather than starting a new one (§10).

carve
1. outer
   1. inner
lazy
   2. sibling
html
<ol>
  <li>outer
    <ol>
      <li>inner
lazy</li>
      <li>sibling</li>
    </ol>
  </li>
</ol>

A blank line is not a list boundary, so the ORDERED spelling loosens exactly as the bullet one does: the marker after the blank is still a sibling of the same list. §11 N1's axes are the bullet character, the ordered-marker alternative, the delimiter and plain-vs-task - a blank line is not among them - and §17 L1 reads "a blank line before the next sibling marker", which is a statement about tightness, not about where the list ends.

carve
1. apples

2. oranges
html
<ol>
  <li><p>apples</p></li>
  <li><p>oranges</p></li>
</ol>

A run of three or more blank lines is a hard list boundary (§11 N1a): the marker after it opens a new sibling list even though every N1 axis matches. One blank line still loosens, and so does two - the boundary is deliberately set above the run lengths documents already contain.

carve
- apples



- oranges
html
<ul>
  <li>apples</li>
</ul>
<ul>
  <li>oranges</li>
</ul>

The boundary applies at every level, not only the top one - a sub-list written at an item's content column separates from the one above it on the same run. That shape had no corpus pair when the clause landed, because the canonical writer could not spell it. It can now, and the pairs are at the end of this section.

The run denies a following sibling marker the right to join; it does not end the item. A continuation that reaches the item's content column still continues it, at any run length.

carve
- apples



  still apples
html
<ul>
  <li><p>apples</p>
    <p>still apples</p>
  </li>
</ul>

§11 N1a's boundary below the top level, and what the writer does with it. The clause is unrestricted, so a sub-list separates from the one above it on the same run - but the writer could not spell that until markup-carve/carve#1501: its tight-item join wrote both sub-lists at the item's MARKER column, which is column 0, and a compatible marker there dissolves them into the list around the item rather than attaching them to it. All three engine mainlines write them at the item's CONTENT column now, so these four pairs pin the reading and the .fmt sidecars beside them pin the spelling. The build this repository PINS is older than that fix and is declared behind on all four, in both engine ledgers, until the pin moves.

carve
- outer

  - a



  - b
html
<ul>
  <li>outer
    <ul>
      <li>a</li>
    </ul>
    <ul>
      <li>b</li>
    </ul>
  </li>
</ul>

The blank line after - outer is not part of the boundary, and the sidecar shows the writer dropping it: a blank line before a SUB-LIST does not loosen an item, only a blank line before a paragraph does. So the item comes back tight, with both sub-lists and the boundary between them.

A source whose run is LONGER than three is what tells a writer that preserves the boundary apart from one that copies its input, because §10i fixes the written run at exactly three whatever the author typed. The HTML is the same either way, so the .fmt sidecar is again what measures it. This is the nested twin of the top-level six-blank case.

carve
- outer

  - a






  - b
html
<ul>
  <li>outer
    <ul>
      <li>a</li>
    </ul>
    <ul>
      <li>b</li>
    </ul>
  </li>
</ul>

A LOOSE item takes the same boundary. That is one document to a reader and two code paths to a writer - the tight-item join is not involved at all - and the engines that got this wrong got it wrong in both places, so the loose shape is pinned rather than assumed to follow the tight one.

carve
- outer

  para

  - a



  - b
html
<ul>
  <li><p>outer</p>
    <p>para</p>
    <ul>
      <li>a</li>
    </ul>
    <ul>
      <li>b</li>
    </ul>
  </li>
</ul>

An item is not the only host with a content column. Inside a quote the boundary is spelled with the quote's own blank line, which is a bare > - an empty line would end the quote and take the second list out of it - and one level deeper it is > >. Only a sidecar can hold that: the marker lines carry NO trailing space, PART 11 §7 forbids one, and neither the HTML nor a check for whitespace-ONLY lines can tell > > from > > .

carve
> > - a
> >
> >
> >
> > - b
html
<blockquote>
  <blockquote>
    <ul>
      <li>a</li>
    </ul>
    <ul>
      <li>b</li>
    </ul>
  </blockquote>
</blockquote>

Ordered marker vs prose ​

1 conformance fixture

Letter and roman markers are ambiguous: a lone a. in running prose stays text (it would need a blank line before, a sibling marker, or indentation to start a list). Decimal markers always start a list.

carve
Pick option a. it is the best one here.
html
<p>Pick option a. it is the best one here.</p>

Parenthesized ordered marker ​

1 conformance fixture

Carve's ordered markers use the . and ) delimiters only; a parenthesized (1) is not a list marker (it is too easily confused with a prose parenthetical), so it stays literal text.

carve
(1) First
(2) Second
html
<p>(1) First
(2) Second</p>

List nesting and looseness ​

9 conformance fixtures

A more-indented marker nests a sublist inside the item.

carve
- a
  - b
  - c
- d
html
<ul>
  <li>a
    <ul>
      <li>b</li>
      <li>c</li>
    </ul>
  </li>
  <li>d</li>
</ul>

A blank line between items makes the list loose (each item wraps in <p>).

carve
- a

- b
html
<ul>
  <li><p>a</p></li>
  <li><p>b</p></li>
</ul>

An item with a second paragraph is loose; the continuation is indented under the marker.

carve
- a

  more
- b
html
<ul>
  <li><p>a</p>
    <p>more</p>
  </li>
  <li><p>b</p></li>
</ul>

A flush-left line after a heading cannot stay in the item that ends on that heading: the heading leaves no paragraph open. At a nested depth it may still resume an enclosing item's open paragraph. What it does not do is fold into the heading: a heading ends at the newline (§18), and its id is built from the heading line alone.

carve
- a
  - b
    # N
lazy
html
<ul>
  <li>a
    <ul>
      <li>b
        <h1 id="N">N</h1>
      </li>
    </ul>
    lazy
  </li>
</ul>

A blank line inside a fenced code block is verbatim content, not an interior block separator, so it does not loosen the list — a sibling item after such a fence stays tight because no blank line actually separates the two items.

carve
- ```
  a

  b
  ```
- c
html
<ul>
  <li>
    <pre><code>a

b
</code></pre>
  </li>
  <li>c</li>
</ul>

Plain text on the line after a fenced code block closes is the item's own trailing text. With no blank line anywhere the item stays tight, so that text is not wrapped in a paragraph.

carve
- ```
  x
  ```
  after
html
<ul>
  <li>
    <pre><code>x
</code></pre>
    after
  </li>
</ul>

A bullet's content column is where the marker actually ends, not a fixed 2. A bullet followed by extra spaces puts its content further right, and a block belongs to the item only if it reaches that column.

carve
-   item
    # Wide
html
<ul>
  <li>item
    <h1 id="Wide">Wide</h1>
  </li>
</ul>

Below that column the line is lazy paragraph text instead, so its marker survives literally — the same content-column rule as everywhere else, measured from the marker rather than assumed.

carve
-   item
  # H
html
<ul>
  <li>item
# H</li>
</ul>

A task item's content column stays at 2. The checkbox is content rather than marker, and extra spaces before it do not move the minimum column. A recognized heading at column 4 therefore uses column 4 as its authored base.

carve
-   [ ] item
    # H
html
<ul>
  <li><input type="checkbox" disabled aria-label="item"> item
    <h1 id="H">H</h1>
  </li>
</ul>

List lazy continuation ​

10 conformance fixtures

A non-indented line that follows a list item folds into the item's lead paragraph when it is plain paragraph text and has no blank line before it. A blank line, or a line that starts a block (heading, blockquote, fenced code, thematic break, table, div, a definition), ends the list instead.

carve
- item
lazy
html
<ul>
  <li>item
lazy</li>
</ul>
carve
- a
# H
html
<ul>
  <li>a</li>
</ul>
<section id="H">
  <h1>H</h1>
</section>

An under-indented continuation line after a nested sublist still folds into the deepest open paragraph (CommonMark lazy continuation); its indentation does not place it at an intermediate level. A blank line before it makes it a fresh paragraph instead.

carve
- a
  - b
 c
html
<ul>
  <li>a
    <ul>
      <li>b
c</li>
    </ul>
  </li>
</ul>
carve
- a
  - b
    - c
   d
html
<ul>
  <li>a
    <ul>
      <li>b
        <ul>
          <li>c
d</li>
        </ul>
      </li>
    </ul>
  </li>
</ul>
carve
- a
  - b

 c
html
<ul>
  <li>a
    <ul>
      <li>b</li>
    </ul>
  </li>
</ul>
<p>c</p>

Lazy continuation only ever extends an open paragraph. After a block inside an item, a dedented line therefore folds in only when that block leaves a paragraph open. A blockquote's trailing paragraph is open, so the line folds into the quote:

carve
- item
  > q
tail
html
<ul>
  <li>item
    <blockquote><p>q
tail</p></blockquote>
  </li>
</ul>

A fenced code block leaves no open paragraph, so a dedented line ends the item and starts a top-level block instead of joining the item:

carve
- item
  ```
  c
  ```
tail
html
<ul>
  <li>item
    <pre><code>c
</code></pre>
  </li>
</ul>
<p>tail</p>

A table is the same — no open paragraph, so the dedented line is a fresh top-level paragraph:

carve
- item
  | a | b |
tail
html
<ul>
  <li>item
    <table>
      <tbody>
        <tr><td>a</td><td>b</td></tr>
      </tbody>
    </table>
  </li>
</ul>
<p>tail</p>

A colon fence that is not a valid opener opens no block, so it leaves the paragraph open and the dedented line folds in. :::note has no space between the fence and the type word, so §12's opener test rejects it and the line is ordinary paragraph text; from there the paragraph absorbs the following fence-shaped line as text too (§12, "the absorption is not width-tagged"). Nothing ever interrupted the item's paragraph, so it is still open when tail arrives, and PART 1 S4 folds tail into it. What decides is whether a block was opened, never the shape of the line that tried - an absorbed fence is prose:

carve
- item
  :::note
  body
  :::
tail
html
<ul>
  <li>item
:::note
body
:::
tail</li>
</ul>

Give the same fence its space and the contrast is exact. Written ::: note, it is a valid opener: it interrupts the item's paragraph, its closer completes the block, and a closed ::: div or admonition leaves no open paragraph - so there tail does end the item and becomes a document paragraph, exactly as after the fenced code block and the table above. One space between the fence and the type word decides which of the two answers the same five lines get.

The same clause settles the neighboring shapes, which is how one knows it is the clause and not a special case, and each of them is a place an implementation could get the right answer here for the wrong reason. Indenting the lazy line to column 1 changes nothing, since it is still below the content column. The malformed fence may be the paragraph's FIRST line, written on the marker line itself (- :::note), and the item then opens with a paragraph that begins with fence-shaped text. Inside a block quote, > tail supplies the quote's prefix but not the item's indentation, which is the partial match S4 is written for. All three fold, for the one reason above; tests/colon-fence-absorbed-in-an-item.test.mjs pins them.

The same rule reaches a list item's second paragraph. The blank before spaced makes the item loose, but it does not close the paragraph that spaced opens. The following flush-left line therefore folds into that innermost paragraph; paragraph depth does not create a special boundary.

carve
1. item

   spaced
flush
html
<ol>
  <li><p>item</p>
    <p>spaced
flush</p>
  </li>
</ol>

Compact list blocks ​

10 conformance fixtures

A blank line is still required to start a block inside a list item, but it no longer makes the list loose when the indented content opens a block (sub-list, block quote, fenced code, fenced div, heading, table). The item stays tight — lead text inline, the block attached — so a checklist with notes or steps with code stay compact. (A Carve deviation: canonical djot renders these loose. Only the tight/loose rendering changes, not the block structure.)

carve
- item

  > note
- next
html
<ul>
  <li>item
    <blockquote><p>note</p></blockquote>
  </li>
  <li>next</li>
</ul>

A sub-list is one of those blocks, and the rule holds when a sibling item follows it: the blank belongs to the sub-list, not to the gap between items, so the whole list stays tight.

carve
- fruit

  - apples
- vegetables
html
<ul>
  <li>fruit
    <ul>
      <li>apples</li>
    </ul>
  </li>
  <li>vegetables</li>
</ul>

A genuine second prose paragraph still makes the list loose (and so does a blank line between items).

carve
- item

  second para
- next
html
<ul>
  <li><p>item</p>
    <p>second para</p>
  </li>
  <li><p>next</p></li>
</ul>

An invisible construct does not loosen either, and for a plainer reason than L2: §17 L1 asks whether the item holds a blank-line-separated second paragraph, and a comment or a definition is not a paragraph - it renders nothing at all. An item wrapped in <p> because of a line that produces no output would be the blank line showing through.

carve
- a

  %% just a note
html
<ul>
  <li>a</li>
</ul>

The same for a definition, which is collected and renders nothing where it stood.

carve
- a

  [r]: /u
html
<ul>
  <li>a</li>
</ul>

A sibling item after it is a different question, and there the list is loose: L1's other clause asks whether an item is followed by a blank line before the next sibling marker, and it is - an invisible line in the gap does not fill it.

carve
- a

  %% just a note
- b
html
<ul>
  <li><p>a</p></li>
  <li><p>b</p></li>
</ul>

A paragraph inside an item carries block attributes like any other, and the attribute line sits above it exactly as it does at document level.

carve
- a

  first

  {.c}
  second
html
<ul>
  <li><p>a</p>
    <p>first</p>
    <p class="c">second</p>
  </li>
</ul>

The attribute still reaches its paragraph across a blank line, exactly as it does at document level: §15 A2a floats it to the next visible block, and a blank is not a block. The item is loose because that paragraph is a real second one, not because of the attribute line.

carve
- a

  {.c}

  b
html
<ul>
  <li><p>a</p>
    <p class="c">b</p>
  </li>
</ul>

On its own, though, an attribute line leaves the item tight — it renders nothing, so it is not the second paragraph §17 L1 asks for, the same reason a comment or a definition is not.

carve
- a

  {.c}
html
<ul>
  <li>a</li>
</ul>

One column further in, the recognized attribute opener uses that authored column as a temporary block base. It remains invisible and the item remains tight.

carve
- a

   {.c}
html
<ul>
  <li>a</li>
</ul>

Marker-line nested lists ​

4 conformance fixtures

A sub-list opened on a parent item's marker line (- - A) is an ordinary persistent nested list, exactly as if the sub-marker sat on its own indented line. It is not a one-off lone item. This matches reference djot.js (@djot/djot) and CommonMark; carve previously inherited a narrower reading from djot-php that did not persist the nested list.

Following markers at the sub-list's indent merge into the same nested list, so - - A then - B and - C yields one list with three items.

carve
- - A
  - B
  - C
html
<ul>
  <li>
    <ul>
      <li>A</li>
      <li>B</li>
      <li>C</li>
    </ul>
  </li>
</ul>

A blank line followed by a block indented to the sub-list's content column is absorbed into the open nested item, just like any list item's lazy continuation. Here the first sub-item gains a second paragraph and the list is loose.

carve
- - A

    second
  - B
html
<ul>
  <li>
    <ul>
      <li><p>A</p>
        <p>second</p>
      </li>
      <li><p>B</p></li>
    </ul>
  </li>
</ul>

One column further out the same blank belongs to the OUTER item: second sits at the outer item's content column, so that item holds two blocks - the sub-list and a paragraph - and goes loose. The lead being a marker line is not part of the looseness test.

carve
- - A

  second
html
<ul>
  <li>
    <ul>
      <li>A</li>
    </ul>
    <p>second</p>
  </li>
</ul>

Flush left, the blank has closed the sub-item's paragraph and the line is below every open item's content column, so the list ends and the text is a document-level paragraph. Without the blank the same line would fold into the sub-item as lazy continuation.

carve
- - A

second
html
<ul>
  <li>
    <ul>
      <li>A</li>
    </ul>
  </li>
</ul>
<p>second</p>

Fence opener with a nested-list body inside a list item ​

7 conformance fixtures

A ::: opener inside a list item opens its block even when its body is a nested list (PART 9 §12). A bullet (-) or ordered marker (1.) on the next line is part of the admonition body, not a sibling list that swallows the opener as literal text. The matching closer sits at the item content column; a ::: at column zero (outside the item) does not close it. The closer is OPTIONAL here as everywhere (PART 2): an opener with none ahead of it still opens, and the container closes at end of input.

A nested unordered list body is wrapped by the admonition:

carve
- ::: note
  - para text
  :::
html
<ul>
  <li>
    <aside class="admonition note" aria-label="Note">
      <ul>
        <li>para text</li>
      </ul>
    </aside>
  </li>
</ul>

A nested ordered list body is wrapped the same way:

carve
- ::: note
  1. para text
  :::
html
<ul>
  <li>
    <aside class="admonition note" aria-label="Note">
      <ol>
        <li>para text</li>
      </ol>
    </aside>
  </li>
</ul>

A two-item nested list is wrapped whole:

carve
- ::: note
  - one
  - two
  :::
html
<ul>
  <li>
    <aside class="admonition note" aria-label="Note">
      <ul>
        <li>one</li>
        <li>two</li>
      </ul>
    </aside>
  </li>
</ul>

A blank line between the opener and the nested list still opens the block:

carve
- ::: note

  - para text
  :::
html
<ul>
  <li>
    <aside class="admonition note" aria-label="Note">
      <ul>
        <li>para text</li>
      </ul>
    </aside>
  </li>
</ul>

With NO closer, the opener still opens and the container closes at end of input, so the nested list is wrapped exactly as it is with a closer at the item content column. This label used to read the other way, calling the opener literal text under bytes that show it opening (carve#1722):

carve
- ::: note
  - para text
html
<ul>
  <li>
    <aside class="admonition note" aria-label="Note">
      <ul>
        <li>para text</li>
      </ul>
    </aside>
  </li>
</ul>

NEGATIVE: a closer at column zero is outside the item, so it does not close the opener. The opener still opens its admonition, which closes at end of input, and the stray ::: opens a second, top-level div with an empty body:

carve
- ::: note
  - para text
:::
html
<ul>
  <li>
    <aside class="admonition note" aria-label="Note">
      <ul>
        <li>para text</li>
      </ul>
    </aside>
  </li>
</ul>
<div>

</div>

GUARD: an empty body (opener immediately followed by its closer) still opens:

carve
- ::: note
  :::
html
<ul>
  <li>
    <aside class="admonition note" aria-label="Note">

    </aside>
  </li>
</ul>

Sublist marker interrupts a continuation paragraph ​

2 conformance fixtures

A list marker reaching a list item's content column always starts a sublist, even when the item holds an open continuation paragraph (PART 0 S3, PART 9 §24 C3). The general rule that list markers never interrupt a paragraph applies to markers below the content column (lazy continuation) and at the top level — not to a correctly indented sublist marker.

carve
- first

  second
  - nested
html
<ul>
  <li><p>first</p>
    <p>second</p>
    <ul>
      <li>nested</li>
    </ul>
  </li>
</ul>

Ordered markers behave identically (the symmetric list rule): an ordered marker at the content column nests.

carve
- first

  second
  1. nested
html
<ul>
  <li><p>first</p>
    <p>second</p>
    <ol>
      <li>nested</li>
    </ol>
  </li>
</ul>

Post-blank list continuation (content-column model) ​

5 conformance fixtures

A block opener or sublist marker attaches to a list item when it reaches at least the item's content column (§24 C3): - -> column 2, 1. -> column 3. One rule, blank line or not - the blank only decides tight vs loose. Below the content column a line lazily continues the item paragraph (no blank) or, after a blank, ends the item and parses at document level. Past the column, a recognized opener establishes its authored block base and remains structural; canonical output returns it to the content column. This is intentionally similar to Djot's deeper-indent leniency while retaining Carve's minimum column.

Below the content column, after a blank line, the block opener ends the item and parses at the document level.

carve
- one

 > q
html
<ul>
  <li>one</li>
</ul>
<p>&gt; q</p>

At the content column, it nests into the item.

carve
- one

  > q
html
<ul>
  <li>one
    <blockquote><p>q</p></blockquote>
  </li>
</ul>

Past the content column, a recognized opener remains structural and uses its authored column as a temporary block base.

carve
- one

   # h
html
<ul>
  <li>one
    <h1 id="h">h</h1>
  </li>
</ul>

With no blank line, a line below the content column lazily continues the open item paragraph.

carve
- one
 > q
html
<ul>
  <li>one
&gt; q</li>
</ul>

A block opener at column 0 is a document-level block: it interrupts and ends the list, exactly as a quote or heading there would.

carve
- one
```
c
```
html
<ul>
  <li>one</li>
</ul>
<pre><code>c
</code></pre>

Nested item looseness does not propagate to the outer item ​

4 conformance fixtures

A post-blank block attached to a nested (inner) item loosens only that inner item; the outer item stays tight (§17). Looseness is decided per level - a descendant's blank never counts toward an ancestor.

carve
- a
  - b

    > q
html
<ul>
  <li>a
    <ul>
      <li>b
        <blockquote><p>q</p></blockquote>
      </li>
    </ul>
  </li>
</ul>

The sibling-blank invariant: a blank between the inner items loosens the inner list but leaves the outer item tight - the same non-propagation.

carve
- a
  - b

  - c
html
<ul>
  <li>a
    <ul>
      <li><p>b</p></li>
      <li><p>c</p></li>
    </ul>
  </li>
</ul>

The content-column threshold follows the marker, so a task item's nested block behaves the same.

carve
- [ ] a
  - b

    > q
html
<ul>
  <li><input type="checkbox" disabled aria-label="a"> a
    <ul>
      <li>b
        <blockquote><p>q</p></blockquote>
      </li>
    </ul>
  </li>
</ul>

An item's own second paragraph after a blank still loosens it - non-propagation removes only the upward leak, not legitimate same-level looseness.

carve
- a

  b
html
<ul>
  <li><p>a</p>
    <p>b</p>
  </li>
</ul>

Table as a block opener in a list item ​

2 conformance fixtures

A |-delimited table row is a block opener under the same content-column rule: it nests at the content column and folds as lazy text below it.

carve
- one
  |= H |
  | x |
html
<ul>
  <li>one
    <table>
      <thead>
        <tr><th scope="col">H</th></tr>
      </thead>
      <tbody>
        <tr><td>x</td></tr>
      </tbody>
    </table>
  </li>
</ul>
carve
- one
 |= H |
 | x |
html
<ul>
  <li>one
|= H |
| x |</li>
</ul>

A paragraph opened after a block in an item is still open for a lazy line ​

5 conformance fixtures

PART 1 S4 asks one question of the open stack: does any container hold an OPEN paragraph. It does not ask where that paragraph sits among the container's blocks. An item whose first block is a table, a fence or a quote and whose next line is prose holds an open paragraph exactly as an item that began with prose does, so a following flush-left line folds into it and nothing closes.

The first case is the one that separates the two readings. | a | is inside the QUOTE, so at the item's own content column the block above + b | is a blockquote and not a table. PART 9 §5 T6 therefore refuses the continuation row, the line is prose, and prose keeps the paragraph open. A reader that consults the table through the container below - close enough to call the line a continuation row for the purpose of ending the paragraph, while still rendering it as text - answers one line two ways in the same parse.

carve
- > | a |
  + b |
tail
html
<ul>
  <li>
    <blockquote>
      <table>
        <tbody>
          <tr><td>a</td></tr>
        </tbody>
      </table>
    </blockquote>
    + b |
tail
  </li>
</ul>

The same rule with no continuation row involved: the item opens on a table, the next line is ordinary prose at the item's content column, and tail folds into the paragraph that prose opened.

carve
- | a |
  b
tail
html
<ul>
  <li>
    <table>
      <tbody>
        <tr><td>a</td></tr>
      </tbody>
    </table>
    b
tail
  </li>
</ul>

The block the paragraph follows is not what decides it, so a fenced block reads the same way.

carve
- ```
  c
  ```
  b
tail
html
<ul>
  <li>
    <pre><code>c
</code></pre>
    b
tail
  </li>
</ul>

CONTROL. A blank line closes the paragraph, and S4's other half then governs: nothing in the stack holds an open paragraph, so the item ends and tail is a document sibling.

carve
- | a |
  b

tail
html
<ul>
  <li>
    <table>
      <tbody>
        <tr><td>a</td></tr>
      </tbody>
    </table>
    b
  </li>
</ul>
<p>tail</p>

CONTROL. Here the table IS above the line at the item's own column, so the second row extends it, no paragraph is opened at all, and tail is again a document sibling. A reader that folded after a table unconditionally would answer this one wrong.

carve
- | a |
  | b |
tail
html
<ul>
  <li>
    <table>
      <tbody>
        <tr><td>a</td></tr>
        <tr><td>b</td></tr>
      </tbody>
    </table>
  </li>
</ul>
<p>tail</p>

An unterminated container does not extend the item past a blank line ​

6 conformance fixtures

A blank line ends the open paragraph, whatever container stands above it. PART 1 S4 then has nothing to continue, so a following line BELOW the item's content column is not the item's: it stands at the enclosing document's own opener column, and the item ends there. The state of the container above the blank does not enter the question - an unterminated ::: div reaches no further past a blank than a terminated one, an opaque body, a quote, or no container at all.

The executable spec answered the unterminated spelling alone. It carried the blank as container content and left the item's paragraph open across it, so a flush-left line folded into the div as a second paragraph, while the terminated div, the code fence, the quote and the bare item all ended the item on the same input. One rule was being answered two ways by whether a closer had been written. carve-js, carve-php and carve-rs end the item in every spelling (carve#1379).

carve
- ::: d
  b

tail
html
<ul>
  <li>
    <div class="d">
      <p>b</p>
    </div>
  </li>
</ul>
<p>tail</p>

CONTROL. Without the blank the paragraph b opened is still open, so the same flush-left line folds into it under S4's lazy branch and nothing closes. The blank is what decides, not the unterminated container - a reader that ended the item whenever a ::: was left open would answer this one wrong.

carve
- ::: d
  b
tail
html
<ul>
  <li>
    <div class="d">
      <p>b
tail</p>
    </div>
  </li>
</ul>

CONTROL. The blank ends the paragraph, not the ITEM. Content that returns at the item's content column is still inside the div, as its second block - so a reader that closed the item on any blank line inside an open container would answer this one wrong in the other direction.

carve
- ::: d
  b

  tail
html
<ul>
  <li>
    <div class="d">
      <p>b</p>
      <p>tail</p>
    </div>
  </li>
</ul>

An explicit closer is a SPELLING CHANGE, and the document above is where that gets tested. Writing the ::: it left open ends the container exactly where the item already ended it, so the two spellings are one document: the same blocks, in the same order, under the same list. The list's TIGHTNESS is part of that, and this is the spelling the canonical writer emits for the document above, so PART 11 §1's parse(fmt(x)) == parse(x) says outright that supplying the closer cannot move it.

The fixture below cannot say any of this. It is byte-identical to the one above, because the item's blocks sit inside the div and a tight list's paragraph suppression never reaches them - so tightness leaves no mark in the HTML, and a check comparing rendered output here passes under either reading. The pair is pinned at the PARSE level instead, by tests/an-explicit-closer-does-not-move-list-tightness.test.mjs.

What the rule settles is that the two spellings AGREE, not which of tight or loose they agree on. carve-js and carve-rs read the open spelling as loose and the closed one as tight, contradicting themselves rather than each other, and converge on loose; carve-php already reads both loose; the executable spec reads both tight, which is self-consistent and therefore conforms. Whether an item whose only child is a container holding a blank line is loose at all is a separate question and stays open (carve#1602).

carve
- ::: d
  b

  tail

```html
<ul>
  <li>
    <div class="d">
      <p>b</p>
      <p>tail</p>
    </div>
  </li>
</ul>

:::

THE SAME PRODUCTION, ONE CONFIGURATION OVER. Above, the container is the item's LEAD, so every block the item holds sits inside it and a tight list's paragraph suppression never reaches any of them - which is why that pair renders byte-identically under either reading and had to be pinned at the parse level. Move the container BELOW a lead block and the item keeps a paragraph of its own, and that paragraph is exactly what suppression does reach: a loose item wraps x in <p>, a tight one leaves it bare. So this configuration PRINTS the tightness the other one hides, and an ordinary .html fixture can hold the rule.

The reading is TIGHT, and it is the missing closer that has to not matter. The blank line is inside the div, so nothing separates the item's blocks and §17 L1 finds no separator to loosen on; writing the ::: the document leaves open ends the container where the item already ended it, so the two spellings are one document and the tightness cannot move across them (carve-js#1376, carve-js#1379).

carve
- x

a

b


```html
<ul>
  <li>x
    <div>
      <p>a</p>
      <p>b</p>
    </div>
  </li>
</ul>

:::

The closed spelling of the document above. Here PART 11 §1's parse(fmt(x)) == parse(x) and §1a's weaker HTML form say the same thing, which they do not in the pair further up: the item's lead paragraph puts the tightness into the output, so a reader that moved it across the closer is caught by the rendered bytes rather than only by the parse.

carve
- x

a

b :::


```html
<ul>
  <li>x
    <div>
      <p>a</p>
      <p>b</p>
    </div>
  </li>
</ul>

:::

A task item's checkbox is not decided by its first block ​

1 conformance fixture

The checkbox belongs to the ITEM. Nothing about what the item's first block turns out to be reaches it: it is written directly after the <li> opener in every spelling, and only the content moves - beside the checkbox when the first block renders inline, on its own indented line below it when it does not.

The executable spec emitted it only where that first block was a PARAGRAPH. Every other marker-line opener dropped it: a block quote, a code fence, a ::: div, a table row, a heading and a thematic break each rendered a plain <li>, so the [ ] or [x] the author wrote was gone from the output while the item itself parsed correctly. One serializer branch built the <li> opener without the checkbox, and it was the branch every non-paragraph lead takes. carve-js and carve-php write it in all of them (carve#1381).

carve
- [ ] > q
- [x] # h
- [ ] ---
html
<ul>
  <li><input type="checkbox" disabled> 
    <blockquote><p>q</p></blockquote>
  </li>
  <li><input type="checkbox" checked disabled> 
    <h1 id="h">h</h1>
  </li>
  <li><input type="checkbox" disabled> 
    <hr>
  </li>
</ul>

Only lazy folding demotes a marker-line colon opener ​

2 conformance fixtures

A ::: opener written as the sole content of a list item's marker line opens a container. What takes that away is LAZY FOLDING and nothing else: an opener whose whole body arrived from lines that folded in from below the item's content column never acquired container content at all, so it stays literal text. A blank line is not one of those lines. It is the container's own content - the item collector keeps it in the item body precisely because a colon fence is open above it - so an opener a blank follows has opened an EMPTY container, not no container.

The executable spec demoted it. Its guard asked only whether the body was non-empty, and a lone blank line satisfied that, so - ::: d before a blank read as literal item text while every neighbouring spelling of the same opener was right: at end of input, with its closer at the content column, with a body line, and inside a quote instead of an item. Four correct neighbours against one wrong one, and the difference was a line the collector had already decided was content. carve-js, carve-php and carve-rs open the div (carve#1382).

carve
- ::: d

tail
html
<ul>
  <li>
    <div class="d">

    </div>
  </li>
</ul>
<p>tail</p>

CONTROL, and the shape the guard exists for. Here the body really is lazy: tail sits below the item's content column and folds into the open paragraph the opener line left, so the opener never acquired a body of its own and the whole item is literal text. The blank that follows rides alongside that folded line and does not rescue the opener - a reader that stopped asking whether folding happened, and asked only whether the body was free of blanks, would answer this one wrong in the other direction.

carve
- ::: d
tail

after
html
<ul>
  <li>::: d
tail</li>
</ul>
<p>after</p>

A blank line before a sibling marker separates the items, whatever consumed it ​

3 conformance fixtures

Section 17 L1's first disjunct is a question about the LIST: is one item followed by a blank line before the next sibling marker? It reads what stands BETWEEN two items, and a blank line with nothing of the item after it stands between them whatever the item's interior was doing with it. An unterminated container above the blank does not change that, any more than it changes where the item ends.

The executable spec answered it by what the line was doing INSIDE the item. A blank inside an open fence is fence content, so it recorded no separator and the list stayed tight - for a ::: div, an admonition, a code fence, a tilde fence, a raw block and a comment fence alike, while the same document with the closer written loosens in every reader. carve-js and carve-rs loosen all six; carve-php loosens four of the six and stays tight for a code or tilde fence (markup-carve/carve-php#1445, carve#1383).

carve
- ::: d
  b

- s
html
<ul>
  <li>
    <div class="d">
      <p>b</p>
    </div>
  </li>
  <li><p>s</p></li>
</ul>

The same holds where the blank is genuinely the container's CONTENT and can be seen in the output. An unterminated code fence carries it as an empty payload line, and it still separates the items - what L1 asks is where the line sits relative to the marker, not which block absorbed it. Reading the payload instead would make a structural answer depend on a detail readers already spell differently: carve-php drops the same trailing blank from a raw block and keeps it in a code block.

carve
- ```
  b

- s
html
<ul>
  <li>
    <pre><code>b

</code></pre>
  </li>
  <li><p>s</p></li>
</ul>

CONTROL. The blank must precede a marker of THIS list. A different bullet character starts a different list under the section 11 axes, so nothing of the first list is followed by a blank before one of its own siblings and it stays tight - a reader that loosened on the blank alone would answer this one wrong. The first item carries the plain text that makes the answer visible: with only the fenced item, tight and loose render the same bytes and the case would assert nothing.

carve
- a
- ```
  b

* s
html
<ul>
  <li>a</li>
  <li>
    <pre><code>b

</code></pre>
  </li>
</ul>
<ul>
  <li>s</li>
</ul>

The INTERIOR blank carve#326 C ruled on is untouched, and its own stated reason is what separates the two: a sibling after such a fence "stays tight because no blank line actually separates the two items". Content follows an interior blank before the marker, so nothing stands between the items, and the case above in this file stays tight in all four readers.

A raw block keeps the blank line at the end of its payload too ​

3 conformance fixtures

The property is the one the fence section above states: a blank line inside a fence is content, and the last one is content too, wherever the fence ends. A raw block is a fence whose interior is a verbatim PAYLOAD rather than content lines, and the payload is every line between the delimiters. Which container the block sits in is not a parameter, and neither is whether the closer was written.

The shape that made this look unsettled is a raw block written LAST in the document. Its payload's trailing newlines then land at the very end of the output, where the trailing-whitespace trim every reader applies removes them, so all four readers print the same bytes and the document cannot tell the readings apart. Put a block after it and the payload becomes visible again (carve#1389).

carve
```=html
b

```

after
html
b

<p>after</p>

The same payload, inside a list item and with the fence left open. The item is loose because a blank line stands before the sibling marker, whatever consumed it; the blank is the payload's last line all the same.

carve
- ```=html
  b

- s
html
<ul>
  <li>
    b

  </li>
  <li><p>s</p></li>
</ul>

CONTROL. A payload with no blank line at the end of it gains none. This document renders the same bytes under either reading of the case above, so it pins nothing about the blank - it is here to catch the over-correction, a reader that emits a separator of its own after the payload.

carve
```=html
b
```

after
html
b
<p>after</p>

An unterminated fence at a content column opens no block, so the paragraph stays open ​

6 conformance fixtures

Section 10 I4 decides whether a code fence interrupts an open paragraph, and it is a question about the CLOSER: without one the fence line is ordinary paragraph text. That is what every reader already does at document level, where q over a bare fence run over b is one paragraph holding an unclosed inline verbatim run rather than a code block.

At a container's content column the same line does the same thing, so PART 1 S4 finds an open paragraph and a flush-left line below folds into it. The container does not end, because nothing closed the paragraph (carve#1387).

carve
- q
  ```
tail
html
<ul>
  <li>q
<code>
tail</code></li>
</ul>

The container is not a parameter. A definition body's content column answers the same way, and so does a block quote's - the quote spelling is the one every reader already folded, which is what made the list spelling a contradiction inside each of them rather than a disagreement between them.

carve
:: t
:  a
   ```
tail
html
<dl>
  <dt>t</dt>
  <dd>a
<code>
tail</code></dd>
</dl>
carve
> q
> ```
tail
html
<blockquote><p>q
<code>
tail</code></p></blockquote>

CONTROL. A blank line closes the paragraph, so S4's other half governs and the item ends whatever container is still waiting for its closer. This is the document the reading above must not swallow.

carve
- q
  ```

tail
html
<ul>
  <li>q
<code></code></li>
</ul>
<p>tail</p>

CONTROL. AT BLOCK START a fence opens a body whether or not it is terminated - there is no paragraph for section 10 I4 to protect, and the body runs to the end of the container. The flush-left line then has nothing to fold into and the item ends, which is the fenced-body clause with its premise intact. Nothing in the corpus pinned this shape before, and a reading that made every unterminated fence at a content column absorb its container's following lines passed all 1267 documents without it.

carve
- a

  ```
  b
tail
html
<ul>
  <li>a
    <pre><code>b
</code></pre>
  </li>
</ul>
<p>tail</p>

CONTROL. A fence WITH its closer is a block, and a block leaves no paragraph open, so the item ends on the flush-left line for the ordinary reason. The premise the clause turns on is the closer, and this is the shape where it holds.

carve
- q
  ```
  y
  ```
tail
html
<ul>
  <li>q
    <pre><code>y
</code></pre>
  </li>
</ul>
<p>tail</p>

A heading at an item's content column leaves no paragraph open ​

2 conformance fixtures

The content column is the item body's column zero, so a heading written there is the item's own heading block. It is not simultaneously a paragraph for the purpose of deciding whether a flush-left line may fold. No paragraph is open, and PART 1 S4 therefore ends the item before tail, exactly as it does when the same heading is written on the marker line or inside a quote. All four readers used to classify the heading correctly and then keep a phantom paragraph open behind it (carve#1377).

carve
- | a |
  # h
tail
html
<ul>
  <li>
    <table>
      <tbody>
        <tr><td>a</td></tr>
      </tbody>
    </table>
    <h1 id="h">h</h1>
  </li>
</ul>
<p>tail</p>

CONTROL. Prose at that same column really does open a paragraph, so the flush-left line lazily continues it. The earlier table does not matter once prose becomes the item's last block.

carve
- | a |
  prose
tail
html
<ul>
  <li>
    <table>
      <tbody>
        <tr><td>a</td></tr>
      </tbody>
    </table>
    prose
tail
  </li>
</ul>

A quote is reached by its marker, and a column never reaches into one ​

4 conformance fixtures

Section 10 I5's columns are read against the container a line is IN. A line that writes no > is in no block quote whatever column it lands on, because section 24 C5 composes the strips and the quote's strip is its marker. Such a line reaches the quote only through PART 1 S4's lazy fold, so it is paragraph text: it renders where it was written and registers nothing.

What made this look like two rules is that the same line answered differently by what the quote HELD. With a list in the quote, the line lands on the inner item's content column, where I5 would make a definition the item's - but it is not inside the item any more than it is inside the quote (carve#1384).

carve
> - x
  [r]: /url

See [r][].
html
<blockquote>
  <ul>
    <li>x
[r]: /url</li>
  </ul>
</blockquote>
<p>See [r][].</p>

The same shape one container deeper now has a live outer list item even though the line does not re-enter the quote. At column 4 it is an over-indented definition in that outer item, so it registers under the authored-base rule.

carve
- > - x
    [r]: /url

See [r][].
html
<ul>
  <li>
    <blockquote>
      <ul>
        <li>x</li>
      </ul>
    </blockquote>
  </li>
</ul>
<p>See <a href="/url">r</a>.</p>

CONTROL. The quote's body is a PARAGRAPH, and the second line is byte for byte the one above. It folds as text and defines nothing, which is what every reader already did - it is the document that shows the quote's body was never the parameter.

carve
> x
  [r]: /url

See [r][].
html
<blockquote><p>x
[r]: /url</p></blockquote>
<p>See [r][].</p>

CONTROL. Write the marker and the definition is inside the quote, where I5 gives it to the item whose content column it sits at. The marker is the parameter.

carve
> - x
>   [r]: /url

See [r][].
html
<blockquote>
  <ul>
    <li>x</li>
  </ul>
</blockquote>
<p>See <a href="/url">r</a>.</p>

A marker folds into a quote below it ​

9 conformance fixtures

An unmarked line at an ENCLOSING item's content column, with a quote below it holding the innermost open paragraph, is lazy paragraph text in that quote's paragraph. A list marker there folds like any other text and renders where it was written (markup-carve/carve#1905).

A quote is reached by its marker and a column never reaches into one, so the line is in no quote whatever column it lands on, and PART 0's lazy fold is the only route by which it touches one. The reach question PART 0's AT OR PAST MEANS THE DEEPEST COLUMN THE LINE REACHES answers therefore does not arise for the quote, and §24 C3's content-column branch -- a marker there opens a sublist -- is never reached, because it asks what a line does IN a container and this line is never classified in the item.

The twins and the controls are pinned here beside the folds rather than the divergent documents alone. Their absence is why this drifted: the paragraph twin has always folded at this column in every reader, and the no-quote shapes have always opened a list element with no blank line before it. Neither may move.

The ticket's document. The quote is written BELOW the item's lead line, and - m sits at column 2 -- the outer item's content column, and below the quote's content column of 4. The marker folds into the quoted item's paragraph and renders as text.

carve
- a
  > - x
  - m
html
<ul>
  <li>a
    <blockquote>
      <ul>
        <li>x
- m</li>
      </ul>
    </blockquote>
  </li>
</ul>

The MARKER-LEAD spelling of the same geometry, where the quote sits on the item's lead line instead of below it. Same answer: which line the quote was written on is not a parameter of this rule.

carve
- > - x
  - m
html
<ul>
  <li>
    <blockquote>
      <ul>
        <li>x
- m</li>
      </ul>
    </blockquote>
  </li>
</ul>

The sharpest case. Once the fold has started, intervening prose does not escape the quote: p folds, the fold leaves the quote open for the line after it, and the marker folds too.

carve
- a
  > - x
  p
  - m
html
<ul>
  <li>a
    <blockquote>
      <ul>
        <li>x
p
- m</li>
      </ul>
    </blockquote>
  </li>
</ul>

The PARAGRAPH TWIN, which every reader already folds at this exact column. Replacing the quoted list with quoted prose changes nothing, which is why ruling the marker out of the fold would have had to move this document as well.

carve
- a
  > q
  - m
html
<ul>
  <li>a
    <blockquote><p>q
- m</p></blockquote>
  </li>
</ul>

CONTROL -- a BLANK LINE is the escape, and the only one. It ends the quote and every column opened inside it, so the marker below is classified in the item and opens a list there.

carve
- a
  > - x

  - m
html
<ul>
  <li>a
    <blockquote>
      <ul>
        <li>x</li>
      </ul>
    </blockquote>
    <ul>
      <li>m</li>
    </ul>
  </li>
</ul>

CONTROL -- an item where the quote was. The line is classified in the enclosing item, so the marker opens a sibling with no blank line before it.

carve
- a
  - b
  - m
html
<ul>
  <li>a
    <ul>
      <li>b</li>
      <li>m</li>
    </ul>
  </li>
</ul>

CONTROL -- a heading where the quote was. It leaves no paragraph open, and the marker at the content column opens a sublist.

carve
- a
  # h
  - m
html
<ul>
  <li>a
    <h1 id="h">h</h1>
    <ul>
      <li>m</li>
    </ul>
  </li>
</ul>

CONTROL -- a fence where the quote was. Same answer, and the fence kind does not enter into it.

carve
- a
  ```
  c
  ```
  - m
html
<ul>
  <li>a
    <pre><code>c
</code></pre>
    <ul>
      <li>m</li>
    </ul>
  </li>
</ul>

CONTROL -- a paragraph where the quote was. That paragraph IS the item's, so §24 C3 governs at the content column and the marker opens a sublist. This is the row that shows the rule is about the QUOTE rather than about the column.

carve
- a
  p
  - m
html
<ul>
  <li>a
p
    <ul>
      <li>m</li>
    </ul>
  </li>
</ul>

An opener under a quote in a nested host opens at one column only ​

13 conformance fixtures

PART 0 [CARVE-P0-021] folds a block opener into a surviving quote's open paragraph at every column but the host's own content column. PART 0 [CARVE-P0-004] rebases a RECOGNIZED opener, and past the content column a line is one only where no open paragraph can take it as text; PART 0 [CARVE-P0-011] is why that column itself always opens. The item's content column is 2 and the quote's is 4, so column 2 is the control and 1, 3, 4 and 8 all fold. A raw fence earns its own documents: folded, its payload reaches the page inside a code span, while an opener there drops a format the target does not match under PART 9 [CARVE-P9-040], so the band decides whether authored text is published or gone (carve#2607).

carve
- a
  > q
  ```js
  c
  ```
html
<ul>
  <li>a
    <blockquote><p>q</p></blockquote>
    <pre><code class="language-js">c
</code></pre>
  </li>
</ul>
carve
- a
  > q
 ```js
 c
 ```
html
<ul>
  <li>a
    <blockquote><p>q
<code>js
c
</code></p></blockquote>
  </li>
</ul>
carve
- a
  > q
   ```js
   c
   ```
html
<ul>
  <li>a
    <blockquote><p>q
<code>js
c
</code></p></blockquote>
  </li>
</ul>
carve
- a
  > q
    ```js
    c
    ```
html
<ul>
  <li>a
    <blockquote><p>q
<code>js
c
</code></p></blockquote>
  </li>
</ul>
carve
- a
  > q
        ```js
        c
        ```
html
<ul>
  <li>a
    <blockquote><p>q
<code>js
c
</code></p></blockquote>
  </li>
</ul>
carve
- a
  > q
   # h
html
<ul>
  <li>a
    <blockquote><p>q
# h</p></blockquote>
  </li>
</ul>
carve
- a
  > q
   ---
html
<ul>
  <li>a
    <blockquote><p>q
—</p></blockquote>
  </li>
</ul>
carve
- a
  > q
   | c |
   |---|
   | 1 |
html
<ul>
  <li>a
    <blockquote><p>q
| c |
|—|
| 1 |</p></blockquote>
  </li>
</ul>
carve
- a
  > q
   ```=latex
   \r
   ```
html
<ul>
  <li>a
    <blockquote><p>q
<code>=latex
\r
</code></p></blockquote>
  </li>
</ul>
carve
- a
  > q
   ```=html
   <b>r</b>
   ```
html
<ul>
  <li>a
    <blockquote><p>q
<code>=html
&lt;b&gt;r&lt;/b&gt;
</code></p></blockquote>
  </li>
</ul>
carve
x[^1]

[^1]: > q
   ```js
   c
   ```
html
<p>x<a id="fnref1" href="#fn1" role="doc-noteref"><sup>1</sup></a></p>
<section role="doc-endnotes" aria-label="Footnotes">
  <hr>
  <ol>
    <li id="fn1">
      <blockquote><p>q
<code>js
c
</code></p></blockquote>
      <p><a href="#fnref1" role="doc-backlink" aria-label="Back to reference">↩</a></p>
    </li>
  </ol>
</section>
carve
x[^1]

[^1]: > q
   ```=latex
   \r
   ```
html
<p>x<a id="fnref1" href="#fn1" role="doc-noteref"><sup>1</sup></a></p>
<section role="doc-endnotes" aria-label="Footnotes">
  <hr>
  <ol>
    <li id="fn1">
      <blockquote><p>q
<code>=latex
\r
</code></p></blockquote>
      <p><a href="#fnref1" role="doc-backlink" aria-label="Back to reference">↩</a></p>
    </li>
  </ol>
</section>
carve
:: t
: > q
   ```js
   c
   ```
html
<dl>
  <dt>t</dt>
  <dd>
    <blockquote><p>q
<code>js
c
</code></p></blockquote>
  </dd>
</dl>

Colon-fence as a block opener in a list item ​

3 conformance fixtures

A ::: colon-fence (admonition / div) is a block opener like every other (§24 C3): it must reach the item's content column, and a deeper authored column becomes the fence's temporary block base.

carve
- one
 ::: note
 b
 :::
html
<ul>
  <li>one
::: note
b
:::</li>
</ul>
carve
- one
  ::: note
  b
  :::
html
<ul>
  <li>one
    <aside class="admonition note" aria-label="Note">
      <p>b</p>
    </aside>
  </li>
</ul>
carve
- one
   ::: note
   b
   :::
html
<ul>
  <li>one
    <aside class="admonition note" aria-label="Note">
      <p>b</p>
    </aside>
  </li>
</ul>

Fence folds as lazy inline code above the content column ​

1 conformance fixture

A fenced code block indented past the content column remains a block opener. Its opener column is the temporary block base, so structural over-indent is removed while payload indentation beyond that base survives. Canonical output writes the fence at the content column.

carve
- one

   ```
   c
   ```
html
<ul>
  <li>one
    <pre><code>c
</code></pre>
  </li>
</ul>

Indented ordered marker content column includes the marker indent ​

1 conformance fixture

The content column of a list item includes the marker's own leading indentation (PART 9 §24 C3): 1. is base column 4 plus marker width 3, so its content column is 7. A block opener dedented below that column but not to column 0 is lazy text, not a new block. A | x | table row at column 2 therefore folds into the item as lazy paragraph text instead of ending the item and escaping the row to a document-level table.

carve
    1. y
  | x |
html
<ol>
  <li>y
| x |</li>
</ol>

Outer item with an internal blank before an attached block is loose ​

1 conformance fixture

An over-indented recognized block after a nested list remains an attached block. Its authored quote column is temporary; it does not turn the quote into a paragraph or make the outer item loose.

carve
- a
  - b

   > q
html
<ul>
  <li>a
    <ul>
      <li>b</li>
    </ul>
    <blockquote><p>q</p></blockquote>
  </li>
</ul>

Tight list item keeps trailing text after a block bare ​

3 conformance fixtures

In a tight list item, text that follows a closed block (a fenced code block, a div, or an admonition) is part of the item's inline content and is not wrapped in a <p>, matching the item's tightness. Only a blank-separated (loose) item wraps its paragraphs.

carve
- item
  ```
  c
  ```
  tail
html
<ul>
  <li>item
    <pre><code>c
</code></pre>
    tail
  </li>
</ul>

The same holds after a div body, and for an ordered item.

carve
- item
  :::note
  body
  :::
  tail
html
<ul>
  <li>item
:::note
body
:::
tail</li>
</ul>

A blank line makes the item loose, so its leading text and the trailing text are each wrapped.

carve
- item

  ```
  c
  ```

  tail
html
<ul>
  <li><p>item</p>
    <pre><code>c
</code></pre>
    <p>tail</p>
  </li>
</ul>

Bare-dot ordered markers ​

3 conformance fixtures

An ordered marker may drop its value when the delimiter is .: a bare . counts from 1, the AsciiDoc-style shorthand for the list nobody numbers by hand.

carve
. first
. second
. third
html
<ol>
  <li>first</li>
  <li>second</li>
  <li>third</li>
</ol>

The bare dot is a spelling, not a dialect: it is decimal-dot, so it opens and continues one list with the explicit form. Only . may drop its value - a leading ) collides with prose parentheticals far more often than a leading . does, the same asymmetry that keeps (1) from being a marker.

carve
1. explicit
. continues the same list

) not a marker, and never opens one
html
<ol>
  <li>explicit</li>
  <li>continues the same list</li>
</ol>
<p>) not a marker, and never opens one</p>

Carrying no value, it cannot set a start - 3. is how that is written - and li-attributes attach to it exactly as they do to every other marker, because the shape is marker, then attributes, then the required space.

carve
.{#x} attributed
. plain
html
<ol>
  <li id="x">attributed</li>
  <li>plain</li>
</ol>

A definition attached by a + continuation marker is collected, and the item keeps no trace ​

1 conformance fixture

The + continuation marker (§17 L3/L4) attaches a flush-left block to the container above it like any other block - a definition is not special-cased out of that. It is collected exactly as one written at the item's own content column (above), and the item that held it renders with no trace of the line at all: no empty block, no blank line left behind (carve#665; §17 L6).

carve
- a
+
[r]: /u

see [t][r]
html
<ul>
  <li>a</li>
</ul>
<p>see <a href="/u">t</a></p>

An uppercase roman numeral is a list marker ​

1 conformance fixture

Roman markers are case-blind: I. opens a list with type="I" as i. does with type="i".

carve
I. one
II. two
html
<ol type="I">
  <li>one</li>
  <li>two</li>
</ol>

Sibling markers that reach one column are one list ​

1 conformance fixture

The same column claim decides sibling markers as decides a block opener: two markers that reach one column are one list, however the indentation was written. A space advances one column and a tab advances to the next multiple of 4 (§24 C1), so four spaces and a space-plus-tab both put a marker at column 4.

This is the third shape of the rule the corpus pinned in a tab indent is the column it reaches, held back until the residual columns a straddling tab leaves behind stopped claiming source offsets they do not have (carve-js#773).

carve
- a
    - b
 	- c
html
<ul>
  <li>a
    <ul>
      <li>b</li>
      <li>c</li>
    </ul>
  </li>
</ul>

The continuation marker at an item's own column, and what follows it ​

3 conformance fixtures

§17's + continuation marker was pinned by the corpus in one shape only: a marker at column 0 with a BLOCK after it. Both axes it varies - where the marker sits, and what kind of thing follows - were unreached, and each hid a live divergence until someone measured it by hand (carve#812).

An INDENTED + is not consumed as a marker, so it survives as text in the item, and a definition below it is still collected:

carve
- a
  +
  [r]: /u

see [t][r]
html
<ul>
  <li>a
+</li>
</ul>
<p>see <a href="/u">t</a></p>

The same indented + with nothing attached stays in the item it was written in, rather than starting a block of its own:

carve
- a
  +

x
html
<ul>
  <li>a
+</li>
</ul>
<p>x</p>

A PARAGRAPH attached by a column-0 + is the shape the marker most obviously serves, and the corpus pinned only non-paragraph blocks - a fenced code block and a block quote - on which the engines had always agreed. Attached paragraph text is bare, not wrapped in its own <p>:

carve
- a
+
b

x
html
<ul>
  <li>a
    b
  </li>
</ul>
<p>x</p>

A continuation marker after a blank line in the item ​

1 conformance fixture

§17 L3 conditions the marker on its COLUMN and on nothing else - not on the item being tight, and not on what the item already holds. The corpus reached it only in a tight item, so an engine could recognize it there and drop it once a blank line had appeared, which is what carve-php did (carve-php#925): the marker came out as literal text inside the paragraph it was meant to end, and the block it should have attached folded in with it.

carve
- a

  b
+
c

x
html
<ul>
  <li><p>a</p>
    <p>b</p>
    <p>c</p>
  </li>
</ul>
<p>x</p>

A continuation marker attaches one block, and the boundary is that block's extent ​

9 conformance fixtures

§17 L3 says it in capitals: a + attaches "the FOLLOWING flush-left block to that container — ONE block of ANY kind". The trailing "up to the next blank line, sibling marker, or a further +" is the extent of that one block, not a count — an attached list, quote or fenced block is many lines long and still one block (markup-carve/carve#1290).

So a marker takes the paragraph and leaves the quote below it outside the item:

carve
- a
+
para
> q
html
<ul>
  <li>a
    para
  </li>
</ul>
<blockquote><p>q</p></blockquote>

A second attached block takes a second marker. This spelling already produces identical output in all three engines, so one block costs a marker line and no expressiveness:

carve
- a
+
para
+
> q
html
<ul>
  <li>a
    para
    <blockquote><p>q</p></blockquote>
  </li>
</ul>

The one block may be many lines. A wrapped paragraph is not cut at its first line, and the quote below it is still outside:

carve
- a
+
p1
p2
> q
html
<ul>
  <li>a
    p1
p2
  </li>
</ul>
<blockquote><p>q</p></blockquote>

An attached LIST is one block too, however many items it holds — the extent clause is what carries them in:

carve
- a
+
> x
> y
- next
html
<ul>
  <li>a
    <blockquote><p>x
y</p></blockquote>
  </li>
  <li>next</li>
</ul>

A sibling marker ends the attachment rather than being swallowed into it, which is the measured case that settles the reading on its own — three flat items, in every engine:

carve
- a
+
- x
- y
html
<ul>
  <li>a</li>
  <li>x</li>
  <li>y</li>
</ul>

The first-block form counts the same way. - + opens an item whose body is the one block that follows, and a second block needs its own marker:

carve
- +
para
> q
html
<ul>
  <li>para</li>
</ul>
<blockquote><p>q</p></blockquote>
carve
- +
para
+
> q
html
<ul>
  <li>para
    <blockquote><p>q</p></blockquote>
  </li>
</ul>

The block-quote form counts the same way. > quoted / + / para / # H attaches the paragraph and leaves the heading outside the quote:

carve
> quoted
+
para
# H
html
<blockquote>
  <p>quoted</p>
  <p>para</p>
</blockquote>
<section id="H">
  <h1>H</h1>
</section>

And a second marker brings it in, exactly as in the list form:

carve
> quoted
+
para
+
# H
html
<blockquote>
  <p>quoted</p>
  <p>para</p>
  <h1 id="H">H</h1>
</blockquote>

A continuation marker after a blank line in a loose item ​

1 conformance fixture

The marker sits at the item's marker column and attaches the flush-left block below it, whether or not a blank line comes first. The blank does not loosen the item on its own - this item is loose because of the blank between a and b, not because of the one before the marker.

carve
- a

  b

+
c

x
html
<ul>
  <li><p>a</p>
    <p>b</p>
    <p>c</p>
  </li>
</ul>
<p>x</p>

A fence opened on a list marker line, body below the content column ​

7 conformance fixtures

A code fence opened on a list MARKER line, with its body below the item's content column, got four different answers from four readers - the executable spec swallowed the closer into the code text, carve-js did the same with an extra space, carve-php read the column-0 line as body and let the column-0 fence close it, and only carve-rs closed the item (markup-carve/carve#646). No corpus case put a fence body below the content column, so nothing could tell.

PART 9 §24's STEP algorithm already decides it, without a new rule. Take x at column 0 with the stack document > list > item(content_column 2) > code fence body:

  • S1 MATCH PREFIXES walks the stack and stops at the first container whose prefix the line does not supply. x supplies no indentation, so the walk stops at the ITEM and the fenced body is never reached.
  • S2 FENCED BODY therefore does not fire: it applies only when the innermost MATCHED container is a fenced body, and here that is the item.
  • S4 PARTIAL MATCH governs. Its lazy-continuation branch continues an OPEN PARAGRAPH, and a fenced body is not one - the NO OPEN PARAGRAPH, NO LAZY LINE clause the spec already spells out for . >. What remains is S4's otherwise: close the unmatched containers and re-classify the residue in the surviving context.

So the item holds an EMPTY code block and x re-parses at document level:

carve
- ```
x
```
html
<ul>
  <li>
    <pre><code></code></pre>
  </li>
</ul>
<p>x
<code></code></p>

The trailing delimiter becoming EMPTY INLINE CODE is pinned deliberately rather than inherited. It is not part of the rule - it is what a backtick run means once the line is ordinary paragraph text - but it is the kind of output nobody would write down on purpose, so it is stated.

One column in is the same answer, and it is a separate row because the two broken readings differed here: one kept the leading space in the code text and one stripped it. Below the content column is below the content column.

carve
- ```
 x
 ```
html
<ul>
  <li>
    <pre><code></code></pre>
  </li>
</ul>
<p>x
<code></code></p>

CONTROL. AT the content column the fence body is the item's, the closer closes it, and nothing leaves the item. All four readers always agreed here, which is the shape every existing corpus case uses:

carve
- ```
  x
  ```
html
<ul>
  <li>
    <pre><code>x
</code></pre>
  </li>
</ul>

The BLOCK QUOTE analogue is the same derivation with the same answer, and all three engines already agree on it - unenforced until now, which is why the list case could drift away from it:

carve
> ```
x
```
html
<blockquote>
  <pre><code></code></pre>
</blockquote>
<p>x
<code></code></p>

A tilde fence takes the same route, and the residue shows the empty inline code above was a property of the BACKTICK run rather than of this rule: ~~~ in paragraph text is just text.

carve
- ~~~
x
~~~
html
<ul>
  <li>
    <pre><code></code></pre>
  </li>
</ul>
<p>x
~~~</p>

The guard is on the OPEN FENCE, not on the item's paragraph state. Once the body has collected a line at the content column, a reader tracking "is a paragraph open" sees one again and folds - so this row and the first one need different mechanisms to pass, and only the fence-shaped rule passes both:

carve
- ```
  x
 y
  ```
html
<ul>
  <li>
    <pre><code>x
</code></pre>
  </li>
</ul>
<p>y
<code></code></p>

The same clause reaches one shape further: a fence opened on a CONTINUATION line, after a has opened a paragraph. §10 I4 decides first whether the fence interrupts a, and its closer lookahead does not stop at the below-column line (PART 1, THE CLOSER LOOKAHEAD DOES NOT STOP AT A BELOW-COLUMN LINE), so it finds the closer and a real code block opens. That open body is what makes y end the item, and the block runs to the item's end with its closer left outside.

The item's own parse takes the same answer. Asking I4 again over the truncated item would find no closer and read the run as paragraph text - one line read two ways in one parse, with a paragraph open that y would then have folded into.

carve
- a
  ```
  b
 y
  ```
html
<ul>
  <li>a
    <pre><code>b
</code></pre>
  </li>
</ul>
<p>y
<code></code></p>

An item's fence is read once, whatever block it follows ​

2 conformance fixtures

A fence on an item's continuation line whose closer sits past a below-column line opens a code block (see A fence opened on a list marker line, body below the content column), and that holds after a caption or a quote as it does after a paragraph. Each reader that asks §10 I4 about the fence line takes the answer the item collector gave, so the fence is not folded into the caption or the quoted paragraph while the item ends at y as though it had opened. With the closer inside the item the same documents open the same block.

carve
- ![a](i)
  ^ cap
  ```
  b
 y
  ```
html
<ul>
  <li>
    <figure>
      <img src="i" alt="a">
      <figcaption>cap</figcaption>
    </figure>
    <pre><code>b
</code></pre>
  </li>
</ul>
<p>y
<code></code></p>
carve
- > q
  ```
  b
 y
  ```
html
<ul>
  <li>
    <blockquote><p>q</p></blockquote>
    <pre><code>b
</code></pre>
  </li>
</ul>
<p>y
<code></code></p>

A definition body's open code fence ends at a line below its column ​

5 conformance fixtures

A FENCED BODY IS NOT A PARAGRAPH (PART 1, CARVE-P0-013), in a definition body as in a list item: a line below the body's column has no paragraph to fold into, so the body ends there and the line is read at document level. Whether the fence opened is §10 I4's question, asked the way An item's fence is read once, whatever block it follows asks it (markup-carve/carve#2143).

carve
:: t
: ```
 y
  ```
html
<dl>
  <dt>t</dt>
  <dd>
    <pre><code></code></pre>
  </dd>
</dl>
<p>y
<code></code></p>
carve
:: t
: ```
  b
 y
html
<dl>
  <dt>t</dt>
  <dd>
    <pre><code>b
</code></pre>
  </dd>
</dl>
<p>y</p>

After a paragraph the fence opens because its closer follows, past the below-column line, and the body's own parse takes the same answer.

carve
:: t
: a
  ```
  b
 y
  ```
html
<dl>
  <dt>t</dt>
  <dd>
    <p>a</p>
    <pre><code>b
</code></pre>
  </dd>
</dl>
<p>y
<code></code></p>

CONTROL. A fence the body already closed leaves the paragraph after it open, so the line folds into that paragraph as it does under a list item.

carve
:: t
: ```
  b
  ```
  c
 y
html
<dl>
  <dt>t</dt>
  <dd>
    <pre><code>b
</code></pre>
    <p>c
y</p>
  </dd>
</dl>

The closer has to be reachable. A blank line followed by a line below the column ends the body (carve#1379), and a fence-shaped line past that is not this fence's closer, so the fence opened nothing and y folds into the paragraph it stayed part of.

carve
:: t
: a
  ```
  b
 y

z
  ```
html
<dl>
  <dt>t</dt>
  <dd>a
<code>
b
y</code></dd>
</dl>
<p>z
<code></code></p>

A closer below the container's column does not count ​

7 conformance fixtures

The closer lookahead runs past a line below the content column but never matches one (PART 1, A BELOW-COLUMN LINE IS SEARCHED PAST, NEVER MATCHED). A flush-left run, or one a column short, is not written inside the item, so the fence opens nothing and the lines fold into the paragraph as text (markup-carve/carve#2145).

carve
- a
  ```
  b
 y
```
html
<ul>
  <li>a
<code>
b
y
</code></li>
</ul>
carve
- a
  ```
  b
 y
 ```
html
<ul>
  <li>a
<code>
b
y
</code></li>
</ul>

A run past the content column is inside the item but is no closer either: a fence delimiter sits exactly at its container's content column (CARVE-P2-006). The one that counts is at the column, as in A fence opened on a list marker line, body below the content column.

carve
- a
  ```
  b
 y
   ```
html
<ul>
  <li>a
<code>
b
y
</code></li>
</ul>

A definition body reads the same way, on both sides.

carve
:: t
: a
  ```
  b
 y
```
html
<dl>
  <dt>t</dt>
  <dd>a
<code>
b
y
</code></dd>
</dl>
carve
:: t
: a
  ```
  b
 y
   ```
html
<dl>
  <dt>t</dt>
  <dd>a
<code>
b
y
</code></dd>
</dl>

The flush-left run folds because §10 I4 lets a fence interrupt a paragraph only when a closer follows it. That holds in a definition body with nothing else in play, as it does under a list item.

carve
:: t
: a
```
html
<dl>
  <dt>t</dt>
  <dd>a
<code></code></dd>
</dl>

CONTROL. With a closer after it the same run does interrupt, so the description ends and the fence opens a block at document level.

carve
:: t
: a
```
b
```
html
<dl>
  <dt>t</dt>
  <dd>a</dd>
</dl>
<pre><code>b
</code></pre>

A bare colon opener in a description body is an opener ​

7 conformance fixtures

A bare ::: is closer-shaped, but in a definition body that closes nothing it opens a container, as a typed ::: d does: a ::: opener is not guarded (§10 I4). An empty container leaves no paragraph open, so a line below the body's column closes it (CARVE-P0-016, and An empty unterminated container ends at a flush-left line for the typed spelling). The list-host spelling is a separate question and is not decided here (markup-carve/carve#2147).

carve
:: t
: :::
 y
  :::
html
<dl>
  <dt>t</dt>
  <dd>
    <div>

    </div>
  </dd>
</dl>
<p>y
:::</p>
carve
:: t
: :::
y
html
<dl>
  <dt>t</dt>
  <dd>
    <div>

    </div>
  </dd>
</dl>
<p>y</p>

After a paragraph it interrupts, whether a line follows it or not, and a pair closed at once is closed.

carve
:: t
: a
  :::
y
html
<dl>
  <dt>t</dt>
  <dd>
    <p>a</p>
    <div>

    </div>
  </dd>
</dl>
<p>y</p>
carve
:: t
: a
  :::
html
<dl>
  <dt>t</dt>
  <dd>
    <p>a</p>
    <div>

    </div>
  </dd>
</dl>
carve
:: t
: :::
  :::
y
html
<dl>
  <dt>t</dt>
  <dd>
    <div>

    </div>
  </dd>
</dl>
<p>y</p>

CONTROL. A container that already holds a paragraph takes the line in as lazy continuation, and a ::: inside an open code fence is code, not an opener.

carve
:: t
: :::
  a
 y
  :::
html
<dl>
  <dt>t</dt>
  <dd>
    <div>
      <p>a
y</p>
    </div>
  </dd>
</dl>
carve
:: t
: a
  ```
  :::
 y
  ```
html
<dl>
  <dt>t</dt>
  <dd>
    <p>a</p>
    <pre><code>:::
</code></pre>
  </dd>
</dl>
<p>y
<code></code></p>

An empty term marker in a description body is text ​

6 conformance fixtures

A :: line with nothing after it but whitespace is not a term: a marker needs content, trailing whitespace is dropped and is not content (CARVE-P2-025), and :: and :: are one line. It opens no block, so below the body's column it folds into the open paragraph like any other plain line (CARVE-P2-017). The third line of the first document is :: and one space, of the second :: and two (markup-carve/carve-js#1891).

carve
:: t
: a
:: 
c
html
<dl>
  <dt>t</dt>
  <dd>a
::
c</dd>
</dl>
carve
:: t
: a
::  
c
html
<dl>
  <dt>t</dt>
  <dd>a
::
c</dd>
</dl>

At the end of the document, after a continuation line, and before a description marker, which opens a second description of the same term.

carve
:: t
: a
::
html
<dl>
  <dt>t</dt>
  <dd>a
::</dd>
</dl>
carve
:: t
: a
  b
:: 
c
html
<dl>
  <dt>t</dt>
  <dd>a
b
::
c</dd>
</dl>
carve
:: t
: a
:: 
: c
html
<dl>
  <dt>t</dt>
  <dd>a
::</dd>
  <dd>c</dd>
</dl>

CONTROL. The same line without the space, which every reader already folds.

carve
:: t
: a
::
c
html
<dl>
  <dt>t</dt>
  <dd>a
::
c</dd>
</dl>

A below-column marker after a comment, where no paragraph is open ​

5 conformance fixtures

A comment closes the paragraph. When the item retains the following line, its content column still sets the minimum indentation for a child list. A marker below that column starts paragraph text inside the retained item.

carve
- a
  %%%
  x
  %%%
 - s
html
<ul>
  <li>a
    - s
  </li>
</ul>

Ordered markers follow the same column rule:

carve
- a
  %%%
  x
  %%%
 1. o
html
<ul>
  <li>a
    1. o
  </li>
</ul>

A heading-shaped line below the content column is also paragraph text:

carve
- a
  %%%
  x
  %%%
 # h
html
<ul>
  <li>a
    # h
  </li>
</ul>

CONTROL, and the one that shows this is the mechanism rather than a coincidence about comments: with the paragraph still OPEN the fold is available and the marker is lazy item text, as C3 says. Deleting the comment fence from the first document inverts its answer.

carve
- a
  b
 - s
html
<ul>
  <li>a
b
- s</li>
</ul>

CONTROL. A BLOCK QUOTE leaves its own paragraph open, so the fold is available there too and the marker folds into the quote - the same rule reaching a third answer purely on whether a paragraph is open:

carve
- a
  > q
 - s
html
<ul>
  <li>a
    <blockquote><p>q
- s</p></blockquote>
  </li>
</ul>

A column-zero definition ends an open list item ​

4 conformance fixtures

Column zero is the surrounding document's opener column. A link or footnote definition there interrupts and closes the item, registers as document metadata, and leaves the following block at document level. Only a nonzero column below the item content column reaches no definition opener and folds as literal text. At the content column the definition belongs to the item, as category 228 pins. A comment remains the explicit exception: its invisibility is accepted independently of column and does not itself close the item.

carve
1. x
[t](u)
_u_
[r]: /u
[t][r]
\#
html
<ol>
  <li>x
<a href="u">t</a>
<u>u</u></li>
</ol>
<p><a href="/u">t</a>
#</p>
carve
- a
[^f]: note
after[^f]
html
<ul>
  <li>a</li>
</ul>
<p>after<a id="fnref1" href="#fn1" role="doc-noteref"><sup>1</sup></a></p>
<section role="doc-endnotes" aria-label="Footnotes">
  <hr>
  <ol>
    <li id="fn1">
      <p>note<a href="#fnref1" role="doc-backlink" aria-label="Back to reference">↩</a></p>
    </li>
  </ol>
</section>
carve
1. x
 [r]: /u
html
<ol>
  <li>x
[r]: /u</li>
</ol>
carve
1. x
   [r]: /u
   [t][r]
html
<ol>
  <li>x
    <a href="/u">t</a>
  </li>
</ol>

A definition between two open content columns reaches the outer one ​

4 conformance fixtures

- - x opens items at content columns 2 and 4. A definition written at column 3 is at or past one of them and below the other, and PART 0's AT OR PAST MEANS THE DEEPEST COLUMN THE LINE REACHES answers it against the column the line reaches: it registers in the outer item, and [r][] resolves (markup-carve/carve#1896).

All four neighbouring columns are pinned here rather than the divergent one alone. A row that pinned only column 3 would leave the columns either side of it free, and it is those neighbours that make the rule legible - and that showed the other reading was a hole rather than a boundary. Read as the deepest container still OPEN, column 3 would fold while 2 and 4 registered, so one added space would remove a definition and a second would restore it.

Column 2, the outer item's content column.

carve
- - x
  [r]: /url

See [r][].
html
<ul>
  <li>
    <ul>
      <li>x</li>
    </ul>
  </li>
</ul>
<p>See <a href="/url">r</a>.</p>

Column 3, strictly between the two. This is the column two engines read as lazy text before the rule was stated.

carve
- - x
   [r]: /url

See [r][].
html
<ul>
  <li>
    <ul>
      <li>x</li>
    </ul>
  </li>
</ul>
<p>See <a href="/url">r</a>.</p>

Column 4, the inner item's content column.

carve
- - x
    [r]: /url

See [r][].
html
<ul>
  <li>
    <ul>
      <li>x</li>
    </ul>
  </li>
</ul>
<p>See <a href="/url">r</a>.</p>

Column 5, past the innermost column. The authored base is erased before the line is parsed, so a definition past a column registers exactly as one at it does.

carve
- - x
     [r]: /url

See [r][].
html
<ul>
  <li>
    <ul>
      <li>x</li>
    </ul>
  </li>
</ul>
<p>See <a href="/url">r</a>.</p>

Adjacent sibling lists survive the round trip ​

3 conformance fixtures

Two lists the parser reads as siblings must still read as two after fmt. Nothing separates them but indentation once their markers match, so the writer keeps one space more on each list than the one before it (PART 11 §1; markup-carve/carve#1088).

carve
1. a

 1. b
html
<ol>
  <li>a</li>
</ol>
<ol>
  <li>b</li>
</ol>

A third list steps again rather than repeating the first offset, which would put it back in the second list's column.

carve
1. a

 1. b

  1. c
html
<ol>
  <li>a</li>
</ol>
<ol>
  <li>b</li>
</ol>
<ol>
  <li>c</li>
</ol>

Where the marker already separates them nothing is owed, and the control is that this pair renders the same way with no indentation at all.

carve
- a

* b
html
<ul>
  <li>a</li>
</ul>
<ul>
  <li>b</li>
</ul>

A multi-letter ordered marker opens no list ​

2 conformance fixtures

PART 2 spells the marker as ordered_marker = (digit+ | letter | roman_numeral), ('.' | ')'). abc is not a run of digits, not the single letter the production admits, and not a roman numeral, so abc. item matches nothing and the line is an ordinary paragraph.

ABC) is the same reading in the other case and with the other delimiter. Note that a SINGLE letter still is a marker - it is the second letter that ends the match - and that a roman run of any length still is one, so iv. item is a list.

The executable spec refused both instead, and no corpus document began a line with a multi-letter word and a dot (markup-carve/carve#1188).

carve
abc. item
html
<p>abc. item</p>
carve
ABC) item
html
<p>ABC) item</p>

A block attached after an invisible line leaves the item tight ​

5 conformance fixtures

PART 9 §17 L1 loosens a list when "some item holds a blank-line-separated second paragraph", and its first clause covers an item followed by a blank line before the next sibling marker. §17 L2 is the other half: a sub-block attached after a blank ATTACHES, and the item stays tight.

An invisible line - a comment, a definition, an attribute block - renders nothing, so it decides neither. 186-an-invisible-line-does-not-cancel-a-blank-line-separation pins that it does not close the separation a blank opened, and 188-a-floating-attribute-stops-at-the-item-boundary pins the case where nothing visible follows it at all and the item really did end at the blank.

What neither of those can say is what happens when a block ATTACHES after the invisible line and the list has a SECOND item. The attachment consumes the separation exactly as it does when no invisible line is there - - a / blank / - b / - c is tight (87-compact-list-blocks-2), and inserting a line that produces no output cannot make the item loose. A reader that remembers the blank and never forgets it loosens here, which is what the executable spec did (carve#1265); every corpus document of this shape had one item, so nothing said so.

An attribute block:

carve
- a

  {.x}
  - b
- c
html
<ul>
  <li>a
    <ul class="x">
      <li>b</li>
    </ul>
  </li>
  <li>c</li>
</ul>

A comment, which is the same rule with a different invisible line - the class of the gap-filler is not the question:

carve
- a

  %% note
  - b
- c
html
<ul>
  <li>a
    <ul>
      <li>b</li>
    </ul>
  </li>
  <li>c</li>
</ul>

A reference definition:

carve
- a

  [r]: /u
  - b
- c
html
<ul>
  <li>a
    <ul>
      <li>b</li>
    </ul>
  </li>
  <li>c</li>
</ul>

Nor is the attached block only a nested list. A quote is a §17 L2 sub-block in the same position:

carve
- a

  {.x}
  > q
- c
html
<ul>
  <li>a
    <blockquote class="x"><p>q</p></blockquote>
  </li>
  <li>c</li>
</ul>

And so is a code fence:

carve
- a

  {.x}

code

- c
html
<ul>
  <li>a
    <pre class="x"><code>code
</code></pre>
  </li>
  <li>c</li>
</ul>

A PARAGRAPH after the invisible line is the boundary and still loosens, because that is §17 L1's own second paragraph rather than an attachment - 186-an-invisible-line-does-not-cancel-a-blank-line-separation already pins it, one item and two.

A blank line loosens an item only when a paragraph follows it ​

3 conformance fixtures

PART 9 §17 L1 loosens a list when "some item holds a blank-line-separated second paragraph"; §17 L2 is the other half, where a sub-block attached after a blank ATTACHES and the item stays tight. Between them sits the question of which of the two a blank line opens, and the answer is decided by what follows it rather than by the blank.

The mechanism is the one carve#1266 settled: an attached block CONSUMES the blank the gap held. A container has an opener, so the opener absorbs the separation and by the time tightness is decided there is no blank left to loosen with. A paragraph has no opener to absorb it, so the separation survives, and a blank-line-separated second paragraph is exactly what L1 asks for.

So the line the rule draws is a following PARAGRAPH against every other block type, and it is the same line the 323-a-block-attached-after-an-invisible-line-leaves-the-item-tight family already pins from the other side - there an invisible line sits in the gap and the attachment still consumes it.

Nothing pinned the plain shapes, which is how carve#1622 found carve-js and carve-php disagreeing about the container. A tight list's HTML cannot show a paragraph boundary INSIDE a container, but it does show the lead's <p> wrapper, so an ordinary pair can see the difference at the item.

A paragraph after the blank: the item is loose, and every item of the list wraps.

carve
- x

  y
- z
html
<ul>
  <li><p>x</p>
    <p>y</p>
  </li>
  <li><p>z</p></li>
</ul>

The same blank line above a container, which is carve#1622's shape: the item is tight, and the lead keeps no wrapper. The container's own body is loose for its own reasons - that is the div's blank line, not the item's.

carve
- x

  ::: d
  a

  b
  • z

```html
<ul>
  <li>x
    <div class="d">
      <p>a</p>
      <p>b</p>
    </div>
  </li>
  <li>z</li>
</ul>

:::

A quote in the same position, because the rule is about the paragraph and not about the container specifically:

carve
- x

  > q
- z
html
<ul>
  <li>x
    <blockquote><p>q</p></blockquote>
  </li>
  <li>z</li>
</ul>

A resumed lazy run belongs to the innermost marker-line item ​

8 conformance fixtures

A marker line may open more than one list item. Once a flush lazy line folds into the innermost item's paragraph, PART 1 S4 closes nothing: the next line is still placed against that innermost open paragraph, whether it is flush, at the outer item's content column, or at the inner item's content column. A line comment ends that paragraph but keeps the same innermost item open for the next paragraph.

carve
* * u
%
 :
html
<ul>
  <li>
    <ul>
      <li>u
%
:</li>
    </ul>
  </li>
</ul>
carve
* * u
%
  :
html
<ul>
  <li>
    <ul>
      <li>u
%
:</li>
    </ul>
  </li>
</ul>
carve
* * u
%
    :
html
<ul>
  <li>
    <ul>
      <li>u
%
:</li>
    </ul>
  </li>
</ul>
carve
* * u
%%
 :
html
<ul>
  <li>
    <ul>
      <li>u
        :
      </li>
    </ul>
  </li>
</ul>

A collected definition instead leaves no paragraph open. The same columns then select the surviving container: below the outer item closes both lists, the outer content column belongs to the outer item, and the inner content column belongs to the inner item. A comment cannot reopen a definition-only item.

carve
* * [d]: u
 :
html
<ul>
  <li>
    <ul>
      <li></li>
    </ul>
  </li>
</ul>
<p>:</p>
carve
* * [d]: u
  :
html
<ul>
  <li>
    <ul>
      <li></li>
    </ul>
    :
  </li>
</ul>
carve
* * [d]: u
    :
html
<ul>
  <li>
    <ul>
      <li>:</li>
    </ul>
  </li>
</ul>
carve
* * [d]: u
%%
:
html
<ul>
  <li>
    <ul>
      <li></li>
    </ul>
  </li>
</ul>
<p>:</p>
2 conformance fixtures

A definition written directly after a list marker is metadata, not item content, and what stands above it does not change that. NO OPEN PARAGRAPH, NO LAZY LINE decides it: a definition line, a heading, a comment and a marker line are each non-blank and none of them leaves a paragraph for the marker line to fold into, so the item is real and the definition in it defines a reference. The item is structurally present and renders empty.

carve
[f]: t
* [d]: u

[go][d]
html
<ul>
  <li></li>
</ul>
<p><a href="u">go</a></p>

Only an OPEN paragraph makes the marker line lazy text. A list does not interrupt one (PART 9 section 10), so here both lines are one paragraph, the definition is part of its text, and nothing is defined.

carve
para
* [d]: u
html
<p>para
* [d]: u</p>

A lazy marker line's definition defines nothing, in any container ​

5 conformance fixtures

NO OPEN PARAGRAPH, NO LAZY LINE holds wherever the paragraph is. A list does not interrupt one (PART 9 section 10), so a marker line under an open quoted paragraph is lazy text of that paragraph - the definition on it renders as the text the author typed and enters no symbol table, exactly as at the document level. The reference below stays literal because nothing defined it.

carve
> r
> - [d]: u

[go][d]
html
<blockquote><p>r
- [d]: u</p></blockquote>
<p>[go][d]</p>

A div holds a paragraph open the same way, and adds no per-line prefix for the question to hide behind.

carve
::: n
r
- [d]: u
:::

[go][d]
html
<div class="n">
  <p>r
- [d]: u</p>
</div>
<p>[go][d]</p>

The footnote kind answers alike - one rule, both definition markers.

carve
> r
> - [^f]: t

see[^f]
html
<blockquote><p>r
- [^f]: t</p></blockquote>
<p>see[^f]</p>

With no paragraph open the marker opens a real item, and the definition in it is metadata: it renders nothing where it was written and the reference resolves.

carve
> - [d]: u

[go][d]
html
<blockquote>
  <ul>
    <li></li>
  </ul>
</blockquote>
<p><a href="u">go</a></p>

A blank quoted line closes the paragraph, so the marker below it opens an item too.

carve
> r
>
> - [d]: u

[go][d]
html
<blockquote>
  <p>r</p>
  <ul>
    <li></li>
  </ul>
</blockquote>
<p><a href="u">go</a></p>

A marker folds only strictly between the item's base and content column ​

9 conformance fixtures

A list marker written under an OPEN item folds into that item's lead text only where its column is STRICTLY BETWEEN the item's base column and its content column. At the base column it starts a SIBLING; at or past the content column it NESTS. Both of those open a real item, so a definition written on such a marker is metadata and registers; inside the window the line is the open item's own lead text and the reference stays literal (markup-carve/carve#1906).

The window WIDENS with the item, which is the property a corpus has to hold. Under - it is the single column 1; under - it is 1, 2 and 3:

item hands out atfoldsopens an item
210, 2
41, 2, 30, 4

Both EDGES are pinned at both widths, and both directions of the error with them: a reader that collects too little fails the rows where a marker at the base or the content column must register, and one that collects too much fails the rows inside the window. The columns alone do not separate the two readings - column 2 opens an item under - and folds under - - so the two widths have to be pinned together, or a reader that answers by a fixed column passes both.

Under - , the base column. A sibling marker opens a real item, so its definition is metadata.

carve
- lead
- [t]: /t

See [t][].
html
<ul>
  <li>lead</li>
  <li></li>
</ul>
<p>See <a href="/t">t</a>.</p>

Column 1, the whole of this item's window. The marker is lead text and the reference stays literal.

carve
- lead
 - [t]: /t

See [t][].
html
<ul>
  <li>lead
- [t]: /t</li>
</ul>
<p>See [t][].</p>

Column 2, the content column. The marker nests and its definition registers.

carve
- lead
  - [t]: /t

See [t][].
html
<ul>
  <li>lead
    <ul>
      <li></li>
    </ul>
  </li>
</ul>
<p>See <a href="/t">t</a>.</p>

Under - , the base column again. Widening the item does not move this edge.

carve
-   lead
- [t]: /t

See [t][].
html
<ul>
  <li>lead</li>
  <li></li>
</ul>
<p>See <a href="/t">t</a>.</p>

Column 2, which opened an item three rows above and is inside the window here. This is the pair that separates the window from a fixed column.

carve
-   lead
  - [t]: /t

See [t][].
html
<ul>
  <li>lead
- [t]: /t</li>
</ul>
<p>See [t][].</p>

Column 3, the window's far edge - one column below the content column, and still lead text.

carve
-   lead
   - [t]: /t

See [t][].
html
<ul>
  <li>lead
- [t]: /t</li>
</ul>
<p>See [t][].</p>

Column 4, the content column. The marker nests and the definition registers.

carve
-   lead
    - [t]: /t

See [t][].
html
<ul>
  <li>lead
    <ul>
      <li></li>
    </ul>
  </li>
</ul>
<p>See <a href="/t">t</a>.</p>

The base column is read from the COLUMN, not from the marker family. An ordered marker there ends the bullet list and opens its own, so the definition is still metadata.

carve
- lead
1. [t]: /t

See [t][].
html
<ul>
  <li>lead</li>
</ul>
<ol>
  <li></li>
</ol>
<p>See <a href="/t">t</a>.</p>

A folded marker does not become the owner the next line is measured against. The second line is inside the window of the item that is still open and stays lead text, so the third line is measured against that same item and stays text too.

carve
-   lead
 - prose
 - [t]: /t

See [t][].
html
<ul>
  <li>lead
- prose
- [t]: /t</li>
</ul>
<p>See [t][].</p>

A continuation marker attaches only a flush-left block ​

8 conformance fixtures

PART 9 §17 L3 means FLUSH-LEFT literally: a + attaches the following block only when that block begins at document column 0. Under nested markers, every other column is interpreted by the ordinary content-column machinery instead of being pulled into the innermost item (markup-carve/carve#1436).

At column 0, the nested marker attaches the paragraph to the inner item.

carve
* * +
x
html
<ul>
  <li>
    <ul>
      <li>x</li>
    </ul>
  </li>
</ul>

At the outer item's content column, the paragraph belongs to the outer item; the inner item stays empty.

carve
* * +
  x
html
<ul>
  <li>
    <ul>
      <li></li>
    </ul>
    x
  </li>
</ul>

A column below every open container ends both items and leaves the paragraph at document level.

carve
* * +
 x
html
<ul>
  <li>
    <ul>
      <li></li>
    </ul>
  </li>
</ul>
<p>x</p>

The single-level controls are unchanged: column 0 attaches, while the item's own content column reaches the item through the ordinary column rule.

carve
- +
x
html
<ul>
  <li>x</li>
</ul>
carve
- +
  x
html
<ul>
  <li>x</li>
</ul>

An INDENTED line under the marker is not attached at all. It is read by the ordinary column rules, which here fold it into the paragraph the sub-list's item left open - so b and c are one paragraph rather than the two blocks the marker would have produced.

carve
- a
  - b
  +
  c
html
<ul>
  <li>a
    <ul>
      <li>b
c</li>
    </ul>
  </li>
</ul>

The same reading one column out. The marker sits at the outer item's marker column, so only a column-0 block could attach; the payload at column 2 is placed by its own column, which leaves it in the sub-list item whose paragraph is still open. The output is byte-identical to the same document without the marker line (markup-carve/carve#2322).

carve
- x
  - L
+
  p
html
<ul>
  <li>x
    <ul>
      <li>L
p</li>
    </ul>
  </li>
</ul>

A + at a column no container's marker column names is not this marker at all. The marker columns here are 0 and 2, so the + written at column 1 is ordinary text and reaches the output, as a lone + does outside any container.

carve
- x
  - L
 +
html
<ul>
  <li>x
    <ul>
      <li>L
+</li>
    </ul>
  </li>
</ul>

A longer run at a list boundary is written as exactly three blank lines ​

1 conformance fixture

The canonical writer normalizes a blank-line run between two blocks to ONE. PART 9 §11 N1a's hard list boundary is the exception: one blank line would MERGE the two lists, so the run has to survive. PART 11 §10i fixes what survives at EXACTLY THREE, whatever the author typed - N1a reads THREE OR MORE, so every longer run parses the same and the writer would otherwise have unboundedly many canonical spellings for one document.

The source below has SIX. Its rendered HTML is the same two lists a three-blank source gives, which is why the .fmt sidecar beside this pair - not the HTML - is what measures the collapse.

carve
- apples






- oranges
html
<ul>
  <li>apples</li>
</ul>
<ul>
  <li>oranges</li>
</ul>

One consumed boolean spells the looseness no blank line can ​

1 conformance fixture

PART 9 section 17 L7. Carve spells looseness with a blank line, and a blank line needs two things to stand between, so the shape with nothing on one side has no spelling at all: a ONE-ITEM loose list, and a definition description holding ONE block. The second is the worse case, because a blank line between two ENTRIES does not loosen a <dl> in the first place - only a second block inside the description wraps it - so <dd><p>x</p></dd> is unspellable at every entry count.

loose on the preceding block-attribute line says both, in the one place the axis exists, and is CONSUMED: neither <ul> nor <dl> below carries a loose attribute. It follows PART 12 section 15's header-rows in all three respects - the same line, a structural fact carried as a boolean, consumed rather than emitted.

The <dl> pair carries a second finding. This repository's own oracle never read a definition list's block attributes at all: {.foo} before a :: term line parsed correctly, attached to the node and was dropped on the way out, where carve-js emits <dl class="foo">. No corpus document had ever put an attribute line before a definition list, so nothing was red - the same gap carve#626 and carve#693 left one container over.

Both documents are declared in resources/engine-pin-drift.txt: the pinned build has not shipped the key and renders the attribute literally, as <ul loose="">.

carve
{loose}
- Note text.
html
<ul>
  <li><p>Note text.</p></li>
</ul>

The writer spells looseness only where a blank line cannot ​

2 conformance fixtures

The other half of L7, and the load-bearing half. loose is legal on a container the blank lines already loosened - it is a no-op there, deliberately, so a producer that always emits it stays simple. What the CANONICAL WRITER does is a separate question, and the answer is that it emits the key only where the blank-line spelling cannot express the looseness. PART 12 section 15's writer "retains header-rows / footer-rows when they are present" rather than deriving them onto every table, and PART 11 section 2 spends a mark only where omitting it would change the re-parsed document; on the list below the blank line already says loose, so the key would be idle by exactly that test.

The alternative - emit it on every loose container - would rewrite a large share of this corpus and of every document anyone has written, and would gain nothing. So the rule needs a fixture that goes red when a writer starts decorating everything, which is what the .fmt sidecar beside this pair is: the HTML is identical under both spellings, so no HTML fixture can see the difference.

carve
- alpha

- beta
html
<ul>
  <li><p>alpha</p></li>
  <li><p>beta</p></li>
</ul>

THE ITEM COUNT IS NOT THE TEST, and this is where an implementation of the rule above goes wrong. "Two or more items already say it" is true, so the tempting converse - fewer than two items, therefore decorate - looks like the same rule read backwards. It is not: a list with one item can be loose because the blank line sits INSIDE that item, and then the blank-line spelling did express the looseness after all. The list below is that shape. So is corpus document 05-lists-11, which is a one-item ordered list whose item holds two paragraphs - a writer keyed on the item count rewrites it, and parse(fmt(x)) == parse(x) fails on a document that was never lossy.

The decidable test is a RE-PARSE, over the document rather than over the render: write the body without the key, read it back, and emit the key only where the container's own looseness field did not survive the trip. The item count is sound as a shortcut in ONE direction only - two or more items always re-parse loose, so the extra read can be skipped there, which keeps it off almost every list in this corpus.

carve
- alpha

  beta
html
<ul>
  <li><p>alpha</p>
    <p>beta</p>
  </li>
</ul>

A floating attribute does not widen a list item's content column ​

7 conformance fixtures

Marker-attached attributes are metadata with zero column width. The heading in each of these first three cases is therefore exactly at the item's content column and remains inside it; the marker-line floating attribute attaches to that heading (PART 1 S4, PART 9 §15 A4, PART 9 §24 C3; carve-rs#1373).

carve
-{#k} {#h}
  # h
html
<ul>
  <li id="k">
    <h1 id="h">h</h1>
  </li>
</ul>
carve
1.{#k} {#h}
   # h
html
<ol>
  <li id="k">
    <h1 id="h">h</h1>
  </li>
</ol>
carve
-{#k} [x] {#h}
  # h
html
<ul>
  <li id="k"><input type="checkbox" checked disabled> 
    <h1 id="h">h</h1>
  </li>
</ul>

Moving the continuation one column left puts it genuinely below the content column. Because a floating attribute opens no paragraph, the item closes, the attribute is dropped at its scope boundary, and the heading-shaped residue is literal top-level paragraph text. Ordinary marker-line text is the control: it does open a paragraph, so the same below-column line lazily continues it.

carve
-{#k} {#h}
 # h
html
<ul>
  <li id="k"></li>
</ul>
<p># h</p>
carve
-{#k} text
 # h
html
<ul>
  <li id="k">text
# h</li>
</ul>
carve
1.{#k} {#h}
  # h
html
<ol>
  <li id="k"></li>
</ol>
<p># h</p>
carve
-{#k} [x] {#h}
 # h
html
<ul>
  <li id="k"><input type="checkbox" checked disabled> </li>
</ul>
<p># h</p>

The continuation marker attaches one block in every container ​

4 conformance fixtures

§17 L3 defines + as one operation: ownership of the next flush-left block passes to the container whose marker column the line sits at, and the block is then parsed like any other. The count is ONE block, and the container does not answer differently because of what kind of block it is attaching.

The clause's own example, in a list item: the marker takes the paragraph and leaves the quote at document level, where a second marker would be needed to attach it.

carve
- a
+
para
> q
html
<ul>
  <li>a
    para
  </li>
</ul>
<blockquote><p>q</p></blockquote>

The same document in a footnote body. The note takes the paragraph and nothing else — the reading that made this two blocks was the extent measured without the one-block narrowing every other container applies.

carve
[^n]: a
+
para
> q

see[^n]
html
<blockquote><p>q</p></blockquote>
<p>see<a id="fnref1" href="#fn1" role="doc-noteref"><sup>1</sup></a></p>
<section role="doc-endnotes" aria-label="Footnotes">
  <hr>
  <ol>
    <li id="fn1">
      <p>a</p>
      <p>para<a href="#fnref1" role="doc-backlink" aria-label="Back to reference">↩</a></p>
    </li>
  </ol>
</section>

And in a definition description, which carries continuation_marker_block for the same reason.

carve
:: t
:  a
+
para
> q
html
<dl>
  <dt>t</dt>
  <dd>
    <p>a</p>
    <p>para</p>
  </dd>
</dl>
<blockquote><p>q</p></blockquote>

A quote attached to a quote NESTS, exactly as a list or a fence attached to one would. The marker only ever attaches, so a following quote line cannot make it a no-op.

carve
> a
+
> q
html
<blockquote>
  <p>a</p>
  <blockquote><p>q</p></blockquote>
</blockquote>

The continuation marker's column gate reaches every container ​

19 conformance fixtures

CONTINUATION-MARKER FLUSH-LEFT MEANS COLUMN 0 (§17 L3, markup-carve/carve#1436) says a + attaches a block that begins at document column 0 and nothing else: a line at any other column is not attached at all, and falls through to the ordinary column rules, which place it by its own column inside whichever container survives. Only the LIST ITEM asked that question - the gate was spelled in the item's attach path and in the item collector's nested guard, and the footnote body, the description and the block quote had no equivalent - so those three reached out for a line the clause leaves where the author put it (markup-carve/carve#1814). Each row below is the same document twice, once with the marker and once with a comment line, which those rules cannot see either - so the pair isolates which container the line reached.

A column below the body's minimum is not the note's. The comment spelling ends the body and the paragraph lands at document level, above the endnotes section.

carve
[^a]: intro
%% c
 more

see[^a]
html
<p>more</p>
<p>see<a id="fnref1" href="#fn1" role="doc-noteref"><sup>1</sup></a></p>
<section role="doc-endnotes" aria-label="Footnotes">
  <hr>
  <ol>
    <li id="fn1">
      <p>intro<a href="#fnref1" role="doc-backlink" aria-label="Back to reference">↩</a></p>
    </li>
  </ol>
</section>

The marker answers the same, where it used to pull the line into the note.

carve
[^a]: intro
+
 more

see[^a]
html
<p>more</p>
<p>see<a id="fnref1" href="#fn1" role="doc-noteref"><sup>1</sup></a></p>
<section role="doc-endnotes" aria-label="Footnotes">
  <hr>
  <ol>
    <li id="fn1">
      <p>intro<a href="#fnref1" role="doc-backlink" aria-label="Back to reference">↩</a></p>
    </li>
  </ol>
</section>

The body's OWN minimum column is not column 0 either, so it is refused for the same reason - the marker names one column, not a range reaching down to the container's floor. An indented comment at that column is a different document and stays inside the body, which is pinned above under "A comment in a footnote body is invisible in both spellings"; the control here is the comment where the marker was.

carve
[^a]: intro
%% c
  more

see[^a]
html
<p>more</p>
<p>see<a id="fnref1" href="#fn1" role="doc-noteref"><sup>1</sup></a></p>
<section role="doc-endnotes" aria-label="Footnotes">
  <hr>
  <ol>
    <li id="fn1">
      <p>intro<a href="#fnref1" role="doc-backlink" aria-label="Back to reference">↩</a></p>
    </li>
  </ol>
</section>
carve
[^a]: intro
+
  more

see[^a]
html
<p>more</p>
<p>see<a id="fnref1" href="#fn1" role="doc-noteref"><sup>1</sup></a></p>
<section role="doc-endnotes" aria-label="Footnotes">
  <hr>
  <ol>
    <li id="fn1">
      <p>intro<a href="#fnref1" role="doc-backlink" aria-label="Back to reference">↩</a></p>
    </li>
  </ol>
</section>

Column 0 is what the marker does reach, and the positive row is what makes the two above mean something: the same note, the same paragraph, one column over.

carve
[^a]: intro
+
more

see[^a]
html
<p>see<a id="fnref1" href="#fn1" role="doc-noteref"><sup>1</sup></a></p>
<section role="doc-endnotes" aria-label="Footnotes">
  <hr>
  <ol>
    <li id="fn1">
      <p>intro</p>
      <p>more<a href="#fnref1" role="doc-backlink" aria-label="Back to reference">↩</a></p>
    </li>
  </ol>
</section>

A description body's content column is 3 here, so column 2 is below it and the ordinary rules put the paragraph outside the dd. The comment spelling:

carve
:: term
:  intro
%% c
  more
html
<dl>
  <dt>term</dt>
  <dd>intro</dd>
</dl>
<p>more</p>

And the marker, which used to pull the same line in.

carve
:: term
:  intro
+
  more
html
<dl>
  <dt>term</dt>
  <dd>intro</dd>
</dl>
<p>more</p>

At column 0 the description takes it, as a second block of the dd.

carve
:: term
:  intro
+
more
html
<dl>
  <dt>term</dt>
  <dd>
    <p>intro</p>
    <p>more</p>
  </dd>
</dl>

A column never reaches into a quote (§10 I5, markup-carve/carve#1384), and the marker does not reach out of one for it. The quoted paragraph is closed here so the row asks about the COLUMN and nothing else; the blank-line control and the comment control agree with each other.

carve
> intro
>

  more
html
<blockquote><p>intro</p></blockquote>
<p>more</p>
carve
> intro
>
%% c
  more
html
<blockquote><p>intro</p></blockquote>
<p>more</p>
carve
> intro
>
+
  more
html
<blockquote><p>intro</p></blockquote>
<p>more</p>

At column 0 the marker attaches, which is the only spelling that puts a block into a quote without a > in front of it.

carve
> intro
>
+
more
html
<blockquote>
  <p>intro</p>
  <p>more</p>
</blockquote>

The list item is the container that always held the gate, and it answers the band the same way: the marker attaches nothing and the line reaches the item by its own column, exactly as the comment spelling leaves it.

carve
- intro
+
  more
html
<ul>
  <li>intro
more</li>
</ul>

The gate reads the MARKER's own column as well as the attached block's. A + is a continuation marker at its container's marker column and nowhere else, so in an item holding a quote there are exactly two columns where it is one: the list's and the quote's. One column between them names no container, and the line is ordinary text that the quote's open paragraph folds in - the answer a word in the same slot gets.

carve
- x
  > q
 +
html
<ul>
  <li>x
    <blockquote><p>q
+</p></blockquote>
  </li>
</ul>

The text control at that column, which is what says the marker is being read as text rather than attached by some other route.

carve
- x
  > q
 ZZZ
html
<ul>
  <li>x
    <blockquote><p>q
ZZZ</p></blockquote>
  </li>
</ul>

The quote's own marker column, one column right. Here the + IS a marker: it is consumed, and with no flush-left block below it attaches nothing.

carve
- x
  > q
  +
html
<ul>
  <li>x
    <blockquote><p>q</p></blockquote>
  </li>
</ul>

The list's marker column answers the same way, which is what makes the column between them the only one in question.

carve
- x
  > q
+
html
<ul>
  <li>x
    <blockquote><p>q</p></blockquote>
  </li>
</ul>

Past the quote's marker the + is quoted content, and text again.

carve
- x
  > q
   +
html
<ul>
  <li>x
    <blockquote><p>q
+</p></blockquote>
  </li>
</ul>

The same two columns without the item around them. A top-level quote's marker sits at column 0, so the marker there attaches the list below it, and one column right it is text in the quoted paragraph.

carve
> q
 +
- m
html
<blockquote><p>q
+
- m</p></blockquote>

A block that opens a tight item is written on the marker line ​

3 conformance fixtures

The canonical writer keeps a tight item's first block on the marker line and puts the continuation marker below it (PART 11 §7e).

carve
- > p
+
> z
html
<ul>
  <li>
    <blockquote><p>p</p></blockquote>
    <blockquote><p>z</p></blockquote>
  </li>
</ul>

The bare-marker spelling parses to the same item and is rewritten to that form.

carve
- +
> p
+
> z
html
<ul>
  <li>
    <blockquote><p>p</p></blockquote>
    <blockquote><p>z</p></blockquote>
  </li>
</ul>

A table below a table stays inside the item in a quote host too.

carve
> - | a |
>   | b |
> +
> | c |
> | d |
html
<blockquote>
  <ul>
    <li>
      <table>
        <tbody>
          <tr><td>a</td></tr>
          <tr><td>b</td></tr>
        </tbody>
      </table>
      <table>
        <tbody>
          <tr><td>c</td></tr>
          <tr><td>d</td></tr>
        </tbody>
      </table>
    </li>
  </ul>
</blockquote>

An empty description body claims no line below column 0 ​

7 conformance fixtures

CONTINUATION-MARKER FLUSH-LEFT MEANS COLUMN 0 (§17 L3, markup-carve/carve#1436) says a line the + does not reach falls through to the ordinary column rules, which a comment line cannot reach either - so the comment spelling is this section's control. In the accepted wider-separator FIRST-BLOCK form : + no paragraph is open, so the + genuinely is a marker and the clause reads its payload's column - and a payload at column 1 or 2 is not flush-left, so the marker is refused and the body ends where the comment ends it. It did not: the description reached out and put the payload in the dd, at both columns, while the comment spelling of the same document left it outside (markup-carve/carve#1821). Each pair below is one document twice, once with the marker and once with its control.

The payload one column in. The comment spelling ends the body, and the dd it leaves is empty because a comment renders nothing.

carve
:: t
:  %% c
 flush
html
<dl>
  <dt>t</dt>
  <dd></dd>
</dl>
<p>flush</p>

The marker answers the same, where it used to claim the line.

carve
:: t
:  +
 flush
html
<dl>
  <dt>t</dt>
  <dd></dd>
</dl>
<p>flush</p>

Column 2 is the last column below the body's own content column, and it is refused for the same reason - the marker names ONE column, not a range reaching down to the container's floor.

carve
:: t
:  %% c
  flush
html
<dl>
  <dt>t</dt>
  <dd></dd>
</dl>
<p>flush</p>
carve
:: t
:  +
  flush
html
<dl>
  <dt>t</dt>
  <dd></dd>
</dl>
<p>flush</p>

The positive half. At column 0 the marker is not refused, and the first-block form keeps the one flush-left block it names - so a rule that refused everything would not satisfy this row.

carve
:: t
:  +
flush
html
<dl>
  <dt>t</dt>
  <dd>flush</dd>
</dl>

The LIST ITEM is the reference. It already answered the band this way, in both spellings, which is what made the description's answer a divergence rather than a rule.

carve
- %% c
 flush
html
<ul>
  <li></li>
</ul>
<p>flush</p>
carve
- +
 flush
html
<ul>
  <li></li>
</ul>
<p>flush</p>

An empty description body is written with the empty sentinel ​

5 conformance fixtures

PART 11 §7d (markup-carve/carve#1827) pins the canonical spelling for a definition_description that holds no blocks: the marker, its separator space, and the sentinel attribute block {empty}. §7b already spells an empty footnote definition body the same way, and this is the same shape one construct over.

The sentinel is an attribute block, so PART 9 §15 A4 drops it - a block-attribute line with no following block inside its own container reaches nothing - and the description is left empty. It claims NO line below it at any column, which is what separates it from the accepted wider-separator : +: the first-block marker attaches a following flush-left block, so it spells an empty body only when a blank line follows.

carve
:: t
: {empty}

flush
html
<dl>
  <dt>t</dt>
  <dd></dd>
</dl>
<p>flush</p>

At end of input, where there is no following block at all.

carve
:: t
: {empty}
html
<dl>
  <dt>t</dt>
  <dd></dd>
</dl>

The line below it is not claimed even at column 0, which is the whole reason the sentinel needs no blank line after it. The same document spelled with the accepted wider-separator : + puts flush inside the dd.

carve
:: t
: {empty}
flush
html
<dl>
  <dt>t</dt>
  <dd></dd>
</dl>
<p>flush</p>

An entry AFTER the empty one. The empty description is spelled where it stands, so this is ONE list and the second term keeps its own description rather than the first term inheriting it (markup-carve/carve#1636).

carve
:: t1
: {empty}
:: t2
: d2
html
<dl>
  <dt>t1</dt>
  <dd></dd>
  <dt>t2</dt>
  <dd>d2</dd>
</dl>

Two empty descriptions in a row, so neither reads as a term sharing the other's body.

carve
:: t1
: {empty}
:: t2
: {empty}
html
<dl>
  <dt>t1</dt>
  <dd></dd>
  <dt>t2</dt>
  <dd></dd>
</dl>

A colon followed by only whitespace is not a description ​

8 conformance fixtures

A description marker takes a separator space and non-empty content (PART 2, MARKER REQUIRES CONTENT), so a : line carrying nothing but whitespace opens no description. It is a plain line under the open term, and the term folds it as a soft break. The line's trailing whitespace run is dropped (PART 2, NO TRAILING WHITESPACE), which makes every such spelling the same document as the bare marker - the separator's width and the marker's own trailing space cannot carry meaning.

The separator is space, and a tab never satisfies it (PART 1, MARKER SEPARATORS AND PADDING SLOTS). The tab spelling is therefore refused at the separator rather than at the content test, and lands in the same place.

One separator space.

carve
:: t
: 

flush
html
<dl>
  <dt>t
:</dt>
</dl>
<p>flush</p>

Two, and three: the width is not read, because there is nothing for it to position.

carve
:: t
:  

flush
html
<dl>
  <dt>t
:</dt>
</dl>
<p>flush</p>
carve
:: t
:   

flush
html
<dl>
  <dt>t
:</dt>
</dl>
<p>flush</p>

A tab, which the separator does not admit.

carve
:: t
:	

flush
html
<dl>
  <dt>t
:</dt>
</dl>
<p>flush</p>

The content control. {} is literal text, not an attribute block, so the marker has content and the description forms.

carve
:: t
: {}

flush
html
<dl>
  <dt>t</dt>
  <dd>{}</dd>
</dl>
<p>flush</p>

The whitespace control. A bare marker has an empty trailing run, so the fold leaves nothing to drop.

carve
:: t
:

flush
html
<dl>
  <dt>t
:</dt>
</dl>
<p>flush</p>

The cell between those two: a separator space, and then a tab. The separator IS satisfied here, so this spelling is refused at the content test rather than at the separator. After the greedy space run a lone tab is trailing whitespace and nothing else, and MARKER REQUIRES CONTENT ignores trailing whitespace, so the marker opens nothing and the line folds like the rows above. The greedy run is spaces only, which is what leaves the tab to be judged as content (markup-carve/carve#1836).

carve
:: t
: 	

flush
html
<dl>
  <dt>t
:</dt>
</dl>
<p>flush</p>

The reach control. The same separator space and the same tab, with text behind it: the content test now finds a character that is neither space nor tab, so the description opens and the tab is content. Only a run of nothing but spaces and tabs is trailing whitespace.

carve
:: t
: 	text

flush
html
<dl>
  <dt>t</dt>
  <dd>text</dd>
</dl>
<p>flush</p>

A leading continuation marker in a footnote body or a quote is text ​

6 conformance fixtures

The FIRST-BLOCK form of the continuation marker (§17 L4) belongs to the LIST ITEM and the DEFINITION DESCRIPTION: - + and the accepted wider-separator : + open a body whose content is the following flush-left block, and over a column-1 line the marker is refused and the body ends. A FOOTNOTE BODY and a BLOCK QUOTE have no such form. A + that opens one of those two bodies is not a marker at all - it is ordinary text, and the line under it lands wherever the ordinary column rules put it, which is a different answer from "place by column" rather than a narrower one (markup-carve/carve#1821).

The executable spec used to REFUSE the whole document here, stray continuation marker, at every payload column including column 0 - one reader of four, while carve-js, carve-php and carve-rs all rendered the text and agreed byte for byte. The band below pins all six documents so the next divergence cannot be silent.

A footnote body whose first line is a lone +. The + is the note's text, and flush is a top-level paragraph: the note ended at the line below its column.

carve
[^a]: +
flush

see[^a]
html
<p>flush</p>
<p>see<a id="fnref1" href="#fn1" role="doc-noteref"><sup>1</sup></a></p>
<section role="doc-endnotes" aria-label="Footnotes">
  <hr>
  <ol>
    <li id="fn1">
      <p>+<a href="#fnref1" role="doc-backlink" aria-label="Back to reference">↩</a></p>
    </li>
  </ol>
</section>

Column 1 is still below the body's column, so it answers the same way. Nothing about the + decides this - the same document with any other one-character first line ends the note here too.

carve
[^a]: +
 flush

see[^a]
html
<p>flush</p>
<p>see<a id="fnref1" href="#fn1" role="doc-noteref"><sup>1</sup></a></p>
<section role="doc-endnotes" aria-label="Footnotes">
  <hr>
  <ol>
    <li id="fn1">
      <p>+<a href="#fnref1" role="doc-backlink" aria-label="Back to reference">↩</a></p>
    </li>
  </ol>
</section>

At column 2 the line is inside the body, and it folds into the paragraph the + opened - one paragraph reading + flush, not two blocks and not an attachment.

carve
[^a]: +
  flush

see[^a]
html
<p>see<a id="fnref1" href="#fn1" role="doc-noteref"><sup>1</sup></a></p>
<section role="doc-endnotes" aria-label="Footnotes">
  <hr>
  <ol>
    <li id="fn1">
      <p>+
flush<a href="#fnref1" role="doc-backlink" aria-label="Back to reference">↩</a></p>
    </li>
  </ol>
</section>

The block quote gives one answer across the whole band, because the + opens a quoted paragraph and every column below it reaches that paragraph by §10 I6's lazy fold. Column 0 first.

carve
> +
flush
html
<blockquote><p>+
flush</p></blockquote>

Column 1 - a lazily folded line supplies no > prefix, so its column says nothing about which container it reached.

carve
> +
 flush
html
<blockquote><p>+
flush</p></blockquote>

Column 2, the column that would be the quote's content column if a marker were reading one here. It is not, and the row is the control that says so.

carve
> +
  flush
html
<blockquote><p>+
flush</p></blockquote>

A band paragraph after an invisible line leaves the item loose ​

5 conformance fixtures

PART 9 §17 L1b reads tightness over the item's blocks and the blank lines between them and names no column, so the authored column of a second paragraph cannot decide it. A follower in the band between the marker column and the content column answers L1b exactly as one at the content column does, and 186-an-invisible-line-does-not-cancel-a-blank-line-separation pins that answer LOOSE.

The first pair is the narrowest band. The second widens it to three columns under a four-wide marker and the third is its content-column twin, which agrees. The fourth writes the invisible line as a %%% span. The last pair is §17 L2's half of the rule: a sub-list in the band ATTACHES, so it consumes the separation and the item stays tight, which is what the same tree written at the content column already answered (carve#2548).

carve
- t

  %% c
 z
html
<ul>
  <li><p>t</p>
    <p>z</p>
  </li>
</ul>
carve
10. t

    %% c
   z
html
<ol start="10">
  <li><p>t</p>
    <p>z</p>
  </li>
</ol>
carve
10. t

    %% c
    z
html
<ol start="10">
  <li><p>t</p>
    <p>z</p>
  </li>
</ol>
carve
- t

  %%%
  c
  %%%
 z
html
<ul>
  <li><p>t</p>
    <p>z</p>
  </li>
</ul>
carve
- t

  %% c
 - b
- s
html
<ul>
  <li><p>t</p>
    <p>- b</p>
  </li>
  <li><p>s</p></li>
</ul>

Released under the MIT License.