Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

fileSourceHtml

html_render.fileSourceHtml
pub fn fileSourceHtml(
    file_index: Walk.File.Index,
    out: *ArrayList(u8),
    root_node: Ast.Node.Index,
    options: RenderSourceOptions,
) !void

File

lib/docs/wasm/html_render.zig:46

Code

pub fn fileSourceHtml(
    file_index: Walk.File.Index,
    out: *ArrayList(u8),
    root_node: Ast.Node.Index,
    options: RenderSourceOptions,
) !void {
    const ast = file_index.get_ast();
    const file = file_index.get();

    const g = struct {
        var field_access_buffer: ArrayList(u8) = .empty;
    };

    const start_token = ast.firstToken(root_node);
    const end_token = ast.lastToken(root_node) + 1;

    var cursor: usize = ast.tokenStart(start_token);

    var indent: usize = 0;
    if (std.mem.lastIndexOf(u8, ast.source[0..cursor], "\n")) |newline_index| {
        for (ast.source[newline_index + 1 .. cursor]) |c| {
            if (c == ' ') {
                indent += 1;
            } else {
                break;
            }
        }
    }

    var next_annotate_index: usize = 0;

    for (
        ast.tokens.items(.tag)[start_token..end_token],
        ast.tokens.items(.start)[start_token..end_token],
        start_token..,
    ) |tag, start, token_index| {
        const between = ast.source[cursor..start];
        if (std.mem.trim(u8, between, " \t\r\n").len > 0) {
            if (!options.skip_comments) {
                try out.appendSlice(gpa, "<span class=\"tok-comment\">");
                try appendUnindented(out, between, indent);
                try out.appendSlice(gpa, "</span>");
            }
        } else if (between.len > 0) {
            if (options.collapse_whitespace) {
                if (out.items.len > 0 and out.items[out.items.len - 1] != ' ')
                    try out.append(gpa, ' ');
            } else {
                try appendUnindented(out, between, indent);
            }
        }
        if (tag == .eof) break;
        const slice = ast.tokenSlice(token_index);
        cursor = start + slice.len;

        // Insert annotations.
        while (true) {
            if (next_annotate_index >= options.source_location_annotations.len) break;
            const next_annotation = options.source_location_annotations[next_annotate_index];
            if (cursor <= next_annotation.file_byte_offset) break;
            try out.print(gpa, "<span id=\"{s}{d}\"></span>", .{
                options.annotation_prefix, next_annotation.dom_id,
            });
            next_annotate_index += 1;
        }

        switch (tag) {
            .eof => unreachable,

            .keyword_addrspace,
            .keyword_align,
            .keyword_and,
            .keyword_asm,
            .keyword_break,
            .keyword_catch,
            .keyword_comptime,
            .keyword_const,
            .keyword_continue,
            .keyword_defer,
            .keyword_else,
            .keyword_enum,
            .keyword_errdefer,
            .keyword_error,
            .keyword_export,
            .keyword_extern,
            .keyword_for,
            .keyword_if,
            .keyword_inline,
            .keyword_noalias,
            .keyword_noinline,
            .keyword_nosuspend,
            .keyword_opaque,
            .keyword_or,
            .keyword_orelse,
            .keyword_packed,
            .keyword_anyframe,
            .keyword_pub,
            .keyword_resume,
            .keyword_return,
            .keyword_linksection,
            .keyword_callconv,
            .keyword_struct,
            .keyword_suspend,
            .keyword_switch,
            .keyword_test,
            .keyword_threadlocal,
            .keyword_try,
            .keyword_union,
            .keyword_unreachable,
            .keyword_var,
            .keyword_volatile,
            .keyword_allowzero,
            .keyword_while,
            .keyword_anytype,
            .keyword_fn,
            => {
                try out.appendSlice(gpa, "<span class=\"tok-kw\">");
                try appendEscaped(out, slice);
                try out.appendSlice(gpa, "</span>");
            },

            .string_literal,
            .char_literal,
            .multiline_string_literal_line,
            => {
                try out.appendSlice(gpa, "<span class=\"tok-str\">");
                try appendEscaped(out, slice);
                try out.appendSlice(gpa, "</span>");
            },

            .builtin => {
                try out.appendSlice(gpa, "<span class=\"tok-builtin\">");
                try appendEscaped(out, slice);
                try out.appendSlice(gpa, "</span>");
            },

            .doc_comment,
            .container_doc_comment,
            => {
                if (!options.skip_doc_comments) {
                    try out.appendSlice(gpa, "<span class=\"tok-comment\">");
                    try appendEscaped(out, slice);
                    try out.appendSlice(gpa, "</span>");
                }
            },

            .identifier => i: {
                if (options.fn_link != .none) {
                    const fn_link = options.fn_link.get();
                    const fn_token = ast.nodeMainToken(fn_link.ast_node);
                    if (token_index == fn_token + 1) {
                        try out.appendSlice(gpa, "<a class=\"tok-fn\" href=\"#");
                        _ = missing_feature_url_escape;
                        try fn_link.fqn(out);
                        try out.appendSlice(gpa, "\">");
                        try appendEscaped(out, slice);
                        try out.appendSlice(gpa, "</a>");
                        break :i;
                    }
                }

                if (token_index > 0 and ast.tokenTag(token_index - 1) == .keyword_fn) {
                    try out.appendSlice(gpa, "<span class=\"tok-fn\">");
                    try appendEscaped(out, slice);
                    try out.appendSlice(gpa, "</span>");
                    break :i;
                }

                if (Walk.isPrimitiveNonType(slice)) {
                    try out.appendSlice(gpa, "<span class=\"tok-null\">");
                    try appendEscaped(out, slice);
                    try out.appendSlice(gpa, "</span>");
                    break :i;
                }

                if (std.zig.primitives.isPrimitive(slice)) {
                    try out.appendSlice(gpa, "<span class=\"tok-type\">");
                    try appendEscaped(out, slice);
                    try out.appendSlice(gpa, "</span>");
                    break :i;
                }

                if (file.token_parents.get(token_index)) |field_access_node| {
                    g.field_access_buffer.clearRetainingCapacity();
                    try walkFieldAccesses(file_index, &g.field_access_buffer, field_access_node);
                    if (g.field_access_buffer.items.len > 0) {
                        try out.appendSlice(gpa, "<a href=\"#");
                        _ = missing_feature_url_escape;
                        try out.appendSlice(gpa, g.field_access_buffer.items);
                        try out.appendSlice(gpa, "\">");
                        try appendEscaped(out, slice);
                        try out.appendSlice(gpa, "</a>");
                    } else {
                        try appendEscaped(out, slice);
                    }
                    break :i;
                }

                {
                    g.field_access_buffer.clearRetainingCapacity();
                    try resolveIdentLink(file_index, &g.field_access_buffer, token_index);
                    if (g.field_access_buffer.items.len > 0) {
                        try out.appendSlice(gpa, "<a href=\"#");
                        _ = missing_feature_url_escape;
                        try out.appendSlice(gpa, g.field_access_buffer.items);
                        try out.appendSlice(gpa, "\">");
                        try appendEscaped(out, slice);
                        try out.appendSlice(gpa, "</a>");
                        break :i;
                    }
                }

                try appendEscaped(out, slice);
            },

            .number_literal => {
                try out.appendSlice(gpa, "<span class=\"tok-number\">");
                try appendEscaped(out, slice);
                try out.appendSlice(gpa, "</span>");
            },

            .bang,
            .pipe,
            .pipe_pipe,
            .pipe_equal,
            .equal,
            .equal_equal,
            .equal_angle_bracket_right,
            .bang_equal,
            .l_paren,
            .r_paren,
            .semicolon,
            .percent,
            .percent_equal,
            .l_brace,
            .r_brace,
            .l_bracket,
            .r_bracket,
            .period,
            .period_asterisk,
            .ellipsis2,
            .ellipsis3,
            .caret,
            .caret_equal,
            .plus,
            .plus_plus,
            .plus_equal,
            .plus_percent,
            .plus_percent_equal,
            .plus_pipe,
            .plus_pipe_equal,
            .minus,
            .minus_equal,
            .minus_percent,
            .minus_percent_equal,
            .minus_pipe,
            .minus_pipe_equal,
            .asterisk,
            .asterisk_equal,
            .asterisk_percent,
            .asterisk_percent_equal,
            .asterisk_pipe,
            .asterisk_pipe_equal,
            .arrow,
            .colon,
            .slash,
            .slash_equal,
            .comma,
            .ampersand,
            .ampersand_equal,
            .question_mark,
            .angle_bracket_left,
            .angle_bracket_left_equal,
            .angle_bracket_angle_bracket_left,
            .angle_bracket_angle_bracket_left_equal,
            .angle_bracket_angle_bracket_left_pipe,
            .angle_bracket_angle_bracket_left_pipe_equal,
            .angle_bracket_right,
            .angle_bracket_right_equal,
            .angle_bracket_angle_bracket_right,
            .angle_bracket_angle_bracket_right_equal,
            .tilde,
            => try appendEscaped(out, slice),

            .invalid => return error.InvalidToken,
        }
    }
}