From 8cddb5706e2409489f11122770b3708edad0646b Mon Sep 17 00:00:00 2001 From: Maciej Jur Date: Wed, 26 Apr 2023 21:36:34 +0200 Subject: [PATCH] Use markdoc for songs, basic list pages --- astro.config.ts | 4 +- markdoc.config.mjs | 14 +++++ package.json | 1 + pnpm-lock.yaml | 54 +++++++++++++++++++ .../{ => markdown}/lyrics/Lyrics.astro | 0 .../{ => markdown}/lyrics/transform.ts | 25 +-------- src/content/config.ts | 11 ++++ src/content/songs/black-eyes.mdoc | 34 ++++++++++++ src/content/songs/black-eyes.mdx | 33 ------------ src/pages/songs/[...slug].astro | 10 ++-- src/pages/songs/[cat].astro | 24 +++++++++ src/pages/songs/index.astro | 13 +++-- src/utils/songs.ts | 15 ++++++ 13 files changed, 170 insertions(+), 68 deletions(-) create mode 100644 markdoc.config.mjs rename src/components/{ => markdown}/lyrics/Lyrics.astro (100%) rename src/components/{ => markdown}/lyrics/transform.ts (70%) create mode 100644 src/content/songs/black-eyes.mdoc delete mode 100644 src/content/songs/black-eyes.mdx create mode 100644 src/pages/songs/[cat].astro create mode 100644 src/utils/songs.ts diff --git a/astro.config.ts b/astro.config.ts index 04d2681..9cae606 100644 --- a/astro.config.ts +++ b/astro.config.ts @@ -5,6 +5,7 @@ import remarkEmoji from 'remark-emoji'; import mdx from '@astrojs/mdx'; import remarkRuby from './src/assets/ruby'; import solid from '@astrojs/solid-js'; +import markdoc from '@astrojs/markdoc'; // https://astro.build/config @@ -26,6 +27,7 @@ export default defineConfig({ }, integrations: [ mdx(), - solid() + solid(), + markdoc(undefined), ], }); diff --git a/markdoc.config.mjs b/markdoc.config.mjs new file mode 100644 index 0000000..2391f8d --- /dev/null +++ b/markdoc.config.mjs @@ -0,0 +1,14 @@ +import { defineMarkdocConfig } from '@astrojs/markdoc/config'; +import Lyrics from './src/components/markdown/lyrics/Lyrics.astro'; + + +export default defineMarkdocConfig({ + tags: { + lyrics: { + render: Lyrics, + attributes: { + type: { type: String }, + } + } + } +}) diff --git a/package.json b/package.json index f9bf997..ae67a2e 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "astro": "astro" }, "dependencies": { + "@astrojs/markdoc": "^0.1.1", "@astrojs/mdx": "^0.19.0", "@astrojs/solid-js": "^2.1.0", "astro": "^2.3.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9270a1d..bf25803 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,6 +1,9 @@ lockfileVersion: '6.0' dependencies: + '@astrojs/markdoc': + specifier: ^0.1.1 + version: 0.1.1(astro@2.3.1) '@astrojs/mdx': specifier: ^0.19.0 version: 0.19.0(astro@2.3.1)(rollup@3.21.0) @@ -118,6 +121,23 @@ packages: vscode-uri: 3.0.7 dev: false + /@astrojs/markdoc@0.1.1(astro@2.3.1): + resolution: {integrity: sha512-NJgMTZWTCcL+4qmDim/wi53Mc6X7hk12hyI3JHWW7oiWVchdrvbdvG5i3c2bmT73+bMtG8XOEt2vvapQRixAKw==} + engines: {node: '>=16.12.0'} + peerDependencies: + astro: ^2.2.0 + dependencies: + '@markdoc/markdoc': 0.2.2 + astro: 2.3.1(sass@1.62.1) + esbuild: 0.17.18 + gray-matter: 4.0.3 + kleur: 4.1.5 + zod: 3.21.4 + transitivePeerDependencies: + - '@types/react' + - react + dev: false + /@astrojs/markdown-remark@2.1.4(astro@2.3.1): resolution: {integrity: sha512-z5diCcFo2xkBAJ11KySAIKpZZkULZmzUvWsZ2VWIOrR6QrEgEfVl5jTpgPSedx4m+xUPuemlUviOotGB7ItNsQ==} peerDependencies: @@ -702,6 +722,21 @@ packages: resolution: {integrity: sha512-4/RWEeXDO6bocPONheFe6gX/oQdP/bEpv0oL4HqjPP5DCenBSt0mHgahppY49N0CpsaqffdwPq+TlX9CYOq2Dw==} dev: false + /@markdoc/markdoc@0.2.2: + resolution: {integrity: sha512-0TiD9jmA5h5znN4lxo7HECAu3WieU5g5vUsfByeucrdR/x88hEilpt16EydFyJwJddQ/3w5HQgW7Ovy62r4cyw==} + engines: {node: '>=14.7.0'} + peerDependencies: + '@types/react': '*' + react: '*' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + optionalDependencies: + '@types/markdown-it': 12.2.3 + dev: false + /@mdx-js/mdx@2.3.0: resolution: {integrity: sha512-jLuwRlz8DQfQNiUCJR50Y09CGPq3fLtmtUQfVrj79E0JWu3dvsVcxVIcfhR5h0iXu+/z++zDrYeiJqifRynJkA==} dependencies: @@ -873,16 +908,35 @@ packages: '@types/geojson': 7946.0.10 dev: true + /@types/linkify-it@3.0.2: + resolution: {integrity: sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==} + dev: false + optional: true + /@types/lunr@2.3.4: resolution: {integrity: sha512-j4x4XJwZvorEUbA519VdQ5b9AOU9TSvfi8tvxMAfP8XzNLtFex7A8vFQwqOx3WACbV0KMXbACV3cZl4/gynQ7g==} dev: true + /@types/markdown-it@12.2.3: + resolution: {integrity: sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==} + requiresBuild: true + dependencies: + '@types/linkify-it': 3.0.2 + '@types/mdurl': 1.0.2 + dev: false + optional: true + /@types/mdast@3.0.11: resolution: {integrity: sha512-Y/uImid8aAwrEA24/1tcRZwpxX3pIFTSilcNDKSPn+Y2iDywSEachzRuvgAYYLR3wpGXAsMbv5lvKLDZLeYPAw==} dependencies: '@types/unist': 2.0.6 dev: false + /@types/mdurl@1.0.2: + resolution: {integrity: sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==} + dev: false + optional: true + /@types/mdx@2.0.4: resolution: {integrity: sha512-qCYrNdpKwN6YO6FVnx+ulfqifKlE3lQGsNhvDaW9Oxzyob/cRLBJWow8GHBBD4NxQ7BVvtsATgLsX0vZAWmtrg==} dev: false diff --git a/src/components/lyrics/Lyrics.astro b/src/components/markdown/lyrics/Lyrics.astro similarity index 100% rename from src/components/lyrics/Lyrics.astro rename to src/components/markdown/lyrics/Lyrics.astro diff --git a/src/components/lyrics/transform.ts b/src/components/markdown/lyrics/transform.ts similarity index 70% rename from src/components/lyrics/transform.ts rename to src/components/markdown/lyrics/transform.ts index 7e1b388..a530ea9 100644 --- a/src/components/lyrics/transform.ts +++ b/src/components/markdown/lyrics/transform.ts @@ -30,11 +30,10 @@ function toStack(html: string): Stack { nodes.reduce((lang, node) => { switch (node.rawTagName) { case 'h1': { - const lang: string = node.id.replace(/-.+/, ''); - createVerse(stack, lang); - return lang; + return node.text; } case 'ul': { + createVerse(stack, lang); const lines = extractLines(node.childNodes); stack[lang].at(-1)!.push(...lines); return lang; @@ -62,26 +61,6 @@ function reduceStack(stack: Stack): Verse[] { return verses.reverse(); } -// function toHtml(verses: Verse[]): string { -// const keys = Object.keys(verses[0]); -// const head = keys.map(lang => `${lang}`); -// const rows = verses.map(verse => -// `${keys.map(lang => -// `${verse[lang].map(line => -// `${line}
`).join('')} -// `).join('')} -// ` -// ) -// .join(''); - -// return [ -// "", -// `${head.join('')}`, -// rows, -// "
", -// ].join(''); -// } - export function transform(html: string) { return reduceStack(toStack(html)); } diff --git a/src/content/config.ts b/src/content/config.ts index 93ac5fd..598fd3c 100644 --- a/src/content/config.ts +++ b/src/content/config.ts @@ -25,5 +25,16 @@ export const collections = { date: z.date(), tags: z.array(z.string()).optional(), }) + }), + songs: defineCollection({ + schema: z.object({ + title: z.string(), + album: z.record( + z.string(), + z.object({ + track: z.number() + }) + ) + }) }) } diff --git a/src/content/songs/black-eyes.mdoc b/src/content/songs/black-eyes.mdoc new file mode 100644 index 0000000..c807a96 --- /dev/null +++ b/src/content/songs/black-eyes.mdoc @@ -0,0 +1,34 @@ +--- +title: Black Eyes +album: + ARCD0051: + track: 7 +--- + +{% lyrics %} +# Japanese +- 瞬きをして 切り取る時間 +- 何気なくても 大切な今を +- 忘れないで 居られるように +- いつか 頭の中 +- 掻き消して しまっても +# Romaji +- Matataki wo shite kiritoru jikan +- Nanigenakutemo taisetsuna ima wo +- Wasurenaide irareru you ni +- Itsuka atama no naka +- Kakikeshite shimattemo +--- +# Japanese +- 瞬きをして 焼き付ける空 +- 永遠の折り 縁取らせたら +- 綺麗なまま 残されてく +- いつか 思い出して +- 色褪せて しまっても +# Romaji +- Matataki wo shite yakitsukeru sora +- Eien no ori fuchidorasetara +- Kireina mama nokosareteku +- Itsuka omoidashite +- Iroasete shimattemo +{% /lyrics %} diff --git a/src/content/songs/black-eyes.mdx b/src/content/songs/black-eyes.mdx deleted file mode 100644 index 03d0af1..0000000 --- a/src/content/songs/black-eyes.mdx +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: Black Eyes ---- -import Lyrics from '../../components/lyrics/Lyrics.astro'; - - - - -# Japanese -- 瞬きをして 切り取る時間 -- 何気なくても 大切な今を -- 忘れないで 居られるように -- いつか 頭の中 -- 掻き消して しまっても -# Romaji -- fddsfsaf -- fdsfadsf -- test -- test ---- -# Japanese -- 瞬きをして 切り取る時間ff -- 何気なくても 大切な今を -- 忘れないで 居られるように -- いつか 頭の中 -- 掻き消して しまっても -# Romaji -- fddsfsaf -- fdsfadsf -- test -- test - - diff --git a/src/pages/songs/[...slug].astro b/src/pages/songs/[...slug].astro index 11d0a5a..72ba000 100644 --- a/src/pages/songs/[...slug].astro +++ b/src/pages/songs/[...slug].astro @@ -4,13 +4,15 @@ import { getCollection } from "astro:content"; export async function getStaticPaths() { return (await getCollection('songs')) - .map(entry => ({params: {slug: entry.slug}, props: {entry}})); + .map(song => Object.keys(song.data.album) + .map(cat => ({ params: {slug: `${cat}/${song.slug}`}, props: {song} }))) + .flat() } -const { entry } = Astro.props; -const { Content } = await entry.render(); +const { song } = Astro.props; +const { Content } = await song.render(); --- - + diff --git a/src/pages/songs/[cat].astro b/src/pages/songs/[cat].astro new file mode 100644 index 0000000..94d12d3 --- /dev/null +++ b/src/pages/songs/[cat].astro @@ -0,0 +1,24 @@ +--- +import List from "../../layouts/List.astro"; +import { getCollection } from 'astro:content'; +import { getAllCats } from "../../utils/songs"; + + +export async function getStaticPaths() { + const songs = await getCollection('songs'); + const cats = getAllCats(songs); + + return [...cats].map(cat => ({ + params: {cat}, + props: { + songs: songs + .filter(entry => cat in entry.data.album) + .map(song => ({ title: song.data.title, slug: `/songs/${cat}/${song.slug}/` })) } + })) +} + +const { cat } = Astro.params; +const { songs } = Astro.props; +--- + + \ No newline at end of file diff --git a/src/pages/songs/index.astro b/src/pages/songs/index.astro index 13e15bf..a3cf9d8 100644 --- a/src/pages/songs/index.astro +++ b/src/pages/songs/index.astro @@ -1,14 +1,13 @@ --- import List from "../../layouts/List.astro"; import { getCollection } from 'astro:content'; +import { getAllCats } from "../../utils/songs"; -const posts = (await getCollection('songs')) - .sort((a, b) => a.data.date < b.data.date ? 1 : -1) - .map(entry => ({ - title: entry.data.title, - slug: `/songs/${entry.slug}/`, - })) + +const pages = [...getAllCats(await getCollection('songs'))] + .sort((a, b) => a < b ? 1 : -1) + .map(catalog => ({ title: catalog, slug: `/songs/${catalog}/` })); --- - + diff --git a/src/utils/songs.ts b/src/utils/songs.ts new file mode 100644 index 0000000..e9feed5 --- /dev/null +++ b/src/utils/songs.ts @@ -0,0 +1,15 @@ +import type { CollectionEntry } from "astro:content"; + + +type Song = CollectionEntry<'songs'>; + + +export function getAllCats(songs: Song[]): Set { + return songs.reduce( + (cats, next) => ( + Object.keys(next.data.album).forEach(cat => cats.add(cat)), + cats + ), + new Set() + ); +}