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

[WIP]create pages for examples, tutorials and videos, refactor examples #1192

Closed
wants to merge 37 commits into from
Closed
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
6e128d6
create pages for examples, tutorials and videos, refactor examples (#…
thisisjofrank Nov 25, 2024
94f1deb
fmt
thisisjofrank Nov 25, 2024
74d68a1
fix test
thisisjofrank Nov 25, 2024
6017f63
fix test
thisisjofrank Nov 25, 2024
10a9b67
Learn landing page (#1194)
philhawksworth Nov 26, 2024
fb2baeb
Merge branch 'main' of https://github.com/denoland/docs into learning…
thisisjofrank Nov 27, 2024
c3e9e22
Merge branch 'learning-center' of https://github.com/denoland/docs in…
thisisjofrank Nov 27, 2024
65e27e4
New tutorials (#1197)
thisisjofrank Nov 27, 2024
7742f55
typo fix
philhawksworth Nov 27, 2024
64202b9
why so sad, fmt? This should fix (#1200)
philhawksworth Nov 27, 2024
04cf228
adding subnav
thisisjofrank Nov 27, 2024
f4d19b3
adding subnav (#1201)
thisisjofrank Nov 27, 2024
53bcba3
merge
thisisjofrank Nov 27, 2024
bbb19d9
broken urls
thisisjofrank Nov 27, 2024
7666363
fix urls
thisisjofrank Nov 27, 2024
56ce72d
fmt
thisisjofrank Nov 27, 2024
030ae9d
more urls fixing
thisisjofrank Nov 27, 2024
4f518a8
more urls fixing
thisisjofrank Nov 27, 2024
30d2262
more urls fixing
thisisjofrank Nov 27, 2024
13c454f
moving all tutorials and examples onto one page (#1203)
thisisjofrank Nov 28, 2024
6d5c114
fix urls
thisisjofrank Nov 28, 2024
8d0ff30
Merge branch 'main' into learning-center
thisisjofrank Nov 28, 2024
d33c9e1
Include videos in learning list (#1206)
philhawksworth Nov 28, 2024
c95cd8b
separate out examples and landingpage generators, make new layout for…
thisisjofrank Nov 29, 2024
5f3ab97
Learning filter (#1210)
thisisjofrank Nov 29, 2024
0c86469
Video page template (#1213)
philhawksworth Nov 29, 2024
fa4086c
fix broken images and fmt
thisisjofrank Nov 29, 2024
275215c
Learn page ordering (#1217)
philhawksworth Nov 29, 2024
5c23195
Learning hub sidebar mobile (#1215)
thisisjofrank Nov 29, 2024
9ebddbf
Update index.tsx
thisisjofrank Nov 29, 2024
d1da36e
add astro, drizzle, trpc, and several videos
lambtron Dec 4, 2024
46acea2
merge with main
thisisjofrank Dec 9, 2024
7285d52
Merge branch 'learning-center' of https://github.com/denoland/docs in…
thisisjofrank Dec 9, 2024
00e7bb3
move all tutorials/examples/videos under the /examples url
thisisjofrank Dec 9, 2024
3efc901
fix broken link
thisisjofrank Dec 9, 2024
2436e1c
fix up examples page
thisisjofrank Dec 9, 2024
c84370a
make filters work with css
thisisjofrank Dec 9, 2024
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: 1 addition & 1 deletion _components/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const data = [
},
{
label: "Examples",
href: "/examples",
href: "/learn/examples",
},
{
label: "Standard Library",
Expand Down
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="Learn"
hideOnMobile
/>
<span class="hidden xl:inline-block text-foreground-secondary mx-2">
Expand Down
4 changes: 2 additions & 2 deletions _config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ site.copy("runtime/fundamentals/images");
site.copy("runtime/getting_started/images");
site.copy("runtime/reference/images");
site.copy("runtime/contributing/images");
site.copy("runtime/tutorials/images");
site.copy("learn/tutorials/images");
site.copy("deploy/manual/images");
site.copy("deno.json");
site.copy("go.json");
Expand All @@ -127,7 +127,7 @@ site.use(
);
site.use(
esbuild({
extensions: [".client.ts"],
extensions: [".client.ts", ".client.js"],
options: {
minify: false,
splitting: true,
Expand Down
247 changes: 30 additions & 217 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 @@ -67,6 +63,8 @@ export default function Page(props: Lume.Data, helpers: Lume.Helpers) {
props.toc = toc.concat(...props.toc);
}

let isLearnHub = props.url.includes("learn");

return (
<>
<aside
Expand Down Expand Up @@ -117,14 +115,17 @@ export default function Page(props: Lume.Data, helpers: Lume.Helpers) {
class="mx-auto max-w-screen-xl w-full pt-2 pb-8 flex flex-grow xl:col-span-5"
>
<div class="flex-grow px-4 sm:px-5 md:px-6 max-w-full">
<article class="max-w-[66ch] mx-auto">
<Breadcrumbs
title={props.title!}
sidebar={sidebar}
url={props.url}
sectionTitle={props.sectionTitle!}
sectionHref={props.sectionHref!}
/>
<article class="{props.toc && props.toc.length > 0 && (max-w-[66ch])} mx-auto">
{!isLearnHub && (
<Breadcrumbs
title={props.title!}
sidebar={sidebar}
url={props.url}
sectionTitle={props.sectionTitle!}
sectionHref={props.sectionHref!}
/>
)}

{props.toc && props.toc.length > 0 && (
<details class="block xl:hidden my-4 bg-background-secondary rounded-md group">
<summary class="px-4 py-2 group-open:border-b border-foreground-tertiary">
Expand Down Expand Up @@ -184,214 +185,26 @@ export default function Page(props: Lume.Data, helpers: Lume.Helpers) {
</div>
</main>

<aside class="hidden xl:block pb-8 pr-8 col-span-2">
<div
class="py-2 sticky overflow-y-auto top-4 h-[calc(100vh-7rem)]"
id="toc"
>
<ul class="border-l border-foreground-tertiary dark:border-background-tertiary py-2 pl-2 relative">
{(props.toc as TableOfContentsItem_[]).map((item) => (
<TableOfContentsItem item={item} />
))}
</ul>
</div>
</aside>
{(props.toc as TableOfContentsItem_[]).length > 0 &&
(
<aside class="hidden xl:block pb-8 pr-8 col-span-2">
<div
class="py-2 sticky overflow-y-auto top-4 h-[calc(100vh-7rem)]"
id="toc"
>
<ul class="border-l border-foreground-tertiary dark:border-background-tertiary py-2 pl-2 relative">
{(props.toc as TableOfContentsItem_[]).map((item) => (
<TableOfContentsItem item={item} />
))}
</ul>
</div>
</aside>
)}

<div class="xl:col-span-full">
<props.comp.Footer />
</div>
</div>
</>
);
}

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("]")) ? "" : "."),
),
}}
/>
)}
</>
);
}
6 changes: 5 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 @@ -70,6 +72,8 @@ export default function Layout(props: Lume.Data) {
<script type="module" src="/search.client.js"></script>
<script type="module" src="/tabs.client.js"></script>
<script type="module" src="/feedback.client.js"></script>
<script type="module" src="/learn_filter.client.js"></script>
<script type="module" src="/youtube-lite.client.js"></script>
<script
async
src="https://www.googletagmanager.com/gtm.js?id=GTM-5B5TH8ZJ"
Expand Down Expand Up @@ -99,7 +103,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