diff --git a/lib/docs/main.js b/lib/docs/main.js index a0b8001a9ea859048230a585488f294f9105cae8..28f8fb1a703194eec24a35ba54d345cf4f0c8b67 100644 --- a/lib/docs/main.js +++ b/lib/docs/main.js @@ -51,7 +51,7 @@ var zigAnalysis; const domHdrName = document.getElementById("hdrName"); const domHelpModal = document.getElementById("helpModal"); const domSearchPlaceholder = document.getElementById("searchPlaceholder"); - const sourceFileUrlTemplate = "src-viewer/{{file}}#L{{line}}" + const sourceFileUrlTemplate = "src/{{file}}#L{{line}}" const domLangRefLink = document.getElementById("langRefLink"); let lineCounter = 1; @@ -989,7 +989,7 @@ var zigAnalysis; "switch(" + cond + ") {" + - ' {}, - else => |err| return err, - }; - const html_dir = try output_dir.openDir("src-viewer", .{}); + { + output_dir.makeDir("src") catch |e| switch (e) { + error.PathAlreadyExists => {}, + else => |err| return err, + }; + const html_dir = try output_dir.openDir("src", .{}); - var files_iterator = self.files.iterator(); + var files_iterator = self.files.iterator(); - while (files_iterator.next()) |entry| { - const new_html_path = entry.key_ptr.*.sub_file_path; + while (files_iterator.next()) |entry| { + const new_html_path = entry.key_ptr.*.sub_file_path; - const html_file = try createFromPath(html_dir, new_html_path); - defer html_file.close(); - var buffer = std.io.bufferedWriter(html_file.writer()); + const html_file = try createFromPath(html_dir, new_html_path); + defer html_file.close(); + var buffer = std.io.bufferedWriter(html_file.writer()); - const out = buffer.writer(); + const out = buffer.writer(); - try Docgen.genHtml(self.module.gpa, entry.key_ptr.*, out); - try buffer.flush(); + try Docgen.genHtml(self.module.gpa, entry.key_ptr.*, out); + try buffer.flush(); + } } // copy main.js, index.html diff --git a/src/Docgen.zig b/src/Docgen.zig deleted file mode 100644 index 1edb551ed9756c6ebc3066aa7fdf5435c4e42eb8..0000000000000000000000000000000000000000 --- a/src/Docgen.zig +++ /dev/null @@ -1,425 +0,0 @@ -const std = @import("std"); -const builtin = @import("builtin"); -const io = std.io; -const fs = std.fs; -const process = std.process; -const ChildProcess = std.ChildProcess; -const Progress = std.Progress; -const print = std.debug.print; -const mem = std.mem; -const testing = std.testing; -const Allocator = std.mem.Allocator; -const Module = @import("Module.zig"); - -pub fn genHtml( - allocator: Allocator, - src: *Module.File, - out: anytype, -) !void { - try out.writeAll( - \\ - \\ - \\ - \\ - \\ - ); - try out.print(" {s} - source view\n", .{src.sub_file_path}); - try out.writeAll( - \\ - \\ - \\ - \\ - \\ - ); - - const source = try src.getSource(allocator); - try tokenizeAndPrintRaw(allocator, out, source.bytes); - try out.writeAll( - \\ - \\ - ); -} - -const start_line = ""; -const end_line = "\n"; - -var line_counter: usize = 1; - -pub fn tokenizeAndPrintRaw( - allocator: Allocator, - out: anytype, - raw_src: [:0]const u8, -) !void { - const src = try allocator.dupeZ(u8, raw_src); - defer allocator.free(src); - - line_counter = 1; - - try out.print("
" ++ start_line, .{line_counter});
-    var tokenizer = std.zig.Tokenizer.init(src);
-    var index: usize = 0;
-    var next_tok_is_fn = false;
-    while (true) {
-        const prev_tok_was_fn = next_tok_is_fn;
-        next_tok_is_fn = false;
-
-        const token = tokenizer.next();
-        if (mem.indexOf(u8, src[index..token.loc.start], "//")) |comment_start_off| {
-            // render one comment
-            const comment_start = index + comment_start_off;
-            const comment_end_off = mem.indexOf(u8, src[comment_start..token.loc.start], "\n");
-            const comment_end = if (comment_end_off) |o| comment_start + o else token.loc.start;
-
-            try writeEscapedLines(out, src[index..comment_start]);
-            try out.writeAll("");
-            try writeEscaped(out, src[comment_start..comment_end]);
-            try out.writeAll("\n");
-            index = comment_end;
-            tokenizer.index = index;
-            continue;
-        }
-
-        try writeEscapedLines(out, src[index..token.loc.start]);
-        switch (token.tag) {
-            .eof => break,
-
-            .keyword_addrspace,
-            .keyword_align,
-            .keyword_and,
-            .keyword_asm,
-            .keyword_async,
-            .keyword_await,
-            .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_usingnamespace,
-            .keyword_var,
-            .keyword_volatile,
-            .keyword_allowzero,
-            .keyword_while,
-            .keyword_anytype,
-            => {
-                try out.writeAll("");
-                try writeEscaped(out, src[token.loc.start..token.loc.end]);
-                try out.writeAll("");
-            },
-
-            .keyword_fn => {
-                try out.writeAll("");
-                try writeEscaped(out, src[token.loc.start..token.loc.end]);
-                try out.writeAll("");
-                next_tok_is_fn = true;
-            },
-
-            .string_literal,
-            .char_literal,
-            => {
-                try out.writeAll("");
-                try writeEscaped(out, src[token.loc.start..token.loc.end]);
-                try out.writeAll("");
-            },
-
-            .multiline_string_literal_line => {
-                if (src[token.loc.end - 1] == '\n') {
-                    try out.writeAll("");
-                    try writeEscaped(out, src[token.loc.start .. token.loc.end - 1]);
-                    line_counter += 1;
-                    try out.print("" ++ end_line ++ "\n" ++ start_line, .{line_counter});
-                } else {
-                    try out.writeAll("");
-                    try writeEscaped(out, src[token.loc.start..token.loc.end]);
-                    try out.writeAll("");
-                }
-            },
-
-            .builtin => {
-                try out.writeAll("");
-                try writeEscaped(out, src[token.loc.start..token.loc.end]);
-                try out.writeAll("");
-            },
-
-            .doc_comment,
-            .container_doc_comment,
-            => {
-                try out.writeAll("");
-                try writeEscaped(out, src[token.loc.start..token.loc.end]);
-                try out.writeAll("");
-            },
-
-            .identifier => {
-                const tok_bytes = src[token.loc.start..token.loc.end];
-                if (mem.eql(u8, tok_bytes, "undefined") or
-                    mem.eql(u8, tok_bytes, "null") or
-                    mem.eql(u8, tok_bytes, "true") or
-                    mem.eql(u8, tok_bytes, "false"))
-                {
-                    try out.writeAll("");
-                    try writeEscaped(out, tok_bytes);
-                    try out.writeAll("");
-                } else if (prev_tok_was_fn) {
-                    try out.writeAll("");
-                    try writeEscaped(out, tok_bytes);
-                    try out.writeAll("");
-                } else {
-                    const is_int = blk: {
-                        if (src[token.loc.start] != 'i' and src[token.loc.start] != 'u')
-                            break :blk false;
-                        var i = token.loc.start + 1;
-                        if (i == token.loc.end)
-                            break :blk false;
-                        while (i != token.loc.end) : (i += 1) {
-                            if (src[i] < '0' or src[i] > '9')
-                                break :blk false;
-                        }
-                        break :blk true;
-                    };
-                    if (is_int or isType(tok_bytes)) {
-                        try out.writeAll("");
-                        try writeEscaped(out, tok_bytes);
-                        try out.writeAll("");
-                    } else {
-                        try writeEscaped(out, tok_bytes);
-                    }
-                }
-            },
-
-            .integer_literal,
-            .float_literal,
-            => {
-                try out.writeAll("");
-                try writeEscaped(out, src[token.loc.start..token.loc.end]);
-                try out.writeAll("");
-            },
-
-            .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_asterisk,
-            .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 writeEscaped(out, src[token.loc.start..token.loc.end]),
-
-            .invalid, .invalid_periodasterisks => return error.ParseError,
-        }
-        index = token.loc.end;
-    }
-    try out.writeAll(end_line ++ "
"); -} - -fn writeEscapedLines(out: anytype, text: []const u8) !void { - for (text) |char| { - if (char == '\n') { - try out.writeAll(end_line); - line_counter += 1; - try out.print(start_line, .{line_counter}); - } else { - try writeEscaped(out, &[_]u8{char}); - } - } -} - -fn writeEscaped(out: anytype, input: []const u8) !void { - for (input) |c| { - try switch (c) { - '&' => out.writeAll("&"), - '<' => out.writeAll("<"), - '>' => out.writeAll(">"), - '"' => out.writeAll("""), - else => out.writeByte(c), - }; - } -} - -const builtin_types = [_][]const u8{ - "f16", "f32", "f64", "f128", "c_longdouble", "c_short", - "c_ushort", "c_int", "c_uint", "c_long", "c_ulong", "c_longlong", - "c_ulonglong", "c_char", "anyopaque", "void", "bool", "isize", - "usize", "noreturn", "type", "anyerror", "comptime_int", "comptime_float", -}; - -fn isType(name: []const u8) bool { - for (builtin_types) |t| { - if (mem.eql(u8, t, name)) - return true; - } - return false; -} diff --git a/src/autodoc/render_source.zig b/src/autodoc/render_source.zig new file mode 100644 index 0000000000000000000000000000000000000000..cafed8d5265c509a3056d54bfa9556cf7efce0ce --- /dev/null +++ b/src/autodoc/render_source.zig @@ -0,0 +1,424 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const io = std.io; +const fs = std.fs; +const process = std.process; +const ChildProcess = std.ChildProcess; +const Progress = std.Progress; +const print = std.debug.print; +const mem = std.mem; +const testing = std.testing; +const Allocator = std.mem.Allocator; +const Module = @import("../Module.zig"); + +pub fn genHtml( + allocator: Allocator, + src: *Module.File, + out: anytype, +) !void { + try out.writeAll( + \\ + \\ + \\ + \\ + \\ + ); + try out.print(" {s} - source view\n", .{src.sub_file_path}); + try out.writeAll( + \\ + \\ + \\ + \\ + \\ + ); + + const source = try src.getSource(allocator); + try tokenizeAndPrintRaw(allocator, out, source.bytes); + try out.writeAll( + \\ + \\ + ); +} + +const start_line = ""; +const end_line = "\n"; + +var line_counter: usize = 1; + +pub fn tokenizeAndPrintRaw( + allocator: Allocator, + out: anytype, + raw_src: [:0]const u8, +) !void { + const src = try allocator.dupeZ(u8, raw_src); + defer allocator.free(src); + + line_counter = 1; + + try out.print("
" ++ start_line, .{line_counter});
+    var tokenizer = std.zig.Tokenizer.init(src);
+    var index: usize = 0;
+    var next_tok_is_fn = false;
+    while (true) {
+        const prev_tok_was_fn = next_tok_is_fn;
+        next_tok_is_fn = false;
+
+        const token = tokenizer.next();
+        if (mem.indexOf(u8, src[index..token.loc.start], "//")) |comment_start_off| {
+            // render one comment
+            const comment_start = index + comment_start_off;
+            const comment_end_off = mem.indexOf(u8, src[comment_start..token.loc.start], "\n");
+            const comment_end = if (comment_end_off) |o| comment_start + o else token.loc.start;
+
+            try writeEscapedLines(out, src[index..comment_start]);
+            try out.writeAll("");
+            try writeEscaped(out, src[comment_start..comment_end]);
+            try out.writeAll("\n");
+            index = comment_end;
+            tokenizer.index = index;
+            continue;
+        }
+
+        try writeEscapedLines(out, src[index..token.loc.start]);
+        switch (token.tag) {
+            .eof => break,
+
+            .keyword_addrspace,
+            .keyword_align,
+            .keyword_and,
+            .keyword_asm,
+            .keyword_async,
+            .keyword_await,
+            .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_usingnamespace,
+            .keyword_var,
+            .keyword_volatile,
+            .keyword_allowzero,
+            .keyword_while,
+            .keyword_anytype,
+            => {
+                try out.writeAll("");
+                try writeEscaped(out, src[token.loc.start..token.loc.end]);
+                try out.writeAll("");
+            },
+
+            .keyword_fn => {
+                try out.writeAll("");
+                try writeEscaped(out, src[token.loc.start..token.loc.end]);
+                try out.writeAll("");
+                next_tok_is_fn = true;
+            },
+
+            .string_literal,
+            .char_literal,
+            => {
+                try out.writeAll("");
+                try writeEscaped(out, src[token.loc.start..token.loc.end]);
+                try out.writeAll("");
+            },
+
+            .multiline_string_literal_line => {
+                if (src[token.loc.end - 1] == '\n') {
+                    try out.writeAll("");
+                    try writeEscaped(out, src[token.loc.start .. token.loc.end - 1]);
+                    line_counter += 1;
+                    try out.print("" ++ end_line ++ "\n" ++ start_line, .{line_counter});
+                } else {
+                    try out.writeAll("");
+                    try writeEscaped(out, src[token.loc.start..token.loc.end]);
+                    try out.writeAll("");
+                }
+            },
+
+            .builtin => {
+                try out.writeAll("");
+                try writeEscaped(out, src[token.loc.start..token.loc.end]);
+                try out.writeAll("");
+            },
+
+            .doc_comment,
+            .container_doc_comment,
+            => {
+                try out.writeAll("");
+                try writeEscaped(out, src[token.loc.start..token.loc.end]);
+                try out.writeAll("");
+            },
+
+            .identifier => {
+                const tok_bytes = src[token.loc.start..token.loc.end];
+                if (mem.eql(u8, tok_bytes, "undefined") or
+                    mem.eql(u8, tok_bytes, "null") or
+                    mem.eql(u8, tok_bytes, "true") or
+                    mem.eql(u8, tok_bytes, "false"))
+                {
+                    try out.writeAll("");
+                    try writeEscaped(out, tok_bytes);
+                    try out.writeAll("");
+                } else if (prev_tok_was_fn) {
+                    try out.writeAll("");
+                    try writeEscaped(out, tok_bytes);
+                    try out.writeAll("");
+                } else {
+                    const is_int = blk: {
+                        if (src[token.loc.start] != 'i' and src[token.loc.start] != 'u')
+                            break :blk false;
+                        var i = token.loc.start + 1;
+                        if (i == token.loc.end)
+                            break :blk false;
+                        while (i != token.loc.end) : (i += 1) {
+                            if (src[i] < '0' or src[i] > '9')
+                                break :blk false;
+                        }
+                        break :blk true;
+                    };
+                    if (is_int or isType(tok_bytes)) {
+                        try out.writeAll("");
+                        try writeEscaped(out, tok_bytes);
+                        try out.writeAll("");
+                    } else {
+                        try writeEscaped(out, tok_bytes);
+                    }
+                }
+            },
+
+            .integer_literal,
+            .float_literal,
+            => {
+                try out.writeAll("");
+                try writeEscaped(out, src[token.loc.start..token.loc.end]);
+                try out.writeAll("");
+            },
+
+            .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_asterisk,
+            .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 writeEscaped(out, src[token.loc.start..token.loc.end]),
+
+            .invalid, .invalid_periodasterisks => return error.ParseError,
+        }
+        index = token.loc.end;
+    }
+    try out.writeAll(end_line ++ "
"); +} + +fn writeEscapedLines(out: anytype, text: []const u8) !void { + for (text) |char| { + if (char == '\n') { + try out.writeAll(end_line); + line_counter += 1; + try out.print(start_line, .{line_counter}); + } else { + try writeEscaped(out, &[_]u8{char}); + } + } +} + +fn writeEscaped(out: anytype, input: []const u8) !void { + for (input) |c| { + try switch (c) { + '&' => out.writeAll("&"), + '<' => out.writeAll("<"), + '>' => out.writeAll(">"), + '"' => out.writeAll("""), + else => out.writeByte(c), + }; + } +} + +const builtin_types = [_][]const u8{ + "f16", "f32", "f64", "f128", "c_longdouble", "c_short", + "c_ushort", "c_int", "c_uint", "c_long", "c_ulong", "c_longlong", + "c_ulonglong", "c_char", "anyopaque", "void", "bool", "isize", + "usize", "noreturn", "type", "anyerror", "comptime_int", "comptime_float", +}; + +fn isType(name: []const u8) bool { + for (builtin_types) |t| { + if (mem.eql(u8, t, name)) + return true; + } + return false; +}