From e8e9d31559e38173093f11d99721392e32e21d60 Mon Sep 17 00:00:00 2001 From: Anhgelus Morhtuuzh Date: Sat, 18 Apr 2026 18:45:16 +0200 Subject: feat(ast): parse paragraph --- src/paragraph.zig | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 src/paragraph.zig (limited to 'src/paragraph.zig') diff --git a/src/paragraph.zig b/src/paragraph.zig new file mode 100644 index 0000000..75651f4 --- /dev/null +++ b/src/paragraph.zig @@ -0,0 +1,59 @@ +const std = @import("std"); +const Lexed = @import("lexer/Lexed.zig"); +const Lexer = @import("lexer/Lexer.zig"); +const Element = @import("dom/Element.zig"); +const Allocator = std.mem.Allocator; +const ast = @import("ast.zig"); +const Error = ast.Error; + +pub fn parseParagraph(alloc: Allocator, l: *Lexer) Error!Element { + var el = try Element.init(alloc, .content, "p"); + while (l.nextKind()) |kind| { + switch (kind) { + // because nextKind returns only an hint for the next rune + .weak_delimiter => { + var v = (try l.next(alloc)).?; + defer v.deinit(); + if (v.kind == .strong_delimiter) return el; + const next = l.nextKind() orelse return el; + switch (next) { + .literal, .italic, .code, .bold => try el.appendContent(try Element.initLit(alloc, " ")), + else => return el, + } + }, + else => try el.appendContent(try parseContent(alloc, l)), + } + } + return el; +} + +pub fn parseContent(alloc: Allocator, l: *Lexer) Error!Element { + var content = Element.initEmpty(alloc); + const v = (try l.next(alloc)).?; + switch (v.kind) { + .literal => { + const el = try Element.initLitEscaped(alloc, v.content.items); + try content.appendContent(el); + }, + .bold => try content.appendContent(try parseModifier(alloc, l, .bold, "b")), + .italic => try content.appendContent(try parseModifier(alloc, l, .italic, "em")), + .code => try content.appendContent(try parseModifier(alloc, l, .code, "code")), + else => return Error.InvalidSequence, + } + return content; +} + +fn parseModifier(alloc: Allocator, l: *Lexer, knd: Lexed.Kind, tag: []const u8) Error!Element { + var el = try Element.init(alloc, .content, tag); + while (l.nextKind()) |it| { + if (it == knd) { + // consuming the finisher + var v = (try l.next(alloc)).?; + v.deinit(); + break; + } + if (it.isDelimiter()) return Error.UnclosedModifier; + try el.appendContent(try parseContent(alloc, l)); + } + return el; +} -- cgit v1.2.3