From 8ddb2bd9a909e0aca7ceb30224b8cd00b662340d Mon Sep 17 00:00:00 2001 From: Mark Scherer Date: Wed, 20 May 2026 02:17:08 +0200 Subject: [PATCH 1/3] tests: pin G3 strip rule for
    -only attrs on
  1. /
    start, type, reversed are HTML attributes valid only on
      . When authored on a list item (or
      ) they currently pass through to the
    1. /
      tag, producing invalid HTML. These tests pin the target behavior: silently strip those three names from
    2. /
      output while leaving class, id, data-*, etc. unchanged. --- tests/TestCase/DjotConverterTest.php | 74 ++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/tests/TestCase/DjotConverterTest.php b/tests/TestCase/DjotConverterTest.php index 144cde52..25d74eb1 100644 --- a/tests/TestCase/DjotConverterTest.php +++ b/tests/TestCase/DjotConverterTest.php @@ -1104,6 +1104,80 @@ public function testListItemAttributesLooseListUnchanged(): void $this->assertStringContainsString('
      ', $result); } + public function testListItemAttributeStartIsStrippedFromLi(): void + { + // G3: `start` is an HTML attribute valid only on
        . It must + // be stripped from
      1. output, never feed
          , and never + // appear in HTML. + $djot = "1. item\n {start=5}\n"; + + $result = $this->converter->convert($djot); + + $this->assertStringContainsString('
        1. ', $result); + $this->assertStringNotContainsString('
        2. . Stripped + // from
        3. ; never overrides marker-derived
            . + $djot = "(a) x\n {type=i}\n"; + + $result = $this->converter->convert($djot); + + $this->assertStringContainsString('
              ', $result); + $this->assertStringNotContainsString('
            1. -only. Stripped from
            2. . + $djot = "1. item\n {reversed}\n"; + + $result = $this->converter->convert($djot); + + $this->assertStringContainsString('
            3. ', $result); + $this->assertStringNotContainsString('
            4. assertStringNotContainsString('reversed=""', $result); + } + + public function testListItemOtherAttributesUnchanged(): void + { + // G3 regression guard: only start/type/reversed are stripped. + // class, id, data-* pass through unchanged on
            5. . + $djot = "1. item\n {#anchor .step data-step=\"1\"}\n"; + + $result = $this->converter->convert($djot); + + $this->assertStringContainsString('id="anchor"', $result); + $this->assertStringContainsString('class="step"', $result); + $this->assertStringContainsString('data-step="1"', $result); + } + + public function testOlStartFromBlockAttrUnchanged(): void + { + // G3 regression guard: a block-attribute line BEFORE a list + // applies to the
                and must still emit start/type as before. + $djot = "{start=5}\n1. item\n2. next\n"; + + $result = $this->converter->convert($djot); + + $this->assertStringContainsString('
                  . + $djot = ": term\n\n definition\n {start=5}\n"; + + $result = $this->converter->convert($djot); + + $this->assertStringContainsString('
                  ', $result); + $this->assertStringNotContainsString('
                  sharedRenderContext = new RenderContext(); @@ -741,7 +750,7 @@ protected function renderList(ListBlock $node): string protected function renderListItem(ListItem $node, bool $tight = true): string { - $attrs = $this->renderAttributes($node); + $attrs = $this->renderAttributesExcluding($node, self::OL_ONLY_ATTRIBUTES); $content = $this->renderChildren($node); if ($tight) { @@ -1239,7 +1248,7 @@ protected function renderDefinitionTerm(DefinitionTerm $node): string protected function renderDefinitionDescription(DefinitionDescription $node): string { - $attrs = $this->renderAttributes($node); + $attrs = $this->renderAttributesExcluding($node, self::OL_ONLY_ATTRIBUTES); $content = $this->renderChildren($node); // Content goes on separate lines From 4d7114f2c6c596a848bd82bb69f0a077fad6a884 Mon Sep 17 00:00:00 2001 From: Mark Scherer Date: Wed, 20 May 2026 02:21:50 +0200 Subject: [PATCH 3/3] docs: note start/type/reversed strip on
                1. /
                  --- docs/reference/enhancements.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/reference/enhancements.md b/docs/reference/enhancements.md index 6156312e..24c301f2 100644 --- a/docs/reference/enhancements.md +++ b/docs/reference/enhancements.md @@ -441,6 +441,12 @@ Works with all list types: block attribute for that following block; the list and item are not terminated. +**Stripped attribute names:** `start`, `type`, and `reversed` are HTML +attributes valid only on `
                    `. When authored on a list item they are +silently dropped from the rendered `
                  1. ` to keep output HTML valid. +To set `
                      `, use a standard block-attribute line **before** +the list: `{start=5}` followed by `1. ...`. + --- ### Table Row and Cell Attributes @@ -749,6 +755,9 @@ Attributes can be attached to individual `
                      `, `
                      `, and `
                      ` elements: - `{...}` on line after term → applies to that `
                      ` - `{...}` as last line in definition block → applies to that `
                      ` (consistent with list items) +**Stripped attribute names:** the same `start`, `type`, `reversed` +strip applies to `
                      ` output. + --- ### Table Multi-line Cells, Rowspan, and Colspan