mirror of
https://github.com/jakejarvis/jarv.is.git
synced 2025-04-26 13:18:26 -04:00
consolidate mdx file parsing
This commit is contained in:
parent
d2b71887b4
commit
3864a57d1a
@ -1,6 +1,5 @@
|
||||
import Link from "next/link";
|
||||
import { format, parseISO } from "date-fns";
|
||||
import groupBy from "lodash.groupby";
|
||||
import { format } from "date-fns";
|
||||
|
||||
import styles from "./List.module.scss";
|
||||
|
||||
@ -10,18 +9,17 @@ type NoteProps = {
|
||||
slug: string;
|
||||
};
|
||||
|
||||
const List = ({ notes }) => {
|
||||
const notesByYear = groupBy(notes, "year");
|
||||
const List = ({ notesByYear }) => {
|
||||
const sections = [];
|
||||
|
||||
Object.entries(notesByYear).forEach(([year, yearNotes]: [string, NoteProps[]]) => {
|
||||
Object.entries(notesByYear).forEach(([year, notes]: [string, NoteProps[]]) => {
|
||||
sections.push(
|
||||
<section key={year} className={styles.section}>
|
||||
<h2 className={styles.year}>{year}</h2>
|
||||
<ul className={styles.list}>
|
||||
{yearNotes.map((note) => (
|
||||
{notes.map((note) => (
|
||||
<li key={note.slug} className={styles.row}>
|
||||
<span className={styles.date}>{format(parseISO(note.date), "MMM d")}</span>
|
||||
<span className={styles.date}>{format(new Date(note.date), "MMM d")}</span>
|
||||
<span>
|
||||
<Link href={`/notes/${note.slug}/`} prefetch={false}>
|
||||
<a>{note.title}</a>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import Link from "next/link";
|
||||
import { format, parseISO } from "date-fns";
|
||||
import { format } from "date-fns";
|
||||
import Hits from "../hits/Hits";
|
||||
import { DateIcon, TagIcon, EditIcon, ViewsIcon } from "../icons";
|
||||
import * as config from "../../lib/config";
|
||||
@ -20,8 +20,8 @@ const Meta = ({ title, date, slug, tags = [] }: Props) => (
|
||||
<span>
|
||||
<DateIcon className={`icon ${styles.icon}`} />
|
||||
</span>
|
||||
<span title={format(parseISO(date), "PPppp")}>
|
||||
<Link href={`/notes/${slug}/`}>{format(parseISO(date), "MMMM d, yyyy")}</Link>
|
||||
<span title={format(new Date(date), "PPppp")}>
|
||||
<Link href={`/notes/${slug}/`}>{format(new Date(date), "MMMM d, yyyy")}</Link>
|
||||
</span>
|
||||
</div>
|
||||
{tags.length > 0 && (
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { intlFormat, formatDistanceToNowStrict, parseISO } from "date-fns";
|
||||
import { intlFormat, formatDistanceToNowStrict } from "date-fns";
|
||||
import { StarOcticon, ForkOcticon } from "../icons/octicons";
|
||||
|
||||
import styles from "./RepoCard.module.scss";
|
||||
@ -69,7 +69,7 @@ const RepoCard = ({ name, url, description, language, stars, forks, updatedAt }:
|
||||
<div
|
||||
className={styles.meta_item}
|
||||
title={intlFormat(
|
||||
parseISO(updatedAt),
|
||||
new Date(updatedAt),
|
||||
{
|
||||
year: "numeric",
|
||||
month: "short",
|
||||
@ -83,7 +83,7 @@ const RepoCard = ({ name, url, description, language, stars, forks, updatedAt }:
|
||||
}
|
||||
)}
|
||||
>
|
||||
<span>Updated {formatDistanceToNowStrict(parseISO(updatedAt), { addSuffix: true })}</span>
|
||||
<span>Updated {formatDistanceToNowStrict(new Date(updatedAt), { addSuffix: true })}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,30 +1,33 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import matter from "gray-matter";
|
||||
import { format, parseISO } from "date-fns";
|
||||
import * as config from "./config";
|
||||
import { NOTES_DIR, baseUrl } from "./config";
|
||||
|
||||
export const getNoteData = (file: string) => {
|
||||
const slug = file.replace(/\.mdx$/, "");
|
||||
const fullPath = path.join(process.cwd(), config.NOTES_DIR, `${slug}.mdx`);
|
||||
const contents = fs.readFileSync(fullPath, "utf8");
|
||||
const { data } = matter(contents);
|
||||
export const getNoteData = (slug: string) => {
|
||||
const fullPath = path.join(process.cwd(), NOTES_DIR, `${slug}.mdx`);
|
||||
const rawContent = fs.readFileSync(fullPath, "utf8");
|
||||
const { data, content } = matter(rawContent);
|
||||
|
||||
return {
|
||||
...data,
|
||||
slug,
|
||||
permalink: `${config.baseUrl}/notes/${slug}/`,
|
||||
date: parseISO(data.date).toISOString(), // validate/normalize the date string provided from front matter
|
||||
year: parseInt(format(parseISO(data.date), "yyyy")), // parse years here so it's easier to group them on list page
|
||||
frontMatter: {
|
||||
...data,
|
||||
slug,
|
||||
permalink: `${baseUrl}/notes/${slug}/`,
|
||||
date: new Date(data.date).toISOString(), // validate/normalize the date string provided from front matter
|
||||
},
|
||||
content,
|
||||
};
|
||||
};
|
||||
|
||||
// all .mdx files in NOTES_DIR
|
||||
export const getNoteFiles = () =>
|
||||
fs.readdirSync(path.join(process.cwd(), config.NOTES_DIR)).filter((notePath) => /\.mdx$/.test(notePath));
|
||||
export const getNoteSlugs = () =>
|
||||
fs
|
||||
.readdirSync(path.join(process.cwd(), NOTES_DIR))
|
||||
.filter((file) => /\.mdx$/.test(file))
|
||||
.map((noteFile) => noteFile.replace(/\.mdx$/, ""));
|
||||
|
||||
export const getAllNotes = () =>
|
||||
getNoteFiles()
|
||||
.map((file) => getNoteData(file))
|
||||
getNoteSlugs()
|
||||
.map((slug) => getNoteData(slug).frontMatter)
|
||||
// sort notes by date in descending order
|
||||
.sort((note1: any, note2: any) => (note1.date > note2.date ? -1 : 1));
|
||||
|
@ -43,7 +43,6 @@
|
||||
"hex-rgb": "^5.0.0",
|
||||
"highlight.js": "^11.3.1",
|
||||
"is-absolute-url": "^4.0.1",
|
||||
"lodash.groupby": "^4.6.0",
|
||||
"modern-normalize": "github:sindresorhus/modern-normalize#1fc6b5a86676b7ac8abc62d04d6080f92debc70f",
|
||||
"next": "v12.0.8-canary.14",
|
||||
"next-mdx-remote": "^3.0.8",
|
||||
|
@ -14,7 +14,7 @@ type ColorLinkProps = {
|
||||
external?: boolean;
|
||||
};
|
||||
|
||||
const ColorLink = ({ children, href, lightColor, darkColor, title, external = false }: ColorLinkProps) => {
|
||||
const ColorLink = ({ href, title, lightColor, darkColor, external = false, children }: ColorLinkProps) => {
|
||||
external = external || isAbsoluteUrl(href);
|
||||
|
||||
// spits out an alpha color in rgb() that's compatible with linear-gradient()
|
||||
|
@ -1,7 +1,3 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import matter from "gray-matter";
|
||||
import { parseISO } from "date-fns";
|
||||
import { MDXRemote } from "next-mdx-remote";
|
||||
import { serialize } from "next-mdx-remote/serialize";
|
||||
import { NextSeo, ArticleJsonLd } from "next-seo";
|
||||
@ -10,7 +6,7 @@ import Container from "../../components/Container";
|
||||
import Content from "../../components/Content";
|
||||
import Meta from "../../components/notes/Meta";
|
||||
import mdxComponents from "../../components/mdxComponents";
|
||||
import { getNoteFiles } from "../../lib/parse-notes";
|
||||
import { getNoteData, getNoteSlugs } from "../../lib/parse-notes";
|
||||
import * as config from "../../lib/config";
|
||||
import type { GetStaticProps, GetStaticPaths } from "next";
|
||||
|
||||
@ -72,12 +68,9 @@ const Note = ({ frontMatter, source }) => (
|
||||
);
|
||||
|
||||
export const getStaticProps: GetStaticProps = async ({ params }) => {
|
||||
const filePath = path.join(process.cwd(), config.NOTES_DIR, `${params.slug}.mdx`);
|
||||
const rawSource = fs.readFileSync(filePath);
|
||||
const { data, content } = matter(rawSource);
|
||||
const { frontMatter, content } = getNoteData(params.slug as string);
|
||||
|
||||
const mdxSource = await serialize(content, {
|
||||
scope: data,
|
||||
const source = await serialize(content, {
|
||||
mdxOptions: {
|
||||
// remarkPlugins: [],
|
||||
rehypePlugins: [
|
||||
@ -94,23 +87,14 @@ export const getStaticProps: GetStaticProps = async ({ params }) => {
|
||||
|
||||
return {
|
||||
props: {
|
||||
frontMatter: {
|
||||
...data,
|
||||
slug: params.slug,
|
||||
permalink: `${config.baseUrl}/notes/${params.slug}/`,
|
||||
date: parseISO(data.date).toISOString(), // validate/normalize the date string provided from front matter
|
||||
},
|
||||
source: mdxSource,
|
||||
frontMatter,
|
||||
source,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export const getStaticPaths: GetStaticPaths = async () => {
|
||||
const paths = getNoteFiles()
|
||||
// Remove file extensions for page paths
|
||||
.map((notePath) => notePath.replace(/\.mdx?$/, ""))
|
||||
// Map the path into the static paths object required by Next.js
|
||||
.map((slug) => ({ params: { slug } }));
|
||||
const paths = getNoteSlugs().map((slug) => ({ params: { slug } }));
|
||||
|
||||
return {
|
||||
paths,
|
||||
|
@ -1,23 +1,29 @@
|
||||
import { format } from "date-fns";
|
||||
import Layout from "../../components/Layout";
|
||||
import Container from "../../components/Container";
|
||||
import List from "../../components/notes/List";
|
||||
import { getAllNotes } from "../../lib/parse-notes";
|
||||
import type { GetStaticProps } from "next";
|
||||
|
||||
const Notes = ({ notes }) => (
|
||||
const Notes = ({ notesByYear }) => (
|
||||
<Layout>
|
||||
<Container title="Notes" description="Recent posts by Jake Jarvis.">
|
||||
<List notes={notes} />
|
||||
<List notesByYear={notesByYear} />
|
||||
</Container>
|
||||
</Layout>
|
||||
);
|
||||
|
||||
export const getStaticProps: GetStaticProps = async () => {
|
||||
const notes = getAllNotes();
|
||||
// parse the year of each note and group them together
|
||||
const notesByYear = {};
|
||||
getAllNotes().map((note) => {
|
||||
const year = parseInt(format(new Date(note.date), "yyyy"));
|
||||
(notesByYear[year] || (notesByYear[year] = [])).push(note);
|
||||
});
|
||||
|
||||
return {
|
||||
props: {
|
||||
notes,
|
||||
notesByYear,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
23
yarn.lock
23
yarn.lock
@ -3807,11 +3807,6 @@ lodash.debounce@^4.0.8:
|
||||
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
|
||||
integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168=
|
||||
|
||||
lodash.groupby@^4.6.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.groupby/-/lodash.groupby-4.6.0.tgz#0b08a1dcf68397c397855c3239783832df7403d1"
|
||||
integrity sha1-Cwih3PaDl8OXhVwyOXg4Mt90A9E=
|
||||
|
||||
lodash.merge@^4.6.2:
|
||||
version "4.6.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
|
||||
@ -4419,7 +4414,7 @@ path-key@^3.0.0, path-key@^3.1.0:
|
||||
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
|
||||
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
|
||||
|
||||
path-parse@^1.0.6:
|
||||
path-parse@^1.0.6, path-parse@^1.0.7:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
|
||||
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
|
||||
@ -4871,12 +4866,13 @@ resolve-from@^5.0.0:
|
||||
integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==
|
||||
|
||||
resolve@^1.10.0, resolve@^1.14.2, resolve@^1.20.0, resolve@^1.3.2:
|
||||
version "1.20.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975"
|
||||
integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==
|
||||
version "1.21.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.21.0.tgz#b51adc97f3472e6a5cf4444d34bc9d6b9037591f"
|
||||
integrity sha512-3wCbTpk5WJlyE4mSOtDLhqQmGFi0/TD9VPwmiolnk8U0wRgMEktqCXd3vy5buTO3tljvalNvKrjHEfrd2WpEKA==
|
||||
dependencies:
|
||||
is-core-module "^2.2.0"
|
||||
path-parse "^1.0.6"
|
||||
is-core-module "^2.8.0"
|
||||
path-parse "^1.0.7"
|
||||
supports-preserve-symlinks-flag "^1.0.0"
|
||||
|
||||
resolve@^2.0.0-next.3:
|
||||
version "2.0.0-next.3"
|
||||
@ -5462,6 +5458,11 @@ supports-color@^9.2.1:
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-9.2.1.tgz#599dc9d45acf74c6176e0d880bab1d7d718fe891"
|
||||
integrity sha512-Obv7ycoCTG51N7y175StI9BlAXrmgZrFhZOb0/PyjHBher/NmsdBgbbQ1Inhq+gIhz6+7Gb+jWF2Vqi7Mf1xnQ==
|
||||
|
||||
supports-preserve-symlinks-flag@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
|
||||
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
|
||||
|
||||
svg-parser@^2.0.2:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/svg-parser/-/svg-parser-2.0.4.tgz#fdc2e29e13951736140b76cb122c8ee6630eb6b5"
|
||||
|
Loading…
x
Reference in New Issue
Block a user