Skip to documentation
SLOP

tiny.zen.math.mathml

Reference tiny.zen math mathml

Defined in math.

API (1)

Actions

Public operations.

No direct callersNo direct callsmathmathml
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Called byCallsprivate sourcelib.zen.src.math.mathmlappendTabletest sourcelib.zen.src.math.mathmltest: mathml emits aligned with displ...test sourcelib.zen.src.math.mathmltest: mathml emits cases with a lone ...test sourcelib.zen.src.math.mathmltest: mathml emits fenced matricestest sourcelib.zen.src.math.mathmltest: mathml emits scripts by placeme...+2 morehtmlappendEscapedprivate sourcelib.zen.src.math.mathmlappendTableprivate sourcelib.zen.src.math.mathmlscriptTagmath.mathmlappend
Static calls · unresolved targets: 1 · external targets: 1.

Source: lib/zen/src/math/mathml.zig

zig
const std = @import("std");const zen = @import("../root.zig");const parse = @import("parse.zig");const html = zen.html;const Allocator = std.mem.Allocator;pub fn append(out: *std.ArrayList(u8), allocator: Allocator, node: parse.Node) Allocator.Error!void {    switch (node) {        .row => |items| {            if (items.len == 1) return append(out, allocator, items[0]);            try out.appendSlice(allocator, "<mrow>");            for (items) |item| try append(out, allocator, item);            try out.appendSlice(allocator, "</mrow>");        },        .ident => |ident| {            if (ident.upright) {                try out.appendSlice(allocator, "<mi mathvariant=\"normal\">");            } else {                try out.appendSlice(allocator, "<mi>");            }            try html.appendEscaped(out, allocator, ident.text);            try out.appendSlice(allocator, "</mi>");        },        .number => |text| {            try out.appendSlice(allocator, "<mn>");            try html.appendEscaped(out, allocator, text);            try out.appendSlice(allocator, "</mn>");        },        .operator => |operator| {            try out.appendSlice(allocator, "<mo");            if (operator.stretchy) try out.appendSlice(allocator, " stretchy=\"true\"");            if (operator.rigid) try out.appendSlice(allocator, " stretchy=\"false\"");            if (operator.movable_word) try out.appendSlice(allocator, " movablelimits=\"true\"");            try out.append(allocator, '>');            try html.appendEscaped(out, allocator, operator.text);            try out.appendSlice(allocator, "</mo>");        },        .space => |width| {            try out.appendSlice(allocator, "<mspace width=\"");            try out.appendSlice(allocator, width);            try out.appendSlice(allocator, "\"/>");        },        .text => |text| {            try out.appendSlice(allocator, "<mtext>");            try html.appendEscaped(out, allocator, text);            try out.appendSlice(allocator, "</mtext>");        },        .frac => |frac| {            try out.appendSlice(allocator, "<mfrac>");            try append(out, allocator, frac.first.*);            try append(out, allocator, frac.second.*);            try out.appendSlice(allocator, "</mfrac>");        },        .radical => |radical| {            if (radical.index) |index| {                try out.appendSlice(allocator, "<mroot>");                try append(out, allocator, radical.radicand.*);                try append(out, allocator, index.*);                try out.appendSlice(allocator, "</mroot>");            } else {                try out.appendSlice(allocator, "<msqrt>");                try append(out, allocator, radical.radicand.*);                try out.appendSlice(allocator, "</msqrt>");            }        },        .scripts => |scripts| {            const tag = scriptTag(scripts);            try out.append(allocator, '<');            try out.appendSlice(allocator, tag);            try out.append(allocator, '>');            try append(out, allocator, scripts.base.*);            if (scripts.sub) |sub| try append(out, allocator, sub.*);            if (scripts.sup) |sup| try append(out, allocator, sup.*);            try out.appendSlice(allocator, "</");            try out.appendSlice(allocator, tag);            try out.append(allocator, '>');        },        .accent => |accent| {            try out.appendSlice(allocator, "<mover accent=\"true\">");            try append(out, allocator, accent.base.*);            try out.appendSlice(allocator, "<mo>");            try html.appendEscaped(out, allocator, accent.mark);            try out.appendSlice(allocator, "</mo></mover>");        },        .table => |table| try appendTable(out, allocator, table),    }}fn appendTable(out: *std.ArrayList(u8), allocator: Allocator, table: parse.Table) Allocator.Error!void {    const fenced = table.env.open != null or table.env.close != null;    if (fenced) try out.appendSlice(allocator, "<mrow>");    if (table.env.open) |text| try appendFence(out, allocator, text);    try out.appendSlice(allocator, "<mtable");    if (table.env.display_cells) try out.appendSlice(allocator, " displaystyle=\"true\"");    if (table.env.class) |class| {        try out.appendSlice(allocator, " class=\"");        try out.appendSlice(allocator, class);        try out.append(allocator, '"');    }    try out.append(allocator, '>');    for (table.rows) |row| {        try out.appendSlice(allocator, "<mtr>");        for (row) |cell| {            try out.appendSlice(allocator, "<mtd>");            for (cell.row) |item| try append(out, allocator, item);            try out.appendSlice(allocator, "</mtd>");        }        try out.appendSlice(allocator, "</mtr>");    }    try out.appendSlice(allocator, "</mtable>");    if (table.env.close) |text| try appendFence(out, allocator, text);    if (fenced) try out.appendSlice(allocator, "</mrow>");}fn appendFence(out: *std.ArrayList(u8), allocator: Allocator, text: []const u8) Allocator.Error!void {    try out.appendSlice(allocator, "<mo stretchy=\"true\">");    try html.appendEscaped(out, allocator, text);    try out.appendSlice(allocator, "</mo>");}fn scriptTag(scripts: parse.Scripts) []const u8 {    const both = scripts.sub != null and scripts.sup != null;    if (scripts.limits) {        if (both) return "munderover";        return if (scripts.sub != null) "munder" else "mover";    }    if (both) return "msubsup";    return if (scripts.sub != null) "msub" else "msup";}test "mathml emits scripts by placement preference" {    var parsed = try parse.parse(std.testing.allocator, "\\sum_{i}^{n} x_i", null);    defer parsed.deinit();    var out: std.ArrayList(u8) = .empty;    defer out.deinit(std.testing.allocator);    try append(&out, std.testing.allocator, parsed.root);    try std.testing.expectEqualStrings(        "<mrow><munderover><mo>∑</mo><mi>i</mi><mi>n</mi></munderover>" ++            "<msub><mi>x</mi><mi>i</mi></msub></mrow>",        out.items,    );}test "mathml emits fenced matrices" {    var parsed = try parse.parse(std.testing.allocator, "\\begin{pmatrix} a & b \\\\ & 1 \\end{pmatrix}", null);    defer parsed.deinit();    var out: std.ArrayList(u8) = .empty;    defer out.deinit(std.testing.allocator);    try append(&out, std.testing.allocator, parsed.root);    try std.testing.expectEqualStrings(        "<mrow><mo stretchy=\"true\">(</mo><mtable>" ++            "<mtr><mtd><mi>a</mi></mtd><mtd><mi>b</mi></mtd></mtr>" ++            "<mtr><mtd></mtd><mtd><mn>1</mn></mtd></mtr>" ++            "</mtable><mo stretchy=\"true\">)</mo></mrow>",        out.items,    );}test "mathml emits cases with a lone brace and class" {    var parsed = try parse.parse(std.testing.allocator, "\\begin{cases} x & y \\end{cases}", null);    defer parsed.deinit();    var out: std.ArrayList(u8) = .empty;    defer out.deinit(std.testing.allocator);    try append(&out, std.testing.allocator, parsed.root);    try std.testing.expectEqualStrings(        "<mrow><mo stretchy=\"true\">{</mo><mtable class=\"zen-cases\">" ++            "<mtr><mtd><mi>x</mi></mtd><mtd><mi>y</mi></mtd></mtr>" ++            "</mtable></mrow>",        out.items,    );}test "mathml emits aligned with display cells" {    var parsed = try parse.parse(std.testing.allocator, "\\begin{aligned} a &= b \\\\ &= c \\end{aligned}", null);    defer parsed.deinit();    var out: std.ArrayList(u8) = .empty;    defer out.deinit(std.testing.allocator);    try append(&out, std.testing.allocator, parsed.root);    try std.testing.expectEqualStrings(        "<mtable displaystyle=\"true\" class=\"zen-aligned\">" ++            "<mtr><mtd><mi>a</mi></mtd><mtd><mo>=</mo><mi>b</mi></mtd></mtr>" ++            "<mtr><mtd></mtd><mtd><mo>=</mo><mi>c</mi></mtd></mtr>" ++            "</mtable>",        out.items,    );}test "mathml escapes text content" {    var parsed = try parse.parse(std.testing.allocator, "a < b \\text{ & so }", null);    defer parsed.deinit();    var out: std.ArrayList(u8) = .empty;    defer out.deinit(std.testing.allocator);    try append(&out, std.testing.allocator, parsed.root);    try std.testing.expectEqualStrings(        "<mrow><mi>a</mi><mo>&lt;</mo><mi>b</mi><mtext> &amp; so </mtext></mrow>",        out.items,    );}

Source: lib/zen/src/math/root.zig:3

zig
pub const mathml = @import("mathml.zig");

Complete caller list for math.mathml.append

7 direct callers.

Audit

Definitions2
Public names2
Members0
Version26.7.0
Revisiondaab053ee433