Skip to content
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
12 changes: 6 additions & 6 deletions _components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,16 @@ export default function Header({
/>
<HeaderItem
url={url}
activeOn="/examples"
href="/examples"
name="Examples"
activeOn="/api"
href="/api/deno"
name="API reference"
hideOnMobile
/>
<HeaderItem
url={url}
activeOn="/api"
href="/api/deno"
name="API reference"
activeOn="/learn"
href="/learn"
name="Learning hub"
hideOnMobile
/>
<span class="hidden xl:inline-block text-foreground-secondary mx-2">
Expand Down
197 changes: 1 addition & 196 deletions _includes/doc.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
import ansiRegex from "npm:ansi-regex";
import Logo from "../_components/Logo.tsx";
import CLI_REFERENCE from "../runtime/reference/cli/_commands_reference.json" with {
type: "json",
};
import {
Sidebar as Sidebar_,
SidebarItem,
TableOfContentsItem as TableOfContentsItem_,
} from "../types.ts";
import { Breadcrumbs } from "../_components/Breadcrumbs.tsx";
import { HeaderAnchor } from "../_components/HeaderAnchor.tsx";
import { NavigationButton } from "../_components/NavigationButton.tsx";
import { TableOfContentsItem } from "../_components/TableOfContentsItem.tsx";
import { TableOfContentsItemMobile } from "../_components/TableOfContentsItemMobile.tsx";
import renderCommand from "./renderCommand.tsx";

export const layout = "layout.tsx";

Expand Down Expand Up @@ -204,194 +200,3 @@ export default function Page(props: Lume.Data, helpers: Lume.Helpers) {
);
}

const ANSI_RE = ansiRegex();
const SUBSEQUENT_ANSI_RE = new RegExp(
`(?:${ANSI_RE.source})(?:${ANSI_RE.source})`,
"g",
);
const ENCAPSULATED_ANSI_RE = new RegExp(
`(${ANSI_RE.source})(.+?)(${ANSI_RE.source})`,
"g",
);
const START_AND_END_ANSI_RE = new RegExp(
`^(?:${ANSI_RE.source}).+?(?:${ANSI_RE.source})$`,
);
const SUBSEQUENT_ENCAPSULATED_ANSI_RE = new RegExp(
`${ENCAPSULATED_ANSI_RE.source}( ?)${ENCAPSULATED_ANSI_RE.source}`,
"g",
);

const FLAGS_RE = /[^`]--\S+/g;
function flagsToInlineCode(text: string): string {
return text.replaceAll(FLAGS_RE, "`$&`");
}

function renderCommand(
commandName: string,
helpers: Lume.Helpers,
): { rendered: any; toc: TableOfContentsItem_[] } {
const command = CLI_REFERENCE.subcommands.find((command) =>
command.name === commandName
)!;

const toc: TableOfContentsItem_[] = [];

let about = command.about!.replaceAll(
SUBSEQUENT_ENCAPSULATED_ANSI_RE,
function (
_,
_opening1,
text1,
_closing1,
space,
opening2,
text2,
closing2,
) {
return `${opening2}${text1}${space}${text2}${closing2}`;
},
).replaceAll(SUBSEQUENT_ANSI_RE, "");
let aboutLines = about.split("\n");
const aboutLinesReadMoreIndex = aboutLines.findLastIndex((line) =>
line.toLowerCase().replaceAll(ANSI_RE, "").trim().startsWith("read more:")
);
if (aboutLinesReadMoreIndex !== -1) {
aboutLines = aboutLines.slice(0, aboutLinesReadMoreIndex);
}

about = aboutLines.join("\n").replaceAll(
ENCAPSULATED_ANSI_RE,
(_, opening, text, _closing, offset, string) => {
if (opening === "\u001b[32m") { // green, used as heading
return `### ${text}`;
} else if (
opening === "\u001b[38;5;245m" || opening === "\u001b[36m" ||
opening === "\u001b[1m" || opening === "\u001b[22m"
) { // gray and cyan used for code and snippets, and we treat yellow and bold as well as such
const lines = string.split("\n");
let line = "";

while (offset > 0) {
line = lines.shift();
offset -= line.length;
}

if (START_AND_END_ANSI_RE.test(line.trim())) {
return "\n```\n" + text + "\n```\n\n";
} else {
return "`" + text + "`";
}
} else {
return text;
}
},
);

const args = [];
const options: Record<string, any> = {};

for (const arg of command.args) {
if (arg.help_heading === "Unstable options") {
continue;
}

if (arg.long) {
options[arg.help_heading ?? "Options"] ??= [];
options[arg.help_heading ?? "Options"].push(arg);
} else {
args.push(arg);
}
}

const rendered = (
<div>
<div class="p-4 bg-stone-100 dark:bg-transparent rounded border border-gray-300 dark:border-background-tertiary mt-6 mb-6 relative">
<h3 class="!text-xs !m-0 -top-2.5 bg-background-primary border border-gray-600/25 px-2 py-0.5 rounded absolute !font-normal">
Command line usage
</h3>
<div>
<pre class="!mb-0 !px-3 !py-2">
<code>{command.usage.replaceAll(ANSI_RE, "").slice("usage: ".length)}</code>
</pre>
</div>
</div>

<div dangerouslySetInnerHTML={{ __html: helpers.md(about) }} />
<br />

{Object.entries(options).map(([heading, flags]) => {
const id = heading.toLowerCase().replace(/\s/g, "-");

const renderedFlags = flags.toSorted((a, b) =>
a.name.localeCompare(b.name)
).map((flag) => renderOption(id, flag, helpers));

toc.push({
text: heading,
slug: id,
children: [],
});

return (
<>
<h2 id={id}>
{heading} <HeaderAnchor id={id} />
</h2>
{renderedFlags}
</>
);
})}
</div>
);

return {
rendered,
toc,
};
}

function renderOption(group: string, arg, helpers: Lume.Helpers) {
const id = `${group}-${arg.name}`;

let docsLink = null;
let help = arg.help.replaceAll(ANSI_RE, "");
const helpLines = help.split("\n");
const helpLinesDocsIndex = helpLines.findLastIndex((line) =>
line.toLowerCase()
.trim()
.startsWith("docs:")
);
if (helpLinesDocsIndex !== -1) {
help = helpLines.slice(0, helpLinesDocsIndex).join("\n");
docsLink = helpLines[helpLinesDocsIndex].trim().slice("docs:".length);
}

return (
<>
<h3 id={id}>
<code>
{docsLink
? <a href={docsLink}>{"--" + arg.name}</a>
: ("--" + arg.name)}
</code>{" "}
<HeaderAnchor id={id} />
</h3>
{arg.short && (
<p>
Short flag: <code>-{arg.short}</code>
</p>
)}
{arg.help && (
<p
class="block !whitespace-pre-line"
dangerouslySetInnerHTML={{
__html: helpers.md(
flagsToInlineCode(help) +
((help.endsWith(".") || help.endsWith("]")) ? "" : "."),
),
}}
/>
)}
</>
);
}
4 changes: 3 additions & 1 deletion _includes/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import Header from "../_components/Header.tsx";

export default function Layout(props: Lume.Data) {
const reference = props.url.startsWith("/api");
const description = props.description ||
Expand Down Expand Up @@ -99,7 +101,7 @@ export default function Layout(props: Lume.Data) {
>
Skip to main content <span aria-hidden="true">-&gt;</span>
</a>
<props.comp.Header url={props.url} hasSidebar={!!props.sidebar} />
<Header url={props.url} hasSidebar={!!props.sidebar} />
{props.children}
</body>
</html>
Expand Down
Loading