mirror of
https://github.com/tauri-apps/rustdocusaurus.git
synced 2026-02-04 18:51:19 +01:00
186 lines
5.4 KiB
JavaScript
186 lines
5.4 KiB
JavaScript
const jsdom = require("jsdom");
|
|
const TurndownService = require("turndown");
|
|
const { clone, itemsReference } = require("../common");
|
|
const pretty = require("pretty");
|
|
const { removeChildren, insertAfter } = require("../utils/dom");
|
|
|
|
// const Entities = require('html-entities').AllHtmlEntities;
|
|
|
|
// const entities = new Entities();
|
|
|
|
// const HTMLParser = require('node-html-parser');
|
|
|
|
const unified = require("unified");
|
|
const parse = require("rehype-parse");
|
|
const toMdast = require("hast-util-to-mdast");
|
|
const stringify = require("remark-stringify");
|
|
|
|
const keys = Object.keys(itemsReference);
|
|
const { JSDOM } = jsdom;
|
|
|
|
const isRelativeLink = (link) => !link.startsWith("http");
|
|
|
|
const serializeDOM = (dom) =>
|
|
pretty(
|
|
dom.window.document.body.innerHTML
|
|
// .replace(/^<html><head><\/head><body>/, "")
|
|
// .replace(/<\/body><\/html>$/, "")
|
|
// .replace(/<br>/g, "<br/>")
|
|
// .replace(/<wbr>/g, "<wbr/>")
|
|
);
|
|
|
|
const transformLinks = (dom, crate) => {
|
|
Array.from(dom.window.document.querySelectorAll("a")).forEach((anchor) => {
|
|
if (isRelativeLink(anchor.href)) {
|
|
// TO REFINE
|
|
anchor.href =
|
|
`/docs/api/rust/${crate}/` + anchor.href.replace(".html", "");
|
|
}
|
|
});
|
|
};
|
|
|
|
const transformSourceLinks = (dom, crate, repositoryInfo) => {
|
|
const getGitHubURL = (fileName) => {
|
|
return [
|
|
`https://github.com`,
|
|
repositoryInfo.owner,
|
|
repositoryInfo.project,
|
|
"blob",
|
|
repositoryInfo.revision,
|
|
fileName,
|
|
].join("/");
|
|
};
|
|
|
|
const transformHeader = (header) => {
|
|
const srclink = header.querySelector("a.srclink");
|
|
if (!srclink) {
|
|
return;
|
|
}
|
|
const parts = srclink.href.split("/");
|
|
const file = srclink.href
|
|
.replace(`../src/${crate}/`, "")
|
|
.replace(".html", "")
|
|
.replace("#", "#L");
|
|
srclink.textContent = parts[parts.length - 1]
|
|
.replace(".html", "")
|
|
.replace(/#(.+)/, ":$1");
|
|
|
|
const functionName = header.querySelector("code > a").textContent;
|
|
|
|
let functionPrototype = header
|
|
.querySelector("code")
|
|
.innerHTML.replace(/\s{4,5}/g, "\n ");
|
|
if (functionPrototype.match(/\(\n/)) {
|
|
functionPrototype = functionPrototype.replace(") ->", "\n) ->");
|
|
}
|
|
functionPrototype = functionPrototype.replace("where", "\nwhere");
|
|
|
|
const functionNameWrapper = dom.window.document.createElement("code");
|
|
const prototype = dom.window.document.createElement("pre");
|
|
const wrapper = dom.window.document.createElement("i");
|
|
const text = dom.window.document.createTextNode("Defined in: ");
|
|
|
|
functionNameWrapper.textContent = functionName;
|
|
prototype.innerHTML = functionPrototype;
|
|
srclink.href = getGitHubURL(`core/${crate}/src/${file}`);
|
|
srclink.title = "";
|
|
|
|
removeChildren(header);
|
|
header.appendChild(functionNameWrapper);
|
|
wrapper.appendChild(text);
|
|
wrapper.appendChild(srclink);
|
|
|
|
insertAfter(dom.window.document, prototype, header);
|
|
|
|
insertAfter(
|
|
dom.window.document,
|
|
wrapper,
|
|
prototype.nextSibling.classList.contains("docblock")
|
|
? prototype.nextSibling
|
|
: prototype
|
|
);
|
|
};
|
|
|
|
Array.from(dom.window.document.querySelectorAll("h3")).forEach(
|
|
transformHeader
|
|
);
|
|
Array.from(dom.window.document.querySelectorAll("h4")).forEach(
|
|
transformHeader
|
|
);
|
|
};
|
|
|
|
const transformMainHeader = (dom) => {
|
|
const header = dom.window.document.querySelector("h1");
|
|
header.textContent = Array.from(header.querySelectorAll("span")).map(
|
|
(span) => span.textContent
|
|
);
|
|
};
|
|
|
|
const removeRustdocTools = (dom) => {
|
|
const selectors = ["#render-detail", "a.anchor", ".loading-content"];
|
|
selectors.forEach((selector) => {
|
|
Array.from(
|
|
dom.window.document.querySelectorAll(selector)
|
|
).forEach((element) => element.parentNode.removeChild(element));
|
|
});
|
|
};
|
|
|
|
const transformCodeBlocks = (dom) => {
|
|
Array.from(dom.window.document.querySelectorAll("pre")).forEach((element) => {
|
|
element.prepend(dom.window.document.createTextNode("```rs\r"));
|
|
element.append(dom.window.document.createTextNode("\r```"));
|
|
});
|
|
};
|
|
|
|
const transform = async (contents, crate, repositoryInfo) => {
|
|
const transformedContents = clone(contents);
|
|
const promises = keys.map(async (key) => {
|
|
if (key === "module") {
|
|
for (const path in transformedContents.module) {
|
|
transformedContents.module[path] = await transform(
|
|
transformedContents.module[path],
|
|
crate,
|
|
repositoryInfo
|
|
);
|
|
}
|
|
return;
|
|
}
|
|
const res = transformedContents[key].map((item) => {
|
|
const dom = new JSDOM(item.content);
|
|
if (repositoryInfo) {
|
|
transformSourceLinks(dom, crate, repositoryInfo);
|
|
}
|
|
transformMainHeader(dom);
|
|
removeRustdocTools(dom);
|
|
transformCodeBlocks(dom);
|
|
transformLinks(dom, crate);
|
|
|
|
const serialized = serializeDOM(dom);
|
|
|
|
const hast = unified().use(parse).parse(serialized);
|
|
|
|
const mdast = toMdast(hast);
|
|
|
|
let doc = unified().use(stringify).stringify(mdast);
|
|
|
|
doc
|
|
.match(/ *```rs[\s\S]*```/g)
|
|
.map((codeblock) => [codeblock, codeblock.replace(/^ {4}/gm, "")])
|
|
.forEach(([original, replacement]) => {
|
|
doc = doc.replace(original, replacement);
|
|
});
|
|
|
|
return {
|
|
path: item.path,
|
|
content: doc.replace(/!\[/g, "![").replace(/\s*$/g, ""),
|
|
};
|
|
});
|
|
transformedContents[key] = await Promise.all(res);
|
|
return;
|
|
});
|
|
await Promise.all(promises);
|
|
return transformedContents;
|
|
};
|
|
|
|
module.exports = transform;
|