mirror of
https://github.com/jakejarvis/jarv.is.git
synced 2025-04-26 13:18:26 -04:00
parse markdown in titles at build time
This commit is contained in:
parent
58321a3844
commit
972a25abc6
@ -1,28 +0,0 @@
|
||||
const Octocat = (props: { repo: string }) => {
|
||||
return (
|
||||
<a
|
||||
className="no-underline"
|
||||
href={`https://github.com/${props.repo}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
style={{ margin: "0 0.3em", color: "var(--text)" }}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 16 16"
|
||||
width="1em"
|
||||
height="1em"
|
||||
aria-hidden="true"
|
||||
className="icon"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"
|
||||
></path>
|
||||
</svg>
|
||||
</a>
|
||||
);
|
||||
};
|
||||
|
||||
export default Octocat;
|
@ -1,11 +1,11 @@
|
||||
import Link from "next/link";
|
||||
import Markdown from "markdown-to-jsx";
|
||||
import { format } from "date-fns";
|
||||
|
||||
import styles from "./List.module.css";
|
||||
|
||||
type NoteProps = {
|
||||
title: string;
|
||||
htmlTitle?: string;
|
||||
date: string;
|
||||
slug: string;
|
||||
};
|
||||
@ -29,9 +29,7 @@ const List = ({ notesByYear }) => {
|
||||
}}
|
||||
prefetch={false}
|
||||
>
|
||||
<a>
|
||||
<Markdown options={{ disableParsingRawHTML: true, forceInline: true }}>{note.title}</Markdown>
|
||||
</a>
|
||||
<a dangerouslySetInnerHTML={{ __html: note.htmlTitle }} />
|
||||
</Link>
|
||||
</span>
|
||||
</li>
|
||||
|
@ -1,6 +1,5 @@
|
||||
import Link from "next/link";
|
||||
import { format } from "date-fns";
|
||||
import Markdown from "markdown-to-jsx";
|
||||
import Hits from "../hits/Hits";
|
||||
import { DateIcon, TagIcon, EditIcon, ViewsIcon } from "../icons";
|
||||
import * as config from "../../lib/config";
|
||||
@ -9,12 +8,13 @@ import styles from "./Meta.module.css";
|
||||
|
||||
export type Props = {
|
||||
title: string;
|
||||
htmlTitle?: string;
|
||||
date: string;
|
||||
slug: string;
|
||||
tags?: string[];
|
||||
};
|
||||
|
||||
const Meta = ({ title, date, slug, tags = [] }: Props) => (
|
||||
const Meta = ({ title, htmlTitle = "", date, slug, tags = [] }: Props) => (
|
||||
<>
|
||||
<div className={styles.meta}>
|
||||
<div className={styles.date}>
|
||||
@ -62,9 +62,7 @@ const Meta = ({ title, date, slug, tags = [] }: Props) => (
|
||||
|
||||
<h1 className={styles.title}>
|
||||
<Link href={`/notes/${slug}/`}>
|
||||
<a>
|
||||
<Markdown options={{ disableParsingRawHTML: true, forceInline: true }}>{title}</Markdown>
|
||||
</a>
|
||||
<a dangerouslySetInnerHTML={{ __html: htmlTitle }} />
|
||||
</Link>
|
||||
</h1>
|
||||
</>
|
||||
|
@ -1,6 +1,8 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import matter from "gray-matter";
|
||||
import { marked } from "marked";
|
||||
import sanitizeHtml from "sanitize-html";
|
||||
import { bundleMDX } from "mdx-bundler";
|
||||
import readingTime from "reading-time";
|
||||
import { NOTES_DIR, baseUrl } from "./config";
|
||||
@ -28,10 +30,11 @@ export const getNoteData = (slug: string) => {
|
||||
return {
|
||||
frontMatter: {
|
||||
...data,
|
||||
htmlTitle: sanitizeHtml(marked.parseInline(data.title), { allowedTags: ["code"] }),
|
||||
slug,
|
||||
permalink: `${baseUrl}/notes/${slug}/`,
|
||||
date: new Date(data.date).toISOString(), // validate/normalize the date string provided from front matter
|
||||
readingTime: readingTime(content).minutes,
|
||||
readingMins: Math.ceil(readingTime(content).minutes),
|
||||
},
|
||||
content,
|
||||
};
|
||||
@ -39,11 +42,10 @@ export const getNoteData = (slug: string) => {
|
||||
|
||||
export const getNote = async (slug: string) => {
|
||||
// https://github.com/kentcdodds/mdx-bundler#nextjs-esbuild-enoent
|
||||
if (process.platform === "win32") {
|
||||
process.env.ESBUILD_BINARY_PATH = path.join(process.cwd(), "node_modules", "esbuild", "esbuild.exe");
|
||||
} else {
|
||||
process.env.ESBUILD_BINARY_PATH = path.join(process.cwd(), "node_modules", "esbuild", "bin", "esbuild");
|
||||
}
|
||||
process.env.ESBUILD_BINARY_PATH =
|
||||
process.platform === "win32"
|
||||
? path.join(process.cwd(), "node_modules", "esbuild", "esbuild.exe")
|
||||
: path.join(process.cwd(), "node_modules", "esbuild", "bin", "esbuild");
|
||||
|
||||
const { frontMatter, content } = getNoteData(slug);
|
||||
const { code: mdxSource } = await bundleMDX({
|
||||
|
@ -13,7 +13,33 @@ image: "/static/images/notes/coronavirus-open-source/covid19dashboards.png"
|
||||
|
||||
import Image from "./components/embeds/Image";
|
||||
import Video from "./components/embeds/Video";
|
||||
import Octocat from "./components/embeds/Octocat";
|
||||
|
||||
export const Octocat = (props) => {
|
||||
return (
|
||||
<a
|
||||
className="no-underline"
|
||||
href={`https://github.com/${props.repo}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
style={{ margin: "0 0.3em", color: "var(--text)" }}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 16 16"
|
||||
width="1em"
|
||||
height="1em"
|
||||
aria-hidden="true"
|
||||
className="icon"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
);
|
||||
};
|
||||
|
||||
We're all quickly learning that worldwide pandemics can bring out both [the best](https://www.vox.com/culture/2020/3/13/21179293/coronavirus-italy-covid19-music-balconies-sing) and [the worst](https://twitter.com/9NewsAUS/status/1236088663093608448) of humanity. But one thing has become readily apparent to me — outside of the large teams of medical professionals risking their lives right this minute, the open source community stands alone in its ability to rapidly organize in the midst of chaos to give back to the world and, in this case, make it safer for all of us.
|
||||
|
||||
|
@ -43,7 +43,7 @@
|
||||
"html-escaper": "^3.0.3",
|
||||
"is-absolute-url": "^4.0.1",
|
||||
"is-email-like": "^2.0.0",
|
||||
"markdown-to-jsx": "^7.1.5",
|
||||
"marked": "^4.0.9",
|
||||
"mdx-bundler": "^8.0.1",
|
||||
"modern-normalize": "github:sindresorhus/modern-normalize#1fc6b5a86676b7ac8abc62d04d6080f92debc70f",
|
||||
"next": "v12.0.8-canary.19",
|
||||
@ -67,6 +67,7 @@
|
||||
"rehype-highlight": "^5.0.2",
|
||||
"rehype-slug": "^5.0.1",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"sanitize-html": "^2.6.1",
|
||||
"styled-jsx": "^4.0.1",
|
||||
"swr": "^1.1.2"
|
||||
},
|
||||
@ -74,10 +75,12 @@
|
||||
"@jakejarvis/eslint-config": "github:jakejarvis/eslint-config#main",
|
||||
"@svgr/webpack": "^6.1.2",
|
||||
"@types/html-escaper": "^3.0.0",
|
||||
"@types/marked": "^4.0.1",
|
||||
"@types/prop-types": "^15.7.4",
|
||||
"@types/react": "^17.0.38",
|
||||
"@types/react-dom": "^17.0.11",
|
||||
"@types/react-is": "^17.0.3",
|
||||
"@types/sanitize-html": "^2.6.1",
|
||||
"autoprefixer": "^10.4.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"esbuild": "^0.14.11",
|
||||
|
51
yarn.lock
51
yarn.lock
@ -1496,6 +1496,11 @@
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/marked@^4.0.1":
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/marked/-/marked-4.0.1.tgz#d588a7bbc4d6551c5e75249bc106ffda96ae33c5"
|
||||
integrity sha512-ZigEmCWdNUU7IjZEuQ/iaimYdDHWHfTe3kg8ORfKjyGYd9RWumPoOJRQXB0bO+XLkNwzCthW3wUIQtANaEZ1ag==
|
||||
|
||||
"@types/mdast@^3.0.0", "@types/mdast@^3.0.3":
|
||||
version "3.0.10"
|
||||
resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.10.tgz#4724244a82a4598884cbbe9bcfd73dff927ee8af"
|
||||
@ -1583,6 +1588,13 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.1.tgz#d8f1c0d0dc23afad6dc16a9e993a0865774b4065"
|
||||
integrity sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==
|
||||
|
||||
"@types/sanitize-html@^2.6.1":
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/sanitize-html/-/sanitize-html-2.6.1.tgz#970193524df719f716c5bcf8db579859c446cd17"
|
||||
integrity sha512-+JLlZdJkIHdgvlFnMorJeLv5WIORNcI+jHsAoPBWMnhGx5Rbz/D1QN5D4qvmoA7fooDlEVy6zlioWSgqbU0KeQ==
|
||||
dependencies:
|
||||
htmlparser2 "^6.0.0"
|
||||
|
||||
"@types/scheduler@*":
|
||||
version "0.16.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39"
|
||||
@ -2442,14 +2454,14 @@ domelementtype@^2.0.1, domelementtype@^2.2.0:
|
||||
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57"
|
||||
integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==
|
||||
|
||||
domhandler@^4.2.0, domhandler@^4.3.0:
|
||||
domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.0.tgz#16c658c626cf966967e306f966b431f77d4a5626"
|
||||
integrity sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==
|
||||
dependencies:
|
||||
domelementtype "^2.2.0"
|
||||
|
||||
domutils@^2.8.0:
|
||||
domutils@^2.5.2, domutils@^2.8.0:
|
||||
version "2.8.0"
|
||||
resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135"
|
||||
integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==
|
||||
@ -3503,6 +3515,16 @@ html-tags@^3.1.0:
|
||||
resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.1.0.tgz#7b5e6f7e665e9fb41f30007ed9e0d41e97fb2140"
|
||||
integrity sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==
|
||||
|
||||
htmlparser2@^6.0.0:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7"
|
||||
integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==
|
||||
dependencies:
|
||||
domelementtype "^2.0.1"
|
||||
domhandler "^4.0.0"
|
||||
domutils "^2.5.2"
|
||||
entities "^2.0.0"
|
||||
|
||||
http-cache-semantics@^4.0.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390"
|
||||
@ -4106,10 +4128,10 @@ markdown-table@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-3.0.2.tgz#9b59eb2c1b22fe71954a65ff512887065a7bb57c"
|
||||
integrity sha512-y8j3a5/DkJCmS5x4dMCQL+OR0+2EAq3DOtio1COSHsmW2BGXnNCK3v12hJt1LrUz5iZH5g0LmuYOjDdI+czghA==
|
||||
|
||||
markdown-to-jsx@^7.1.5:
|
||||
version "7.1.5"
|
||||
resolved "https://registry.yarnpkg.com/markdown-to-jsx/-/markdown-to-jsx-7.1.5.tgz#caf72ad8a8c34a2bb692c4d17e44aabbe4eb19fd"
|
||||
integrity sha512-YQEMMMCX3PYOWtUAQu8Fmz5/sH09s17eyQnDubwaAo8sWmnRTT1og96EFv1vL59l4nWfmtF3L91pqkuheVqRlA==
|
||||
marked@^4.0.9:
|
||||
version "4.0.9"
|
||||
resolved "https://registry.yarnpkg.com/marked/-/marked-4.0.9.tgz#96862d67bd31b4770917f01c93e1d9b3cc73ed96"
|
||||
integrity sha512-HmoFvQwFLxNESeGupeOC+6CLb5WzcCWQmqvVetsErmrI3vrZ6gBumty5IP0ynLPR0zYSoVY7ITC1GffsYIGkog==
|
||||
|
||||
mathml-tag-names@^2.1.3:
|
||||
version "2.1.3"
|
||||
@ -5147,6 +5169,11 @@ parse-json@^5.0.0:
|
||||
json-parse-even-better-errors "^2.3.0"
|
||||
lines-and-columns "^1.1.6"
|
||||
|
||||
parse-srcset@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/parse-srcset/-/parse-srcset-1.0.2.tgz#f2bd221f6cc970a938d88556abc589caaaa2bde1"
|
||||
integrity sha1-8r0iH2zJcKk42IVWq8WJyqqiveE=
|
||||
|
||||
path-exists@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
|
||||
@ -5719,6 +5746,18 @@ safe-buffer@~5.2.0:
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
||||
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
|
||||
|
||||
sanitize-html@^2.6.1:
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-2.6.1.tgz#5d37c08e189c61c0631560a889b10d9d155d000e"
|
||||
integrity sha512-DzjSz3H5qDntD7s1TcWCSoRPmNR8UmA+y+xZQOvWgjATe2Br9ZW73+vD3Pj6Snrg0RuEuJdXgrKvnYuiuixRkA==
|
||||
dependencies:
|
||||
deepmerge "^4.2.2"
|
||||
escape-string-regexp "^4.0.0"
|
||||
htmlparser2 "^6.0.0"
|
||||
is-plain-object "^5.0.0"
|
||||
parse-srcset "^1.0.2"
|
||||
postcss "^8.3.11"
|
||||
|
||||
sax@^1.2.4:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
|
||||
|
Loading…
x
Reference in New Issue
Block a user