From 3c97332fd8440cda2e95f1fc50a6b9755c5867dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A0=20Arrufat?= Date: Mon, 9 Mar 2026 18:23:52 +0900 Subject: [PATCH] feat(dump): add semantic_tree and semantic_tree_text formats Adds support for dumping the semantic tree in JSON or text format via the --dump option. Updates the Config enum and usage help. --- src/Config.zig | 4 +++- src/lightpanda.zig | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/Config.zig b/src/Config.zig index 5a4cc58e..f93c0efa 100644 --- a/src/Config.zig +++ b/src/Config.zig @@ -192,6 +192,8 @@ pub const DumpFormat = enum { html, markdown, wpt, + semantic_tree, + semantic_tree_text, }; pub const Fetch = struct { @@ -338,7 +340,7 @@ pub fn printUsageAndExit(self: *const Config, success: bool) void { \\ \\Options: \\--dump Dumps document to stdout. - \\ Argument must be 'html' or 'markdown'. + \\ Argument must be 'html', 'markdown', 'semantic_tree', or 'semantic_tree_text'. \\ Defaults to no dump. \\ \\--strip_mode Comma separated list of tag groups to remove from dump diff --git a/src/lightpanda.zig b/src/lightpanda.zig index e506e61b..d11a9ff5 100644 --- a/src/lightpanda.zig +++ b/src/lightpanda.zig @@ -32,6 +32,7 @@ pub const js = @import("browser/js/js.zig"); pub const dump = @import("browser/dump.zig"); pub const markdown = @import("browser/markdown.zig"); pub const SemanticTree = @import("SemanticTree.zig"); +pub const CDPNode = @import("cdp/Node.zig"); pub const mcp = @import("mcp.zig"); pub const build_config = @import("build_config"); pub const crash_handler = @import("crash_handler.zig"); @@ -108,6 +109,24 @@ pub fn fetch(app: *App, url: [:0]const u8, opts: FetchOpts) !void { switch (mode) { .html => try dump.root(page.window._document, opts.dump, writer, page), .markdown => try markdown.dump(page.window._document.asNode(), .{}, writer, page), + .semantic_tree, .semantic_tree_text => { + var registry = CDPNode.Registry.init(app.allocator); + defer registry.deinit(); + + const st = SemanticTree{ + .dom_node = page.window._document.asNode(), + .registry = ®istry, + .page = page, + .arena = page.call_arena, + .prune = true, + }; + + if (mode == .semantic_tree) { + try std.json.Stringify.value(st, .{}, writer); + } else { + try st.textStringify(writer); + } + }, .wpt => try dumpWPT(page, writer), } }