retypeset-odyssey 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (213) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +168 -0
  3. package/astro.config.ts +18 -0
  4. package/default-config.yaml +136 -0
  5. package/discover-collections.ts +160 -0
  6. package/integration.ts +394 -0
  7. package/package.json +105 -0
  8. package/patches/@qwik.dev__partytown@0.11.2.patch +98 -0
  9. package/public/_redirects +819 -0
  10. package/public/feeds/atom-style.xsl +105 -0
  11. package/public/feeds/rss-style.xsl +105 -0
  12. package/public/fonts/EarlySummer-VF-Split/00785494587e3487ac63a0e7e4fa30f0.woff2 +0 -0
  13. package/public/fonts/EarlySummer-VF-Split/08e5d941a4c76fad7b68e7a937ebb21f.woff2 +0 -0
  14. package/public/fonts/EarlySummer-VF-Split/1268e5072156188d601f1eeb4473655d.woff2 +0 -0
  15. package/public/fonts/EarlySummer-VF-Split/12a385475353c815d7a5add53ee51e37.woff2 +0 -0
  16. package/public/fonts/EarlySummer-VF-Split/12b11ca08223c65a21fc731d59dcfc11.woff2 +0 -0
  17. package/public/fonts/EarlySummer-VF-Split/16d6676d3cb645c520ee6df8a1f89afd.woff2 +0 -0
  18. package/public/fonts/EarlySummer-VF-Split/2912a75ffef95e7a5ae9e2b2311ad61d.woff2 +0 -0
  19. package/public/fonts/EarlySummer-VF-Split/298d96ea561e419a4104bc9fc18499ce.woff2 +0 -0
  20. package/public/fonts/EarlySummer-VF-Split/2a2c71acc17ec39f6780835899e53096.woff2 +0 -0
  21. package/public/fonts/EarlySummer-VF-Split/2a7e2d0e59d3f638074c50fab39fdef1.woff2 +0 -0
  22. package/public/fonts/EarlySummer-VF-Split/36931fc4370e1670ed76af5d3feccba2.woff2 +0 -0
  23. package/public/fonts/EarlySummer-VF-Split/3a68fdc792e4a9e0399a04e32d0cc2e3.woff2 +0 -0
  24. package/public/fonts/EarlySummer-VF-Split/4054d6a4d6b37719b51e0f71da6e7cd9.woff2 +0 -0
  25. package/public/fonts/EarlySummer-VF-Split/429cb25f825c3cbde6bfac5b36ae9675.woff2 +0 -0
  26. package/public/fonts/EarlySummer-VF-Split/42a9efc11298368ecdc1b85ab46f0b4f.woff2 +0 -0
  27. package/public/fonts/EarlySummer-VF-Split/432018d2bdc9df92a7662056eb2b1261.woff2 +0 -0
  28. package/public/fonts/EarlySummer-VF-Split/44a6fb782f2a01560faa0f95248b60ef.woff2 +0 -0
  29. package/public/fonts/EarlySummer-VF-Split/45367b060e8ba0aa2507e6b91b86620b.woff2 +0 -0
  30. package/public/fonts/EarlySummer-VF-Split/571db7564bda7c1a93542881b8976f4b.woff2 +0 -0
  31. package/public/fonts/EarlySummer-VF-Split/58d55eeef4cf455e86a1142b1f3110d3.woff2 +0 -0
  32. package/public/fonts/EarlySummer-VF-Split/59ea41e77309160a0f63cdc76a010202.woff2 +0 -0
  33. package/public/fonts/EarlySummer-VF-Split/5d19d9174e568db4755981aa2e4ab380.woff2 +0 -0
  34. package/public/fonts/EarlySummer-VF-Split/5e811eb3b4175ee93d7ec000bf4631c2.woff2 +0 -0
  35. package/public/fonts/EarlySummer-VF-Split/6268e0cd5d66d6fe05b331f259e7b9e4.woff2 +0 -0
  36. package/public/fonts/EarlySummer-VF-Split/6549844aa3d833ca06a68a8e839db465.woff2 +0 -0
  37. package/public/fonts/EarlySummer-VF-Split/714b459658a7321ceeb1e1386ce165c2.woff2 +0 -0
  38. package/public/fonts/EarlySummer-VF-Split/7511d97a469915013683eae06cb21cd9.woff2 +0 -0
  39. package/public/fonts/EarlySummer-VF-Split/7784b4ebe543d13f62f6f6e05beb0b2e.woff2 +0 -0
  40. package/public/fonts/EarlySummer-VF-Split/77c9bea70b3c6ab24e1497d5468c825b.woff2 +0 -0
  41. package/public/fonts/EarlySummer-VF-Split/789ebea9e81df623e930b86de98fbfab.woff2 +0 -0
  42. package/public/fonts/EarlySummer-VF-Split/885bb7ab0717e8a47fc17f953adcdbf1.woff2 +0 -0
  43. package/public/fonts/EarlySummer-VF-Split/896c58aff69a9a857764cee0663bc56d.woff2 +0 -0
  44. package/public/fonts/EarlySummer-VF-Split/8fb6fc01c59d1e3ad1910b58dec7f5e7.woff2 +0 -0
  45. package/public/fonts/EarlySummer-VF-Split/95be5462b91b9a0458797cdc89d94cb5.woff2 +0 -0
  46. package/public/fonts/EarlySummer-VF-Split/9a5b2724f983ca0fc0d5ff8d10c41396.woff2 +0 -0
  47. package/public/fonts/EarlySummer-VF-Split/9ffe17f9c0e4cc4356cb3f08ffdb9c6d.woff2 +0 -0
  48. package/public/fonts/EarlySummer-VF-Split/EarlySummer-VF-Subset.woff2 +0 -0
  49. package/public/fonts/EarlySummer-VF-Split/EarlySummerSerif License.txt +91 -0
  50. package/public/fonts/EarlySummer-VF-Split/a097ef49be62cd2565aca45600e1e3ac.woff2 +0 -0
  51. package/public/fonts/EarlySummer-VF-Split/a17a1ae6063088e5b3a48c06b816929a.woff2 +0 -0
  52. package/public/fonts/EarlySummer-VF-Split/a83fdcfc5ecf2f6996704b0c02758689.woff2 +0 -0
  53. package/public/fonts/EarlySummer-VF-Split/a8cf15ff9b71e59407d8406866ff6f99.woff2 +0 -0
  54. package/public/fonts/EarlySummer-VF-Split/af530ed51dd519e4456f8a5e259e908b.woff2 +0 -0
  55. package/public/fonts/EarlySummer-VF-Split/b195a8924915deec4aa9c3ec777cc93f.woff2 +0 -0
  56. package/public/fonts/EarlySummer-VF-Split/b4b6bb5df9239dd67b52ca858fd2a506.woff2 +0 -0
  57. package/public/fonts/EarlySummer-VF-Split/b7592e1e027923f19e0e55dfdac69668.woff2 +0 -0
  58. package/public/fonts/EarlySummer-VF-Split/b965859f69d8ccceaf0e2d6292afbcfb.woff2 +0 -0
  59. package/public/fonts/EarlySummer-VF-Split/bbe9333f1ff242bd96ecb23ff9e723b1.woff2 +0 -0
  60. package/public/fonts/EarlySummer-VF-Split/be758580e295339ea98f0240b9869f24.woff2 +0 -0
  61. package/public/fonts/EarlySummer-VF-Split/c07099e1d025617f6d40966986e1941b.woff2 +0 -0
  62. package/public/fonts/EarlySummer-VF-Split/c1b593dda62fdeb7dde3af02016da282.woff2 +0 -0
  63. package/public/fonts/EarlySummer-VF-Split/c89f0335910a68a0958f2846108370e8.woff2 +0 -0
  64. package/public/fonts/EarlySummer-VF-Split/ca49aa409fdedd3f2f894cd20a16640a.woff2 +0 -0
  65. package/public/fonts/EarlySummer-VF-Split/ccd4a28d2f63797e0183c87792e20b75.woff2 +0 -0
  66. package/public/fonts/EarlySummer-VF-Split/d2718da923fce8e7ea229d65e306e92c.woff2 +0 -0
  67. package/public/fonts/EarlySummer-VF-Split/d893e9b307d96041e9cfcbd03761b9f4.woff2 +0 -0
  68. package/public/fonts/EarlySummer-VF-Split/dafaedaee41b75e21479d4ff324b6a34.woff2 +0 -0
  69. package/public/fonts/EarlySummer-VF-Split/db392af65f1867e5fd580eed2195df99.woff2 +0 -0
  70. package/public/fonts/EarlySummer-VF-Split/dc7c73a9e5577143ccd11e05ab55cb39.woff2 +0 -0
  71. package/public/fonts/EarlySummer-VF-Split/de396881189f747eba67685298363242.woff2 +0 -0
  72. package/public/fonts/EarlySummer-VF-Split/df625b213228bba22a7733d4eff8f148.woff2 +0 -0
  73. package/public/fonts/EarlySummer-VF-Split/e6e60b384f220b893ef31a926ece829a.woff2 +0 -0
  74. package/public/fonts/EarlySummer-VF-Split/e6e8ce2c5972ab665630bb705383d0fb.woff2 +0 -0
  75. package/public/fonts/EarlySummer-VF-Split/e963c7ed7104c2d6d68fcb5f952fe2f5.woff2 +0 -0
  76. package/public/fonts/EarlySummer-VF-Split/e966b23b4cd7783f43e31032d41784f4.woff2 +0 -0
  77. package/public/fonts/EarlySummer-VF-Split/edaac57c3856ec13128f4c6c3e00975c.woff2 +0 -0
  78. package/public/fonts/EarlySummer-VF-Split/ee54e0d86edf068c6c9cbddb76a856fe.woff2 +0 -0
  79. package/public/fonts/EarlySummer-VF-Split/f612c78a5544ff2dd3e8296ac3e58344.woff2 +0 -0
  80. package/public/fonts/EarlySummer-VF-Split/f9e539bd9b7bf999c3da82f5403ec3b6.woff2 +0 -0
  81. package/public/fonts/EarlySummer-VF-Split/fa5863b923ac15993c52a619f699ee63.woff2 +0 -0
  82. package/public/fonts/EarlySummer-VF-Split/fc759e56ec6f6e6d3d4cb163d62fb557.woff2 +0 -0
  83. package/public/fonts/Font Subset List/CJK Common Characters.txt +7534 -0
  84. package/public/fonts/Font Subset List/EarlySummer Subset.txt +3 -0
  85. package/public/fonts/Font Subset List/Japanese Kana + Korean Letters.txt +6123 -0
  86. package/public/fonts/Font Subset List/Latin + Cyrillic + Greek + Arabic Glyphs.txt +121 -0
  87. package/public/fonts/Font Subset List/unicode_range.py +49 -0
  88. package/public/fonts/NotoSansSC-Bold.otf +0 -0
  89. package/public/fonts/NotoSansSC-Regular.otf +0 -0
  90. package/public/fonts/STIX-Italic-VF.woff2 +0 -0
  91. package/public/fonts/STIX-VF.woff2 +0 -0
  92. package/public/fonts/Snell-Black-SF.woff2 +0 -0
  93. package/public/fonts/Snell-Bold-SF.woff2 +0 -0
  94. package/public/giscus/theme-dark.css +208 -0
  95. package/public/giscus/theme-light.css +208 -0
  96. package/public/icons/favicon.svg +4 -0
  97. package/public/icons/og-logo.png +0 -0
  98. package/public/robots.txt +4 -0
  99. package/public/sounds/tap_01.wav +0 -0
  100. package/public/sounds/tap_02.wav +0 -0
  101. package/public/sounds/tap_03.wav +0 -0
  102. package/public/sounds/tap_04.wav +0 -0
  103. package/public/sounds/tap_05.wav +0 -0
  104. package/public/sounds/type_01.wav +0 -0
  105. package/public/sounds/type_02.wav +0 -0
  106. package/public/sounds/type_03.wav +0 -0
  107. package/public/sounds/type_04.wav +0 -0
  108. package/public/sounds/type_05.wav +0 -0
  109. package/scripts/apply-lqip.ts +276 -0
  110. package/scripts/format-posts.ts +105 -0
  111. package/scripts/migration/README.md +52 -0
  112. package/scripts/migration/migrate-hexo.ts +185 -0
  113. package/scripts/migration/validate-abbrlinks.ts +161 -0
  114. package/scripts/new-post.ts +52 -0
  115. package/scripts/seo/generate-legacy-redirects.ts +407 -0
  116. package/scripts/update-theme.ts +46 -0
  117. package/src/assets/icons/copy-check.svg +3 -0
  118. package/src/assets/icons/copy-icon.svg +4 -0
  119. package/src/assets/icons/go-back.svg +3 -0
  120. package/src/assets/icons/heading-anchor.svg +4 -0
  121. package/src/assets/icons/lang-en.svg +3 -0
  122. package/src/assets/icons/lang-ja.svg +5 -0
  123. package/src/assets/icons/lang-zh.svg +5 -0
  124. package/src/assets/icons/language-switcher.svg +3 -0
  125. package/src/assets/icons/pin-icon.svg +3 -0
  126. package/src/assets/icons/search-icon.svg +3 -0
  127. package/src/assets/icons/theme-toggle.svg +3 -0
  128. package/src/assets/icons/toc-icon.svg +3 -0
  129. package/src/assets/icons/top-icon.svg +3 -0
  130. package/src/assets/lqip-map.json +10 -0
  131. package/src/components/Button.astro +152 -0
  132. package/src/components/CategoryList.astro +66 -0
  133. package/src/components/Comment/Giscus.astro +119 -0
  134. package/src/components/Comment/Index.astro +30 -0
  135. package/src/components/Comment/Twikoo.astro +114 -0
  136. package/src/components/Comment/Waline.astro +149 -0
  137. package/src/components/FloatingButtons.astro +101 -0
  138. package/src/components/Footer.astro +74 -0
  139. package/src/components/Header.astro +62 -0
  140. package/src/components/JournalList.astro +56 -0
  141. package/src/components/Navbar.astro +69 -0
  142. package/src/components/NoteList.astro +56 -0
  143. package/src/components/Pagination.astro +267 -0
  144. package/src/components/PostDate.astro +80 -0
  145. package/src/components/PostList.astro +87 -0
  146. package/src/components/SearchModal.astro +340 -0
  147. package/src/components/TagList.astro +135 -0
  148. package/src/components/Widgets/BackButton.astro +43 -0
  149. package/src/components/Widgets/CodeCopyButton.astro +47 -0
  150. package/src/components/Widgets/GithubCard.astro +110 -0
  151. package/src/components/Widgets/ImageZoom.astro +135 -0
  152. package/src/components/Widgets/MediaEmbed.astro +127 -0
  153. package/src/components/Widgets/SoundEffect.astro +179 -0
  154. package/src/components/Widgets/TOC.astro +198 -0
  155. package/src/config-schema.ts +164 -0
  156. package/src/config.ts +127 -0
  157. package/src/config.ts.example +205 -0
  158. package/src/content/about/_example-about-en.md +6 -0
  159. package/src/content/about/about-en.md +21 -0
  160. package/src/content/about/about-ja.md +21 -0
  161. package/src/content/about/about-zh.md +24 -0
  162. package/src/content.config.ts +247 -0
  163. package/src/env.d.ts +25 -0
  164. package/src/i18n/config.ts +65 -0
  165. package/src/i18n/lang.ts +70 -0
  166. package/src/i18n/path.ts +160 -0
  167. package/src/i18n/ui.ts +214 -0
  168. package/src/layouts/Head.astro +203 -0
  169. package/src/layouts/Layout.astro +69 -0
  170. package/src/pages/404.astro +20 -0
  171. package/src/pages/[...lang]/[...page].astro +48 -0
  172. package/src/pages/[...lang]/about.astro +28 -0
  173. package/src/pages/[...lang]/atom.xml.ts +14 -0
  174. package/src/pages/[...lang]/categories/index.astro +35 -0
  175. package/src/pages/[...lang]/journals/[slug].astro +89 -0
  176. package/src/pages/[...lang]/journals/index.astro +55 -0
  177. package/src/pages/[...lang]/journals/page/[page].astro +66 -0
  178. package/src/pages/[...lang]/notes/[slug].astro +88 -0
  179. package/src/pages/[...lang]/notes/index.astro +55 -0
  180. package/src/pages/[...lang]/notes/page/[page].astro +66 -0
  181. package/src/pages/[...lang]/posts/[slug].astro +101 -0
  182. package/src/pages/[...lang]/rss.xml.ts +14 -0
  183. package/src/pages/[...lang]/search.astro +65 -0
  184. package/src/pages/[...lang]/tags/[tag].astro +53 -0
  185. package/src/pages/[...lang]/tags/index.astro +36 -0
  186. package/src/pages/_dynamic/list.astro +101 -0
  187. package/src/pages/_dynamic/slug.astro +100 -0
  188. package/src/pages/og/[...image].ts +114 -0
  189. package/src/pages/robots.txt.ts +20 -0
  190. package/src/plugins/rehype-code-copy-button.mjs +82 -0
  191. package/src/plugins/rehype-external-links.mjs +18 -0
  192. package/src/plugins/rehype-heading-anchor.mjs +55 -0
  193. package/src/plugins/rehype-image-processor.mjs +77 -0
  194. package/src/plugins/remark-container-directives.mjs +135 -0
  195. package/src/plugins/remark-leaf-directives.mjs +184 -0
  196. package/src/plugins/remark-reading-time.mjs +11 -0
  197. package/src/styles/comment.css +205 -0
  198. package/src/styles/extension.css +180 -0
  199. package/src/styles/font.css +111 -0
  200. package/src/styles/global.css +91 -0
  201. package/src/styles/lqip.css +71 -0
  202. package/src/styles/markdown.css +276 -0
  203. package/src/styles/transition.css +173 -0
  204. package/src/types/global.d.ts +22 -0
  205. package/src/types/index.d.ts +111 -0
  206. package/src/utils/cache.ts +32 -0
  207. package/src/utils/content.ts +819 -0
  208. package/src/utils/description.ts +147 -0
  209. package/src/utils/dynamic-collections.ts +155 -0
  210. package/src/utils/feed.ts +238 -0
  211. package/src/utils/page.ts +107 -0
  212. package/tsconfig.json +13 -0
  213. package/uno.config.ts +75 -0
@@ -0,0 +1,69 @@
1
+ ---
2
+ import type { Language } from '@/i18n/config'
3
+ import Button from '@/components/Button.astro'
4
+ import Footer from '@/components/Footer.astro'
5
+ import Header from '@/components/Header.astro'
6
+ import Navbar from '@/components/Navbar.astro'
7
+ import SearchModal from '@/components/SearchModal.astro'
8
+ import CodeCopyButton from '@/components/Widgets/CodeCopyButton.astro'
9
+ import GithubCard from '@/components/Widgets/GithubCard.astro'
10
+ import ImageZoom from '@/components/Widgets/ImageZoom.astro'
11
+ import MediaEmbed from '@/components/Widgets/MediaEmbed.astro'
12
+ import SoundEffect from '@/components/Widgets/SoundEffect.astro'
13
+ import { themeConfig } from '@/config'
14
+ import Head from '@/layouts/Head.astro'
15
+ import { getPageInfo } from '@/utils/page'
16
+ import '@/styles/comment.css'
17
+ import '@/styles/extension.css'
18
+ import '@/styles/font.css'
19
+ import '@/styles/global.css'
20
+ import '@/styles/lqip.css'
21
+ import '@/styles/markdown.css'
22
+ import '@/styles/transition.css'
23
+
24
+ interface Props {
25
+ postTitle?: string
26
+ postDescription?: string
27
+ postSlug?: string
28
+ supportedLangs?: Language[]
29
+ }
30
+
31
+ const { postTitle, postDescription, postSlug, supportedLangs = [] } = Astro.props
32
+ const { isPost, isNote, isJournal } = getPageInfo(Astro.url.pathname)
33
+ const isArticle = isPost || isNote || isJournal
34
+ const fontStyle = themeConfig.global.fontStyle === 'serif' ? 'font-serif' : 'font-sans'
35
+ const MarginBottom = isPost && themeConfig.comment.enabled
36
+ ? 'mb-10' // Post page with comment
37
+ : 'mb-12' // Other pages without comment
38
+ ---
39
+
40
+ <html
41
+ lang={Astro.currentLocale}
42
+ class:list={[
43
+ fontStyle,
44
+ isArticle ? 'scroll-smooth' : '',
45
+ ]}
46
+ >
47
+ <Head {postTitle} {postDescription} {postSlug} />
48
+ <body>
49
+ <div
50
+ class="mx-auto max-w-205.848 min-h-vh w-full min-h-dvh"
51
+ p="x-[min(7.25vw,3.731rem)] y-10"
52
+ lg="mx-[max(5.75rem,calc(50vw-34.25rem))] my-20 max-w-[min(calc(75vw-16rem),44rem)] min-h-full p-0"
53
+ >
54
+ <Header />
55
+ <Navbar />
56
+ <main class={MarginBottom}>
57
+ <slot />
58
+ </main>
59
+ <Footer />
60
+ </div>
61
+ <Button supportedLangs={supportedLangs} />
62
+ <SoundEffect />
63
+ <CodeCopyButton />
64
+ <GithubCard />
65
+ <MediaEmbed />
66
+ <ImageZoom />
67
+ <SearchModal />
68
+ </body>
69
+ </html>
@@ -0,0 +1,20 @@
1
+ ---
2
+ import Layout from '@/layouts/Layout.astro'
3
+ ---
4
+
5
+ <Layout>
6
+ <!-- Decorative Line -->
7
+ <div class="uno-decorative-line" />
8
+ <!-- Page Not Found -->
9
+ <h3 class="mt--1.3 flex flex-col text-8 c-primary font-bold leading-1.2em font-navbar lg:text-9">
10
+ <span>PAGE</span>
11
+ <span>NOT</span>
12
+ <span>FOUND</span>
13
+ </h3>
14
+ <p class="mt-3.6 flex flex-col text-3.6 leading-1.4em font-navbar lg:(mt-4 text-4)">
15
+ <span>It looks like the page you're looking for</span>
16
+ <span>does not exist or has been moved.</span>
17
+ </p>
18
+ <!-- Unused Div -->
19
+ <div class="" />
20
+ </Layout>
@@ -0,0 +1,48 @@
1
+ ---
2
+ import type { GetStaticPathsOptions, Page } from 'astro'
3
+ import type { Post } from '@/types'
4
+ import Pagination from '@/components/Pagination.astro'
5
+ import PostList from '@/components/PostList.astro'
6
+ import { POSTS_PER_PAGE, allLocales } from '@/config'
7
+ import { getLangFromLocale, getLangRouteParam } from '@/i18n/lang'
8
+ import { getLocalizedPath } from '@/i18n/path'
9
+ import Layout from '@/layouts/Layout.astro'
10
+ import { getPosts } from '@/utils/content'
11
+
12
+ export async function getStaticPaths({ paginate }: GetStaticPathsOptions) {
13
+ const results = []
14
+
15
+ for (const lang of allLocales) {
16
+ const posts = await getPosts(lang)
17
+ const langParam = getLangRouteParam(lang)
18
+
19
+ const paginatedPages = paginate(posts, {
20
+ pageSize: POSTS_PER_PAGE,
21
+ params: { lang: langParam },
22
+ props: { lang },
23
+ })
24
+
25
+ results.push(...paginatedPages)
26
+ }
27
+
28
+ return results
29
+ }
30
+
31
+ const page = Astro.props.page as Page<Post>
32
+ const currentLang = getLangFromLocale(Astro.currentLocale)
33
+
34
+ // Base URL for pagination (root path for the language)
35
+ const baseUrl = getLocalizedPath('/', currentLang)
36
+ ---
37
+
38
+ <Layout>
39
+ <section class="mb-7.5">
40
+ <div class="uno-decorative-line" />
41
+ <PostList posts={page.data} lang={currentLang} />
42
+ <Pagination
43
+ currentPage={page.currentPage}
44
+ totalPages={page.lastPage}
45
+ baseUrl={baseUrl}
46
+ />
47
+ </section>
48
+ </Layout>
@@ -0,0 +1,28 @@
1
+ ---
2
+ import { getCollection, render } from 'astro:content'
3
+ import { allLocales } from '@/config'
4
+ import { getLangFromLocale, getLangRouteParam } from '@/i18n/lang'
5
+ import Layout from '@/layouts/Layout.astro'
6
+
7
+ export async function getStaticPaths() {
8
+ return allLocales.map(lang => ({
9
+ params: { lang: getLangRouteParam(lang) },
10
+ }))
11
+ }
12
+
13
+ const currentLang = getLangFromLocale(Astro.currentLocale)
14
+ // Get about page content with different language
15
+ const allAboutEntries = await getCollection('about')
16
+ const aboutEntry = allAboutEntries.find(entry => entry.data.lang === currentLang)
17
+ ?? allAboutEntries.find(entry => entry.data.lang === '')
18
+ const { Content } = aboutEntry ? await render(aboutEntry) : { Content: null }
19
+ ---
20
+
21
+ <Layout>
22
+ <!-- Decorative Line -->
23
+ <div class="uno-decorative-line" />
24
+ <!-- About Page Content -->
25
+ <div class="heti">
26
+ {Content && <Content />}
27
+ </div>
28
+ </Layout>
@@ -0,0 +1,14 @@
1
+ import type { APIContext } from 'astro'
2
+ import { allLocales } from '@/config'
3
+ import { getLangRouteParam } from '@/i18n/lang'
4
+ import { generateAtom } from '@/utils/feed'
5
+
6
+ export function getStaticPaths() {
7
+ return allLocales.map(lang => ({
8
+ params: { lang: getLangRouteParam(lang) },
9
+ }))
10
+ }
11
+
12
+ export async function GET(context: APIContext) {
13
+ return generateAtom(context)
14
+ }
@@ -0,0 +1,35 @@
1
+ ---
2
+ import CategoryList from '@/components/CategoryList.astro'
3
+ import { allLocales } from '@/config'
4
+ import { getLangFromLocale, getLangRouteParam } from '@/i18n/lang'
5
+ import { ui } from '@/i18n/ui'
6
+ import Layout from '@/layouts/Layout.astro'
7
+ import { getUserCategoriesWithCounts } from '@/utils/content'
8
+
9
+ export async function getStaticPaths() {
10
+ return allLocales.map(lang => ({
11
+ params: { lang: getLangRouteParam(lang) },
12
+ }))
13
+ }
14
+
15
+ const currentLang = getLangFromLocale(Astro.currentLocale)
16
+ const categoriesWithCounts = await getUserCategoriesWithCounts(currentLang)
17
+ const totalCategories = categoriesWithCounts.length
18
+ const currentUI = ui[currentLang as keyof typeof ui] ?? {}
19
+ ---
20
+
21
+ <Layout postTitle={currentUI.categories || 'Categories'}>
22
+ <section class="mb-7.5">
23
+ <h1 class="mb-2 text-5 font-bold cjk:tracking-wide lg:text-6">
24
+ {currentUI.categories || 'Categories'}
25
+ </h1>
26
+ <p class="mb-6 text-3.5 c-secondary">
27
+ {totalCategories} {currentUI.categoriesInTotal || 'categories in total'}
28
+ </p>
29
+ <div class="uno-decorative-line" />
30
+ <CategoryList
31
+ categories={categoriesWithCounts}
32
+ lang={currentLang}
33
+ />
34
+ </section>
35
+ </Layout>
@@ -0,0 +1,89 @@
1
+ ---
2
+ import type { CollectionEntry } from 'astro:content'
3
+ import type { Language } from '@/i18n/config'
4
+ import { render } from 'astro:content'
5
+ import PostDate from '@/components/PostDate.astro'
6
+ import BackButton from '@/components/Widgets/BackButton.astro'
7
+ import TOC from '@/components/Widgets/TOC.astro'
8
+ import { allLocales } from '@/config'
9
+ import { getLangFromLocale, getLangRouteParam } from '@/i18n/lang'
10
+ import Layout from '@/layouts/Layout.astro'
11
+ import { getJournalGroups, getJournalSlug } from '@/utils/content'
12
+ import { getJournalDescription } from '@/utils/description'
13
+
14
+ export async function getStaticPaths() {
15
+ const groups = await getJournalGroups()
16
+
17
+ return allLocales.flatMap(lang => groups
18
+ .map((group) => {
19
+ const journal = group.byLang[lang]
20
+ if (!journal) {
21
+ return null
22
+ }
23
+
24
+ return {
25
+ params: {
26
+ lang: getLangRouteParam(lang),
27
+ slug: group.slug,
28
+ },
29
+ props: {
30
+ journal,
31
+ supportedLangs: group.supportedLangs,
32
+ },
33
+ }
34
+ })
35
+ .filter(Boolean),
36
+ )
37
+ }
38
+
39
+ interface Props {
40
+ journal: CollectionEntry<'journals'>
41
+ supportedLangs: Language[]
42
+ }
43
+
44
+ const { journal, supportedLangs } = Astro.props as Props
45
+ const currentLang = getLangFromLocale(Astro.currentLocale)
46
+ const slug = getJournalSlug(journal)
47
+ const description = getJournalDescription(journal, 'meta')
48
+ const { Content, headings, remarkPluginFrontmatter } = await render(journal)
49
+ ---
50
+
51
+ <Layout
52
+ postTitle={journal.data.title}
53
+ postDescription={description}
54
+ postSlug={`journals/${journal.id}`}
55
+ supportedLangs={supportedLangs}
56
+ >
57
+ <article class="heti">
58
+ <div class="relative">
59
+ <BackButton />
60
+ <h1 class="post-title">
61
+ <span
62
+ transition:name={`journal-${slug}${currentLang ? `-${currentLang}` : ''}`}
63
+ data-disable-theme-toggle-transition
64
+ >
65
+ {journal.data.title}
66
+ </span>
67
+ </h1>
68
+ </div>
69
+
70
+ <div
71
+ class="mb-17.2 block c-primary font-time"
72
+ transition:name={`journal-time-${slug}${currentLang ? `-${currentLang}` : ''}`}
73
+ data-disable-theme-toggle-transition
74
+ >
75
+ <PostDate
76
+ date={journal.data.published}
77
+ updatedDate={journal.data.updated}
78
+ minutes={remarkPluginFrontmatter.minutes}
79
+ />
80
+ </div>
81
+
82
+ {journal.data.toc && <TOC headings={headings} />}
83
+
84
+ <div id="post-content">
85
+ <Content />
86
+ </div>
87
+ </article>
88
+ </Layout>
89
+
@@ -0,0 +1,55 @@
1
+ ---
2
+ import JournalList from '@/components/JournalList.astro'
3
+ import Pagination from '@/components/Pagination.astro'
4
+ import { JOURNALS_PER_PAGE, allLocales } from '@/config'
5
+ import { getLangFromLocale, getLangRouteParam } from '@/i18n/lang'
6
+ import { getLocalizedPath } from '@/i18n/path'
7
+ import { ui } from '@/i18n/ui'
8
+ import Layout from '@/layouts/Layout.astro'
9
+ import { getJournals } from '@/utils/content'
10
+
11
+ export async function getStaticPaths() {
12
+ return allLocales.map(lang => ({
13
+ params: { lang: getLangRouteParam(lang) },
14
+ }))
15
+ }
16
+
17
+ const currentLang = getLangFromLocale(Astro.currentLocale)
18
+ const currentUI = ui[currentLang as keyof typeof ui] ?? {}
19
+ const allJournals = await getJournals(currentLang)
20
+ const totalPages = Math.max(1, Math.ceil(allJournals.length / JOURNALS_PER_PAGE))
21
+ const journals = allJournals.slice(0, JOURNALS_PER_PAGE)
22
+ const baseUrl = getLocalizedPath('/journals/', currentLang)
23
+ ---
24
+
25
+ <Layout
26
+ postTitle={currentUI.journals ?? 'Journal'}
27
+ postDescription={currentUI.journalsIntro}
28
+ >
29
+ <section class="mb-7.5">
30
+ <h1 class="mb-2 text-5 font-bold cjk:tracking-wide lg:text-6">
31
+ {currentUI.journals ?? 'Journal'}
32
+ </h1>
33
+ {currentUI.journalsIntro && (
34
+ <p class="mb-6 text-3.5 c-secondary">
35
+ {currentUI.journalsIntro}
36
+ </p>
37
+ )}
38
+ <div class="uno-decorative-line" />
39
+
40
+ {journals.length > 0
41
+ ? <JournalList journals={journals} lang={currentLang} />
42
+ : (
43
+ <p class="mt-6 text-3.5 c-secondary">
44
+ {currentUI.journalsEmpty ?? 'No journal entries yet.'}
45
+ </p>
46
+ )}
47
+
48
+ <Pagination
49
+ currentPage={1}
50
+ totalPages={totalPages}
51
+ baseUrl={baseUrl}
52
+ pagePrefix="page"
53
+ />
54
+ </section>
55
+ </Layout>
@@ -0,0 +1,66 @@
1
+ ---
2
+ import JournalList from '@/components/JournalList.astro'
3
+ import Pagination from '@/components/Pagination.astro'
4
+ import { JOURNALS_PER_PAGE, allLocales } from '@/config'
5
+ import { getLangFromLocale, getLangRouteParam } from '@/i18n/lang'
6
+ import { getLocalizedPath } from '@/i18n/path'
7
+ import { ui } from '@/i18n/ui'
8
+ import Layout from '@/layouts/Layout.astro'
9
+ import { getJournals } from '@/utils/content'
10
+
11
+ export async function getStaticPaths() {
12
+ const paths = []
13
+
14
+ for (const lang of allLocales) {
15
+ const journals = await getJournals(lang)
16
+ const totalPages = Math.ceil(journals.length / JOURNALS_PER_PAGE)
17
+
18
+ for (let page = 2; page <= totalPages; page++) {
19
+ paths.push({
20
+ params: {
21
+ lang: getLangRouteParam(lang),
22
+ page: String(page),
23
+ },
24
+ })
25
+ }
26
+ }
27
+
28
+ return paths
29
+ }
30
+
31
+ const currentLang = getLangFromLocale(Astro.currentLocale)
32
+ const currentUI = ui[currentLang as keyof typeof ui] ?? {}
33
+ const pageNumber = Number(Astro.params.page)
34
+ const allJournals = await getJournals(currentLang)
35
+ const totalPages = Math.max(1, Math.ceil(allJournals.length / JOURNALS_PER_PAGE))
36
+
37
+ const start = (pageNumber - 1) * JOURNALS_PER_PAGE
38
+ const journals = allJournals.slice(start, start + JOURNALS_PER_PAGE)
39
+ const baseUrl = getLocalizedPath('/journals/', currentLang)
40
+ ---
41
+
42
+ <Layout
43
+ postTitle={`${currentUI.journals ?? 'Journal'} - ${pageNumber}`}
44
+ postDescription={currentUI.journalsIntro}
45
+ >
46
+ <section class="mb-7.5">
47
+ <h1 class="mb-2 text-5 font-bold cjk:tracking-wide lg:text-6">
48
+ {currentUI.journals ?? 'Journal'}
49
+ </h1>
50
+ {currentUI.journalsIntro && (
51
+ <p class="mb-6 text-3.5 c-secondary">
52
+ {currentUI.journalsIntro}
53
+ </p>
54
+ )}
55
+ <div class="uno-decorative-line" />
56
+
57
+ <JournalList journals={journals} lang={currentLang} />
58
+
59
+ <Pagination
60
+ currentPage={pageNumber}
61
+ totalPages={totalPages}
62
+ baseUrl={baseUrl}
63
+ pagePrefix="page"
64
+ />
65
+ </section>
66
+ </Layout>
@@ -0,0 +1,88 @@
1
+ ---
2
+ import type { CollectionEntry } from 'astro:content'
3
+ import type { Language } from '@/i18n/config'
4
+ import { render } from 'astro:content'
5
+ import PostDate from '@/components/PostDate.astro'
6
+ import BackButton from '@/components/Widgets/BackButton.astro'
7
+ import TOC from '@/components/Widgets/TOC.astro'
8
+ import { allLocales } from '@/config'
9
+ import { getLangFromLocale, getLangRouteParam } from '@/i18n/lang'
10
+ import Layout from '@/layouts/Layout.astro'
11
+ import { getNoteGroups, getNoteSlug } from '@/utils/content'
12
+ import { getNoteDescription } from '@/utils/description'
13
+
14
+ export async function getStaticPaths() {
15
+ const groups = await getNoteGroups()
16
+
17
+ return allLocales.flatMap(lang => groups
18
+ .map((group) => {
19
+ const note = group.byLang[lang]
20
+ if (!note) {
21
+ return null
22
+ }
23
+
24
+ return {
25
+ params: {
26
+ lang: getLangRouteParam(lang),
27
+ slug: group.slug,
28
+ },
29
+ props: {
30
+ note,
31
+ supportedLangs: group.supportedLangs,
32
+ },
33
+ }
34
+ })
35
+ .filter(Boolean),
36
+ )
37
+ }
38
+
39
+ interface Props {
40
+ note: CollectionEntry<'notes'>
41
+ supportedLangs: Language[]
42
+ }
43
+
44
+ const { note, supportedLangs } = Astro.props as Props
45
+ const currentLang = getLangFromLocale(Astro.currentLocale)
46
+ const slug = getNoteSlug(note)
47
+ const description = getNoteDescription(note, 'meta')
48
+ const { Content, headings, remarkPluginFrontmatter } = await render(note)
49
+ ---
50
+
51
+ <Layout
52
+ postTitle={note.data.title}
53
+ postDescription={description}
54
+ postSlug={`notes/${note.id}`}
55
+ supportedLangs={supportedLangs}
56
+ >
57
+ <article class="heti">
58
+ <div class="relative">
59
+ <BackButton />
60
+ <h1 class="post-title">
61
+ <span
62
+ transition:name={`note-${slug}${currentLang ? `-${currentLang}` : ''}`}
63
+ data-disable-theme-toggle-transition
64
+ >
65
+ {note.data.title}
66
+ </span>
67
+ </h1>
68
+ </div>
69
+
70
+ <div
71
+ class="mb-17.2 block c-primary font-time"
72
+ transition:name={`note-time-${slug}${currentLang ? `-${currentLang}` : ''}`}
73
+ data-disable-theme-toggle-transition
74
+ >
75
+ <PostDate
76
+ date={note.data.published}
77
+ updatedDate={note.data.updated}
78
+ minutes={remarkPluginFrontmatter.minutes}
79
+ />
80
+ </div>
81
+
82
+ {note.data.toc && <TOC headings={headings} />}
83
+
84
+ <div id="post-content">
85
+ <Content />
86
+ </div>
87
+ </article>
88
+ </Layout>
@@ -0,0 +1,55 @@
1
+ ---
2
+ import NoteList from '@/components/NoteList.astro'
3
+ import Pagination from '@/components/Pagination.astro'
4
+ import { NOTES_PER_PAGE, allLocales } from '@/config'
5
+ import { getLangFromLocale, getLangRouteParam } from '@/i18n/lang'
6
+ import { getLocalizedPath } from '@/i18n/path'
7
+ import { ui } from '@/i18n/ui'
8
+ import Layout from '@/layouts/Layout.astro'
9
+ import { getNotes } from '@/utils/content'
10
+
11
+ export async function getStaticPaths() {
12
+ return allLocales.map(lang => ({
13
+ params: { lang: getLangRouteParam(lang) },
14
+ }))
15
+ }
16
+
17
+ const currentLang = getLangFromLocale(Astro.currentLocale)
18
+ const currentUI = ui[currentLang as keyof typeof ui] ?? {}
19
+ const allNotes = await getNotes(currentLang)
20
+ const totalPages = Math.max(1, Math.ceil(allNotes.length / NOTES_PER_PAGE))
21
+ const notes = allNotes.slice(0, NOTES_PER_PAGE)
22
+ const baseUrl = getLocalizedPath('/notes/', currentLang)
23
+ ---
24
+
25
+ <Layout
26
+ postTitle={currentUI.notes ?? 'Notes'}
27
+ postDescription={currentUI.notesIntro}
28
+ >
29
+ <section class="mb-7.5">
30
+ <h1 class="mb-2 text-5 font-bold cjk:tracking-wide lg:text-6">
31
+ {currentUI.notes ?? 'Notes'}
32
+ </h1>
33
+ {currentUI.notesIntro && (
34
+ <p class="mb-6 text-3.5 c-secondary">
35
+ {currentUI.notesIntro}
36
+ </p>
37
+ )}
38
+ <div class="uno-decorative-line" />
39
+
40
+ {notes.length > 0
41
+ ? <NoteList notes={notes} lang={currentLang} />
42
+ : (
43
+ <p class="mt-6 text-3.5 c-secondary">
44
+ {currentUI.notesEmpty ?? 'No notes yet.'}
45
+ </p>
46
+ )}
47
+
48
+ <Pagination
49
+ currentPage={1}
50
+ totalPages={totalPages}
51
+ baseUrl={baseUrl}
52
+ pagePrefix="page"
53
+ />
54
+ </section>
55
+ </Layout>
@@ -0,0 +1,66 @@
1
+ ---
2
+ import NoteList from '@/components/NoteList.astro'
3
+ import Pagination from '@/components/Pagination.astro'
4
+ import { NOTES_PER_PAGE, allLocales } from '@/config'
5
+ import { getLangFromLocale, getLangRouteParam } from '@/i18n/lang'
6
+ import { getLocalizedPath } from '@/i18n/path'
7
+ import { ui } from '@/i18n/ui'
8
+ import Layout from '@/layouts/Layout.astro'
9
+ import { getNotes } from '@/utils/content'
10
+
11
+ export async function getStaticPaths() {
12
+ const paths = []
13
+
14
+ for (const lang of allLocales) {
15
+ const notes = await getNotes(lang)
16
+ const totalPages = Math.ceil(notes.length / NOTES_PER_PAGE)
17
+
18
+ for (let page = 2; page <= totalPages; page++) {
19
+ paths.push({
20
+ params: {
21
+ lang: getLangRouteParam(lang),
22
+ page: String(page),
23
+ },
24
+ })
25
+ }
26
+ }
27
+
28
+ return paths
29
+ }
30
+
31
+ const currentLang = getLangFromLocale(Astro.currentLocale)
32
+ const currentUI = ui[currentLang as keyof typeof ui] ?? {}
33
+ const pageNumber = Number(Astro.params.page)
34
+ const allNotes = await getNotes(currentLang)
35
+ const totalPages = Math.max(1, Math.ceil(allNotes.length / NOTES_PER_PAGE))
36
+
37
+ const start = (pageNumber - 1) * NOTES_PER_PAGE
38
+ const notes = allNotes.slice(start, start + NOTES_PER_PAGE)
39
+ const baseUrl = getLocalizedPath('/notes/', currentLang)
40
+ ---
41
+
42
+ <Layout
43
+ postTitle={`${currentUI.notes ?? 'Notes'} - ${pageNumber}`}
44
+ postDescription={currentUI.notesIntro}
45
+ >
46
+ <section class="mb-7.5">
47
+ <h1 class="mb-2 text-5 font-bold cjk:tracking-wide lg:text-6">
48
+ {currentUI.notes ?? 'Notes'}
49
+ </h1>
50
+ {currentUI.notesIntro && (
51
+ <p class="mb-6 text-3.5 c-secondary">
52
+ {currentUI.notesIntro}
53
+ </p>
54
+ )}
55
+ <div class="uno-decorative-line" />
56
+
57
+ <NoteList notes={notes} lang={currentLang} />
58
+
59
+ <Pagination
60
+ currentPage={pageNumber}
61
+ totalPages={totalPages}
62
+ baseUrl={baseUrl}
63
+ pagePrefix="page"
64
+ />
65
+ </section>
66
+ </Layout>