diff options
| author | Anhgelus Morhtuuzh <william@herges.fr> | 2026-04-30 18:25:15 +0200 |
|---|---|---|
| committer | Anhgelus Morhtuuzh <william@herges.fr> | 2026-04-30 18:25:15 +0200 |
| commit | a36f5482ad90d6899d56e016666a2ca09240abd6 (patch) | |
| tree | 662910a41786a7d77cfb55f069236eef1c2a2639 /src/math.zig | |
| parent | 3fd5b4a9ad676b722f1f889f523b4ca368f05275 (diff) | |
feat(): support math block
Diffstat (limited to 'src/math.zig')
| -rw-r--r-- | src/math.zig | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/src/math.zig b/src/math.zig new file mode 100644 index 0000000..e28b3b9 --- /dev/null +++ b/src/math.zig @@ -0,0 +1,56 @@ +const std = @import("std"); +const Allocator = std.mem.Allocator; +const Token = @import("lexer/Token.zig"); +const Lexer = @import("lexer/Lexer.zig"); +const Element = @import("eval/Element.zig"); +const testing = @import("testing.zig"); +const doTest = testing.doMath; +const doTestError = testing.doError; + +pub const Error = error{InvalidMathBlock} || Allocator.Error; + +pub fn parse(alloc: Allocator, l: *Lexer) Error!Element { + _ = l.next(); + const beg = l.next() orelse return Error.InvalidMathBlock; + if (!beg.kind.isDelimiter()) return Error.InvalidMathBlock; + const math = try Element.Math.Block.init(alloc); + var acc = try std.ArrayList(u8).initCapacity(alloc, 2); + while (l.next()) |it| { + if (it.kind == .math_block) return Error.InvalidMathBlock; + try acc.appendSlice(alloc, it.content); + // restore modifications done by the lexer + if (it.kind.requiresSpace()) + try acc.append(alloc, ' '); + if (it.kind.isDelimiter()) { + const next = l.peek() orelse return Error.InvalidMathBlock; + if (next.kind == .math_block) break; + } + } + var end = l.next() orelse return Error.InvalidMathBlock; + if (end.kind != .math_block) return Error.InvalidMathBlock; + const el = try Element.Figure.init(alloc, math.element()); + math.content = try acc.toOwnedSlice(alloc); + end = l.next() orelse return el.element(); + if (!end.kind.isDelimiter()) return Error.InvalidMathBlock; + return el.element(); +} + +test { + const alloc = std.testing.allocator; + + try doTest(parse, alloc, + \\$$$ + \\x + \\$$$ + , "<figure>" ++ @embedFile("data/test_block_1.svg") ++ "</figure>"); + try doTest(parse, alloc, + \\$$$ + \\x^2 + \\$$$ + , "<figure>" ++ @embedFile("data/test_block_2.svg") ++ "</figure>"); + try doTest(parse, alloc, + \\$$$ + \\forall x in RR, quad f(x) = x^2 + \\$$$ + , "<figure>" ++ @embedFile("data/test_block_3.svg") ++ "</figure>"); +} |
