Skip to documentation
SLOP

tiny.markdown.block

Reference tiny.markdown block

Defined in tiny.markdown.

API (4)

Actions

Public operations.

Types and contracts

Public types and contracts.

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

Source

Source: lib/markdown/src/block.zig

zig
const std = @import("std");pub const BlockType = enum {    paragraph,    heading1,    heading2,    heading3,    heading4,    code_block,    bullet_list,    numbered_list,    blockquote,    horizontal_rule,};pub const Block = struct {    block_type: BlockType = .paragraph,    content: []const u8,    indent: u8 = 0,    number: ?u16 = null,    language: ?[]const u8 = null,};pub const Parsed = struct {    block_type: BlockType,    content: []const u8,    number: ?u16,    indent: u8,};pub fn parseType(line: []const u8) Parsed {    const indent = markdownIndent(line);    const trimmed = trimLeft(line, " \t");    if (trimmed.len == 0) {        return .{ .block_type = .paragraph, .content = "", .number = null, .indent = indent };    }    if (trimmed.len >= 3 and (std.mem.startsWith(u8, trimmed, "---") or std.mem.startsWith(u8, trimmed, "***") or std.mem.startsWith(u8, trimmed, "___"))) {        var all_same = true;        const first = trimmed[0];        for (trimmed) |c| {            if (c != first and c != ' ') {                all_same = false;                break;            }        }        if (all_same) {            return .{ .block_type = .horizontal_rule, .content = "", .number = null, .indent = indent };        }    }    if (std.mem.startsWith(u8, trimmed, "#### ")) {        return .{ .block_type = .heading4, .content = trimmed[5..], .number = null, .indent = indent };    }    if (std.mem.startsWith(u8, trimmed, "### ")) {        return .{ .block_type = .heading3, .content = trimmed[4..], .number = null, .indent = indent };    }    if (std.mem.startsWith(u8, trimmed, "## ")) {        return .{ .block_type = .heading2, .content = trimmed[3..], .number = null, .indent = indent };    }    if (std.mem.startsWith(u8, trimmed, "# ")) {        return .{ .block_type = .heading1, .content = trimmed[2..], .number = null, .indent = indent };    }    if (std.mem.startsWith(u8, trimmed, "> ")) {        return .{ .block_type = .blockquote, .content = trimmed[2..], .number = null, .indent = indent };    }    if (std.mem.startsWith(u8, trimmed, ">")) {        return .{ .block_type = .blockquote, .content = trimmed[1..], .number = null, .indent = indent };    }    if (trimmed.len >= 2 and (trimmed[0] == '-' or trimmed[0] == '*' or trimmed[0] == '+') and trimmed[1] == ' ') {        return .{ .block_type = .bullet_list, .content = trimmed[2..], .number = null, .indent = indent };    }    if (trimmed.len >= 3) {        var num_end: usize = 0;        while (num_end < trimmed.len and trimmed[num_end] >= '0' and trimmed[num_end] <= '9') {            num_end += 1;        }        if (num_end > 0 and num_end < trimmed.len and trimmed[num_end] == '.' and num_end + 1 < trimmed.len and trimmed[num_end + 1] == ' ') {            const num = std.fmt.parseInt(u16, trimmed[0..num_end], 10) catch 1;            return .{ .block_type = .numbered_list, .content = trimmed[num_end + 2 ..], .number = num, .indent = indent };        }    }    if (std.mem.startsWith(u8, trimmed, "```")) {        return .{ .block_type = .code_block, .content = trimmed[3..], .number = null, .indent = indent };    }    return .{ .block_type = .paragraph, .content = trimmed, .number = null, .indent = indent };}fn markdownIndent(line: []const u8) u8 {    var columns: usize = 0;    for (line) |char| {        switch (char) {            ' ' => columns += 1,            '\t' => columns += 4,            else => break,        }    }    return @intCast(@min(columns / 2, @as(usize, std.math.maxInt(u8))));}fn trimLeft(bytes: []const u8, values: []const u8) []const u8 {    var start: usize = 0;    while (start < bytes.len and std.mem.indexOfScalar(u8, values, bytes[start]) != null) start += 1;    return bytes[start..];}test "parseType heading" {    const h1 = parseType("# Title");    try std.testing.expectEqual(BlockType.heading1, h1.block_type);    try std.testing.expectEqualStrings("Title", h1.content);    const h2 = parseType("## Subtitle");    try std.testing.expectEqual(BlockType.heading2, h2.block_type);    const h3 = parseType("### Section");    try std.testing.expectEqual(BlockType.heading3, h3.block_type);}test "parseType bullet list" {    const bullet = parseType("- Item");    try std.testing.expectEqual(BlockType.bullet_list, bullet.block_type);    try std.testing.expectEqualStrings("Item", bullet.content);    try std.testing.expectEqual(@as(u8, 0), bullet.indent);    const star = parseType("* Another");    try std.testing.expectEqual(BlockType.bullet_list, star.block_type);    const nested = parseType("  - Nested");    try std.testing.expectEqual(BlockType.bullet_list, nested.block_type);    try std.testing.expectEqual(@as(u8, 1), nested.indent);}test "parseType numbered list" {    const num = parseType("1. First");    try std.testing.expectEqual(BlockType.numbered_list, num.block_type);    try std.testing.expectEqualStrings("First", num.content);    try std.testing.expectEqual(@as(?u16, 1), num.number);    const num2 = parseType("42. Item");    try std.testing.expectEqual(@as(?u16, 42), num2.number);    const nested = parseType("\t3. Nested");    try std.testing.expectEqual(@as(?u16, 3), nested.number);    try std.testing.expectEqual(@as(u8, 2), nested.indent);}test "parseType blockquote" {    const quote = parseType("> Quote text");    try std.testing.expectEqual(BlockType.blockquote, quote.block_type);    try std.testing.expectEqualStrings("Quote text", quote.content);}test "parseType horizontal rule" {    const hr1 = parseType("---");    try std.testing.expectEqual(BlockType.horizontal_rule, hr1.block_type);    const hr2 = parseType("***");    try std.testing.expectEqual(BlockType.horizontal_rule, hr2.block_type);}test "parseType paragraph" {    const para = parseType("Normal text");    try std.testing.expectEqual(BlockType.paragraph, para.block_type);    try std.testing.expectEqualStrings("Normal text", para.content);}test "BlockType values" {    try std.testing.expectEqual(BlockType.paragraph, BlockType.paragraph);    try std.testing.expectEqual(BlockType.heading1, BlockType.heading1);    try std.testing.expectEqual(BlockType.code_block, BlockType.code_block);}

Source: lib/markdown/src/root.zig:9

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

Audit

Definitions1
Public names1
Members0
Version26.7.0
Revisiondaab053ee433