Skip to content

Commit 662865f

Browse files
committed
fmt: respect single empty lines
Allow users to place empty lines between sibling elements. Multiple empty lines in a row will be collapsed to a single empty line. This allows for visual separation of content "blocks" while still offering a normalized render of the document.
1 parent d07ca9b commit 662865f

File tree

1 file changed

+66
-2
lines changed

1 file changed

+66
-2
lines changed

src/html/Ast.zig

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -710,9 +710,10 @@ pub fn init(
710710

711711
pub fn render(ast: Ast, src: []const u8, w: *Writer) !void {
712712
std.debug.assert(ast.errors.len == 0);
713+
if (ast.nodes.len < 2) return;
713714

714715
var indentation: u32 = 0;
715-
var current = ast.nodes[0];
716+
var current = ast.nodes[1];
716717
var direction: enum { enter, exit } = .enter;
717718
var last_rbracket: u32 = 0;
718719
// var last_open_was_vertical = false;
@@ -744,7 +745,15 @@ pub fn render(ast: Ast, src: []const u8, w: *Writer) !void {
744745

745746
if (vertical) {
746747
log.debug("adding a newline", .{});
747-
try w.writeAll("\n");
748+
const lines = std.mem.count(u8, maybe_ws, "\n");
749+
if (last_rbracket > 0) {
750+
if (lines >= 2) {
751+
try w.writeAll("\n\n");
752+
} else {
753+
try w.writeAll("\n");
754+
}
755+
}
756+
748757
for (0..indentation) |_| {
749758
try w.writeAll(" ");
750759
}
@@ -1296,6 +1305,7 @@ test "what" {
12961305
\\ </a>
12971306
\\ </body>
12981307
\\</html>
1308+
\\
12991309
\\<a href="#">foo</a>
13001310
\\
13011311
;
@@ -1370,6 +1380,7 @@ test "self-closing tag complex example" {
13701380
;
13711381
const expected =
13721382
\\extend template="base.html"/>
1383+
\\
13731384
\\<div id="content">
13741385
\\ <svg viewBox="0 0 24 24">
13751386
\\ <path d="M14.4,6H20V16H13L12.6,14H7V21H5V4H14L14.4,6M14,14H16V12H18V10H16V8H14V10L13,8V6H11V8H9V6H7V8H9V10H7V12H9V10H11V12H13V10L14,12V14M11,10V8H13V10H11M14,10H16V12H14V10Z"/>
@@ -1383,6 +1394,59 @@ test "self-closing tag complex example" {
13831394
try std.testing.expectFmt(expected, "{f}", .{ast.formatter(case)});
13841395
}
13851396

1397+
test "respect empty lines" {
1398+
const case =
1399+
\\
1400+
\\<div> a
1401+
\\</div>
1402+
\\
1403+
\\<div></div>
1404+
\\
1405+
\\<div></div>
1406+
\\<div></div>
1407+
\\
1408+
\\
1409+
\\<div></div>
1410+
\\
1411+
\\
1412+
\\
1413+
\\<div></div>
1414+
\\<div> a
1415+
\\</div>
1416+
\\
1417+
\\
1418+
\\
1419+
\\<div> a
1420+
\\</div>
1421+
;
1422+
const expected =
1423+
\\<div>
1424+
\\ a
1425+
\\</div>
1426+
\\
1427+
\\<div></div>
1428+
\\
1429+
\\<div></div>
1430+
\\<div></div>
1431+
\\
1432+
\\<div></div>
1433+
\\
1434+
\\<div></div>
1435+
\\<div>
1436+
\\ a
1437+
\\</div>
1438+
\\
1439+
\\<div>
1440+
\\ a
1441+
\\</div>
1442+
\\
1443+
;
1444+
const ast = try Ast.init(std.testing.allocator, case, .html, true);
1445+
defer ast.deinit(std.testing.allocator);
1446+
1447+
try std.testing.expectFmt(expected, "{f}", .{ast.formatter(case)});
1448+
}
1449+
13861450
pub const Cursor = struct {
13871451
ast: Ast,
13881452
idx: u32,

0 commit comments

Comments
 (0)