mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 06:15:21 +00:00
autodoc: init support for guides
This commit is contained in:
parent
5d46addd25
commit
af820bbb94
@ -117,6 +117,48 @@
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.sidebar ul.guides-api-switch {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.sidebar .guides-api-switch a {
|
||||
display: block;
|
||||
padding: 0.5rem 1rem;
|
||||
color: var(--sidebar-pkglnk-tx-color);
|
||||
background-color: var(--sidebar-pkglnk-bg-color);
|
||||
border: 1px solid var(--tx-color);
|
||||
}
|
||||
|
||||
|
||||
#ApiSwitch {
|
||||
border-radius: 10px 0 0 10px;
|
||||
}
|
||||
|
||||
#guideSwitch {
|
||||
border-radius: 0 10px 10px 0;
|
||||
}
|
||||
|
||||
|
||||
#ApiSwitch:hover, #guideSwitch:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#ApiSwitch:hover:not(.active), #guideSwitch:hover:not(.active) {
|
||||
color: var(--sidebar-pkglnk-tx-color-hover);
|
||||
background-color: var(--sidebar-pkglnk-bg-color-hover);
|
||||
}
|
||||
|
||||
.sidebar .guides-api-switch .active {
|
||||
color: var(--sidebar-pkglnk-tx-color-active);
|
||||
background-color: var(--sidebar-pkglnk-bg-color-active);
|
||||
}
|
||||
|
||||
.sidebar h2 {
|
||||
margin: 0.5rem;
|
||||
padding: 0;
|
||||
@ -157,6 +199,14 @@
|
||||
font-family: var(--mono);
|
||||
}
|
||||
|
||||
#guides {
|
||||
padding: 1rem 0.7rem 2.4rem 1.4rem;
|
||||
box-sizing: border-box;
|
||||
font-size: 1rem;
|
||||
background-color: var(--bg-color);
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
/* docs section */
|
||||
.docs {
|
||||
padding: 1rem 0.7rem 2.4rem 1.4rem;
|
||||
@ -643,28 +693,42 @@
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
<div id="sectMainPkg" class="hidden">
|
||||
<h2><span>Main Package</span></h2>
|
||||
<ul class="packages">
|
||||
<li><a id="mainPkg" class="" href=""></a></li>
|
||||
<div id="sectGudeApiSwitch">
|
||||
<ul class="guides-api-switch">
|
||||
<li><a id="ApiSwitch" class="active" href="#A;">API</a></li>
|
||||
<li><a id="guideSwitch" class="" href="#G;">Guides</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="sectPkgs" class="hidden">
|
||||
<h2><span>Dependencies</span></h2>
|
||||
<ul id="listPkgs" class="packages"></ul>
|
||||
<div id="guidesMenu" class="hidden">
|
||||
<h2><span>Guide List</span></h2>
|
||||
<ul id="guidesList" class="packages"></ul>
|
||||
</div>
|
||||
<div id="sectInfo" class="hidden">
|
||||
<h2><span>Zig Version</span></h2>
|
||||
<p class="str" id="tdZigVer"></p>
|
||||
</div>
|
||||
<div>
|
||||
<input id="privDeclsBox" type="checkbox"/>
|
||||
<label for="privDeclsBox">Internal Doc Mode</label>
|
||||
<div id="apiMenu" class="hidden">
|
||||
<div id="sectMainPkg" class="hidden">
|
||||
<h2><span>Main Package</span></h2>
|
||||
<ul class="packages">
|
||||
<li><a id="mainPkg" class="" href=""></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="sectPkgs" class="hidden">
|
||||
<h2><span>Dependencies</span></h2>
|
||||
<ul id="listPkgs" class="packages"></ul>
|
||||
</div>
|
||||
<div id="sectInfo" class="hidden">
|
||||
<h2><span>Zig Version</span></h2>
|
||||
<p class="str" id="tdZigVer"></p>
|
||||
</div>
|
||||
<div>
|
||||
<input id="privDeclsBox" type="checkbox"/>
|
||||
<label for="privDeclsBox">Internal Doc Mode</label>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
<div id="docs" class="flex-right">
|
||||
<div class="wrap">
|
||||
<div class="flex-right">
|
||||
<div id="guides" class="wrap hidden">
|
||||
</div>
|
||||
<div id="docs" class="wrap hidden">
|
||||
<section class="docs">
|
||||
<div style="position: relative">
|
||||
<span id="searchPlaceholder"><kbd>s</kbd> to search, <kbd>?</kbd> for more options</span>
|
||||
|
||||
224
lib/docs/main.js
224
lib/docs/main.js
@ -2,10 +2,21 @@
|
||||
|
||||
var zigAnalysis;
|
||||
|
||||
const NAV_MODES = {
|
||||
API: "#A;",
|
||||
API_INTERNAL: "#a;",
|
||||
GUIDES: "#G;",
|
||||
};
|
||||
|
||||
(function () {
|
||||
const domStatus = document.getElementById("status");
|
||||
const domSectNav = document.getElementById("sectNav");
|
||||
const domListNav = document.getElementById("listNav");
|
||||
const domApiSwitch = document.getElementById("ApiSwitch");
|
||||
const domGuideSwitch = document.getElementById("guideSwitch");
|
||||
const domGuidesMenu = document.getElementById("guidesMenu");
|
||||
const domApiMenu = document.getElementById("apiMenu");
|
||||
const domGuidesList = document.getElementById("guidesList");
|
||||
const domSectMainPkg = document.getElementById("sectMainPkg");
|
||||
const domSectPkgs = document.getElementById("sectPkgs");
|
||||
const domListPkgs = document.getElementById("listPkgs");
|
||||
@ -45,6 +56,7 @@ var zigAnalysis;
|
||||
const domSectSearchResults = document.getElementById("sectSearchResults");
|
||||
const domSectSearchAllResultsLink = document.getElementById("sectSearchAllResultsLink");
|
||||
const domDocs = document.getElementById("docs");
|
||||
const domGuides = document.getElementById("guides");
|
||||
const domListSearchResults = document.getElementById("listSearchResults");
|
||||
const domSectSearchNoResults = document.getElementById("sectSearchNoResults");
|
||||
const domSectInfo = document.getElementById("sectInfo");
|
||||
@ -83,7 +95,8 @@ var zigAnalysis;
|
||||
let canonTypeDecls = null; // lazy; use getCanonTypeDecl
|
||||
|
||||
let curNav = {
|
||||
showPrivDecls: false,
|
||||
mode: NAV_MODES.API,
|
||||
activeGuide: "",
|
||||
// each element is a package name, e.g. @import("a") then within there @import("b")
|
||||
// starting implicitly from root package
|
||||
pkgNames: [],
|
||||
@ -152,7 +165,7 @@ var zigAnalysis;
|
||||
);
|
||||
|
||||
if (location.hash == "") {
|
||||
location.hash = "#root";
|
||||
location.hash = "#A;";
|
||||
}
|
||||
|
||||
// make the modal disappear if you click outside it
|
||||
@ -173,17 +186,21 @@ var zigAnalysis;
|
||||
domLangRefLink.href = `https://ziglang.org/documentation/${langRefVersion}/`;
|
||||
|
||||
function renderTitle() {
|
||||
let list = curNav.pkgNames.concat(curNav.declNames);
|
||||
let suffix = " - Zig";
|
||||
if (list.length === 0) {
|
||||
if (rootIsStd) {
|
||||
document.title = "std" + suffix;
|
||||
} else {
|
||||
document.title = zigAnalysis.params.rootName + suffix;
|
||||
}
|
||||
} else {
|
||||
document.title = list.join(".") + suffix;
|
||||
}
|
||||
switch (curNav.mode) {
|
||||
case NAV_MODES.API:
|
||||
case NAV_MODES.API_INTERNAL:
|
||||
let list = curNav.pkgNames.concat(curNav.declNames);
|
||||
if (list.length === 0) {
|
||||
document.title = zigAnalysis.packages[zigAnalysis.rootPkg].name + suffix;
|
||||
} else {
|
||||
document.title = list.join(".") + suffix;
|
||||
}
|
||||
return;
|
||||
case NAV_MODES.GUIDES:
|
||||
document.title = "[G] " + curNav.activeGuide + suffix;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
function isDecl(x) {
|
||||
@ -377,8 +394,80 @@ var zigAnalysis;
|
||||
// console.assert(false);
|
||||
// return ({});
|
||||
// }
|
||||
function renderGuides() {
|
||||
renderTitle();
|
||||
|
||||
function render() {
|
||||
// set guide mode
|
||||
domGuideSwitch.classList.add("active");
|
||||
domApiSwitch.classList.remove("active");
|
||||
domDocs.classList.add("hidden");
|
||||
domGuides.classList.remove("hidden");
|
||||
domApiMenu.classList.add("hidden");
|
||||
|
||||
// sidebar guides list
|
||||
const list = Object.keys(zigAnalysis.guides);
|
||||
resizeDomList(domGuidesList, list.length, '<li><a href="#"></a></li>');
|
||||
for (let i = 0; i < list.length; i += 1) {
|
||||
let liDom = domGuidesList.children[i];
|
||||
let aDom = liDom.children[0];
|
||||
aDom.textContent = list[i];
|
||||
aDom.setAttribute("href", NAV_MODES.GUIDES + list[i]);
|
||||
if (list[i] === curNav.activeGuide) {
|
||||
aDom.classList.add("active");
|
||||
} else {
|
||||
aDom.classList.remove("active");
|
||||
}
|
||||
}
|
||||
|
||||
if (list.length > 0) {
|
||||
domGuidesMenu.classList.remove("hidden");
|
||||
}
|
||||
|
||||
// main content
|
||||
const activeGuide = zigAnalysis.guides[curNav.activeGuide];
|
||||
if (activeGuide == undefined) {
|
||||
const root_file_idx = zigAnalysis.packages[zigAnalysis.rootPkg].file;
|
||||
const root_file_name = zigAnalysis.files[root_file_idx];
|
||||
domGuides.innerHTML = markdown(`
|
||||
# Zig Guides
|
||||
These autodocs don't contain any guide.
|
||||
|
||||
While the API section is a reference guide autogenerated from Zig source code,
|
||||
guides are meant to be handwritten explanations that provide for example:
|
||||
|
||||
- how-to explanations for common use-cases
|
||||
- technical documentation
|
||||
- information about advanced usage patterns
|
||||
|
||||
You can add guides by specifying which markdown files to include
|
||||
in the top level doc comment of your root file, like so:
|
||||
|
||||
(At the top of \`${root_file_name}\`)
|
||||
\`\`\`
|
||||
//!zig-autodoc-guide: intro.md
|
||||
//!zig-autodoc-guide: quickstart.md
|
||||
//!zig-autodoc-guide: ../advanced-docs/advanced-stuff.md
|
||||
\`\`\`
|
||||
|
||||
**Note that this feature is still under heavy development so expect bugs**
|
||||
**and missing features!**
|
||||
|
||||
Happy writing!
|
||||
`);
|
||||
} else {
|
||||
domGuides.innerHTML = markdown(activeGuide);
|
||||
}
|
||||
}
|
||||
|
||||
function renderApi() {
|
||||
// set Api mode
|
||||
domApiSwitch.classList.add("active");
|
||||
domGuideSwitch.classList.remove("active");
|
||||
domGuides.classList.add("hidden");
|
||||
domDocs.classList.remove("hidden");
|
||||
domApiMenu.classList.remove("hidden");
|
||||
domGuidesMenu.classList.add("hidden");
|
||||
|
||||
domStatus.classList.add("hidden");
|
||||
domFnProto.classList.add("hidden");
|
||||
domSectParams.classList.add("hidden");
|
||||
@ -411,17 +500,16 @@ var zigAnalysis;
|
||||
renderInfo();
|
||||
renderPkgList();
|
||||
|
||||
domPrivDeclsBox.checked = curNav.showPrivDecls;
|
||||
domPrivDeclsBox.checked = curNav.mode == NAV_MODES.API_INTERNAL;
|
||||
|
||||
if (curNavSearch !== "") {
|
||||
return renderSearch();
|
||||
}
|
||||
|
||||
|
||||
let rootPkg = zigAnalysis.packages[zigAnalysis.rootPkg];
|
||||
let pkg = rootPkg;
|
||||
curNav.pkgObjs = [pkg];
|
||||
for (let i = 0; i < curNav.pkgNames.length; i += 1) {
|
||||
for (let i = 1; i < curNav.pkgNames.length; i += 1) {
|
||||
let childPkg = zigAnalysis.packages[pkg.table[curNav.pkgNames[i]]];
|
||||
if (childPkg == null) {
|
||||
return render404();
|
||||
@ -494,6 +582,19 @@ var zigAnalysis;
|
||||
|
||||
}
|
||||
|
||||
function render() {
|
||||
switch (curNav.mode) {
|
||||
case NAV_MODES.API:
|
||||
case NAV_MODES.API_INTERNAL:
|
||||
return renderApi();
|
||||
case NAV_MODES.GUIDES:
|
||||
return renderGuides();
|
||||
default:
|
||||
throw "?";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function renderDocTest(decl) {
|
||||
if (!decl.decltest) return;
|
||||
const astNode = getAstNode(decl.decltest);
|
||||
@ -705,7 +806,6 @@ var zigAnalysis;
|
||||
for (let i = 0; i < curNav.pkgNames.length; i += 1) {
|
||||
hrefPkgNames.push(curNav.pkgNames[i]);
|
||||
let name = curNav.pkgNames[i];
|
||||
if (name == "root") name = zigAnalysis.rootPkgName;
|
||||
list.push({
|
||||
name: name,
|
||||
link: navLink(hrefPkgNames, hrefDeclNames),
|
||||
@ -747,12 +847,12 @@ var zigAnalysis;
|
||||
}
|
||||
|
||||
function renderPkgList() {
|
||||
let rootPkg = zigAnalysis.packages[zigAnalysis.rootPkg];
|
||||
const rootPkg = zigAnalysis.packages[zigAnalysis.rootPkg];
|
||||
let list = [];
|
||||
for (let key in rootPkg.table) {
|
||||
let pkgIndex = rootPkg.table[key];
|
||||
if (zigAnalysis.packages[pkgIndex] == null) continue;
|
||||
if (key == zigAnalysis.params.rootName) continue;
|
||||
if (key == rootPkg.name) continue;
|
||||
list.push({
|
||||
name: key,
|
||||
pkg: pkgIndex,
|
||||
@ -761,9 +861,9 @@ var zigAnalysis;
|
||||
|
||||
{
|
||||
let aDom = domSectMainPkg.children[1].children[0].children[0];
|
||||
aDom.textContent = zigAnalysis.rootPkgName;
|
||||
aDom.textContent = rootPkg.name;
|
||||
aDom.setAttribute("href", navLinkPkg(zigAnalysis.rootPkg));
|
||||
if (zigAnalysis.params.rootName === curNav.pkgNames[0]) {
|
||||
if (rootPkg.name === curNav.pkgNames[0]) {
|
||||
aDom.classList.add("active");
|
||||
} else {
|
||||
aDom.classList.remove("active");
|
||||
@ -794,20 +894,17 @@ var zigAnalysis;
|
||||
}
|
||||
|
||||
function navLink(pkgNames, declNames, callName) {
|
||||
let base = "#";
|
||||
if (curNav.showPrivDecls) {
|
||||
base += "*";
|
||||
}
|
||||
|
||||
let base = curNav.mode;
|
||||
|
||||
if (pkgNames.length === 0 && declNames.length === 0) {
|
||||
return base;
|
||||
} else if (declNames.length === 0 && callName == null) {
|
||||
return base + pkgNames.join(".");
|
||||
} else if (callName == null) {
|
||||
return base + pkgNames.join(".") + ";" + declNames.join(".");
|
||||
return base + pkgNames.join(".") + ":" + declNames.join(".");
|
||||
} else {
|
||||
return (
|
||||
base + pkgNames.join(".") + ";" + declNames.join(".") + ";" + callName
|
||||
base + pkgNames.join(".") + ":" + declNames.join(".") + ";" + callName
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -2734,9 +2831,10 @@ var zigAnalysis;
|
||||
throw new Error("No type 'type' found");
|
||||
}
|
||||
|
||||
function updateCurNav() {
|
||||
|
||||
function updateCurNav() {
|
||||
curNav = {
|
||||
showPrivDecls: false,
|
||||
mode: NAV_MODES.API,
|
||||
pkgNames: [],
|
||||
pkgObjs: [],
|
||||
declNames: [],
|
||||
@ -2745,30 +2843,54 @@ var zigAnalysis;
|
||||
};
|
||||
curNavSearch = "";
|
||||
|
||||
if (location.hash[0] === "#" && location.hash.length > 1) {
|
||||
let query = location.hash.substring(1);
|
||||
if (query[0] === "*") {
|
||||
curNav.showPrivDecls = true;
|
||||
query = query.substring(1);
|
||||
}
|
||||
const mode = location.hash.substring(0, 3);
|
||||
let query = location.hash.substring(3);
|
||||
|
||||
const DEFAULT_HASH = NAV_MODES.API + zigAnalysis.packages[zigAnalysis.rootPkg].name;
|
||||
switch (mode) {
|
||||
case NAV_MODES.API:
|
||||
case NAV_MODES.API_INTERNAL:
|
||||
// #A;PACKAGE:decl.decl.decl?search-term
|
||||
curNav.mode = mode;
|
||||
|
||||
let qpos = query.indexOf("?");
|
||||
let nonSearchPart;
|
||||
if (qpos === -1) {
|
||||
nonSearchPart = query;
|
||||
} else {
|
||||
nonSearchPart = query.substring(0, qpos);
|
||||
curNavSearch = decodeURIComponent(query.substring(qpos + 1));
|
||||
}
|
||||
let qpos = query.indexOf("?");
|
||||
let nonSearchPart;
|
||||
if (qpos === -1) {
|
||||
nonSearchPart = query;
|
||||
} else {
|
||||
nonSearchPart = query.substring(0, qpos);
|
||||
curNavSearch = decodeURIComponent(query.substring(qpos + 1));
|
||||
}
|
||||
|
||||
let parts = nonSearchPart.split(":");
|
||||
if (parts[0] == "") {
|
||||
location.hash = DEFAULT_HASH;
|
||||
} else {
|
||||
curNav.pkgNames = decodeURIComponent(parts[0]).split(".");
|
||||
}
|
||||
|
||||
let parts = nonSearchPart.split(";");
|
||||
curNav.pkgNames = decodeURIComponent(parts[0]).split(".");
|
||||
if (parts[1] != null) {
|
||||
curNav.declNames = decodeURIComponent(parts[1]).split(".");
|
||||
}
|
||||
if (parts[1] != null) {
|
||||
curNav.declNames = decodeURIComponent(parts[1]).split(".");
|
||||
}
|
||||
|
||||
return;
|
||||
case NAV_MODES.GUIDES:
|
||||
const guides = Object.keys(zigAnalysis.guides);
|
||||
if (guides.length != 0 && query == "") {
|
||||
location.hash = NAV_MODES.GUIDES + guides[0];
|
||||
return;
|
||||
}
|
||||
|
||||
curNav.mode = mode;
|
||||
curNav.activeGuide = query;
|
||||
|
||||
return;
|
||||
default:
|
||||
location.hash = DEFAULT_HASH;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function onHashChange() {
|
||||
updateCurNav();
|
||||
if (domSearch.value !== curNavSearch) {
|
||||
|
||||
@ -28,6 +28,7 @@ decls: std.ArrayListUnmanaged(DocData.Decl) = .{},
|
||||
exprs: std.ArrayListUnmanaged(DocData.Expr) = .{},
|
||||
ast_nodes: std.ArrayListUnmanaged(DocData.AstNode) = .{},
|
||||
comptime_exprs: std.ArrayListUnmanaged(DocData.ComptimeExpr) = .{},
|
||||
guides: std.StringHashMapUnmanaged([]const u8) = .{},
|
||||
|
||||
// These fields hold temporary state of the analysis process
|
||||
// and are mainly used by the decl path resolving algorithm.
|
||||
@ -193,10 +194,15 @@ pub fn generateZirData(self: *Autodoc) !void {
|
||||
}
|
||||
}
|
||||
|
||||
const rootName = blk: {
|
||||
const rootName = std.fs.path.basename(self.module.main_pkg.root_src_path);
|
||||
break :blk rootName[0 .. rootName.len - 4];
|
||||
};
|
||||
|
||||
const main_type_index = self.types.items.len;
|
||||
{
|
||||
try self.packages.put(self.arena, self.module.main_pkg, .{
|
||||
.name = "root",
|
||||
.name = rootName,
|
||||
.main = main_type_index,
|
||||
.table = .{},
|
||||
});
|
||||
@ -204,7 +210,7 @@ pub fn generateZirData(self: *Autodoc) !void {
|
||||
self.arena,
|
||||
self.module.main_pkg,
|
||||
.{
|
||||
.name = "root",
|
||||
.name = rootName,
|
||||
.value = 0,
|
||||
},
|
||||
);
|
||||
@ -215,12 +221,13 @@ pub fn generateZirData(self: *Autodoc) !void {
|
||||
.enclosing_type = main_type_index,
|
||||
};
|
||||
|
||||
const maybe_tldoc_comment = try self.getTLDocComment(file);
|
||||
const tldoc_comment = try self.getTLDocComment(file);
|
||||
try self.ast_nodes.append(self.arena, .{
|
||||
.name = "(root)",
|
||||
.docs = maybe_tldoc_comment,
|
||||
.docs = tldoc_comment,
|
||||
});
|
||||
try self.files.put(self.arena, file, main_type_index);
|
||||
try self.findGuidePaths(file, tldoc_comment);
|
||||
|
||||
_ = try self.walkInstruction(file, &root_scope, .{}, Zir.main_struct_inst, false);
|
||||
|
||||
@ -236,13 +243,8 @@ pub fn generateZirData(self: *Autodoc) !void {
|
||||
@panic("some decl paths were never fully analized");
|
||||
}
|
||||
|
||||
const rootName = blk: {
|
||||
const rootName = std.fs.path.basename(self.module.main_pkg.root_src_path);
|
||||
break :blk rootName[0 .. rootName.len - 4];
|
||||
};
|
||||
var data = DocData{
|
||||
.rootPkgName = rootName,
|
||||
.params = .{ .rootName = "root" },
|
||||
.params = .{},
|
||||
.packages = self.packages.values(),
|
||||
.files = self.files,
|
||||
.calls = self.calls.items,
|
||||
@ -251,6 +253,7 @@ pub fn generateZirData(self: *Autodoc) !void {
|
||||
.exprs = self.exprs.items,
|
||||
.astNodes = self.ast_nodes.items,
|
||||
.comptimeExprs = self.comptime_exprs.items,
|
||||
.guides = self.guides,
|
||||
};
|
||||
|
||||
const base_dir = self.doc_location.directory orelse
|
||||
@ -370,12 +373,10 @@ const Scope = struct {
|
||||
const DocData = struct {
|
||||
typeKinds: []const []const u8 = std.meta.fieldNames(DocTypeKinds),
|
||||
rootPkg: u32 = 0,
|
||||
rootPkgName: []const u8,
|
||||
params: struct {
|
||||
zigId: []const u8 = "arst",
|
||||
zigVersion: []const u8 = build_options.version,
|
||||
target: []const u8 = "arst",
|
||||
rootName: []const u8,
|
||||
builds: []const struct { target: []const u8 } = &.{
|
||||
.{ .target = "arst" },
|
||||
},
|
||||
@ -391,6 +392,9 @@ const DocData = struct {
|
||||
decls: []Decl,
|
||||
exprs: []Expr,
|
||||
comptimeExprs: []ComptimeExpr,
|
||||
|
||||
guides: std.StringHashMapUnmanaged([]const u8),
|
||||
|
||||
const Call = struct {
|
||||
func: Expr,
|
||||
args: []Expr,
|
||||
@ -410,6 +414,7 @@ const DocData = struct {
|
||||
try jsw.objectField(f_name);
|
||||
switch (f) {
|
||||
.files => try writeFileTableToJson(self.files, &jsw),
|
||||
.guides => try writeGuidesToJson(self.guides, &jsw),
|
||||
else => {
|
||||
try std.json.stringify(@field(self, f_name), opts, w);
|
||||
jsw.state_index -= 1;
|
||||
@ -852,7 +857,7 @@ fn walkInstruction(
|
||||
|
||||
const maybe_other_package: ?*Package = blk: {
|
||||
if (self.module.main_pkg_is_std and std.mem.eql(u8, path, "std")) {
|
||||
path = "root";
|
||||
path = "std";
|
||||
break :blk self.module.main_pkg;
|
||||
} else {
|
||||
break :blk file.pkg.table.get(path);
|
||||
@ -4364,6 +4369,16 @@ fn writeFileTableToJson(map: std.AutoArrayHashMapUnmanaged(*File, usize), jsw: a
|
||||
try jsw.endArray();
|
||||
}
|
||||
|
||||
fn writeGuidesToJson(map: std.StringHashMapUnmanaged([]const u8), jsw: anytype) !void {
|
||||
try jsw.beginObject();
|
||||
var it = map.iterator();
|
||||
while (it.next()) |entry| {
|
||||
try jsw.objectField(entry.key_ptr.*);
|
||||
try jsw.emitString(entry.value_ptr.*);
|
||||
}
|
||||
try jsw.endObject();
|
||||
}
|
||||
|
||||
fn writePackageTableToJson(
|
||||
map: std.AutoHashMapUnmanaged(*Package, DocData.DocPackage.TableEntry),
|
||||
jsw: anytype,
|
||||
@ -4422,8 +4437,40 @@ fn getTLDocComment(self: *Autodoc, file: *File) ![]const u8 {
|
||||
var tok = tokenizer.next();
|
||||
var comment = std.ArrayList(u8).init(self.arena);
|
||||
while (tok.tag == .container_doc_comment) : (tok = tokenizer.next()) {
|
||||
try comment.appendSlice(source[tok.loc.start + 3 .. tok.loc.end + 1]);
|
||||
try comment.appendSlice(source[tok.loc.start + "//!".len .. tok.loc.end + 1]);
|
||||
}
|
||||
|
||||
return comment.items;
|
||||
}
|
||||
|
||||
fn findGuidePaths(self: *Autodoc, file: *File, str: []const u8) !void {
|
||||
const prefix = "zig-autodoc-guide:";
|
||||
var it = std.mem.tokenize(u8, str, "\n");
|
||||
while (it.next()) |line| {
|
||||
const trimmed_line = std.mem.trim(u8, line, " ");
|
||||
if (std.mem.startsWith(u8, trimmed_line, prefix)) {
|
||||
const path = trimmed_line[prefix.len..];
|
||||
const trimmed_path = std.mem.trim(u8, path, " ");
|
||||
try self.addGuide(file, trimmed_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn addGuide(self: *Autodoc, file: *File, guide_path: []const u8) !void {
|
||||
if (guide_path.len == 0) return error.MissingAutodocGuideName;
|
||||
|
||||
const cur_pkg_dir_path = file.pkg.root_src_directory.path orelse ".";
|
||||
const resolved_path = try std.fs.path.resolve(self.arena, &[_][]const u8{
|
||||
cur_pkg_dir_path, file.sub_file_path, "..", guide_path,
|
||||
});
|
||||
|
||||
var guide_file = try file.pkg.root_src_directory.handle.openFile(resolved_path, .{});
|
||||
defer guide_file.close();
|
||||
|
||||
const guide = guide_file.reader().readAllAlloc(self.arena, 1 * 1024 * 1024) catch |err| switch (err) {
|
||||
error.StreamTooLong => @panic("stream too long"),
|
||||
else => |e| return e,
|
||||
};
|
||||
|
||||
try self.guides.put(self.arena, resolved_path, guide);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user