autodoc: add initial support for linking decls mentioned in markdown

this works both on doc comments and guides
This commit is contained in:
Loris Cro 2023-04-15 18:26:20 +02:00
parent aa765c1d70
commit bd3e248c7e

View File

@ -2762,7 +2762,7 @@ const NAV_MODES = {
if (container.src != null) {
let docs = getAstNode(container.src).docs;
if (docs != null) {
domTldDocs.innerHTML = markdown(docs);
domTldDocs.innerHTML = markdown(docs, container);
domTldDocs.classList.remove("hidden");
}
}
@ -2845,13 +2845,13 @@ const NAV_MODES = {
docs = docs.trim();
var short = shortDesc(docs);
if (short != docs) {
short = markdown(short);
var long = markdown(docs);
short = markdown(short, container);
var long = markdown(docs, container); // TODO: this needs to be the file top lvl struct
tdDesc.innerHTML =
"<div class=\"expand\" ><span class=\"button\" onclick=\"toggleExpand(event)\"></span><div class=\"sum-less\">" + short + "</div>" + "<div class=\"sum-more\">" + long + "</div></details>";
}
else {
tdDesc.innerHTML = markdown(short);
tdDesc.innerHTML = markdown(short, container);
}
} else {
tdDesc.innerHTML = "<p><i>No documentation provided.</i><p>";
@ -3389,7 +3389,7 @@ function addDeclToSearchResults(decl, declIndex, pkgNames, item, list, stack) {
return markdown(shortDesc(docs));
}
function markdown(input) {
function markdown(input, contextType) {
const raw_lines = input.split("\n"); // zig allows no '\r', so we don't need to split on CR
const lines = [];
@ -3474,7 +3474,7 @@ function addDeclToSearchResults(decl, declIndex, pkgNames, item, list, stack) {
// Render HTML from markdown lines.
// Look at each line and emit fitting HTML code
function markdownInlines(innerText) {
function markdownInlines(innerText, contextType) {
// inline types:
// **{INLINE}** : <strong>
// __{INLINE}__ : <u>
@ -3521,6 +3521,10 @@ function addDeclToSearchResults(decl, declIndex, pkgNames, item, list, stack) {
let codetag = "";
let in_code = false;
// state used to link decl references
let quote_start = undefined;
let quote_start_html = undefined;
for (let i = 0; i < innerText.length; i++) {
if (parsing_code && in_code) {
if (innerText.substr(i, codetag.length) == codetag) {
@ -3537,6 +3541,16 @@ function addDeclToSearchResults(decl, declIndex, pkgNames, item, list, stack) {
parsing_code = false;
innerHTML += "</code>";
codetag = "";
// find out if this is a decl that should be linked
const maybe_decl_path = innerText.substr(quote_start, i-quote_start);
const decl_hash = detectDeclPath(maybe_decl_path, contextType);
if (decl_hash) {
const anchor_opening_tag = "<a href='"+ decl_hash +"'>";
innerHTML = innerHTML.slice(0, quote_start_html)
+ anchor_opening_tag
+ innerHTML.slice(quote_start_html) + "</a>";
}
} else {
currentRun += innerText[i];
}
@ -3546,6 +3560,8 @@ function addDeclToSearchResults(decl, declIndex, pkgNames, item, list, stack) {
if (innerText[i] == "`") {
flushRun();
if (!parsing_code) {
quote_start = i + 1;
quote_start_html = innerHTML.length;
innerHTML += "<code>";
}
parsing_code = true;
@ -3600,6 +3616,44 @@ function addDeclToSearchResults(decl, declIndex, pkgNames, item, list, stack) {
return innerHTML;
}
function detectDeclPath(text, context) {
let result = "";
let separator = ":";
const components = text.split(".");
let curDeclOrType = undefined;
if (context) {
curDeclOrType = findSubDecl(context, components[0]);
if (curDeclOrType) {
separator = '.';
result = location.hash + separator + components[0];
}
}
if (!curDeclOrType) {
for (let i = 0; i < zigAnalysis.packages.length; i += 1){
const p = zigAnalysis.packages[i];
if (p.name == components[0]) {
curDeclOrType = getType(p.main);
result += "#A;" + components[0];
break;
}
}
}
if (!curDeclOrType) return null;
for (let i = 1; i < components.length; i += 1) {
curDeclOrType = findSubDecl(curDeclOrType, components[i]);
if (!curDeclOrType) return null;
result += separator + components[i];
separator = '.';
}
return result;
}
function previousLineIs(type, line_no) {
if (line_no > 0) {
return lines[line_no - 1].type == type;
@ -3647,7 +3701,7 @@ function addDeclToSearchResults(decl, declIndex, pkgNames, item, list, stack) {
"<" +
line.type +
">" +
markdownInlines(line.text) +
markdownInlines(line.text, contextType) +
"</" +
line.type +
">\n";
@ -3662,7 +3716,7 @@ function addDeclToSearchResults(decl, declIndex, pkgNames, item, list, stack) {
html += "<" + line.type + ">\n";
}
html += "<li>" + markdownInlines(line.text) + "</li>\n";
html += "<li>" + markdownInlines(line.text, contextType) + "</li>\n";
if (
!nextLineIs(line.type, line_no) ||
@ -3676,7 +3730,7 @@ function addDeclToSearchResults(decl, declIndex, pkgNames, item, list, stack) {
if (!previousLineIs("p", line_no)) {
html += "<p>\n";
}
html += markdownInlines(line.text) + "\n";
html += markdownInlines(line.text, contextType) + "\n";
if (!nextLineIs("p", line_no)) {
html += "</p>\n";
}