tiny.termtex.flat
Defined in tiny.termtex.
API (1)
Actions
Public operations.
Source
Source: lib/termtex/src/flat.zig
zig
const std = @import("std");const alloc_arena = @import("alloc_arena");const ast = @import("ast.zig");const layout = @import("layout.zig");const parse = @import("parse.zig");pub fn renderAlloc(allocator: std.mem.Allocator, source: []const u8) ![]u8 { var arena = alloc_arena.Arena.init(allocator); defer arena.deinit(); const expr = try parse.parse(arena.allocator(), source); var out: std.ArrayListUnmanaged(u8) = .empty; errdefer out.deinit(allocator); try appendFlat(allocator, arena.allocator(), &out, expr); return out.toOwnedSlice(allocator);}fn appendFlat( allocator: std.mem.Allocator, scratch: std.mem.Allocator, out: *std.ArrayListUnmanaged(u8), expr: *const ast.Expr,) std.mem.Allocator.Error!void { switch (expr.*) { .row => |items| for (items) |item| try appendFlat(allocator, scratch, out, item), .text => |value| try out.appendSlice(allocator, value), .operator => |value| try appendFlat(allocator, scratch, out, value.body), .space => |value| try appendFlatSpace(allocator, out, value), .fraction => |value| { try appendFlatGrouped(allocator, scratch, out, value.numerator); try out.appendSlice(allocator, "⁄"); try appendFlatGrouped(allocator, scratch, out, value.denominator); }, .sqrt => |value| { try out.appendSlice(allocator, "√"); if (value.index) |index| { try out.append(allocator, '['); try appendFlat(allocator, scratch, out, index); try out.append(allocator, ']'); } try appendFlatGrouped(allocator, scratch, out, value.body); }, .scripts => |value| { try appendFlat(allocator, scratch, out, value.base); if (value.sub) |sub| try appendScript(allocator, scratch, out, sub, .sub); if (value.sup) |sup| try appendScript(allocator, scratch, out, sup, .sup); }, .accent => |value| { switch (value.mark) { .bar => try out.appendSlice(allocator, "bar"), .hat => try out.appendSlice(allocator, "hat"), .vec => try out.appendSlice(allocator, "vec"), .dot => try out.appendSlice(allocator, "dot"), .underline => try out.appendSlice(allocator, "underline"), .tilde => try out.appendSlice(allocator, "tilde"), .check => try out.appendSlice(allocator, "check"), .breve => try out.appendSlice(allocator, "breve"), .ddot => try out.appendSlice(allocator, "ddot"), .acute => try out.appendSlice(allocator, "acute"), .grave => try out.appendSlice(allocator, "grave"), .ring => try out.appendSlice(allocator, "ring"), .overleft => try out.appendSlice(allocator, "overleftarrow"), .overleftright => try out.appendSlice(allocator, "overleftrightarrow"), } try appendFlatGrouped(allocator, scratch, out, value.body); }, .grid => |value| try appendFlatGrid(allocator, scratch, out, value), .annotation => |value| try appendFlatAnnotation(allocator, scratch, out, value), .delimited => |value| try appendFlatDelimited(allocator, scratch, out, value), }}fn appendFlatSpace( allocator: std.mem.Allocator, out: *std.ArrayListUnmanaged(u8), value: ast.Space,) std.mem.Allocator.Error!void { if (out.items.len == 0) return; for (0..layout.spaceCells(value)) |_| try out.append(allocator, ' ');}fn appendFlatDelimited( allocator: std.mem.Allocator, scratch: std.mem.Allocator, out: *std.ArrayListUnmanaged(u8), value: ast.Delimited,) std.mem.Allocator.Error!void { if (flatDelimiter(value.left)) |delimiter| try out.appendSlice(allocator, delimiter); try appendFlat(allocator, scratch, out, value.body); if (flatDelimiter(value.right)) |delimiter| try out.appendSlice(allocator, delimiter);}fn appendFlatAnnotation( allocator: std.mem.Allocator, scratch: std.mem.Allocator, out: *std.ArrayListUnmanaged(u8), value: ast.Annotation,) std.mem.Allocator.Error!void { switch (value.kind) { .plain => { if (value.over) |over| { try out.appendSlice(allocator, "overset("); try appendFlat(allocator, scratch, out, over); try out.append(allocator, ','); try appendFlat(allocator, scratch, out, value.base); try out.append(allocator, ')'); } else if (value.under) |under| { try out.appendSlice(allocator, "underset("); try appendFlat(allocator, scratch, out, under); try out.append(allocator, ','); try appendFlat(allocator, scratch, out, value.base); try out.append(allocator, ')'); } else { try appendFlat(allocator, scratch, out, value.base); } }, .overbrace => { try out.appendSlice(allocator, "overbrace"); try appendFlatGrouped(allocator, scratch, out, value.base); }, .underbrace => { try out.appendSlice(allocator, "underbrace"); try appendFlatGrouped(allocator, scratch, out, value.base); }, .boxed => { try out.append(allocator, '['); try appendFlat(allocator, scratch, out, value.base); try out.append(allocator, ']'); }, }}fn appendFlatGrid( allocator: std.mem.Allocator, scratch: std.mem.Allocator, out: *std.ArrayListUnmanaged(u8), value: ast.Grid,) std.mem.Allocator.Error!void { if (flatLeftFence(value.fence)) |fence| try out.appendSlice(allocator, fence); for (value.rows, 0..) |row, row_index| { if (row_index != 0) try out.append(allocator, ';'); for (row.cells, 0..) |cell, cell_index| { if (cell_index != 0) try out.append(allocator, ','); try appendFlat(allocator, scratch, out, cell); } } if (flatRightFence(value.fence)) |fence| try out.appendSlice(allocator, fence);}fn appendFlatGrouped( allocator: std.mem.Allocator, scratch: std.mem.Allocator, out: *std.ArrayListUnmanaged(u8), expr: *const ast.Expr,) std.mem.Allocator.Error!void { const grouped = switch (expr.*) { .text => false, .operator => false, .space => false, .scripts => false, else => true, }; if (grouped) try out.append(allocator, '('); try appendFlat(allocator, scratch, out, expr); if (grouped) try out.append(allocator, ')');}fn flatLeftFence(fence: ast.GridFence) ?[]const u8 { return switch (fence) { .none => null, .paren => "(", .bracket => "[", .brace, .left_brace => "{", .bar => "|", .double_bar => "‖", };}fn flatRightFence(fence: ast.GridFence) ?[]const u8 { return switch (fence) { .none, .left_brace => null, .paren => ")", .bracket => "]", .brace => "}", .bar => "|", .double_bar => "‖", };}fn flatDelimiter(delimiter: ast.Delimiter) ?[]const u8 { return switch (delimiter) { .none => null, .shape => |shape| flatDelimiterShape(shape), .text => |value| value, };}fn flatDelimiterShape(shape: ast.DelimiterShape) []const u8 { return switch (shape) { .left_paren => "(", .right_paren => ")", .left_bracket => "[", .right_bracket => "]", .left_brace => "{", .right_brace => "}", .bar => "|", .double_bar => "‖", .left_angle => "⟨", .right_angle => "⟩", .left_double_angle => "⟪", .right_double_angle => "⟫", .left_double_bracket => "⟦", .right_double_bracket => "⟧", .left_floor => "⌊", .right_floor => "⌋", .left_ceil => "⌈", .right_ceil => "⌉", };}const ScriptMode = enum { sub, sup,};fn appendScript( allocator: std.mem.Allocator, scratch: std.mem.Allocator, out: *std.ArrayListUnmanaged(u8), expr: *const ast.Expr, mode: ScriptMode,) std.mem.Allocator.Error!void { var raw: std.ArrayListUnmanaged(u8) = .empty; defer raw.deinit(scratch); try appendFlat(scratch, scratch, &raw, expr); if (try appendMappedScript(allocator, out, raw.items, mode)) return; try out.append(allocator, switch (mode) { .sup => '^', .sub => '_', }); try out.append(allocator, '('); try out.appendSlice(allocator, raw.items); try out.append(allocator, ')');}fn appendMappedScript( allocator: std.mem.Allocator, out: *std.ArrayListUnmanaged(u8), raw: []const u8, mode: ScriptMode,) std.mem.Allocator.Error!bool { var index: usize = 0; while (index < raw.len) { const len = std.unicode.utf8ByteSequenceLength(raw[index]) catch return false; const end = index + @min(len, raw.len - index); if (scriptGlyph(raw[index..end], mode) == null) return false; index = end; } index = 0; while (index < raw.len) { const len = std.unicode.utf8ByteSequenceLength(raw[index]) catch unreachable; const end = index + @min(len, raw.len - index); try out.appendSlice(allocator, scriptGlyph(raw[index..end], mode).?); index = end; } return true;}fn scriptGlyph(value: []const u8, mode: ScriptMode) ?[]const u8 { return switch (mode) { .sup => superscriptGlyph(value), .sub => subscriptGlyph(value), };}fn superscriptGlyph(value: []const u8) ?[]const u8 { if (std.mem.eql(u8, value, "0")) return "⁰"; if (std.mem.eql(u8, value, "1")) return "¹"; if (std.mem.eql(u8, value, "2")) return "²"; if (std.mem.eql(u8, value, "3")) return "³"; if (std.mem.eql(u8, value, "4")) return "⁴"; if (std.mem.eql(u8, value, "5")) return "⁵"; if (std.mem.eql(u8, value, "6")) return "⁶"; if (std.mem.eql(u8, value, "7")) return "⁷"; if (std.mem.eql(u8, value, "8")) return "⁸"; if (std.mem.eql(u8, value, "9")) return "⁹"; if (std.mem.eql(u8, value, "+")) return "⁺"; if (std.mem.eql(u8, value, "-")) return "⁻"; if (std.mem.eql(u8, value, "=")) return "⁼"; if (std.mem.eql(u8, value, "(")) return "⁽"; if (std.mem.eql(u8, value, ")")) return "⁾"; if (std.mem.eql(u8, value, "n")) return "ⁿ"; if (std.mem.eql(u8, value, "i")) return "ⁱ"; return null;}fn subscriptGlyph(value: []const u8) ?[]const u8 { if (std.mem.eql(u8, value, "0")) return "₀"; if (std.mem.eql(u8, value, "1")) return "₁"; if (std.mem.eql(u8, value, "2")) return "₂"; if (std.mem.eql(u8, value, "3")) return "₃"; if (std.mem.eql(u8, value, "4")) return "₄"; if (std.mem.eql(u8, value, "5")) return "₅"; if (std.mem.eql(u8, value, "6")) return "₆"; if (std.mem.eql(u8, value, "7")) return "₇"; if (std.mem.eql(u8, value, "8")) return "₈"; if (std.mem.eql(u8, value, "9")) return "₉"; if (std.mem.eql(u8, value, "+")) return "₊"; if (std.mem.eql(u8, value, "-")) return "₋"; if (std.mem.eql(u8, value, "=")) return "₌"; if (std.mem.eql(u8, value, "(")) return "₍"; if (std.mem.eql(u8, value, ")")) return "₎"; if (std.mem.eql(u8, value, "a")) return "ₐ"; if (std.mem.eql(u8, value, "e")) return "ₑ"; if (std.mem.eql(u8, value, "h")) return "ₕ"; if (std.mem.eql(u8, value, "i")) return "ᵢ"; if (std.mem.eql(u8, value, "j")) return "ⱼ"; if (std.mem.eql(u8, value, "k")) return "ₖ"; if (std.mem.eql(u8, value, "l")) return "ₗ"; if (std.mem.eql(u8, value, "m")) return "ₘ"; if (std.mem.eql(u8, value, "n")) return "ₙ"; if (std.mem.eql(u8, value, "o")) return "ₒ"; if (std.mem.eql(u8, value, "p")) return "ₚ"; if (std.mem.eql(u8, value, "r")) return "ᵣ"; if (std.mem.eql(u8, value, "s")) return "ₛ"; if (std.mem.eql(u8, value, "t")) return "ₜ"; if (std.mem.eql(u8, value, "u")) return "ᵤ"; if (std.mem.eql(u8, value, "v")) return "ᵥ"; if (std.mem.eql(u8, value, "x")) return "ₓ"; return null;}Source: lib/termtex/src/root.zig:11
zig
pub const flat = @import("flat.zig");Audit
| Definitions | 2 |
|---|---|
| Public names | 2 |
| Members | 0 |
| Version | 26.7.0 |
| Revision | daab053ee433 |