Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[docs][1/2] Update plugin #20701

Merged
merged 9 commits into from
Jan 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/content/references/contribute/mdx-components.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ When including sections of code, understand that the code might change from what

To include the entire source file, use the `{@inject}` directive with a path to the file, based on the Sui repo root. For example, to include the source file at `sui/examples/move/hero/sources/example.move`, write `{@inject: examples/move/hero/sources/example.move`. The file location is automatically used as the title for the codeblock.

You can use source code from other GitHub repositories, but should do so sparingly and purposefully. There is almost no way to track those projects to ensure the code is valid, unlike the CI processes running on the sui repo. To use, format the directive as `{@inject: github:<GITHUB_ORG_NAME>/<GITHUB_REPO_NAME>/<PATH_TO_FILE>}`.

#### Include part of code

To include only sections of code, add an ID to identify the section, function, struct, or module. The ID is used in the directive syntax and in source code comments. The following sections provide examples of different uses and how to format them.
Expand Down
80 changes: 65 additions & 15 deletions docs/site/src/plugins/inject-code/injectLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,84 @@

const fs = require("fs");
const path = require("path");
const https = require("https");
const utils = require("./utils.js");

const addCodeInject = function (source) {
const GITHUB = "https://raw.githubusercontent.com/";
const GITHUB_RAW = "refs/heads/main/";

const addCodeInject = async function (source) {
let fileString = source;
const callback = this.async();
const options = this.getOptions();

const markdownFilename = path.basename(this.resourcePath);
const repoPath = path.join(__dirname, "../../../../..");

// Do not load and render markdown files without docusaurus header.
// These files are only used to be included in other files and should not generate their own web page
if (fileString.length >= 3 && fileString.substring(0, 3) !== "---") {
return callback && callback(null, "");
}

function addMarkdownIncludes(fileContent) {
const fetchFile = (url) => {
return new Promise((res, rej) => {
let data = "";
https
.get(url, (response) => {
if (response.statusCode !== 200) {
console.error(
`Failed to fetch GitHub data: ${response.statusCode}`,
);
res("Error loading content");
}

response.on("data", (chunk) => {
data += chunk;
});

response.on("end", () => {
res(data);
});
})
.on("error", (err) => {
rej(`Error: ${err.message}`);
});
});
};

const pathBuild = (srcPath) => {
const parts = srcPath.split("/");
if (parts[0].includes("github")) {
const githubOrgName = parts[0].split(":")[1];
const githubRepoName = parts[1];
return path.join(
GITHUB,
githubOrgName,
githubRepoName,
GITHUB_RAW,
parts.slice(2).join("/"),
);
} else {
return path.join(__dirname, "../../../../..", srcPath);
}
};

async function addMarkdownIncludes(fileContent) {
let res = fileContent;
const matches = fileContent.match(/(?<!`)\{@\w+: .+\}/g);
if (matches) {
matches.forEach((match) => {
for (const match of matches) {
const replacer = new RegExp(match, "g");
const key = "{@inject: ";

if (match.startsWith(key)) {
const parts = match.split(" ");
const [, , ...options] = parts.length > 2 ? parts : [];
let injectFileFull = parts[1].replace(/\}$/, "");

const injectFile = injectFileFull.split("#")[0];

let injectFile = injectFileFull.split("#")[0];
let fileExt = injectFile.substring(injectFile.lastIndexOf(".") + 1);
let language = "";
const fullPath = path.join(repoPath, injectFile);
const fullPath = pathBuild(injectFile);

switch (fileExt) {
case "lock":
Expand Down Expand Up @@ -64,10 +108,16 @@ const addCodeInject = function (source) {
const isMove = language === "move";
const isTs = language === "ts" || language === "js";

if (fs.existsSync(fullPath)) {
let injectFileContent = fs
.readFileSync(fullPath, "utf8")
.replaceAll(`\t`, " ");
if (fs.existsSync(fullPath) || fullPath.match(/^https/)) {
let injectFileContent;
if (fullPath.match(/^https/)) {
injectFileContent = await fetchFile(fullPath);
} else {
injectFileContent = fs
.readFileSync(fullPath, "utf8")
.replaceAll(`\t`, " ");
}

const marker =
injectFileFull.indexOf("#") > 0
? injectFileFull.substring(injectFileFull.indexOf("#"))
Expand Down Expand Up @@ -507,7 +557,7 @@ const addCodeInject = function (source) {
options,
);
res = res.replace(replacer, injectFileContent);
res = addMarkdownIncludes(res);
res = await addMarkdownIncludes(res);
} else {
// Handle import of all the code
const processed = utils.processOptions(
Expand Down Expand Up @@ -546,7 +596,7 @@ const addCodeInject = function (source) {
}
}
}
});
}
}
return res;
}
Expand All @@ -570,7 +620,7 @@ const addCodeInject = function (source) {
return res;
}

fileString = replacePlaceHolders(addMarkdownIncludes(fileString));
fileString = replacePlaceHolders(await addMarkdownIncludes(fileString));

return callback && callback(null, fileString);
};
Expand Down
25 changes: 20 additions & 5 deletions docs/site/src/theme/CodeBlock/Content/String.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ import WordWrapButton from "@theme/CodeBlock/WordWrapButton";
import Container from "@theme/CodeBlock/Container";
import styles from "./styles.module.css";

const GITHUB = "https://github.com";
const GITHUB_BLOB = "blob/main";

// Prism languages are always lowercase
// We want to fail-safe and allow both "php" and "PHP"
// See https://github.com/facebook/docusaurus/issues/9012
Expand Down Expand Up @@ -54,12 +57,24 @@ export default function CodeBlockString({

// Sui added code.
// Change component to render title as anchor.
const sourceLink =
title && !title.match(/^http/)
? `https://github.com/MystenLabs/sui/tree/main/${title}`
: title;
let sourceLink;
if (title) {
if (title.match(/^http/)) {
sourceLink = title;
} else if (title.match(/github:/)) {
const parts = title.split("/");
const githubOrgName = parts[0].split(":")[1];
const githubRepoName = parts[1];
sourceLink = `${GITHUB}/${githubOrgName}/${githubRepoName}/${GITHUB_BLOB}/${parts.slice(2).join("/")}`;
} else {
sourceLink = `https://github.com/MystenLabs/sui/tree/main/${title}`;
}
}

const tailwind = "relative ";

const displayTitle = title ? title.replace("github:", "") : "";

return (
<Container
as="div"
Expand All @@ -74,7 +89,7 @@ export default function CodeBlockString({
{title && (
<div className={styles.codeBlockTitle}>
<a href={sourceLink} target="_blank" rel="noreferrer">
{title}
{displayTitle}
</a>
</div>
)}
Expand Down
Loading