Use markdoc for songs, basic list pages
This commit is contained in:
parent
b67105736e
commit
8cddb5706e
|
@ -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),
|
||||
],
|
||||
});
|
||||
|
|
14
markdoc.config.mjs
Normal file
14
markdoc.config.mjs
Normal file
|
@ -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 },
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 => `<th>${lang}</th>`);
|
||||
// const rows = verses.map(verse =>
|
||||
// `<tr>${keys.map(lang =>
|
||||
// `<td>${verse[lang].map(line =>
|
||||
// `<span>${line}</span><br/>`).join('')}
|
||||
// </td>`).join('')}
|
||||
// </tr>`
|
||||
// )
|
||||
// .join('');
|
||||
|
||||
// return [
|
||||
// "<table>",
|
||||
// `<tr>${head.join('')}</tr>`,
|
||||
// rows,
|
||||
// "</table>",
|
||||
// ].join('');
|
||||
// }
|
||||
|
||||
export function transform(html: string) {
|
||||
return reduceStack(toStack(html));
|
||||
}
|
|
@ -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()
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
34
src/content/songs/black-eyes.mdoc
Normal file
34
src/content/songs/black-eyes.mdoc
Normal file
|
@ -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 %}
|
|
@ -1,33 +0,0 @@
|
|||
---
|
||||
title: Black Eyes
|
||||
---
|
||||
import Lyrics from '../../components/lyrics/Lyrics.astro';
|
||||
|
||||
|
||||
<Lyrics>
|
||||
|
||||
# Japanese
|
||||
- 瞬きをして 切り取る時間
|
||||
- 何気なくても 大切な今を
|
||||
- 忘れないで 居られるように
|
||||
- いつか 頭の中
|
||||
- 掻き消して しまっても
|
||||
# Romaji
|
||||
- fddsfsaf
|
||||
- fdsfadsf
|
||||
- test
|
||||
- test
|
||||
---
|
||||
# Japanese
|
||||
- 瞬きをして 切り取る時間ff
|
||||
- 何気なくても 大切な今を
|
||||
- 忘れないで 居られるように
|
||||
- いつか 頭の中
|
||||
- 掻き消して しまっても
|
||||
# Romaji
|
||||
- fddsfsaf
|
||||
- fdsfadsf
|
||||
- test
|
||||
- test
|
||||
|
||||
</Lyrics>
|
|
@ -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();
|
||||
---
|
||||
|
||||
<Lyrics frontmatter={entry.data}>
|
||||
<Lyrics frontmatter={song.data}>
|
||||
<Content />
|
||||
</Lyrics>
|
||||
|
|
24
src/pages/songs/[cat].astro
Normal file
24
src/pages/songs/[cat].astro
Normal file
|
@ -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;
|
||||
---
|
||||
|
||||
<List title={cat!} pages={songs} />
|
|
@ -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}/` }));
|
||||
|
||||
---
|
||||
|
||||
<List title="Songs" pages={posts} />
|
||||
<List title="Songs" pages={pages} />
|
||||
|
|
15
src/utils/songs.ts
Normal file
15
src/utils/songs.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
import type { CollectionEntry } from "astro:content";
|
||||
|
||||
|
||||
type Song = CollectionEntry<'songs'>;
|
||||
|
||||
|
||||
export function getAllCats(songs: Song[]): Set<string> {
|
||||
return songs.reduce(
|
||||
(cats, next) => (
|
||||
Object.keys(next.data.album).forEach(cat => cats.add(cat)),
|
||||
cats
|
||||
),
|
||||
new Set<string>()
|
||||
);
|
||||
}
|
Loading…
Reference in a new issue