(songs) delete songs for now
This commit is contained in:
parent
09de7c070f
commit
72a9611f1a
|
@ -1,41 +0,0 @@
|
||||||
---
|
|
||||||
import type { Dayjs } from "dayjs";
|
|
||||||
import Base from "./Base.astro";
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
title: string;
|
|
||||||
date: Dayjs;
|
|
||||||
tags?: string[];
|
|
||||||
github?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { title, date, tags = [], github } = Astro.props;
|
|
||||||
---
|
|
||||||
|
|
||||||
<Base title={title}>
|
|
||||||
<div class="p-header__meta">
|
|
||||||
<span class="p_date">
|
|
||||||
<img class="p_date__icon" width="120" height="123" src="/static/svg/calendar.svg" alt="">
|
|
||||||
<time datetime={date.toISOString()}>{date.format("MMM DD, YYYY")}</time>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<!-- {%- include "partials/tags.html" -%} -->
|
|
||||||
<section class="p_tags">
|
|
||||||
<img class="p_tags__icon" width="123" height="105" src="/static/svg/tags.svg" alt="">
|
|
||||||
<ul class="p_tags__list">
|
|
||||||
{tags.map(tag => <li><a href={`/tags/${tag}/`}>{tag}</a></li>)}
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- {%- include "partials/github.html" -%} -->
|
|
||||||
{github && (
|
|
||||||
<a href={github} class="p-github" aria-label="View source on GitHub">
|
|
||||||
<svg width="40" height="40" viewBox="0 0 250 250" aria-hidden="true">
|
|
||||||
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
|
|
||||||
<path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path>
|
|
||||||
<path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
)}
|
|
||||||
</Base>
|
|
|
@ -1,12 +0,0 @@
|
||||||
---
|
|
||||||
interface Props {
|
|
||||||
title: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { title } = Astro.props;
|
|
||||||
---
|
|
||||||
|
|
||||||
<header class="p-header">
|
|
||||||
<h1 class="p-header__heading">{title}</h1>
|
|
||||||
<slot />
|
|
||||||
</header>
|
|
|
@ -1,19 +0,0 @@
|
||||||
---
|
|
||||||
interface Props {
|
|
||||||
albums: Array<{
|
|
||||||
title: string;
|
|
||||||
cover: string;
|
|
||||||
url: string;
|
|
||||||
}>
|
|
||||||
}
|
|
||||||
|
|
||||||
const { albums } = Astro.props;
|
|
||||||
---
|
|
||||||
<section class="c-album-grid">
|
|
||||||
{albums.map(album =>
|
|
||||||
<a class="c-album-grid__item" href={album.url}>
|
|
||||||
<img class="c-album-grid__image" src={album.cover} alt=""/>
|
|
||||||
<div class="c-album-grid__title">{album.title}</div>
|
|
||||||
</a>
|
|
||||||
)}
|
|
||||||
</section>
|
|
|
@ -1,19 +0,0 @@
|
||||||
---
|
|
||||||
interface Props {
|
|
||||||
image: string;
|
|
||||||
title: string;
|
|
||||||
small: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { image, title, small } = Astro.props;
|
|
||||||
---
|
|
||||||
|
|
||||||
<section class="c-song">
|
|
||||||
<a href={image}><img src={image} /></a>
|
|
||||||
<div class="c-song__title">
|
|
||||||
<h2 class="c-song__heading">{title}</h2>
|
|
||||||
<span class="c-song__cat">{small}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<slot />
|
|
||||||
</section>
|
|
|
@ -1,27 +0,0 @@
|
||||||
---
|
|
||||||
import Ruby from "./Ruby.astro";
|
|
||||||
import { transform } from "../../utils/songs/parse";
|
|
||||||
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
markdown?: boolean;
|
|
||||||
song?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = Astro.props.song || await Astro.slots.render('default');
|
|
||||||
const markdown = Astro.props.markdown;
|
|
||||||
|
|
||||||
const lyrics = transform(data, markdown);
|
|
||||||
const cols = lyrics.length ? Object.keys(lyrics[0]) : [];
|
|
||||||
---
|
|
||||||
|
|
||||||
<table class="c-lyrics">
|
|
||||||
<tr>{cols.map(col => <th>{col}</th>)}</tr>
|
|
||||||
{lyrics.map(row =>
|
|
||||||
<tr>{cols.map(col =>
|
|
||||||
<td>
|
|
||||||
{row[col].map(line => <span><Ruby text={line}/></span><br/>)}
|
|
||||||
</td>
|
|
||||||
)}</tr>
|
|
||||||
)}
|
|
||||||
</table>
|
|
|
@ -1,14 +0,0 @@
|
||||||
---
|
|
||||||
import { transform } from '../../utils/ruby';
|
|
||||||
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
text: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const text = transform(Astro.props.text);
|
|
||||||
---
|
|
||||||
{text.map(annotated => typeof annotated === 'object'
|
|
||||||
? <ruby>{annotated.text}<rp>(</rp><rt>{annotated.ruby}</rt><rp>)</rp></ruby>
|
|
||||||
: annotated
|
|
||||||
)}
|
|
|
@ -1,61 +0,0 @@
|
||||||
---
|
|
||||||
interface Props {
|
|
||||||
metadata: {
|
|
||||||
cover: string;
|
|
||||||
title: string;
|
|
||||||
track: number;
|
|
||||||
name: string;
|
|
||||||
composer?: string;
|
|
||||||
lyrics?: string;
|
|
||||||
vocal?: string[];
|
|
||||||
other: Array<{
|
|
||||||
cat: string;
|
|
||||||
}>;
|
|
||||||
origin?: string[]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const { metadata } = Astro.props;
|
|
||||||
---
|
|
||||||
<table class="c-song__table">
|
|
||||||
<tr>
|
|
||||||
<td>Track</td>
|
|
||||||
<td>{metadata.track}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Circle</td>
|
|
||||||
<td>{metadata.name}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Composer</td>
|
|
||||||
<td>{metadata.composer}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Lyrics</td>
|
|
||||||
<td>{metadata.lyrics}</td>
|
|
||||||
</tr>
|
|
||||||
{!!metadata.vocal?.length &&
|
|
||||||
<tr>
|
|
||||||
<td>Vocal</td>
|
|
||||||
<td>
|
|
||||||
<ul>{metadata.vocal.map(vocalist => <li>{vocalist}</li>)}</ul>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
}
|
|
||||||
{!!metadata.origin?.length &&
|
|
||||||
<tr>
|
|
||||||
<td>Origin</td>
|
|
||||||
<td>
|
|
||||||
<ul>{metadata.origin.map(title => <li>{title}</li>)}</ul>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
}
|
|
||||||
{!!metadata.other?.length &&
|
|
||||||
<tr>
|
|
||||||
<td>Other versions</td>
|
|
||||||
<td>
|
|
||||||
<ul>{metadata.other.map(version => <li>{version.cat}</li>)}</ul>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
}
|
|
||||||
</table>
|
|
|
@ -16,21 +16,6 @@ export const collections = {
|
||||||
tags: z.array(z.string()).optional(),
|
tags: z.array(z.string()).optional(),
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
songs: defineCollection({
|
|
||||||
schema: z.object({
|
|
||||||
title: z.string(),
|
|
||||||
composer: z.string().optional(),
|
|
||||||
lyrics: z.string().optional(),
|
|
||||||
origin: z.array(z.string()).optional(),
|
|
||||||
album: z.record(
|
|
||||||
z.string(),
|
|
||||||
z.object({
|
|
||||||
track: z.number(),
|
|
||||||
vocal: z.array(z.string()).optional()
|
|
||||||
})
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
wiki: defineCollection({
|
wiki: defineCollection({
|
||||||
schema: z.object({
|
schema: z.object({
|
||||||
title: z.string(),
|
title: z.string(),
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
---
|
|
||||||
slug: dont-lose
|
|
||||||
title: "Don't lose"
|
|
||||||
composer: Masayoshi Minoshima
|
|
||||||
lyrics: Mei Ayakura
|
|
||||||
origin:
|
|
||||||
- 亡き王女の為のセプテット
|
|
||||||
album:
|
|
||||||
ARCD0054:
|
|
||||||
track: 7
|
|
||||||
vocal:
|
|
||||||
- nomico
|
|
||||||
---
|
|
||||||
|
|
||||||
# Japanese
|
|
||||||
- こんなにも 綺麗な月は
|
|
||||||
- どうしても 届かないけど
|
|
||||||
- どんなにも 赤さは絶えず
|
|
||||||
- いつまでも 燃え続けていて
|
|
||||||
- あんなにも 求めてるのに
|
|
||||||
- なんどでも 深く底まで
|
|
||||||
- そんなにも 堕ちてくのなら
|
|
||||||
- なにもかも 終わりにするから
|
|
||||||
---
|
|
||||||
- 飲み込んだ 暗闇の奥
|
|
||||||
- 寂しいの 独りにしないで
|
|
||||||
- 暖かな 揺らめきがまだ
|
|
||||||
- ほんの僅かに 視界に
|
|
||||||
- 消えないで 夢なら醒めて
|
|
||||||
- 壊してしまう 無くさないように
|
|
||||||
- 必要と してしまうほど
|
|
||||||
- 離れていくの どこまでも
|
|
||||||
---
|
|
||||||
- 愛してた 閉じ込めるほどに
|
|
||||||
- 哀してた 閉じ込めるほどに
|
|
||||||
- 「I」してた 閉じ込めるほどに
|
|
||||||
- だけどもう 違うから
|
|
|
@ -1,37 +0,0 @@
|
||||||
---
|
|
||||||
slug: eyes-of-truth
|
|
||||||
title: Eyes of Truth (ALR Remix)
|
|
||||||
composer: Masayoshi Minoshima
|
|
||||||
lyrics: 溝口ゆうま
|
|
||||||
origin:
|
|
||||||
- ラストリモート
|
|
||||||
album:
|
|
||||||
ARCD0054:
|
|
||||||
track: 9
|
|
||||||
vocal:
|
|
||||||
- KUMI(ヲタみん)
|
|
||||||
---
|
|
||||||
|
|
||||||
# Japanese
|
|
||||||
- 回る 運命の歯車 人の手に委ねては
|
|
||||||
- 未来さえ 創られてゆく 決められた
|
|
||||||
- 朝を迎えて繰り返す生命
|
|
||||||
|
|
||||||
- 「心」繋ぐ希望などエゴが纏わりついて
|
|
||||||
- 命さえ0と1で守られては死の行く先へ道連れを探して
|
|
||||||
|
|
||||||
- 彷徨う「瞳」は殻の中で微睡み
|
|
||||||
- 世界に真実よあれ 涙の答えは
|
|
||||||
- 切り刻んだ 心の奥底で笑う
|
|
||||||
- Eyes of Truth
|
|
||||||
|
|
||||||
- 回る 地上の歯車 人の手に染められて
|
|
||||||
- もういいよ 欲しいモノは全て消えて
|
|
||||||
- 朝を忘れて 「瞳」は死を語る
|
|
||||||
|
|
||||||
- 答え知らずに突き進む命の愚かさ
|
|
||||||
|
|
||||||
- 彷徨う「瞳」は殻の中で微睡み
|
|
||||||
- 世界に真実よあれ 涙の答えは
|
|
||||||
- 切り刻んだ 心の奥底で笑う
|
|
||||||
- Eyes of Truth
|
|
|
@ -1,13 +0,0 @@
|
||||||
---
|
|
||||||
slug: beautiful-sky
|
|
||||||
title: Beautiful Sky
|
|
||||||
composer: Masayoshi Minoshima
|
|
||||||
lyrics: Mei Ayakura
|
|
||||||
origin:
|
|
||||||
- U.N.オーエンは彼女なのか?
|
|
||||||
album:
|
|
||||||
ARCD0054:
|
|
||||||
track: 2
|
|
||||||
vocal:
|
|
||||||
- nachi
|
|
||||||
---
|
|
|
@ -1,22 +0,0 @@
|
||||||
---
|
|
||||||
slug: dream-again
|
|
||||||
title: "Dream Again"
|
|
||||||
composer: Camellia
|
|
||||||
lyrics: Camellia
|
|
||||||
origin:
|
|
||||||
- the Last Judgment
|
|
||||||
album:
|
|
||||||
ARCD0054:
|
|
||||||
track: 5
|
|
||||||
vocal:
|
|
||||||
- Mei Ayakura
|
|
||||||
---
|
|
||||||
|
|
||||||
# Japanese
|
|
||||||
- 秒針の音が響空間 狭くて安心するほど
|
|
||||||
- 割り込んだ感覚に目を閉じる 光がまた眩かしすぎて
|
|
||||||
|
|
||||||
- どこまでも続いていく階段 [降]{くだ}った途方もないほど
|
|
||||||
- 行きたい場所はもう決まっている 幻想の声のする所
|
|
||||||
|
|
||||||
- 夢溢れる海へ
|
|
|
@ -1,39 +0,0 @@
|
||||||
---
|
|
||||||
slug: black-eyes
|
|
||||||
title: Black Eyes
|
|
||||||
composer: Kirin (EastNewSound)
|
|
||||||
lyrics: Mei Ayakura
|
|
||||||
origin:
|
|
||||||
- 天狗が見ている 〜 Black Eyes
|
|
||||||
album:
|
|
||||||
ARCD0051:
|
|
||||||
track: 7
|
|
||||||
vocal:
|
|
||||||
- Mei Ayakura
|
|
||||||
---
|
|
||||||
|
|
||||||
# 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
|
|
|
@ -1,15 +0,0 @@
|
||||||
{
|
|
||||||
"alstroemeria-records": {
|
|
||||||
"name": "Alstroemeria Records",
|
|
||||||
"albums": {
|
|
||||||
"ARCD0051": {
|
|
||||||
"title": "Engaged Dancehall",
|
|
||||||
"cover": "/static/albums/ARCD0051.jpg"
|
|
||||||
},
|
|
||||||
"ARCD0054": {
|
|
||||||
"title": "Ignition Dancehall",
|
|
||||||
"cover": "/static/albums/ARCD0054.jpg"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -7,6 +7,23 @@ import Footer from "../components/base/Footer.astro";
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<Head/>
|
<Head/>
|
||||||
<body>
|
<body>
|
||||||
|
<script is:inline>
|
||||||
|
(() => {
|
||||||
|
const theme = (
|
||||||
|
localStorage?.getItem("theme") ||
|
||||||
|
window.matchMedia("(prefers-color-scheme: dark)").matches && "dark" ||
|
||||||
|
"light"
|
||||||
|
);
|
||||||
|
|
||||||
|
const cl = document.body.classList;
|
||||||
|
switch (theme) {
|
||||||
|
case "light": return cl.remove("dark");
|
||||||
|
case "dark": return cl.add("dark");
|
||||||
|
}
|
||||||
|
localStorage?.setItem("theme", theme);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
|
||||||
<slot name="header">
|
<slot name="header">
|
||||||
<Header/>
|
<Header/>
|
||||||
</slot>
|
</slot>
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
---
|
|
||||||
import type { Dayjs } from "dayjs";
|
|
||||||
import Base from "./Base.astro";
|
|
||||||
import Header from "../components/headers/Base.astro";
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
title: string;
|
|
||||||
pages: Array<{
|
|
||||||
title: string;
|
|
||||||
slug: string;
|
|
||||||
date?: Dayjs;
|
|
||||||
}>;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { title, pages } = Astro.props;
|
|
||||||
const dates = pages.every(page => page.date);
|
|
||||||
---
|
|
||||||
|
|
||||||
<Base>
|
|
||||||
<main class="l-pages">
|
|
||||||
<article class="l-pages__list readable">
|
|
||||||
<Header title={title} />
|
|
||||||
<div class="p-pagelist" class:list={{dates}}>
|
|
||||||
{pages.map(page => (<>
|
|
||||||
{dates && (
|
|
||||||
<time class="date" datetime={page.date!.toISOString()}>
|
|
||||||
{page.date!.format("MMM DD, YYYY")}
|
|
||||||
</time>
|
|
||||||
)}
|
|
||||||
<a href={page.slug}>{page.title}</a>
|
|
||||||
</>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</article>
|
|
||||||
</main>
|
|
||||||
</Base>
|
|
|
@ -1,56 +0,0 @@
|
||||||
---
|
|
||||||
import Base from "@layouts/Base.astro";
|
|
||||||
import Info from "@components/songs/Info.astro";
|
|
||||||
import SongInfo from "@components/songs/SongInfo.astro";
|
|
||||||
import Lyrics from "@components/songs/Lyrics.astro";
|
|
||||||
import { CollectionEntry, getCollection } from "astro:content";
|
|
||||||
import { ALBUMS } from "@utils/songs/data";
|
|
||||||
|
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
|
||||||
return []; /*(await getCollection('songs'))
|
|
||||||
.map(song => Object.keys(song.data.album)
|
|
||||||
.map(cat => ({
|
|
||||||
params: { circle: ALBUMS[cat].circle, cat, song: song.slug},
|
|
||||||
props: { song, cat }
|
|
||||||
})))
|
|
||||||
.flat()*/
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
cat: string;
|
|
||||||
song: CollectionEntry<'songs'>;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { cat, song } = Astro.props;
|
|
||||||
|
|
||||||
/** Other versions of this song */
|
|
||||||
const other = Object.keys(song.data.album)
|
|
||||||
.filter(other => other != cat)
|
|
||||||
.map(cat => ({ cat, title: ALBUMS[cat].title }));
|
|
||||||
|
|
||||||
const metadata = {
|
|
||||||
...song.data,
|
|
||||||
...song.data.album[cat],
|
|
||||||
...ALBUMS[cat],
|
|
||||||
other
|
|
||||||
}
|
|
||||||
---
|
|
||||||
|
|
||||||
<Base>
|
|
||||||
<main class="l-songs-aside">
|
|
||||||
<article class="l-songs-aside__page">
|
|
||||||
<header class="p-header">
|
|
||||||
<h1 class="p-header__heading">{song.data.title}</h1>
|
|
||||||
</header>
|
|
||||||
<Lyrics song={song.body} />
|
|
||||||
</article>
|
|
||||||
|
|
||||||
<aside class="l-song__aside">
|
|
||||||
<Info image={metadata.cover} title={metadata.title} small={cat}>
|
|
||||||
<SongInfo metadata={metadata} />
|
|
||||||
</Info>
|
|
||||||
</aside>
|
|
||||||
</main>
|
|
||||||
</Base>
|
|
|
@ -47,3 +47,7 @@
|
||||||
|
|
||||||
--momiji: url("/static/svg/momiji.svg") 0 0, url("/static/svg/momiji.svg") 16px 16px;
|
--momiji: url("/static/svg/momiji.svg") 0 0, url("/static/svg/momiji.svg") 16px 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body.dark {
|
||||||
|
// todo dark mode
|
||||||
|
}
|
||||||
|
|
16
src/types.d.ts
vendored
16
src/types.d.ts
vendored
|
@ -1,16 +0,0 @@
|
||||||
type TODO = any;
|
|
||||||
|
|
||||||
/** @file src/data/circles.json */
|
|
||||||
interface CirclesSchema {
|
|
||||||
/** slug */
|
|
||||||
[key: string]: {
|
|
||||||
name: string,
|
|
||||||
albums: {
|
|
||||||
/** catalog number */
|
|
||||||
[key: string]: {
|
|
||||||
title: string;
|
|
||||||
cover: string;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
import circles from "../../data/circles.json";
|
|
||||||
import type { CollectionEntry } from "astro:content";
|
|
||||||
|
|
||||||
|
|
||||||
type Song = CollectionEntry<'songs'>;
|
|
||||||
|
|
||||||
interface Metadata {
|
|
||||||
[key: string]: {
|
|
||||||
/** Circle slug */
|
|
||||||
circle: string;
|
|
||||||
/** Circle name */
|
|
||||||
name: string,
|
|
||||||
/** Album title */
|
|
||||||
title: string,
|
|
||||||
/** Path to album cover image */
|
|
||||||
cover: string,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export function order(cat: string) {
|
|
||||||
return (a: Song, b: Song) => a.data.album[cat].track < b.data.album[cat].track ? -1 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
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>()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createMetadata(circles: CirclesSchema): Metadata {
|
|
||||||
const metadata: Metadata = {};
|
|
||||||
|
|
||||||
for (const circle of Object.keys(circles)) {
|
|
||||||
const data = circles[circle];
|
|
||||||
for (const cat of Object.keys(data.albums))
|
|
||||||
metadata[cat] = { circle, name: data.name, ...data.albums[cat] }
|
|
||||||
}
|
|
||||||
return metadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const CIRCLES: CirclesSchema = circles;
|
|
||||||
export const ALBUMS: Metadata = createMetadata(circles);
|
|
|
@ -1,63 +0,0 @@
|
||||||
interface Stack {
|
|
||||||
[key: string]: string[][];
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Verse {
|
|
||||||
[key: string]: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function increaseStack(data: Stack, lang: string) {
|
|
||||||
lang in data
|
|
||||||
? data[lang].push([])
|
|
||||||
: data[lang] = [[]];
|
|
||||||
}
|
|
||||||
|
|
||||||
function fromMarkdown(markdown: string): Stack {
|
|
||||||
const stack: Stack = {};
|
|
||||||
if (!markdown) return stack;
|
|
||||||
|
|
||||||
let space = true;
|
|
||||||
let lang = '';
|
|
||||||
for (const line of markdown.split('\n').map(x => x.trim())) {
|
|
||||||
if (line.startsWith('#')) {
|
|
||||||
lang = line.match(/#+ (.+)/)![1];
|
|
||||||
space = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line === '' || line.startsWith('---'))
|
|
||||||
space = true;
|
|
||||||
|
|
||||||
if (line.startsWith('- ')) {
|
|
||||||
if (space === true) {
|
|
||||||
increaseStack(stack, lang);
|
|
||||||
space = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const text = line.match(/- (.+)/)![1];
|
|
||||||
stack[lang].at(-1)!.push(text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return stack
|
|
||||||
}
|
|
||||||
|
|
||||||
function reduceStack(stack: Stack): Verse[] {
|
|
||||||
const langs = Object.keys(stack);
|
|
||||||
const length = langs.reduce((acc, lang) => Math.max(acc, stack[lang].length), 0);
|
|
||||||
const verses: Verse[] = [];
|
|
||||||
|
|
||||||
for (const _ of Array(length)) {
|
|
||||||
const verse: Verse = {};
|
|
||||||
for (const lang of langs) {
|
|
||||||
const lines = stack[lang].pop();
|
|
||||||
verse[lang] = lines ? lines : [];
|
|
||||||
}
|
|
||||||
verses.push(verse);
|
|
||||||
}
|
|
||||||
return verses.reverse();
|
|
||||||
}
|
|
||||||
|
|
||||||
export function transform(data: string, markdown = false) {
|
|
||||||
return reduceStack(fromMarkdown(data));
|
|
||||||
}
|
|
Loading…
Reference in a new issue