zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 6dcbad780cb716fe1d2a4b2ce201a757ea7f03a4 (tree)
parent 355cceebc7104d2e818b4959b0e43f822e19a9b5
Author: Ian Johnson <ian@ianjohnson.dev>
Date:   Mon,  8 Apr 2024 05:49:22 -0400

Autodoc: fix Markdown indented lists (#19577)

Previously, indentation was not being handled correctly in some cases,
causing examples such as `std.json.WriteStream` to be rendered with
improper list nesting.

Additionally, some more test cases have been added to ensure
indentation (or lack of indentation) is handled correctly in some other
constructs.
Diffstat:
Mlib/docs/wasm/markdown.zig | 132+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mlib/docs/wasm/markdown/Parser.zig | 26+++++++++++++-------------
2 files changed, 145 insertions(+), 13 deletions(-)

diff --git a/lib/docs/wasm/markdown.zig b/lib/docs/wasm/markdown.zig @@ -376,6 +376,106 @@ test "lists with block content" { ); } +test "indented lists" { + try testRender( + \\Test: + \\ * a1 + \\ * a2 + \\ * b1 + \\ * b2 + \\ + \\--- + \\ + \\ Test: + \\ - One + \\Two + \\ - Three + \\Four + \\ Five + \\Six + \\ + \\--- + \\ + \\None of these items are indented far enough from the previous one to + \\start a nested list: + \\ - One + \\ - Two + \\ - Three + \\ - Four + \\ - Five + \\ - Six + \\ - Seven + \\ - Eight + \\ - Nine + \\ + \\--- + \\ + \\ - One + \\ - Two + \\ - Three + \\ - Four + \\ - Five + \\ - Six + \\- Seven + \\ + , + \\<p>Test:</p> + \\<ul> + \\<li>a1</li> + \\<li>a2<ul> + \\<li>b1</li> + \\<li>b2</li> + \\</ul> + \\</li> + \\</ul> + \\<hr /> + \\<p>Test:</p> + \\<ul> + \\<li>One + \\Two<ul> + \\<li>Three + \\Four + \\Five + \\Six</li> + \\</ul> + \\</li> + \\</ul> + \\<hr /> + \\<p>None of these items are indented far enough from the previous one to + \\start a nested list:</p> + \\<ul> + \\<li>One</li> + \\<li>Two</li> + \\<li>Three</li> + \\<li>Four</li> + \\<li>Five</li> + \\<li>Six</li> + \\<li>Seven</li> + \\<li>Eight</li> + \\<li>Nine</li> + \\</ul> + \\<hr /> + \\<ul> + \\<li>One<ul> + \\<li>Two<ul> + \\<li>Three<ul> + \\<li>Four</li> + \\</ul> + \\</li> + \\</ul> + \\</li> + \\<li>Five<ul> + \\<li>Six</li> + \\</ul> + \\</li> + \\</ul> + \\</li> + \\<li>Seven</li> + \\</ul> + \\ + ); +} + test "tables" { try testRender( \\| Operator | Meaning | @@ -394,6 +494,10 @@ test "tables" { \\| :--- | :----: | ----: | \\| Left | Center | Right | \\ + \\ | One | Two | + \\ | Three | Four | + \\ | Five | Six | + \\ , \\<table> \\<tr> @@ -446,6 +550,20 @@ test "tables" { \\<td style="text-align: right">Right</td> \\</tr> \\</table> + \\<table> + \\<tr> + \\<td>One</td> + \\<td>Two</td> + \\</tr> + \\<tr> + \\<td>Three</td> + \\<td>Four</td> + \\</tr> + \\<tr> + \\<td>Five</td> + \\<td>Six</td> + \\</tr> + \\</table> \\ ); } @@ -597,6 +715,14 @@ test "code blocks" { \\ try std.testing.expect(2 + 2 == 4); \\} \\``` + \\ ``` + \\ Indentation up to the fence is removed. + \\ Like this. + \\ Doesn't need to be fully indented. + \\ ``` + \\``` + \\Overly indented closing fence is fine: + \\ ``` \\ , \\<pre><code>Hello, world! @@ -608,6 +734,12 @@ test "code blocks" { \\ try std.testing.expect(2 + 2 == 4); \\} \\</code></pre> + \\<pre><code>Indentation up to the fence is removed. + \\ Like this. + \\Doesn't need to be fully indented. + \\</code></pre> + \\<pre><code>Overly indented closing fence is fine: + \\</code></pre> \\ ); } diff --git a/lib/docs/wasm/markdown/Parser.zig b/lib/docs/wasm/markdown/Parser.zig @@ -152,7 +152,7 @@ const Block = struct { "" else null, - .table => if (unindented.len > 0) unindented else null, + .table => if (unindented.len > 0) line else null, .table_row => null, .heading => null, .code_block => code_block: { @@ -168,7 +168,7 @@ const Block = struct { unindented[1..] else null, - .paragraph => if (unindented.len > 0) unindented else null, + .paragraph => if (unindented.len > 0) line else null, .thematic_break => null, }; } @@ -225,7 +225,7 @@ pub fn feedLine(p: *Parser, line: []const u8) Allocator.Error!void { p.pending_blocks.items.len > 0 and p.pending_blocks.getLast().tag == .paragraph) { - try p.addScratchStringLine(rest_line); + try p.addScratchStringLine(mem.trimLeft(u8, rest_line, " \t")); return; } @@ -271,8 +271,8 @@ pub fn feedLine(p: *Parser, line: []const u8) Allocator.Error!void { // loose, since we might just be looking at a blank line after the // end of the last item in the list. The final determination will be // made when appending the next child of the list or list item. - const maybe_containing_list = if (p.pending_blocks.items.len > 0 and p.pending_blocks.getLast().tag == .list_item) - &p.pending_blocks.items[p.pending_blocks.items.len - 2] + const maybe_containing_list_index = if (p.pending_blocks.items.len > 0 and p.pending_blocks.getLast().tag == .list_item) + p.pending_blocks.items.len - 2 else null; @@ -285,8 +285,8 @@ pub fn feedLine(p: *Parser, line: []const u8) Allocator.Error!void { try p.addScratchStringLine(rest_line_trimmed); } - if (maybe_containing_list) |containing_list| { - containing_list.data.list.last_line_blank = rest_line_trimmed.len == 0; + if (maybe_containing_list_index) |containing_list_index| { + p.pending_blocks.items[containing_list_index].data.list.last_line_blank = rest_line_trimmed.len == 0; } }, .inlines => try p.addScratchStringLine(rest_line_trimmed), @@ -515,7 +515,7 @@ fn startBlock(p: *Parser, line: []const u8) !?BlockStart { .data = .{ .list_item = .{ .marker = list_item.marker, .number = list_item.number, - .continuation_indent = list_item.continuation_indent, + .continuation_indent = indent + list_item.marker_len, } }, .rest = list_item.rest, }; @@ -559,7 +559,7 @@ fn startBlock(p: *Parser, line: []const u8) !?BlockStart { const ListItemStart = struct { marker: Block.Data.ListMarker, number: u30, - continuation_indent: usize, + marker_len: usize, rest: []const u8, }; @@ -568,21 +568,21 @@ fn startListItem(unindented_line: []const u8) ?ListItemStart { return .{ .marker = .@"-", .number = undefined, - .continuation_indent = 2, + .marker_len = 2, .rest = unindented_line[2..], }; } else if (mem.startsWith(u8, unindented_line, "* ")) { return .{ .marker = .@"*", .number = undefined, - .continuation_indent = 2, + .marker_len = 2, .rest = unindented_line[2..], }; } else if (mem.startsWith(u8, unindented_line, "+ ")) { return .{ .marker = .@"+", .number = undefined, - .continuation_indent = 2, + .marker_len = 2, .rest = unindented_line[2..], }; } @@ -600,7 +600,7 @@ fn startListItem(unindented_line: []const u8) ?ListItemStart { return .{ .marker = marker, .number = number, - .continuation_indent = number_end + 2, + .marker_len = number_end + 2, .rest = after_number[2..], }; }