diff --git a/README.md b/README.md index 3e82d53..132def8 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ## REQUIREMENTS: -- zig 0.13.0 +- zig 0.14.0 ## HOW TO EDIT WITH LIVE-PREVIEW & COMMIT DOCS diff --git a/assets/main.wasm b/assets/main.wasm deleted file mode 100644 index c97f31c..0000000 Binary files a/assets/main.wasm and /dev/null differ diff --git a/assets/zml_api.js b/assets/zml_api.js index 7c5cabb..64e56f0 100644 --- a/assets/zml_api.js +++ b/assets/zml_api.js @@ -983,3 +983,4 @@ wasmArray.set(jsArray); } })(); + diff --git a/build.zig b/build.zig index f01cc38..458835b 100644 --- a/build.zig +++ b/build.zig @@ -7,6 +7,11 @@ pub fn build(b: *std.Build) !void { // the zine dev server needs this option!!! const opt_debug = b.option(bool, "debug", "zine debug, unused") orelse true; + const include_drafts = b.option( + bool, + "include-drafts", + "Include drafts in zine output", + ) orelse false; const pcre2_dep = b.dependency("pcre2", .{ .target = target, @@ -15,7 +20,7 @@ pub fn build(b: *std.Build) !void { }); const docs_wasm = try buildDocsWasm(b, optimize); - const website_step, const serve_step = try buildWebSite(b, docs_wasm, opt_debug); + const website_step, const serve_step = try buildWebSite(b, docs_wasm, opt_debug, include_drafts); // has to be run with zig build website _ = website_step; // has to be run with zig build serve @@ -54,7 +59,7 @@ fn buildDocsWasm(b: *std.Build, optimize: std.builtin.OptimizeMode) !*std.Build. return docs_wasm; } -fn buildWebSite(b: *std.Build, docs_wasm: *std.Build.Step.Compile, debug: bool) !struct { +fn buildWebSite(b: *std.Build, docs_wasm: *std.Build.Step.Compile, debug: bool, include_drafts: bool) !struct { *std.Build.Step, *std.Build.Step, } { @@ -107,7 +112,7 @@ fn buildWebSite(b: *std.Build, docs_wasm: *std.Build.Step.Compile, debug: bool) "website", "Builds the website", ); - zine.addWebsite(b, opts, website_step, site); + zine.addWebsite(b, opts, website_step, site, include_drafts); const serve_step = b.step( "serve", diff --git a/build.zig.zon b/build.zig.zon index 57541de..43d978f 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -8,15 +8,12 @@ // .hash = "1220a59c2cf0e42a6f42cf1bf9b6a6c2691abfd91fcafa0e81a6282c4a197d05c41a", // modified zine - .url = "git+https://github.com/renerocksai/zine#170567737efc5333b38886cfe83211e011267b24", - .hash = "1220ec97928f9e1f1a95ff8c39a943cf6ebab2ff2e6acb1900aeb7844f906b1ce3aa", - - // rene local dev - // .path = "../../renerocksai/zine", + .url = "https://github.com/renerocksai/zine/archive/refs/tags/zig-0.14.0.tar.gz", + .hash = "1220dfe5a9352fc7c9c16b07c5c6d7417fc96ee92dbab5f27b8d4d02400ba5a9f88c", }, .pcre2 = .{ - .url = "https://github.com/renerocksai/pcre2/archive/refs/tags/pcre2-10.45.tar.gz", - .hash = "12207d56c8b27a141c793fc596af11e6eca919efbbcf49b04f7803c603e2f6081b1b", + .url = "https://github.com/renerocksai/pcre2/archive/refs/tags/zig-0.14.tar.gz", + .hash = "12202a2e5043bd8641208b0eb597bc0346fd94fdec5b1ae92ee0096e83d6ff33fc45", }, }, .paths = .{"."}, diff --git a/zig_docs/Decl.zig b/zig_docs/Decl.zig index 4f0d2c3..2546355 100644 --- a/zig_docs/Decl.zig +++ b/zig_docs/Decl.zig @@ -12,9 +12,6 @@ file: Walk.File.Index, /// The decl whose namespace this is in. parent: Index, -/// Delete this to find out where URL escaping needs to be added. -const missing_feature_url_escape = true; - pub const ExtraInfo = struct { is_pub: bool, name: []const u8, @@ -160,16 +157,6 @@ pub fn fqn(decl: *const Decl, out: *std.ArrayListUnmanaged(u8)) Oom!void { } } -threadlocal var _fqn_buf: [1024]u8 = undefined; - -pub fn fqnAsHref(decl: *const Decl, allocator: std.mem.Allocator, out: *std.ArrayListUnmanaged(u8)) Oom!void { - var _fqn = std.ArrayListUnmanaged(u8).fromOwnedSlice(&_fqn_buf); - _fqn.items.len = 0; - try decl.fqn(&_fqn); - - try renderHref(out.writer(allocator), _fqn.items); -} - pub fn reset_with_path(decl: *const Decl, list: *std.ArrayListUnmanaged(u8)) Oom!void { list.clearRetainingCapacity(); try append_path(decl, list); @@ -237,26 +224,3 @@ pub fn find(search_string: []const u8) Decl.Index { } return current_decl_index; } - -/// Replace a fully qualified name from Zig std symbol by an external link. -/// fqn is not allowed to alias to out. -pub fn renderHref(writer: anytype, noalias name: []const u8) !void { - std.log.debug("checking fqn: \"{s}\"", .{name}); - - const std_module = std.mem.indexOf(u8, name, ".std."); - const std_root = if (std.mem.endsWith(u8, name, ".std")) name.len - 4 else null; - - if (std_module orelse std_root) |std_dot_start| { - const std_href = " href=\"https://ziglang.org/documentation/0.13.0/std/#"; - try writer.writeAll(std_href); - _ = missing_feature_url_escape; - try writer.writeAll(name[std_dot_start + 1 ..]); - try writer.writeByte('"'); - std.log.debug("replaced name: \"{s}\" -> {s}{s}", .{ name, std_href, name }); - } else { - try writer.writeAll(" href=\"#"); - _ = missing_feature_url_escape; - try writer.writeAll(name); - try writer.writeByte('"'); - } -} diff --git a/zig_docs/Walk.zig b/zig_docs/Walk.zig index ae924b8..49a5e73 100644 --- a/zig_docs/Walk.zig +++ b/zig_docs/Walk.zig @@ -10,9 +10,9 @@ const Oom = error{OutOfMemory}; pub const Decl = @import("Decl.zig"); -pub var files: std.StringArrayHashMapUnmanaged(File) = .{}; -pub var decls: std.ArrayListUnmanaged(Decl) = .{}; -pub var modules: std.StringArrayHashMapUnmanaged(File.Index) = .{}; +pub var files: std.StringArrayHashMapUnmanaged(File) = .empty; +pub var decls: std.ArrayListUnmanaged(Decl) = .empty; +pub var modules: std.StringArrayHashMapUnmanaged(File.Index) = .empty; file: File.Index, @@ -36,23 +36,23 @@ pub const Category = union(enum(u8)) { /// A function that returns a type. type_function: Ast.Node.Index, - pub const Tag = @typeInfo(Category).Union.tag_type.?; + pub const Tag = @typeInfo(Category).@"union".tag_type.?; }; pub const File = struct { ast: Ast, /// Maps identifiers to the declarations they point to. - ident_decls: std.AutoArrayHashMapUnmanaged(Ast.TokenIndex, Ast.Node.Index) = .{}, + ident_decls: std.AutoArrayHashMapUnmanaged(Ast.TokenIndex, Ast.Node.Index) = .empty, /// Maps field access identifiers to the containing field access node. - token_parents: std.AutoArrayHashMapUnmanaged(Ast.TokenIndex, Ast.Node.Index) = .{}, + token_parents: std.AutoArrayHashMapUnmanaged(Ast.TokenIndex, Ast.Node.Index) = .empty, /// Maps declarations to their global index. - node_decls: std.AutoArrayHashMapUnmanaged(Ast.Node.Index, Decl.Index) = .{}, + node_decls: std.AutoArrayHashMapUnmanaged(Ast.Node.Index, Decl.Index) = .empty, /// Maps function declarations to doctests. - doctests: std.AutoArrayHashMapUnmanaged(Ast.Node.Index, Ast.Node.Index) = .{}, + doctests: std.AutoArrayHashMapUnmanaged(Ast.Node.Index, Ast.Node.Index) = .empty, /// root node => its namespace scope /// struct/union/enum/opaque decl node => its namespace scope /// local var decl node => its local variable scope - scopes: std.AutoArrayHashMapUnmanaged(Ast.Node.Index, *Scope) = .{}, + scopes: std.AutoArrayHashMapUnmanaged(Ast.Node.Index, *Scope) = .empty, pub fn lookup_token(file: *File, token: Ast.TokenIndex) Decl.Index { const decl_node = file.ident_decls.get(token) orelse return .none; @@ -464,8 +464,8 @@ pub const Scope = struct { const Namespace = struct { base: Scope = .{ .tag = .namespace }, parent: *Scope, - names: std.StringArrayHashMapUnmanaged(Ast.Node.Index) = .{}, - doctests: std.StringArrayHashMapUnmanaged(Ast.Node.Index) = .{}, + names: std.StringArrayHashMapUnmanaged(Ast.Node.Index) = .empty, + doctests: std.StringArrayHashMapUnmanaged(Ast.Node.Index) = .empty, decl_index: Decl.Index, }; diff --git a/zig_docs/html_render.zig b/zig_docs/html_render.zig index 684452e..d9cb74f 100644 --- a/zig_docs/html_render.zig +++ b/zig_docs/html_render.zig @@ -8,11 +8,24 @@ const Decl = Walk.Decl; const gpa = std.heap.wasm_allocator; const Oom = error{OutOfMemory}; +/// Delete this to find out where URL escaping needs to be added. +pub const missing_feature_url_escape = true; + pub const RenderSourceOptions = struct { skip_doc_comments: bool = false, skip_comments: bool = false, collapse_whitespace: bool = false, fn_link: Decl.Index = .none, + /// Assumed to be sorted ascending. + source_location_annotations: []const Annotation = &.{}, + /// Concatenated with dom_id. + annotation_prefix: []const u8 = "l", +}; + +pub const Annotation = struct { + file_byte_offset: u32, + /// Concatenated with annotation_prefix. + dom_id: u32, }; pub fn fileSourceHtml( @@ -25,7 +38,7 @@ pub fn fileSourceHtml( const file = file_index.get(); const g = struct { - var field_access_buffer: std.ArrayListUnmanaged(u8) = .{}; + var field_access_buffer: std.ArrayListUnmanaged(u8) = .empty; }; const token_tags = ast.tokens.items(.tag); @@ -48,6 +61,8 @@ pub fn fileSourceHtml( } } + var next_annotate_index: usize = 0; + for ( token_tags[start_token..end_token], token_starts[start_token..end_token], @@ -71,6 +86,18 @@ pub fn fileSourceHtml( 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.writer(gpa).print("", .{ + options.annotation_prefix, next_annotation.dom_id, + }); + next_annotate_index += 1; + } + switch (tag) { .eof => unreachable, @@ -159,8 +186,9 @@ pub fn fileSourceHtml( const fn_link = options.fn_link.get(); const fn_token = main_tokens[fn_link.ast_node]; if (token_index == fn_token + 1) { - try out.appendSlice(gpa, ""); try appendEscaped(out, slice); try out.appendSlice(gpa, ""); @@ -193,9 +221,10 @@ pub fn fileSourceHtml( 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, ""); + try out.appendSlice(gpa, ""); try appendEscaped(out, slice); try out.appendSlice(gpa, ""); } else { @@ -208,9 +237,10 @@ pub fn fileSourceHtml( 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, ""); + try out.appendSlice(gpa, ""); try appendEscaped(out, slice); try out.appendSlice(gpa, ""); break :i; diff --git a/zig_docs/main.zig b/zig_docs/main.zig index 3e0d19b..0ec2227 100644 --- a/zig_docs/main.zig +++ b/zig_docs/main.zig @@ -9,7 +9,7 @@ const Decl = Walk.Decl; const fileSourceHtml = @import("html_render.zig").fileSourceHtml; const appendEscaped = @import("html_render.zig").appendEscaped; const resolveDeclLink = @import("html_render.zig").resolveDeclLink; -const renderHref = Decl.renderHref; +const missing_feature_url_escape = @import("html_render.zig").missing_feature_url_escape; const gpa = std.heap.wasm_allocator; @@ -60,8 +60,8 @@ export fn unpack(tar_ptr: [*]u8, tar_len: usize) void { }; } -var query_string: std.ArrayListUnmanaged(u8) = .{}; -var query_results: std.ArrayListUnmanaged(Decl.Index) = .{}; +var query_string: std.ArrayListUnmanaged(u8) = .empty; +var query_results: std.ArrayListUnmanaged(Decl.Index) = .empty; /// Resizes the query string to be the correct length; returns the pointer to /// the query string. @@ -93,11 +93,11 @@ fn query_exec_fallible(query: []const u8, ignore_case: bool) !void { segments: u16, }; const g = struct { - var full_path_search_text: std.ArrayListUnmanaged(u8) = .{}; - var full_path_search_text_lower: std.ArrayListUnmanaged(u8) = .{}; - var doc_search_text: std.ArrayListUnmanaged(u8) = .{}; + var full_path_search_text: std.ArrayListUnmanaged(u8) = .empty; + var full_path_search_text_lower: std.ArrayListUnmanaged(u8) = .empty; + var doc_search_text: std.ArrayListUnmanaged(u8) = .empty; /// Each element matches a corresponding query_results element. - var scores: std.ArrayListUnmanaged(Score) = .{}; + var scores: std.ArrayListUnmanaged(Score) = .empty; }; // First element stores the size of the list. @@ -238,8 +238,9 @@ const ErrorIdentifier = packed struct(u64) { try out.appendSlice(gpa, "