Skip to content

Commit 93ebaa4

Browse files
committed
chore(docs): Use react-marked-renderer for markdown stuffs
1 parent 9bdf6ba commit 93ebaa4

14 files changed

Lines changed: 222 additions & 237 deletions

File tree

packages/documentation/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@
2828
"fuse.js": "6.4.6",
2929
"js-cookie": "^3.0.1",
3030
"lodash": "^4.17.21",
31-
"marked": "^3.0.7",
3231
"mobile-detect": "^1.4.5",
3332
"next": "11.1.2",
3433
"prismjs": "^1.25.0",
3534
"qs": "^6.10.0",
3635
"react": "^17.0.2",
3736
"react-dom": "^17.0.1",
3837
"react-hook-form": "^7.17.2",
38+
"react-marked-renderer": "^0.2.1",
3939
"react-md": "^3.1.1",
4040
"react-router-dom": "^5.3.0",
4141
"react-swipeable": "^6.2.0",
@@ -49,7 +49,6 @@
4949
"@types/formidable": "^1.2.4",
5050
"@types/gtag.js": "^0.0.7",
5151
"@types/js-cookie": "^3.0.0",
52-
"@types/marked": "^3.0.1",
5352
"@types/prismjs": "^1.16.6",
5453
"@types/qs": "^6.9.7",
5554
"@types/react-virtualized": "^9.21.13",
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
import React, { HTMLAttributes, ReactElement } from "react";
22
import cn from "classnames";
3-
import { Text } from "@react-md/typography";
3+
4+
import styles from "./Blockquote.module.scss";
45

56
export default function Blockquote({
67
className,
78
children,
89
...props
910
}: HTMLAttributes<HTMLDivElement>): ReactElement {
1011
return (
11-
<blockquote {...props} className={cn("blockquote", className)}>
12-
<Text>{children}</Text>
12+
<blockquote {...props} className={cn(styles.blockquote, className)}>
13+
{children}
1314
</blockquote>
1415
);
1516
}

packages/documentation/src/components/Code/CodeBlock.module.scss

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
}
2626

2727
// prismjs custom theme
28-
// this is _basically_ my current vim theme, but not aas good since
28+
// this is _basically_ my current vim theme, but not as good since
2929
// Prism doesn't have as many tokenizers
3030
:global {
3131
.token {
@@ -95,8 +95,7 @@
9595
color: $solarized-blue;
9696
}
9797

98-
&:global(.language-ts) :global .token + .class-name,
99-
&:global(.language-tsx) :global .token + .class-name {
98+
&:global(.language-ts) :global .token + .class-name {
10099
color: $solarized-base-1;
101100
}
102101

packages/documentation/src/components/Code/CodeBlock.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@ import React, {
66
} from "react";
77
import cn from "classnames";
88

9-
import { highlightCode } from "components/Markdown/utils";
10-
119
import styles from "./CodeBlock.module.scss";
1210
import Code from "./Code";
1311
import LineNumbers from "./LineNumbers";
12+
import { highlightCode } from "./utils";
1413

1514
export interface CodeBlockProps extends HTMLAttributes<HTMLPreElement> {
1615
/**
@@ -64,14 +63,19 @@ export default forwardRef<HTMLPreElement, CodeBlockProps>(function CodeBlock(
6463
language = "markdown",
6564
children,
6665
highlight = true,
67-
lineNumbers = false,
66+
lineNumbers: propLineNumbers,
6867
suppressHydrationWarning = false,
6968
...props
7069
},
7170
ref
7271
) {
7372
const code = typeof children === "string" ? children : "";
7473

74+
const lineNumbers =
75+
propLineNumbers ??
76+
(!/markup|markdown|shell/.test(language) &&
77+
(code.match(/\r?\n/g) || []).length + 1 > 3);
78+
7579
let dangerouslySetInnerHTML: DOMAttributes<HTMLElement>["dangerouslySetInnerHTML"];
7680
if (code && highlight) {
7781
dangerouslySetInnerHTML = {
@@ -82,6 +86,7 @@ export default forwardRef<HTMLPreElement, CodeBlockProps>(function CodeBlock(
8286
return (
8387
<pre
8488
{...props}
89+
data-linenumbers={lineNumbers || undefined}
8590
ref={ref}
8691
className={cn(
8792
styles.block,
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { highlight, languages } from "prismjs";
2+
import {
3+
DangerouslyHighlightCode,
4+
GetCodeLanguage,
5+
} from "react-marked-renderer";
6+
7+
export const getLanguage: GetCodeLanguage = (lang, _rawCode) => {
8+
// allow aliases
9+
lang = lang === "sh" ? "shell" : lang;
10+
11+
// if the Prism doesn't support the language, default to nothing instead
12+
// of crashing
13+
if (!languages[lang]) {
14+
return "none";
15+
}
16+
17+
return lang;
18+
};
19+
20+
export const highlightCode: DangerouslyHighlightCode = (code, lang) =>
21+
highlight(code, languages[lang], lang);

packages/documentation/src/components/DemoSandbox/CodePreview.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ export default function CodePreview({
3737
if (typeof content !== "string") {
3838
content = `${JSON.stringify(content, null, 2)}\n`;
3939
}
40+
41+
content = content.trim();
4042
}
4143

4244
const code = useRef<HTMLPreElement | null>(null);

packages/documentation/src/components/Demos/DemoContainer.module.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ $demo-padding-extra: 6rem;
1111

1212
padding: 0 $demo-padding-extra;
1313

14-
:global .code--counted {
14+
[data-linenumbers] {
1515
width: calc(100vw - #{$demo-padding-extra * 2});
1616
}
1717
}
1818

1919
@include rmd-utils-desktop-media {
20-
:global .code--counted {
20+
[data-linenumbers] {
2121
$offset: $rmd-sheet-static-width + $toc-width + ($demo-padding-extra * 2);
2222

2323
width: calc(100vw - #{$offset});

packages/documentation/src/components/Demos/Layout/LayoutVisibility.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React, { ReactElement } from "react";
22
import { Button } from "@react-md/button";
33
import { isPersistentLayout, useLayoutConfig } from "@react-md/layout";
4+
import { Text } from "@react-md/typography";
45

56
import CodeBlock from "components/Code/CodeBlock";
67
import Blockquote from "components/Blockquote";
@@ -22,8 +23,10 @@ export default function LayoutVisibility(): ReactElement {
2223
<CodeBlock language="typescript">{code}</CodeBlock>
2324
{isPersistentLayout(remaining.layout) && (
2425
<Blockquote>
25-
The visibility cannot be changed for persistent layouts so the buttons
26-
will do nothing.
26+
<Text>
27+
The visibility cannot be changed for persistent layouts so the
28+
buttons will do nothing.
29+
</Text>
2730
</Blockquote>
2831
)}
2932
<Button onClick={showNav}>Show</Button>

packages/documentation/src/components/Markdown/Markdown.module.scss

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
@use 'react-md' as *;
22

3-
.p,
4-
.list {
5-
@include rmd-typography(subtitle-1);
6-
}
7-
83
.container {
94
@include rmd-utils-phone-media {
105
@each $headline in (1 2 3) {
Lines changed: 17 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,100 +1,39 @@
1-
/* eslint-disable react/no-danger */
21
import React, {
32
HTMLAttributes,
4-
MutableRefObject,
53
ReactElement,
64
useEffect,
7-
useMemo,
8-
useRef,
95
useState,
106
} from "react";
117
import cn from "classnames";
12-
import { useRouter } from "next/router";
8+
import { Markdown as MarkdownRenderer } from "react-marked-renderer";
9+
10+
import { getLanguage, highlightCode } from "components/Code/utils";
1311

1412
import styles from "./Markdown.module.scss";
15-
import { markdownToHTML } from "./utils";
13+
import { renderers } from "./renderers";
14+
import { transformMarkdown } from "./utils";
1615

1716
function useMarkdownResolver(markdown: MarkdownProps["children"]): string {
1817
/* eslint-disable react-hooks/rules-of-hooks */
1918
// i will never swap between strings and promises
2019
if (typeof markdown === "string") {
21-
return markdown;
20+
return transformMarkdown(markdown);
2221
}
2322

2423
const [resolved, setResolved] = useState("");
2524
useEffect(() => {
2625
markdown().then((md) => {
2726
if (typeof md === "string") {
28-
setResolved(md);
27+
setResolved(transformMarkdown(md));
2928
} else if (typeof md.default === "string") {
30-
setResolved(md.default);
29+
setResolved(transformMarkdown(md.default));
3130
}
3231
});
3332
}, [markdown]);
3433

3534
return resolved;
3635
}
3736

38-
interface DangerHTML {
39-
__html: string;
40-
}
41-
42-
function useHTML(children: MarkdownChildren): DangerHTML {
43-
const markdown = useMarkdownResolver(children);
44-
const html = useMemo(
45-
() => ({
46-
__html: markdownToHTML(markdown),
47-
}),
48-
[markdown]
49-
);
50-
51-
return html;
52-
}
53-
54-
function useCustomMarkdownBehavior({
55-
__html: html,
56-
}: DangerHTML): MutableRefObject<HTMLDivElement | null> {
57-
const ref = useRef<HTMLDivElement | null>(null);
58-
const router = useRouter();
59-
useEffect(() => {
60-
const instance = ref.current;
61-
if (!instance) {
62-
return;
63-
}
64-
65-
const { origin } = window.location;
66-
const links = Array.from(
67-
instance.querySelectorAll<HTMLAnchorElement>("a[href]")
68-
);
69-
70-
links.forEach((link) => {
71-
if (link.href.startsWith(origin)) {
72-
link.onclick = (event) => {
73-
event.preventDefault();
74-
const href = link.href.replace(origin, "");
75-
76-
router.push(href).then((success) => {
77-
if (success) {
78-
const [, hash] = href.split("#");
79-
if (hash) {
80-
const el = document.getElementById(hash);
81-
if (el && typeof el.focus === "function") {
82-
el.focus();
83-
return;
84-
}
85-
}
86-
87-
window.scrollTo(0, 0);
88-
}
89-
});
90-
};
91-
}
92-
});
93-
}, [html, router]);
94-
95-
return ref;
96-
}
97-
9837
export type ResolveMarkdown = () => Promise<string | { default: string }>;
9938
export type MarkdownChildren = string | ResolveMarkdown;
10039

@@ -109,23 +48,27 @@ export default function Markdown({
10948
disableSinglePMargin,
11049
...props
11150
}: MarkdownProps): ReactElement {
112-
const html = useHTML(children);
113-
const ref = useCustomMarkdownBehavior(html);
51+
const markdown = useMarkdownResolver(children);
11452

11553
return (
11654
<>
11755
<div
11856
{...props}
119-
ref={ref}
12057
className={cn(
12158
styles.container,
12259
{
12360
[styles.marginless]: disableSinglePMargin,
12461
},
12562
className
12663
)}
127-
dangerouslySetInnerHTML={html}
128-
/>
64+
>
65+
<MarkdownRenderer
66+
markdown={markdown}
67+
renderers={renderers}
68+
getLanguage={getLanguage}
69+
highlightCode={highlightCode}
70+
/>
71+
</div>
12972
</>
13073
);
13174
}

0 commit comments

Comments
 (0)