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

DOC: WIP: Convert markdown to rehype's hast at build time. #1495

Draft
wants to merge 2 commits into
base: dev
Choose a base branch
from
Draft
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,614 changes: 2,400 additions & 214 deletions package-lock.json

Large diffs are not rendered by default.

10 changes: 8 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
"clsx": "^1.2.1",
"date-fns": "^2.30.0",
"escodegen": "^2.1.0",
"hast-util-to-jsx-runtime": "^2.3.0",
"html-loader": "^5.0.0",
"js-sha256": "^0.9.0",
"jszip": "^3.10.1",
"material-ui-color": "^1.2.0",
Expand All @@ -42,12 +44,16 @@
"react-beautiful-dnd": "^13.1.1",
"react-dom": "^17.0.2",
"react-draggable": "^4.4.6",
"react-markdown": "^8.0.7",
"react-resizable": "^3.0.5",
"react-syntax-highlighter": "^15.5.0",
"rehype-stringify": "^9.0.4",
"remark": "^14.0.3",
"remark-gfm": "^3.0.1",
"remark-loader": "^6.0.0",
"remark-rehype": "^10.1.0",
"sprintf-js": "^1.1.3",
"tss-react": "^4.9.10"
"tss-react": "^4.9.10",
"unified": "^10.1.2"
},
"description": "A cyberpunk-themed incremental game",
"devDependencies": {
Expand Down
122 changes: 61 additions & 61 deletions src/Documentation/pages.ts
Original file line number Diff line number Diff line change
@@ -1,65 +1,65 @@
// THIS FILE IS AUTOGENERATED
import file0 from "./doc/advanced/bitnodes.md?raw";
import file1 from "./doc/advanced/bladeburners.md?raw";
import file2 from "./doc/advanced/corporation/basic-gameplay-and-term.md?raw";
import file3 from "./doc/advanced/corporation/boost-material.md?raw";
import file4 from "./doc/advanced/corporation/demand-competition.md?raw";
import file5 from "./doc/advanced/corporation/division-raw-production.md?raw";
import file6 from "./doc/advanced/corporation/faq.md?raw";
import file7 from "./doc/advanced/corporation/financial-statement.md?raw";
import file8 from "./doc/advanced/corporation/general-advice.md?raw";
import file9 from "./doc/advanced/corporation/industry-supply-chain.md?raw";
import file10 from "./doc/advanced/corporation/miscellany.md?raw";
import file11 from "./doc/advanced/corporation/office.md?raw";
import file12 from "./doc/advanced/corporation/optimal-selling-price-market-ta2.md?raw";
import file13 from "./doc/advanced/corporation/product.md?raw";
import file14 from "./doc/advanced/corporation/quality.md?raw";
import file15 from "./doc/advanced/corporation/smart-supply.md?raw";
import file16 from "./doc/advanced/corporation/unlocks-upgrade-research.md?raw";
import file17 from "./doc/advanced/corporation/warehouse.md?raw";
import file18 from "./doc/advanced/corporation/wilson-analytics-advert.md?raw";
import file19 from "./doc/advanced/corporations.md?raw";
import file20 from "./doc/advanced/faction_list.md?raw";
import file21 from "./doc/advanced/gang.md?raw";
import file22 from "./doc/advanced/grafting.md?raw";
import file23 from "./doc/advanced/hacknetservers.md?raw";
import file24 from "./doc/advanced/intelligence.md?raw";
import file25 from "./doc/advanced/offlineandbonustime.md?raw";
import file26 from "./doc/advanced/sleeves.md?raw";
import file27 from "./doc/advanced/sourcefiles.md?raw";
import file28 from "./doc/advanced/stanek.md?raw";
import file29 from "./doc/basic/augmentations.md?raw";
import file30 from "./doc/basic/codingcontracts.md?raw";
import file31 from "./doc/basic/companies.md?raw";
import file32 from "./doc/basic/crimes.md?raw";
import file33 from "./doc/basic/factions.md?raw";
import file34 from "./doc/basic/hacking.md?raw";
import file35 from "./doc/basic/hacknet_nodes.md?raw";
import file36 from "./doc/basic/infiltration.md?raw";
import file37 from "./doc/basic/programs.md?raw";
import file38 from "./doc/basic/ram.md?raw";
import file39 from "./doc/basic/reputation.md?raw";
import file40 from "./doc/basic/scripts.md?raw";
import file41 from "./doc/basic/servers.md?raw";
import file42 from "./doc/basic/stats.md?raw";
import file43 from "./doc/basic/stockmarket.md?raw";
import file44 from "./doc/basic/terminal.md?raw";
import file45 from "./doc/basic/world.md?raw";
import file46 from "./doc/changelog-v0.md?raw";
import file47 from "./doc/changelog-v1.md?raw";
import file48 from "./doc/changelog.md?raw";
import file49 from "./doc/help/bitnode_order.md?raw";
import file50 from "./doc/help/getting_started.md?raw";
import file51 from "./doc/help/tools_and_resources.md?raw";
import file52 from "./doc/index.md?raw";
import file53 from "./doc/migrations/ns2.md?raw";
import file54 from "./doc/migrations/v1.md?raw";
import file55 from "./doc/migrations/v2.md?raw";
import file56 from "./doc/programming/game_frozen.md?raw";
import file57 from "./doc/programming/go_algorithms.md?raw";
import file58 from "./doc/programming/hackingalgorithms.md?raw";
import file59 from "./doc/programming/learn.md?raw";
import file60 from "./doc/programming/remote_api.md?raw";
import file0 from "./doc/advanced/bitnodes.md";
import file1 from "./doc/advanced/bladeburners.md";
import file2 from "./doc/advanced/corporation/basic-gameplay-and-term.md";
import file3 from "./doc/advanced/corporation/boost-material.md";
import file4 from "./doc/advanced/corporation/demand-competition.md";
import file5 from "./doc/advanced/corporation/division-raw-production.md";
import file6 from "./doc/advanced/corporation/faq.md";
import file7 from "./doc/advanced/corporation/financial-statement.md";
import file8 from "./doc/advanced/corporation/general-advice.md";
import file9 from "./doc/advanced/corporation/industry-supply-chain.md";
import file10 from "./doc/advanced/corporation/miscellany.md";
import file11 from "./doc/advanced/corporation/office.md";
import file12 from "./doc/advanced/corporation/optimal-selling-price-market-ta2.md";
import file13 from "./doc/advanced/corporation/product.md";
import file14 from "./doc/advanced/corporation/quality.md";
import file15 from "./doc/advanced/corporation/smart-supply.md";
import file16 from "./doc/advanced/corporation/unlocks-upgrade-research.md";
import file17 from "./doc/advanced/corporation/warehouse.md";
import file18 from "./doc/advanced/corporation/wilson-analytics-advert.md";
import file19 from "./doc/advanced/corporations.md";
import file20 from "./doc/advanced/faction_list.md";
import file21 from "./doc/advanced/gang.md";
import file22 from "./doc/advanced/grafting.md";
import file23 from "./doc/advanced/hacknetservers.md";
import file24 from "./doc/advanced/intelligence.md";
import file25 from "./doc/advanced/offlineandbonustime.md";
import file26 from "./doc/advanced/sleeves.md";
import file27 from "./doc/advanced/sourcefiles.md";
import file28 from "./doc/advanced/stanek.md";
import file29 from "./doc/basic/augmentations.md";
import file30 from "./doc/basic/codingcontracts.md";
import file31 from "./doc/basic/companies.md";
import file32 from "./doc/basic/crimes.md";
import file33 from "./doc/basic/factions.md";
import file34 from "./doc/basic/hacking.md";
import file35 from "./doc/basic/hacknet_nodes.md";
import file36 from "./doc/basic/infiltration.md";
import file37 from "./doc/basic/programs.md";
import file38 from "./doc/basic/ram.md";
import file39 from "./doc/basic/reputation.md";
import file40 from "./doc/basic/scripts.md";
import file41 from "./doc/basic/servers.md";
import file42 from "./doc/basic/stats.md";
import file43 from "./doc/basic/stockmarket.md";
import file44 from "./doc/basic/terminal.md";
import file45 from "./doc/basic/world.md";
import file46 from "./doc/changelog-v0.md";
import file47 from "./doc/changelog-v1.md";
import file48 from "./doc/changelog.md";
import file49 from "./doc/help/bitnode_order.md";
import file50 from "./doc/help/getting_started.md";
import file51 from "./doc/help/tools_and_resources.md";
import file52 from "./doc/index.md";
import file53 from "./doc/migrations/ns2.md";
import file54 from "./doc/migrations/v1.md";
import file55 from "./doc/migrations/v2.md";
import file56 from "./doc/programming/game_frozen.md";
import file57 from "./doc/programming/go_algorithms.md";
import file58 from "./doc/programming/hackingalgorithms.md";
import file59 from "./doc/programming/learn.md";
import file60 from "./doc/programming/remote_api.md";

import type { Document } from "./root.ts";

Expand Down
5 changes: 5 additions & 0 deletions src/ScriptEditor/raw-loader.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,8 @@ declare module "*?raw" {
const contents: string;
export default contents;
}

declare module "*.md" {
const jsonHast: any;
export default jsonHast;
}
60 changes: 33 additions & 27 deletions src/ui/MD/MD.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,38 @@
import React, { useEffect } from "react";
import ReactMarkdown from "react-markdown";

Check failure on line 2 in src/ui/MD/MD.tsx

View workflow job for this annotation

GitHub Actions / Lint

'ReactMarkdown' is defined but never used. Allowed unused vars must match /^__/u
import { TableHead } from "@mui/material";
import remarkGfm from "remark-gfm";

Check failure on line 4 in src/ui/MD/MD.tsx

View workflow job for this annotation

GitHub Actions / Lint

'remarkGfm' is defined but never used. Allowed unused vars must match /^__/u
import { h1, h2, h3, h4, h5, h6, li, Td, Th, table, tr, Blockquote, p } from "./components";
import { code, Pre } from "./code";
import { A } from "./a";
import remarkMath from "remark-math";

Check failure on line 8 in src/ui/MD/MD.tsx

View workflow job for this annotation

GitHub Actions / Lint

'remarkMath' is defined but never used. Allowed unused vars must match /^__/u
import rehypeMathjax from "rehype-mathjax/svg";

Check failure on line 9 in src/ui/MD/MD.tsx

View workflow job for this annotation

GitHub Actions / Lint

'rehypeMathjax' is defined but never used. Allowed unused vars must match /^__/u
import { FilePath } from "../../Paths/FilePath";
import { getPage } from "../../Documentation/root";
import { toJsxRuntime, type Components } from "hast-util-to-jsx-runtime";

import { Fragment, jsx, jsxs } from "react/jsx-runtime";

const COMPONENTS: Components = {
h1: h1,
h2: h2,
h3: h3,
h4: h4,
h5: h5,
h6: h6,
pre: Pre,
p: p,
code: code,
li: li,

th: Th,
td: Td,
table: table,
thead: TableHead,
tr: tr,
blockquote: Blockquote,
a: A,
};

export function MD(props: { pageFilePath: FilePath; top: number }): React.ReactElement {
const pageContent = getPage(props.pageFilePath);
Expand All @@ -21,32 +45,14 @@
}, 0);
});

return (
<ReactMarkdown
components={{
h1: h1,
h2: h2,
h3: h3,
h4: h4,
h5: h5,
h6: h6,
pre: Pre,
p: p,
code: code,
li: li,
return toJsxRuntime(pageContent as any, {
Fragment,
components: COMPONENTS,

th: Th,
td: Td,
table: table,
thead: TableHead,
tr: tr,
blockquote: Blockquote,
a: A,
}}
remarkPlugins={[remarkGfm, remarkMath]}
rehypePlugins={[rehypeMathjax]}
>
{pageContent}
</ReactMarkdown>
);
ignoreInvalidStyle: true,
jsx,
jsxs,
passKeys: true,
passNode: true,
});
}
9 changes: 5 additions & 4 deletions src/ui/MD/code.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import SyntaxHighlighter from "react-syntax-highlighter";
import { monokaiSublime as theme } from "react-syntax-highlighter/dist/esm/styles/hljs";
import { Theme } from "@mui/material/styles";
import { CodeProps } from "react-markdown/lib/ast-to-react";

Check failure on line 5 in src/ui/MD/code.tsx

View workflow job for this annotation

GitHub Actions / Lint

'CodeProps' is defined but never used. Allowed unused vars must match /^__/u
import { Typography } from "@mui/material";
import { makeStyles } from "tss-react/mui";

Expand All @@ -21,7 +21,7 @@
},
}));

export const Pre = (props: React.PropsWithChildren<object>): React.ReactElement => {
export const Pre = (props: JSX.IntrinsicElements["code"]): React.ReactElement => {
const { classes } = useStyles();
return (
<Typography component="span" classes={{ root: classes.pre }}>
Expand All @@ -30,13 +30,13 @@
);
};

const InlineCode = (props: React.PropsWithChildren<CodeProps>): React.ReactElement => (
const InlineCode = (props: JSX.IntrinsicElements["code"]): React.ReactElement => (
<Typography component="span" classes={{ root: useStyles().classes.code }}>
{props.children}
</Typography>
);

const BigCode = (props: React.PropsWithChildren<CodeProps>): React.ReactElement => (
const BigCode = (props: JSX.IntrinsicElements["code"]): React.ReactElement => (
<SyntaxHighlighter
language="javascript"
style={theme}
Expand All @@ -49,5 +49,6 @@
</SyntaxHighlighter>
);

export const code = (props: React.PropsWithChildren<CodeProps>): React.ReactElement =>
export const code = (props: JSX.IntrinsicElements["code"]): React.ReactElement =>
// FIXME: inline is no longer supported
props.inline ? <InlineCode {...props} /> : <BigCode {...props} />;
39 changes: 21 additions & 18 deletions src/ui/MD/components.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from "react";
import { Theme } from "@mui/material/styles";
import { ListItemText, Table, TableCell, TableCellProps, TableRow, Typography } from "@mui/material";
import { LiProps, TableDataCellProps, TableHeaderCellProps } from "react-markdown/lib/ast-to-react";
import { makeStyles } from "tss-react/mui";
const useStyles = makeStyles()((theme: Theme) => ({
th: { whiteSpace: "pre", fontWeight: "bold" },
Expand All @@ -15,41 +14,42 @@ const useStyles = makeStyles()((theme: Theme) => ({
},
}));

export const h1 = (props: React.PropsWithChildren<object>): React.ReactElement => (
export const h1 = (props: JSX.IntrinsicElements["h1"]): React.ReactElement => (
// We are just going to cheat and lower every h# by 1.
<Typography variant="h2">{props.children}</Typography>
);

export const h2 = (props: React.PropsWithChildren<object>): React.ReactElement => (
export const h2 = (props: JSX.IntrinsicElements["h2"]): React.ReactElement => (
// We are just going to cheat and lower every h# by 1.
<Typography variant="h3">{props.children}</Typography>
);

export const h3 = (props: React.PropsWithChildren<object>): React.ReactElement => (
export const h3 = (props: JSX.IntrinsicElements["h3"]): React.ReactElement => (
// We are just going to cheat and lower every h# by 1.
<Typography variant="h4">{props.children}</Typography>
);

export const h4 = (props: React.PropsWithChildren<object>): React.ReactElement => (
export const h4 = (props: JSX.IntrinsicElements["h4"]): React.ReactElement => (
// We are just going to cheat and lower every h# by 1.
<Typography variant="h5">{props.children}</Typography>
);

export const h5 = (props: React.PropsWithChildren<object>): React.ReactElement => (
export const h5 = (props: JSX.IntrinsicElements["h5"]): React.ReactElement => (
// We are just going to cheat and lower every h# by 1.
<Typography variant="h6">{props.children}</Typography>
);

export const h6 = (props: React.PropsWithChildren<object>): React.ReactElement => (
export const h6 = (props: JSX.IntrinsicElements["h6"]): React.ReactElement => (
// Except for h6, that's going to stay h6. If there's complaints we'll figure it out.
<Typography variant="h6">{props.children}</Typography>
);

export const p = (props: React.PropsWithChildren<object>): React.ReactElement => (
export const p = (props: JSX.IntrinsicElements["p"]): React.ReactElement => (
<Typography sx={{ mb: 1 }}>{props.children}</Typography>
);

export const li = (props: React.PropsWithChildren<LiProps>): React.ReactElement => {
export const li = (props: JSX.IntrinsicElements["li"]): React.ReactElement => {
// FIXME: .ordered and .index are not defined automatically
const prefix = props.ordered ? `${props.index + 1}. ` : "· ";
return (
<ListItemText>
Expand All @@ -73,13 +73,16 @@ const fixAlign = (align: React.CSSProperties["textAlign"]): TableCellProps["alig
return align;
};

export const Td = (props: React.PropsWithChildren<TableDataCellProps>): React.ReactElement => {
export const Td = (props: JSX.IntrinsicElements["td"]): React.ReactElement => {
const { classes } = useStyles();
const align = fixAlign(props.style?.textAlign);
const content = props.children?.map((child, i) => {
if (child === "<br />") return <br key={i} />;
return child;
});
// FIXME: children isn't nescesarily an array
const content = Array.isArray(props.children)
? props.children?.map((child, i) => {
if (child === "<br />") return <br key={i} />;
return child;
})
: props.children;
return (
<TableCell align={align}>
<Typography align={align} classes={{ root: classes.td }}>
Expand All @@ -89,7 +92,7 @@ export const Td = (props: React.PropsWithChildren<TableDataCellProps>): React.Re
);
};

export const Th = (props: React.PropsWithChildren<TableHeaderCellProps>): React.ReactElement => {
export const Th = (props: JSX.IntrinsicElements["td"]): React.ReactElement => {
const { classes } = useStyles();
const align = fixAlign(props.style?.textAlign);

Expand All @@ -102,15 +105,15 @@ export const Th = (props: React.PropsWithChildren<TableHeaderCellProps>): React.
);
};

export const table = (props: React.PropsWithChildren<object>): React.ReactElement => {
export const table = (props: JSX.IntrinsicElements["table"]): React.ReactElement => {
return <Table sx={{ width: "inherit" }}>{props.children}</Table>;
};

export const tr = (props: React.PropsWithChildren<object>): React.ReactElement => {
export const tr = (props: JSX.IntrinsicElements["tr"]): React.ReactElement => {
return <TableRow>{props.children}</TableRow>;
};

export const Blockquote = (props: React.PropsWithChildren<object>): React.ReactElement => {
export const Blockquote = (props: JSX.IntrinsicElements["blockquote"]): React.ReactElement => {
const { classes } = useStyles();
return <blockquote className={classes.blockquote}>{props.children}</blockquote>;
};
2 changes: 1 addition & 1 deletion tools/bundle-doc/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const processDir = (dir) => {
processDir(docRoot);

const autogenfile = `// THIS FILE IS AUTOGENERATED
${files.map((f, i) => `import file${i} from "./doc/${f}?raw";`).join("\n")}
${files.map((f, i) => `import file${i} from "./doc/${f}";`).join("\n")}

import type { Document } from "./root.ts";

Expand Down
Loading
Loading