@hutusi/amytis 1.14.0 → 1.16.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.
- package/.github/workflows/ci.yml +1 -1
- package/.github/workflows/publish.yml +2 -2
- package/CHANGELOG.md +42 -0
- package/CLAUDE.md +90 -219
- package/README.md +33 -1
- package/README.zh.md +33 -1
- package/TODO.md +10 -0
- package/bun.lock +205 -539
- package/content/books/sample-book/index.mdx +3 -0
- package/content/posts/code-block-features-showcase.mdx +223 -0
- package/content/series/rst-legacy/deeper-notes/images/test.svg +4 -0
- package/content/series/rst-legacy/deeper-notes/index.rst +15 -0
- package/content/series/rst-legacy/getting-started.rst +24 -0
- package/content/series/rst-legacy/index.rst +9 -0
- package/content/series/rst-readme/README.rst +9 -0
- package/content/series/rst-readme/readme-index-post.rst +10 -0
- package/content/series/rst-toctree/first-post.rst +6 -0
- package/content/series/rst-toctree/index.rst +10 -0
- package/content/series/rst-toctree/second-post.rst +6 -0
- package/content/series/rst-toctree-precedence/first-post.rst +6 -0
- package/content/series/rst-toctree-precedence/index.rst +12 -0
- package/content/series/rst-toctree-precedence/second-post.rst +6 -0
- package/docs/ALERTS.md +112 -0
- package/docs/ARCHITECTURE.md +239 -8
- package/docs/CODE-BLOCKS.md +238 -0
- package/docs/CONTRIBUTING.md +36 -0
- package/docs/guides/README.md +11 -0
- package/docs/guides/importing-vuepress-books.md +178 -0
- package/eslint.config.mjs +20 -6
- package/next.config.ts +2 -2
- package/package.json +52 -24
- package/packages/create-amytis/package.json +1 -1
- package/packages/create-amytis/src/index.test.ts +43 -1
- package/packages/create-amytis/src/index.ts +64 -8
- package/public/next-image-export-optimizer-hashes.json +14 -73
- package/scripts/build-pagefind.ts +172 -0
- package/scripts/copy-assets.ts +246 -56
- package/scripts/generate-code-group-icons.ts +79 -0
- package/scripts/generate-knowledge-graph.ts +2 -1
- package/scripts/render-rst.py +923 -0
- package/scripts/run-with-rst-python.ts +42 -0
- package/scripts/sync-vuepress-book.ts +499 -0
- package/src/app/[slug]/[postSlug]/page.tsx +20 -10
- package/src/app/[slug]/page/[page]/page.tsx +15 -0
- package/src/app/books/[slug]/{[chapter] → [...chapter]}/page.tsx +32 -10
- package/src/app/books/[slug]/page.tsx +67 -32
- package/src/app/globals.css +639 -94
- package/src/app/page.tsx +1 -1
- package/src/app/series/[slug]/page/[page]/page.tsx +74 -6
- package/src/app/series/[slug]/page.tsx +11 -13
- package/src/app/series/page.tsx +3 -3
- package/src/app/sitemap.ts +3 -3
- package/src/components/ArticleCopyCleaner.tsx +64 -0
- package/src/components/AuthorCard.tsx +25 -16
- package/src/components/BookMobileNav.tsx +44 -50
- package/src/components/BookSidebar.tsx +0 -0
- package/src/components/CodeBlock.test.tsx +93 -8
- package/src/components/CodeBlock.tsx +39 -101
- package/src/components/CodeBlockToolbar.tsx +88 -0
- package/src/components/CodeGroup.tsx +81 -0
- package/src/components/CoverImage.tsx +6 -2
- package/src/components/ExternalLinkIcon.tsx +15 -0
- package/src/components/FeaturedStoriesSection.tsx +3 -3
- package/src/components/GithubAlert.tsx +97 -0
- package/src/components/MarkdownRenderer.test.tsx +30 -4
- package/src/components/MarkdownRenderer.tsx +148 -24
- package/src/components/Mermaid.tsx +32 -1
- package/src/components/PostList.tsx +1 -1
- package/src/components/PostNavigation.tsx +13 -2
- package/src/components/PostSidebar.tsx +13 -2
- package/src/components/RstRenderer.test.tsx +93 -0
- package/src/components/RstRenderer.tsx +157 -0
- package/src/components/Search.tsx +18 -4
- package/src/components/SeriesCatalog.tsx +1 -1
- package/src/components/ShareBar.tsx +5 -0
- package/src/components/TocPanel.tsx +10 -2
- package/src/i18n/translations.ts +2 -0
- package/src/layouts/BookLayout.tsx +35 -4
- package/src/layouts/PostLayout.tsx +10 -2
- package/src/layouts/SimpleLayout.tsx +10 -3
- package/src/lib/code-group-icons.test.ts +78 -0
- package/src/lib/code-group-icons.ts +148 -0
- package/src/lib/image-utils.test.ts +19 -0
- package/src/lib/image-utils.ts +11 -0
- package/src/lib/markdown.test.ts +195 -14
- package/src/lib/markdown.ts +928 -254
- package/src/lib/normalize-vuepress-math.ts +118 -0
- package/src/lib/rehype-fence-meta.ts +22 -0
- package/src/lib/rehype-image-metadata.ts +2 -2
- package/src/lib/remark-book-chapter-links.ts +106 -0
- package/src/lib/remark-code-group.ts +54 -0
- package/src/lib/remark-github-alerts.test.ts +83 -0
- package/src/lib/remark-github-alerts.ts +65 -0
- package/src/lib/remark-vuepress-containers.ts +130 -0
- package/src/lib/rst-renderer.test.ts +355 -0
- package/src/lib/rst-renderer.ts +629 -0
- package/src/lib/rst.test.ts +350 -0
- package/src/lib/rst.ts +674 -0
- package/src/lib/series-redirects.ts +42 -0
- package/src/lib/shiki-rst.ts +185 -0
- package/src/lib/shiki.test.ts +153 -0
- package/src/lib/shiki.ts +292 -0
- package/src/lib/urls.ts +57 -0
- package/src/test-utils/render.ts +23 -0
- package/tests/fixtures/sync-vuepress-book/docs/.vuepress/config.js +43 -0
- package/tests/fixtures/sync-vuepress-book/docs/intro/welcome.md +7 -0
- package/tests/fixtures/sync-vuepress-book/docs/maths/linear/assets/diagram.png +1 -0
- package/tests/fixtures/sync-vuepress-book/docs/maths/linear/matrices.md +7 -0
- package/tests/fixtures/sync-vuepress-book/docs/maths/linear/vectors.md +9 -0
- package/tests/helpers/env.ts +19 -0
- package/tests/integration/book-chapter-links.test.ts +107 -0
- package/tests/integration/books-nested-toc.test.ts +176 -0
- package/tests/integration/books.test.ts +3 -2
- package/tests/integration/code-block-features.test.ts +188 -0
- package/tests/integration/code-group.test.ts +183 -0
- package/tests/integration/code-notation.test.ts +97 -0
- package/tests/integration/feed-utils.test.ts +13 -0
- package/tests/integration/github-alerts.test.ts +82 -0
- package/tests/integration/markdown-external-links.test.ts +103 -0
- package/tests/integration/normalize-vuepress-math.test.ts +149 -0
- package/tests/integration/reading-time-headings.test.ts +12 -14
- package/tests/integration/series-draft.test.ts +12 -5
- package/tests/integration/series.test.ts +93 -0
- package/tests/integration/sync-vuepress-book.test.ts +240 -0
- package/tests/integration/vuepress-containers.test.ts +107 -0
- package/tests/tooling/build-pagefind.test.ts +66 -0
- package/tests/tooling/new-post.test.ts +1 -1
- package/tests/unit/static-params.test.ts +166 -13
package/.github/workflows/ci.yml
CHANGED
|
@@ -19,7 +19,7 @@ jobs:
|
|
|
19
19
|
|
|
20
20
|
- uses: oven-sh/setup-bun@v1
|
|
21
21
|
with:
|
|
22
|
-
bun-version:
|
|
22
|
+
bun-version: 1.3.11
|
|
23
23
|
|
|
24
24
|
- run: bun install --frozen-lockfile
|
|
25
25
|
|
|
@@ -43,7 +43,7 @@ jobs:
|
|
|
43
43
|
|
|
44
44
|
- uses: oven-sh/setup-bun@v1
|
|
45
45
|
with:
|
|
46
|
-
bun-version:
|
|
46
|
+
bun-version: 1.3.11
|
|
47
47
|
|
|
48
48
|
- run: bun install --frozen-lockfile
|
|
49
49
|
|
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,48 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.16.0] - 2026-06-01
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **VuePress Book Pipeline**: Books are now first-class with nested chapter ids and TOCs, a catch-all chapter route, collapsible sections in the chapter sidebar, book-level LaTeX/math, VuePress `:::container` admonitions, and inter-chapter links. Includes a new `bun run sync-vuepress-book` importer that handles frontmatter-less chapters and stale `.md` references gracefully.
|
|
12
|
+
- **Shiki Syntax Highlighting**: Replaced `react-syntax-highlighter`/Prism with a build-time Shiki pipeline across both Markdown/MDX and rST. Unknown fence languages now degrade to plaintext with a build-log warning instead of crashing the build, and any bundled Shiki language is lazy-loaded on demand.
|
|
13
|
+
- **Code-Group Tabs**: New `:::code-group` (Markdown) and `.. code-group::` (rST) directives render fenced blocks as switchable tabs, with auto-detected icons for languages, package managers, and config files.
|
|
14
|
+
- **Shiki Notation Comments**: Inline `// [!code focus]`, `[!code error]`, `[!code warning]`, `[!code highlight]`, and diff markers render with visual indicators inside code blocks.
|
|
15
|
+
- **GitHub-Flavored Alert Blockquotes**: `> [!NOTE]`, `> [!TIP]`, `> [!IMPORTANT]`, `> [!WARNING]`, `> [!CAUTION]` render as styled callouts in both Markdown and rST (admonition visual parity).
|
|
16
|
+
- **Reading Meta**: Word count appears alongside reading time on post and chapter headers, with Chinese localization (`5 分钟阅读`).
|
|
17
|
+
- **External Link Affordance**: Outward-arrow icon on external links, opened in a new tab.
|
|
18
|
+
- **Code Block Polish**: Real tab icons via Iconify for code-group headers, proper-case language labels, a more prominent highlighted-line background, and rST `:linenos:` / `:emphasize-lines:` / `:caption:` support.
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
- **Mermaid Diagrams** now render frameless by default — no outer border, padding, background, or shadow. Diagram SVGs use the full column width.
|
|
22
|
+
- **`showChapterExcerpt`** defaults to `false` on books; opt back in per-book.
|
|
23
|
+
- **Markdown Rendering Fidelity**: Single-line `$$ x $$` block math now expands and parses as display math; block math centers via `.katex-display`; VuePress inline `<img>` styling is preserved through import; KaTeX `unicodeTextInMathMode` warnings (noise on CJK math labels) are scoped-silenced.
|
|
24
|
+
- **Dependency Refresh**: TypeScript 5.9 → 6.0, ESLint 9 → 10 (config rewritten without `eslint-config-next`), Next.js + safe minor/patch sweep, `@types/node` 24 → 25, `pdf-to-img` 5 → 6.
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
- **Hydration Mismatches**: Locale-bound text in `TocPanel`, `PostNavigation`, `PostSidebar`, and `ShareBar` no longer logs a hydration error on first paint for users whose stored locale differs from `siteConfig.i18n.defaultLocale`. Mermaid's mutation-prone wrapper is likewise marked.
|
|
28
|
+
- **Table Padding**: Restored horizontal padding on prose table cells (the earlier `:where()`-based override was silently stripped by Tailwind v4 / Lightning CSS; replaced with a plain descendant selector that survives compilation).
|
|
29
|
+
- **rST Fallback Parser**: Added rendering for `.. figure::`, line blocks, admonitions (including custom `.. cnote::` with caption), `:doc:` / `:ref:` / `:numref:` roles; suppresses `.. toctree::` from rendered body; normalizes escaped whitespace in inline rST.
|
|
30
|
+
- **React 19 Warnings**: Resolved `react-hooks/set-state-in-effect` warnings and silenced image-preload warnings for local images. Eager `CoverImage` variants are no longer deprioritized.
|
|
31
|
+
- **Copy-Paste UX**: Stripped per-paragraph backgrounds on article copy to prevent "striping" when pasting into rich-text editors. Clipboard-API guard before `preventDefault`.
|
|
32
|
+
- **Misc**: `<summary>` styled as an interactive link; code-group icon lookups via `Object.hasOwn`; shiki dedup state reset in `finally`; `<style>` element scoping for shiki output; book import edge cases (URI decode, Vue component warnings, fenced blocks in container normalizer, chapter image paths relative to parent dir).
|
|
33
|
+
|
|
34
|
+
## [1.15.0] - 2026-04-12
|
|
35
|
+
|
|
36
|
+
### Added
|
|
37
|
+
- **First-Class rST Support**: Added robust reStructuredText post and series support through the Python/docutils pipeline, including README-based series indexes and better handling of legacy rST metadata and content structure.
|
|
38
|
+
- **Legacy rST Link Resolution**: Added support for legacy `:doc:` references, including same-series and cross-series links, so migrated rST content can keep its internal navigation intact.
|
|
39
|
+
|
|
40
|
+
### Changed
|
|
41
|
+
- **rST Rendering Fidelity**: Improved rST rendering parity with Markdown for links, tables, code blocks, images, and general article presentation, making legacy content feel native inside Amytis.
|
|
42
|
+
- **Series Ordering Accuracy**: Series listing pages now sort by the real newest post date in each series instead of assuming the first rendered post is the latest one.
|
|
43
|
+
- **Build Performance**: Significantly reduced rebuild cost by caching rendered rST output, preserving nested image optimizer caches, tightening asset sync behavior, reducing generated image width buckets, and skipping Pagefind work when exported HTML is unchanged.
|
|
44
|
+
|
|
45
|
+
### Fixed
|
|
46
|
+
- **Legacy rST Edge Cases**: Fixed broken rST image rendering, restored docutils-based runtime rendering, accepted legacy single-digit date formats, improved adjacency/order handling for manually ordered rST series, and kept rST excerpts explicit when metadata omits them.
|
|
47
|
+
- **Image Optimizer Compatibility**: Prevented broken optimized URLs for local `.avif` and `.webp` sources by bypassing `next-image-export-optimizer` for those files in shared image renderers.
|
|
48
|
+
- **Create Amytis on Windows**: Fixed `create-amytis` scaffolding on Windows for releases containing Unicode paths by switching the Windows extraction path to ZIP + PowerShell. The scaffold package was also released separately as `create-amytis@0.1.2`.
|
|
49
|
+
|
|
8
50
|
## [1.14.0] - 2026-04-05
|
|
9
51
|
|
|
10
52
|
### Added
|
package/CLAUDE.md
CHANGED
|
@@ -1,231 +1,102 @@
|
|
|
1
1
|
# CLAUDE.md
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Guidance for Claude Code in this repo. Rules, gotchas, and pointers — not reference material.
|
|
4
4
|
|
|
5
|
-
## Project
|
|
5
|
+
## Project
|
|
6
6
|
|
|
7
|
-
Amytis
|
|
7
|
+
Amytis: static digital-garden blog (Next.js 16 App Router, React 19, Tailwind v4, static export). Content in MDX / Markdown (primary), rST (legacy support); everything resolves at build time. Package manager: bun.
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Essential commands
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
#
|
|
13
|
-
bun
|
|
14
|
-
bun
|
|
15
|
-
|
|
16
|
-
#
|
|
17
|
-
bun
|
|
18
|
-
bun run test:unit # Run unit tests (src/)
|
|
19
|
-
bun run test:int # Run integration tests
|
|
20
|
-
bun run test:e2e # Run end-to-end tests
|
|
21
|
-
bun run test:mobile # Run Playwright mobile compatibility tests (requires dev server)
|
|
22
|
-
bun test path/to/file.test.ts # Run a single test file
|
|
23
|
-
|
|
24
|
-
# Build
|
|
25
|
-
bun run build # Full production build (copies assets, builds Next.js, optimizes images)
|
|
26
|
-
bun run build:dev # Development build (no image optimization, faster) — also regenerates Pagefind search index in public/pagefind/
|
|
27
|
-
bun run clean # Remove .next, out, public/posts directories
|
|
28
|
-
|
|
29
|
-
# Deploy
|
|
30
|
-
bun run deploy # Deploy out/ to Linux/nginx server via rsync+sshpass (reads .env.local)
|
|
31
|
-
|
|
32
|
-
# Content creation
|
|
33
|
-
bun run new "Post Title" # Create new post
|
|
34
|
-
bun run new-series "Series Name" # Create new series
|
|
35
|
-
bun run new-from-pdf doc.pdf # Create post from PDF
|
|
36
|
-
bun run new-from-images ./photos # Create post from image folder
|
|
37
|
-
bun run new-flow # Create today's flow note
|
|
38
|
-
bun run add-series-redirects # Add redirectFrom to all series posts (for autoPaths migration)
|
|
39
|
-
bun run add-series-redirects <series-slug> # Add redirectFrom to one series only
|
|
40
|
-
bun run add-series-redirects --dry-run # Preview without writing
|
|
41
|
-
bun run new-flow-from-chat # Import all new files from imports/chats/
|
|
42
|
-
bun run sync-book # Sync chapters list for all books from disk
|
|
43
|
-
bun run sync-book <slug> # Sync chapters list for one book
|
|
12
|
+
bun dev # dev server (Turbopack, http://localhost:3000)
|
|
13
|
+
bun run lint # ESLint
|
|
14
|
+
bun test # all tests
|
|
15
|
+
bun run build # production build (image optimization + Pagefind)
|
|
16
|
+
bun run build:dev # faster build; regenerates public/pagefind/ for search-in-dev
|
|
17
|
+
bun run clean # nuke .next, out, public/posts when caches misbehave
|
|
44
18
|
```
|
|
45
19
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
- **Strict build over silent runtime failure.** This is a statically exported site — all misconfiguration must be caught at build time. Prefer `throw` in `generateStaticParams` and similar build-time functions over silent skips or `console.warn`. Examples: `validateSeriesAutoPaths` throws on slug collisions; `redirectFrom` alias conflicts should throw rather than silently producing broken redirects.
|
|
49
|
-
|
|
50
|
-
## Architecture
|
|
51
|
-
|
|
52
|
-
### Data Flow
|
|
53
|
-
|
|
54
|
-
1. **Content source**: MDX/Markdown files in `content/posts/` and `content/series/`
|
|
55
|
-
2. **Data layer**: `src/lib/markdown.ts` - reads files with Node `fs`, parses frontmatter with `gray-matter`, validates with Zod
|
|
56
|
-
3. **Static generation**: Routes use `generateStaticParams` to pre-render at build time
|
|
57
|
-
4. **Rendering**: `react-markdown` with remark/rehype plugins for GFM, math (KaTeX), syntax highlighting, and Mermaid diagrams
|
|
58
|
-
|
|
59
|
-
### Key Files
|
|
60
|
-
|
|
61
|
-
- `site.config.ts` - Site configuration (nav, social, pagination, themes, i18n, analytics, comments)
|
|
62
|
-
- `src/lib/markdown.ts` - Data access layer with all content query functions
|
|
63
|
-
- `src/lib/urls.ts` - Central URL helpers (`getPostUrl`, `getPostsBasePath`, `getSeriesCustomPaths`, etc.) — always use these instead of hardcoding `/posts/[slug]`
|
|
64
|
-
- `src/lib/search-utils.ts` - Pure search utilities (URL type detection, date extraction, title cleaning, markdown stripping) shared by `Search` and the search index route
|
|
65
|
-
- `src/app/globals.css` - Theme CSS variables and color palettes
|
|
66
|
-
- `src/components/MarkdownRenderer.tsx` - MDX rendering with all plugins
|
|
67
|
-
- `src/i18n/translations.ts` - Language strings for i18n
|
|
68
|
-
|
|
69
|
-
### Route Structure
|
|
70
|
-
|
|
71
|
-
- `/` - Homepage with hero, featured series, featured posts, latest writing
|
|
72
|
-
- `/posts/[slug]` - Individual post pages
|
|
73
|
-
- `/posts/page/[page]` - Paginated post listing
|
|
74
|
-
- `/series` - All series overview
|
|
75
|
-
- `/series/[slug]` - Single series with its posts
|
|
76
|
-
- `/series/[slug]/page/[page]` - Series pagination
|
|
77
|
-
- `/tags` - Tag cloud with post counts
|
|
78
|
-
- `/tags/[tag]` - Posts filtered by tag
|
|
79
|
-
- `/authors/[author]` - Posts filtered by author
|
|
80
|
-
- `/archive` - Chronological listing grouped by year/month
|
|
81
|
-
- `/books` - All books overview
|
|
82
|
-
- `/books/[slug]` - Single book with chapter listing
|
|
83
|
-
- `/books/[slug]/[chapter]` - Individual chapter page
|
|
84
|
-
- `/flows` - Flow notes listing (paginated)
|
|
85
|
-
- `/flows/page/[page]` - Paginated flow listing
|
|
86
|
-
- `/flows/[year]` - Flows filtered by year
|
|
87
|
-
- `/flows/[year]/[month]` - Flows filtered by month
|
|
88
|
-
- `/flows/[year]/[month]/[day]` - Single flow detail page
|
|
89
|
-
- `/[slug]` - Static pages (about, subscribe, etc.) and custom posts/series listing pages
|
|
90
|
-
- `/[prefix]/[slug]` - Posts at custom URL prefixes (e.g. `/articles/my-post`, `/weeklies/my-post`)
|
|
91
|
-
- `/[prefix]/page/[page]` - Paginated listing at custom URL prefixes
|
|
92
|
-
|
|
93
|
-
### Content Structure
|
|
94
|
-
|
|
95
|
-
**Posts** support two formats:
|
|
96
|
-
- **Flat file**: `content/posts/my-post.mdx`
|
|
97
|
-
- **Nested folder**: `content/posts/my-post/index.mdx` (allows co-located images in `./images/`)
|
|
98
|
-
|
|
99
|
-
**Series** live in `content/series/[slug]/index.mdx` with optional `images/` folder for cover images.
|
|
100
|
-
|
|
101
|
-
**Books** live in `content/books/[slug]/` with `index.mdx` for metadata and separate `.mdx` files per chapter. The `index.mdx` frontmatter defines chapter ordering with an optional parts structure.
|
|
102
|
-
|
|
103
|
-
**Flows** (daily notes) live in `content/flows/YYYY/MM/DD.md` (or `.mdx`). Each flow has a date, title, excerpt, tags, and markdown content.
|
|
104
|
-
|
|
105
|
-
Date-prefixed filenames (`2026-01-01-my-post.mdx`) extract dates automatically.
|
|
106
|
-
|
|
107
|
-
## Config Files
|
|
108
|
-
|
|
109
|
-
There are two config files that must be kept in sync:
|
|
110
|
-
|
|
111
|
-
- **`site.config.ts`** — the live config for this repo (i18n enabled; locale-aware fields use `{ en: '...', zh: '...' }` objects)
|
|
112
|
-
- **`site.config.example.ts`** — single-language starter template shipped via `create-amytis`; locale-aware fields use plain strings; optional features (books, flow) default to disabled
|
|
113
|
-
|
|
114
|
-
**Rule:** Any schema change to `site.config.ts` (new field, renamed field, type change) must be mirrored in `site.config.example.ts`. Locale-aware values (`string | Record<string, string>`) should use plain strings in the example.
|
|
115
|
-
|
|
116
|
-
## Configuration (`site.config.ts`)
|
|
117
|
-
|
|
118
|
-
Key configuration options:
|
|
119
|
-
- `nav` - Navigation links with weights
|
|
120
|
-
- `social` - GitHub, Twitter, email links for footer
|
|
121
|
-
- `series.navbar` - Series slugs to show in navbar dropdown
|
|
122
|
-
- `series.customPaths` - Per-series custom URL prefix e.g. `{ 'weeklies': 'weeklies' }` → posts at `/weeklies/[slug]`
|
|
123
|
-
- `pagination.posts`, `pagination.series` - Items per page
|
|
124
|
-
- `themeColor` - 'default' | 'blue' | 'rose' | 'amber'
|
|
125
|
-
- `hero` - Homepage hero title and subtitle
|
|
126
|
-
- `i18n` - Default locale and supported locales
|
|
127
|
-
- `featured.series` - Scrollable series: `scrollThreshold` (default: 2), `maxItems` (default: 6)
|
|
128
|
-
- `featured.stories` - Scrollable stories: `scrollThreshold` (default: 1), `maxItems` (default: 5)
|
|
129
|
-
- `analytics.providers` - array of enabled providers: `['umami', 'google']`; `[]` disables analytics
|
|
130
|
-
- `comments.provider` - 'giscus' | 'disqus' | null
|
|
131
|
-
- `feed.format` - 'rss' | 'atom' | 'both'
|
|
132
|
-
- `feed.content` - 'full' | 'excerpt'
|
|
133
|
-
- `feed.maxItems` - max feed items (0 = unlimited)
|
|
134
|
-
- `footer.bottomLinks` - custom links in the footer bottom bar (ICP, cookie policy, etc.); `text` accepts plain string or `{ en, zh }` locale map
|
|
135
|
-
- `posts.basePath` - Custom URL prefix for all posts (default: `'posts'`); e.g. `'articles'` → posts at `/articles/[slug]`
|
|
136
|
-
- `posts.authors.default` - Fallback authors when a post has none set in frontmatter
|
|
137
|
-
- `posts.authors.showInHeader` - Show author byline below post title (default: true)
|
|
138
|
-
- `posts.authors.showAuthorCard` - Show author card at end of post (default: true)
|
|
139
|
-
- `posts.excludeFromListing` - Series slugs whose posts are hidden from `/posts` listing pages
|
|
140
|
-
- `authors` - Per-author profiles: `bio`, `avatar` (image path), `social` (array of `{ image, description }`)
|
|
141
|
-
|
|
142
|
-
## Content Frontmatter
|
|
143
|
-
|
|
144
|
-
### Posts
|
|
145
|
-
|
|
146
|
-
```yaml
|
|
147
|
-
---
|
|
148
|
-
title: "Post Title"
|
|
149
|
-
subtitle: "Optional subtitle line" # Rendered below the title in italic
|
|
150
|
-
date: "2026-01-01"
|
|
151
|
-
excerpt: "Optional summary (auto-generated if omitted)"
|
|
152
|
-
category: "Category Name"
|
|
153
|
-
tags: ["tag1", "tag2"]
|
|
154
|
-
authors: ["Author Name"]
|
|
155
|
-
series: "series-slug" # Link to a series
|
|
156
|
-
draft: true # Hidden in production
|
|
157
|
-
featured: true # Show in featured section
|
|
158
|
-
pinned: true # Always shown in featured section; never shuffled away (hero = most recent pinned)
|
|
159
|
-
coverImage: "./images/cover.jpg" # Local or external URL
|
|
160
|
-
latex: true # Enable KaTeX math
|
|
161
|
-
toc: false # Hide table of contents
|
|
162
|
-
layout: "simple" # Use simple layout (default: "post")
|
|
163
|
-
externalLinks: # Links to external discussions
|
|
164
|
-
- name: "Hacker News"
|
|
165
|
-
url: "https://news.ycombinator.com/item?id=12345"
|
|
166
|
-
- name: "V2EX"
|
|
167
|
-
url: "https://v2ex.com/t/123456"
|
|
168
|
-
redirectFrom: # Old URLs that should redirect to this post (prefix changes only)
|
|
169
|
-
- /posts/my-old-slug
|
|
170
|
-
- /old-series/my-old-slug
|
|
171
|
-
---
|
|
172
|
-
```
|
|
20
|
+
Content-creation scripts, test layout, validate pipeline → `docs/CONTRIBUTING.md`.
|
|
173
21
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
```yaml
|
|
177
|
-
---
|
|
178
|
-
title: "Series Title"
|
|
179
|
-
excerpt: "Series description"
|
|
180
|
-
date: "2026-01-01"
|
|
181
|
-
coverImage: "./images/cover.jpg"
|
|
182
|
-
featured: true # Show in featured series
|
|
183
|
-
draft: true # Hidden in production (default: false)
|
|
184
|
-
sort: "date-asc" # 'date-asc' | 'date-desc' | 'manual'
|
|
185
|
-
posts: ["post-1", "post-2"] # Manual post ordering (optional)
|
|
186
|
-
---
|
|
187
|
-
```
|
|
22
|
+
## Architecture map
|
|
188
23
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
24
|
+
Quick "where do routes live" lookup. Full reference: `docs/ARCHITECTURE.md`.
|
|
25
|
+
|
|
26
|
+
- Standard routes follow folder names under `src/app/`: `/posts`, `/series`, `/tags`, `/notes`, `/books`, `/authors`, `/archive`, `/graph`, `/flows/[year]/[month]/[day]`.
|
|
27
|
+
- **Top-level `[slug]` and `[slug]/[postSlug]`** resolve `redirectFrom` aliases and `series.customPaths` — highest-risk dynamic surface; touch with care.
|
|
28
|
+
- Feeds at `feed.xml` / `feed.atom` / `all.xml` / `all.atom` / `flows/feed.{xml,atom}`; sitemap at `sitemap.ts`; search index at `search.json`.
|
|
29
|
+
- Rendering pipeline lives in `src/lib/`: Shiki (`shiki.ts`, `shiki-rst.ts`), remark/rehype plugins (`remark-github-alerts`, `remark-wikilinks`, `remark-code-group`, `rehype-fence-meta`, `rehype-image-metadata`), redirects (`series-redirects.ts`), feeds/JSON-LD (`feed-utils.ts`, `json-ld.ts`).
|
|
30
|
+
|
|
31
|
+
## Design principles
|
|
32
|
+
|
|
33
|
+
- **Strict build over silent runtime failure.** Static export means misconfiguration must fail at build time. Use `throw` in `generateStaticParams` and similar — never silent skips or `console.warn`. Precedent: `validateSeriesAutoPaths` throws on slug collisions; `redirectFrom` alias conflicts (reserved slug or duplicate) should also throw, not produce broken redirects.
|
|
34
|
+
- **Exception**: fence-language resolution in `src/lib/shiki.ts` deliberately degrades to `plaintext` + a deduped `console.warn` instead of throwing. Authors can't reliably predict Shiki's alias coverage, and "typo" vs "legitimate community alias" are indistinguishable from our side, so production deploys shouldn't fail on a single unhighlighted code block. Real typos still surface via the warn output in local/CI build logs.
|
|
35
|
+
- **Validate author input at build time; keep content portable.** Frontmatter via Zod; slug / redirect conflicts throw. Files on disk stay valid `.md` / `.mdx` / `.rst` — no Amytis-specific syntax that breaks other tools.
|
|
36
|
+
|
|
37
|
+
## Integration-point rules (always go through X)
|
|
38
|
+
|
|
39
|
+
- **URLs:** always `getPostUrl()` / `getPostsBasePath()` / `getSeriesCustomPaths()` from `src/lib/urls.ts`. Never hardcode `/posts/[slug]` — posts may live at `/articles/[slug]`, custom prefixes (`series.customPaths`), or under `posts.basePath`.
|
|
40
|
+
- **Content reads:** always via `src/lib/markdown.ts` (`getAllPosts`, `getPostBySlug`, `getSeriesData`, etc.). Frontmatter validation belongs in its Zod schemas, not in route files.
|
|
41
|
+
- **Search utilities:** pure helpers (URL type detection, date extraction, title cleaning, markdown stripping) live in `src/lib/search-utils.ts` and are shared by the `Search` component and the search-index route. Don't duplicate them.
|
|
42
|
+
- **i18n strings:** add to `src/i18n/translations.ts`. Locale-aware config fields are `string | Record<string, string>`; resolve via `resolveLocale()` / `resolveLocaleValue()` from `src/lib/i18n.ts`.
|
|
43
|
+
|
|
44
|
+
## Config sync
|
|
45
|
+
|
|
46
|
+
`site.config.ts` (this repo — i18n object form, `{ en, zh }`) and `site.config.example.ts` (shipped via `create-amytis` — plain strings, single-locale, optional features default disabled) must stay in sync. Any schema change to one must be mirrored in the other.
|
|
47
|
+
|
|
48
|
+
## Gotchas (things Claude will get wrong on first try)
|
|
49
|
+
|
|
50
|
+
- **`turbopackIgnore` on fs reads.** Any `fs.readFileSync()` path expression must be preceded by `/* turbopackIgnore: true */` (see `src/lib/markdown.ts`, `src/lib/rehype-image-metadata.ts`). Missing it causes incorrect bundling.
|
|
51
|
+
- **No AVIF for `coverImage`.** Upstream bug in `next-image-export-optimizer` emits `.webp` files but a `srcset` pointing at `.avif` → 404 in prod. Use `.jpg` / `.png` / `.webp`. See `docs/TROUBLESHOOTING.md`.
|
|
52
|
+
- **Unicode slugs.** Dynamic route pages call `safeDecodeParam()` and try decoded / raw / NFC / NFD variants — don't shortcut with bare `decodeURIComponent()` (it throws on malformed input). When touching dynamic routes, verify both ASCII and Unicode slugs.
|
|
53
|
+
- **`generateStaticParams` returns raw values.** Don't `encodeURIComponent` route params; Next.js handles encoding. Don't link to placeholder routes like `/posts/[slug]` — always link to concrete URLs.
|
|
54
|
+
- **Series format is locked.** A series index can be `index.md` / `.mdx` / `README.md` / `README.mdx` / `index.rst` / `README.rst` (first match wins). All child posts must match. Mixing formats is a build error.
|
|
55
|
+
- **rST needs Python `docutils`.** Set `AMYTIS_RST_PYTHON=/path/to/python` if not on `$PATH`. Without it, falls back to a lower-fidelity built-in parser.
|
|
56
|
+
- **Pagefind index.** `bun run build:dev` regenerates `public/pagefind/`; search returns stale results until you rerun it after content changes.
|
|
57
|
+
- **`trailingSlash: true` is load-bearing.** Lets co-located post assets (`posts/slug/images/`) coexist with `posts/slug/index.html`. Don't flip it in `next.config.ts`.
|
|
58
|
+
- **Shiki highlighter is a `globalThis` singleton.** Never instantiate it per render — `createHighlighter` loads Oniguruma WASM + grammars (~1–2 s). See `src/lib/shiki.ts`.
|
|
59
|
+
- **rST sanitize-html allowlist must keep `style` + `data-*` on `pre`/`code`/`span`/`div`.** Stripping any of these silently kills Shiki output (monochrome text in prod, looks fine locally because dev rST isn't sanitized). See `src/components/RstRenderer.tsx`.
|
|
60
|
+
- **Bump `RST_RENDERER_DISK_CACHE_VERSION` (`src/lib/rst-renderer.ts`) on highlighter-output changes.** Stale on-disk caches in `.cache/rst-renderer/` will serve old markup otherwise. Run `rm -rf .cache/rst-renderer` after pulling such a change.
|
|
61
|
+
- **Fence meta needs `rehype-fence-meta` BEFORE `rehype-raw`.** `mdast-util-to-hast` stores fence meta on `node.data.meta`, which `rehype-raw` drops during HTML round-trip. The plugin copies it to a real `data-meta` attribute first. Order matters in `MarkdownRenderer.tsx`.
|
|
62
|
+
- **Code-group tabs add `<input type="radio">` + `<label>` to the rST sanitize-html allowlist.** Keep the `transformTags` guard in `RstRenderer.tsx` that strips any `<input>` whose `type !== "radio"` — that's the defense against an rST author injecting password/file/etc. inputs through raw HTML.
|
|
63
|
+
- **GitHub alerts (`> [!NOTE]`, etc.) need the custom `remarkGithubAlerts` plugin.** `remark-gfm` v4 does NOT transform `[!TYPE]` blockquotes — they pass through as plain blockquotes with the literal marker visible. The custom plugin in `src/lib/remark-github-alerts.ts` is what detects them and routes to `<GithubAlert>`. If a future remark-gfm adds native alert support, that's a regression to watch for (covered by an integration test).
|
|
64
|
+
- **Single-line block math `$$ x $$` is silently inline.** `micromark-extension-math` (under `remark-math` v6) requires the `$$` markers on their own lines — single-line collapses to *inline* math (no `katex-display` wrapper, no centering, no display margin) and looks like a subtly under-styled formula. `src/lib/normalize-vuepress-math.ts` expands single-line `$$ x $$` to opener / body / closer before parsing, so authored content stays portable. If a chapter formula stops centering, suspect the normalizer's regex first.
|
|
65
|
+
|
|
66
|
+
## Development workflow
|
|
67
|
+
|
|
68
|
+
- **Don't push or open PRs unless asked.** Local commits are fine; anything touching the remote needs explicit go-ahead.
|
|
69
|
+
- **Commit in focused slices.** Keep `bun run validate` green at each commit so the branch stays bisectable.
|
|
70
|
+
- **Tests + docs in the same change.** Update `docs/ARCHITECTURE.md` / `docs/CONTRIBUTING.md` / `docs/TROUBLESHOOTING.md` alongside seam/workflow/invariant changes — not as a follow-up.
|
|
71
|
+
- **Commits** follow Conventional Commits: `feat | fix | refactor | perf | chore | docs | test | release`. Subject under ~70 chars; body explains *why*.
|
|
72
|
+
- **Branches:** `<type>/<kebab-slug>` matching commit prefixes.
|
|
73
|
+
- **No Claude attribution.** Do not add `Co-Authored-By: Claude ...` trailers to commit messages or the `🤖 Generated with [Claude Code]` footer to PR descriptions. The default templates in the harness include both — strip them.
|
|
74
|
+
|
|
75
|
+
## Verifying a change
|
|
76
|
+
|
|
77
|
+
- **Default verify loop: `bun run lint && bun run test` only.** Stop here.
|
|
78
|
+
- **Do NOT run `bun run build:dev` (or `bun run build` / `bun run validate`) unless the user asks OR it is genuinely needed.** It takes ~1–2 minutes (Turbopack compile + 800+ static pages + Pagefind index) and the cost adds up fast across many small steps. None of these are "needed" on their own: markdown pipeline edits, schema changes, route moves, branch tip, pre-PR readiness, "just to be safe."
|
|
79
|
+
- "Genuinely needed" means lint+test **cannot** catch the failure mode you're worried about — e.g. a strict-build invariant that only fires during static export (a `throw` in `generateStaticParams`, a `redirectFrom` collision, a Zod-schema failure that only triggers on real content). If unsure, prefer asking over running.
|
|
80
|
+
- `bun run validate` chains lint + test + build:dev; same rule — same bar.
|
|
81
|
+
- Touched `src/lib/markdown.ts`, `src/lib/urls.ts`, or `site.config.ts`? Add an integration test under `tests/integration/`.
|
|
82
|
+
- Touched any dynamic route? Verify both ASCII and Unicode slugs render.
|
|
83
|
+
|
|
84
|
+
## Context compression hints
|
|
85
|
+
|
|
86
|
+
When compressing history, preserve in priority order:
|
|
87
|
+
|
|
88
|
+
1. **Build-time invariants touched** — strict-build/throw boundaries, Zod schemas, `site.config.ts` shape, helpers in `src/lib/urls.ts` / `src/lib/markdown.ts`.
|
|
89
|
+
2. **Modified files and why** — file list with one-line reasons, not the diff.
|
|
90
|
+
3. **Verification status** — `bun run lint && bun test` (and `build:dev` if run) pass/fail.
|
|
91
|
+
4. **Cache version bumps** — `RST_RENDERER_DISK_CACHE_VERSION` etc.; easy to lose after compression.
|
|
92
|
+
5. **Open TODOs and rollback notes.**
|
|
93
|
+
6. **Tool output**: drop; keep pass/fail summary only.
|
|
94
|
+
|
|
95
|
+
## Where to find more
|
|
211
96
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
- `
|
|
215
|
-
- `
|
|
216
|
-
- `
|
|
217
|
-
- `
|
|
218
|
-
- `SeriesCatalog` - Timeline-style series post listing with numbered entries and progress indicator
|
|
219
|
-
- `SeriesSidebar` - Series navigation sidebar with progress bar and color-coded states
|
|
220
|
-
- `SeriesList` - Mobile-optimized series navigation matching sidebar design
|
|
221
|
-
- `Search` - Full-text search (Cmd/Ctrl+K) powered by Pagefind (build-time index); features type filter tabs (All/Post/Flow/Book), recent searches, keyboard navigation (arrows + number keys), debounced input, body scroll lock, focus trap, ARIA accessibility, and search syntax tips (`"phrase"`, `-exclude`)
|
|
222
|
-
- `TableOfContents` - Sticky TOC with scroll tracking, reading progress, and back-to-top
|
|
223
|
-
- `MarkdownRenderer` - MDX rendering with GFM, math, syntax highlighting, diagrams
|
|
224
|
-
- `CoverImage` - Optimized image component with WebP support
|
|
225
|
-
- `Comments` - Giscus or Disqus integration (theme-aware)
|
|
226
|
-
- `Analytics` - Umami, Plausible, or Google Analytics integration
|
|
227
|
-
- `FlowContent` - Client wrapper for flow pages with tag filtering state management
|
|
228
|
-
- `FlowCalendarSidebar` - Calendar sidebar with date navigation, browse panel, and clickable tag filters
|
|
229
|
-
- `FlowTimelineEntry` - Individual flow entry in timeline list
|
|
230
|
-
- `LanguageSwitch` - i18n language selector
|
|
231
|
-
- `ThemeToggle` - Light/dark mode toggle
|
|
97
|
+
- `docs/ARCHITECTURE.md` — route map, content model, components, data layer, frontmatter schemas, full configuration reference
|
|
98
|
+
- `docs/CONTRIBUTING.md` — full command list, test layout, content-creation scripts
|
|
99
|
+
- `docs/TROUBLESHOOTING.md` — known issues (AVIF, dev-mode browser-extension CSP/SharedStorage noise)
|
|
100
|
+
- `docs/deployment.md` — production deploy steps
|
|
101
|
+
- `docs/guides/` — task-oriented walkthroughs (e.g. `importing-vuepress-books.md`)
|
|
102
|
+
- `site.config.ts` — live config (read it directly; don't infer from this file)
|
package/README.md
CHANGED
|
@@ -44,6 +44,8 @@ Further reading: [How to Get AI to Write Better Code](https://hutusi.com/weeklie
|
|
|
44
44
|
- **Full-text Search:** Fast, static client-side search across all content (Cmd/Ctrl+K) powered by Pagefind.
|
|
45
45
|
- **Structured Content:**
|
|
46
46
|
- **Series:** Multi-part content organization with manual or automatic ordering.
|
|
47
|
+
- **Legacy rST Series:** A series can opt into reStructuredText by using `index.rst` or `README.rst`; mixed Markdown and rST files in the same series fail the build.
|
|
48
|
+
- **Docutils-backed rST Rendering:** When `docutils` is available, rST series render through the Python/docutils path instead of the lightweight fallback parser.
|
|
47
49
|
- **Books:** Long-form content with explicit chapters, parts, and a dedicated reading interface.
|
|
48
50
|
- **Notes:** Atomic, evergreen concepts for personal knowledge management.
|
|
49
51
|
- **Flows:** Stream-style daily notes or micro-blogging for quick thoughts.
|
|
@@ -213,6 +215,8 @@ Amytis is built around Next.js static export with `output: "export"` and `traili
|
|
|
213
215
|
- Posts default to `/<posts.basePath>/<slug>` and `posts.basePath` defaults to `/posts`.
|
|
214
216
|
- If `series.autoPaths` is enabled, series posts move to `/<series-slug>/<post-slug>`.
|
|
215
217
|
- If `series.customPaths` is configured, those custom prefixes override `autoPaths`.
|
|
218
|
+
- Frontmatter `redirectFrom` entries are exported as static redirect pages so legacy URLs can keep working.
|
|
219
|
+
- Prefer URL helpers over hardcoded post paths, because a canonical post URL may live under `/posts`, a series slug, or a custom prefix depending on config.
|
|
216
220
|
- Before moving series posts off the default posts path, run `bun run add-series-redirects --dry-run` and then `bun run add-series-redirects` so legacy URLs still resolve.
|
|
217
221
|
|
|
218
222
|
## Writing Content
|
|
@@ -236,11 +240,39 @@ Create daily notes in `content/flows/YYYY/MM/DD.md` or `.mdx`.
|
|
|
236
240
|
|
|
237
241
|
### Series
|
|
238
242
|
|
|
239
|
-
Create a directory in `content/series/<slug>/` with
|
|
243
|
+
Create a directory in `content/series/<slug>/` with either:
|
|
244
|
+
|
|
245
|
+
- `index.mdx` or `index.md` for a Markdown series
|
|
246
|
+
- `index.rst` or `README.rst` for an rST series
|
|
247
|
+
|
|
248
|
+
`README.mdx` and `README.md` are also accepted as Markdown series indexes. Then add posts as sibling files or folders using the same format as the series index. Mixed Markdown and rST files in one series are rejected at build time.
|
|
240
249
|
|
|
241
250
|
- CLI: `bun run new-series "Series Name"`
|
|
242
251
|
- You can also create a post directly inside an existing series with `bun run new "Post Title" --series <series-slug>`
|
|
243
252
|
|
|
253
|
+
#### rST / docutils workflow
|
|
254
|
+
|
|
255
|
+
For full-fidelity rST rendering, install `docutils` in a Python environment that the project can execute:
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
python3 -m pip install docutils pygments
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
If you want Amytis to use a specific interpreter, point `AMYTIS_RST_PYTHON` at it:
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
export AMYTIS_RST_PYTHON=/absolute/path/to/python
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Current behavior:
|
|
268
|
+
|
|
269
|
+
- `index.rst` or `README.rst` makes the whole series rST-only.
|
|
270
|
+
- For rST series ordering, explicit `:posts:` metadata takes precedence. If `:posts:` is absent, Amytis uses simple local `.. toctree::` entry order from the series index. If neither exists, the series falls back to the existing date-based sort.
|
|
271
|
+
- rST assets such as `.. image::` and `.. figure::` are resolved relative to the source file and rewritten to the site asset paths.
|
|
272
|
+
- Supported legacy roles such as `:doc:`, `:ref:`, `:numref:`, `:math:`, and `:dtag:` are either rendered directly or degraded into readable inline output instead of docutils error blocks.
|
|
273
|
+
- Top-of-file docinfo metadata is parsed into Amytis metadata, but it is not rendered at the top of blog-style article HTML.
|
|
274
|
+
- If Python/docutils is unavailable, Amytis falls back to the lightweight built-in rST compatibility path. That path keeps series loading working, but it has lower fidelity than the docutils-backed renderer.
|
|
275
|
+
|
|
244
276
|
### Books
|
|
245
277
|
|
|
246
278
|
Books are long-form structured content under `content/books/<slug>/`.
|
package/README.zh.md
CHANGED
|
@@ -44,6 +44,8 @@ Amytis 围绕一条从碎片想法到精炼知识的路径来帮助个人或组
|
|
|
44
44
|
- **全文搜索:** 基于 Pagefind 的快速静态客户端全文搜索,支持 Cmd/Ctrl+K。
|
|
45
45
|
- **结构化内容体系:**
|
|
46
46
|
- **Series:** 支持手动或自动排序的多篇内容组织方式。
|
|
47
|
+
- **Legacy rST Series:** 当系列入口文件使用 `index.rst` 或 `README.rst` 时,该系列会按 reStructuredText 解析;同一系列中混用 Markdown 和 rST 会在构建时直接失败。
|
|
48
|
+
- **基于 docutils 的 rST 渲染:** 当环境中可用 `docutils` 时,rST 系列会走 Python/docutils 渲染路径,而不是轻量回退解析器。
|
|
47
49
|
- **Books:** 支持明确章节、分部以及专用阅读界面的长篇内容。
|
|
48
50
|
- **Notes:** 面向个人知识管理的原子化常青概念。
|
|
49
51
|
- **Flows:** 用于快速记录想法的流式日记或微博客。
|
|
@@ -219,6 +221,8 @@ Amytis 基于 Next.js 静态导出构建,关键配置为 `output: "export"`
|
|
|
219
221
|
- 文章默认路径为 `/<posts.basePath>/<slug>`,其中 `posts.basePath` 默认值为 `/posts`。
|
|
220
222
|
- 启用 `series.autoPaths` 后,系列文章会移动到 `/<series-slug>/<post-slug>`。
|
|
221
223
|
- 如果配置了 `series.customPaths`,则会以这些自定义前缀覆盖 `autoPaths`。
|
|
224
|
+
- frontmatter 中的 `redirectFrom` 会在导出时生成静态跳转页,用于保留旧链接。
|
|
225
|
+
- 不要硬编码文章路径,优先使用 URL helper,因为规范 URL 可能位于 `/posts`、系列 slug 或自定义前缀之下。
|
|
222
226
|
- 在把系列文章从默认的 posts 路径迁走之前,先运行 `bun run add-series-redirects --dry-run`,再执行 `bun run add-series-redirects`,以确保旧链接仍然可访问。
|
|
223
227
|
|
|
224
228
|
## 内容写作
|
|
@@ -242,11 +246,39 @@ Amytis 基于 Next.js 静态导出构建,关键配置为 `output: "export"`
|
|
|
242
246
|
|
|
243
247
|
### Series
|
|
244
248
|
|
|
245
|
-
在 `content/series/<slug>/`
|
|
249
|
+
在 `content/series/<slug>/` 下创建目录,并选择以下其中一种入口文件:
|
|
250
|
+
|
|
251
|
+
- `index.mdx` 或 `index.md`,表示 Markdown 系列
|
|
252
|
+
- `index.rst` 或 `README.rst`,表示 rST 系列
|
|
253
|
+
|
|
254
|
+
`README.mdx` 和 `README.md` 也可作为 Markdown 系列入口。随后使用与入口文件一致的格式添加同级文章文件或子目录。同一系列中混用 Markdown 和 rST 会在构建时被拒绝。
|
|
246
255
|
|
|
247
256
|
- CLI: `bun run new-series "Series Name"`
|
|
248
257
|
- 也可以直接将文章创建到已有系列中: `bun run new "Post Title" --series <series-slug>`
|
|
249
258
|
|
|
259
|
+
#### rST / docutils 工作流
|
|
260
|
+
|
|
261
|
+
如果希望获得更完整的 rST 渲染效果,请在一个可执行的 Python 环境中安装 `docutils`:
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
python3 -m pip install docutils pygments
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
如果需要显式指定解释器,可设置 `AMYTIS_RST_PYTHON`:
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
export AMYTIS_RST_PYTHON=/absolute/path/to/python
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
当前行为:
|
|
274
|
+
|
|
275
|
+
- `index.rst` 或 `README.rst` 会让整个系列进入 rST 模式。
|
|
276
|
+
- 对于 rST 系列文章顺序,显式的 `:posts:` 元数据优先级最高;如果没有 `:posts:`,Amytis 会使用系列入口文件中简单本地 `.. toctree::` 条目的顺序;如果两者都没有,则回退到现有的基于日期排序。
|
|
277
|
+
- `.. image::`、`.. figure::` 等资源路径会相对源文件解析,并重写为站点可用的静态资源路径。
|
|
278
|
+
- `:doc:`、`:ref:`、`:numref:`、`:math:`、`:dtag:` 等常见 legacy role 会尽量直接渲染;无法完整支持时也会降级为可读的内联输出,而不是 docutils 报错块。
|
|
279
|
+
- 文件顶部的 docinfo 元数据会被解析为 Amytis 元数据,但不会再渲染为文章顶部的作者/版本信息块。
|
|
280
|
+
- 如果 Python/docutils 不可用,Amytis 会回退到内置的轻量 rST 兼容路径。这样仍可加载系列,但渲染保真度会低于 docutils 路径。
|
|
281
|
+
|
|
250
282
|
### Books
|
|
251
283
|
|
|
252
284
|
书籍是位于 `content/books/<slug>/` 下的长篇结构化内容。
|
package/TODO.md
CHANGED
|
@@ -22,6 +22,15 @@
|
|
|
22
22
|
- [ ] **Link Validator**: Script to check for broken internal wiki-links and external URLs.
|
|
23
23
|
- [ ] **Content Porter**: Tool to import/export notes from Obsidian or Notion.
|
|
24
24
|
- [ ] **Optimization**: Automatically compress and resize co-located images during build.
|
|
25
|
+
- [ ] **Build Performance**: Profile `build:dev`, clean stale export/search outputs before indexing, and consider a lighter local build path that skips expensive full-site indexing when not needed.
|
|
26
|
+
|
|
27
|
+
## 📚 rST Follow-up
|
|
28
|
+
- [ ] **Fixture Coverage**: Add more compatibility fixtures from legacy rST series, including nested lists, tables, directives, images, and internal links.
|
|
29
|
+
- [ ] **Parser Diagnostics**: Improve rST build errors with clearer file context, line numbers where possible, and actionable unsupported-syntax messages.
|
|
30
|
+
- [ ] **Syntax Contract**: Document the exact supported rST subset and explicitly list unsupported or partial constructs.
|
|
31
|
+
- [ ] **Asset & Link Handling**: Harden relative asset resolution and add validation for broken local rST links and image references.
|
|
32
|
+
- [ ] **Reading Time**: Reuse the shared mixed-CJK reading-time rules for rST content so Chinese, Japanese, and Korean text are counted consistently.
|
|
33
|
+
- [ ] **Advanced Constructs**: Evaluate the highest-value next rST features from real imported content, such as footnotes, simple tables, and selected directives.
|
|
25
34
|
|
|
26
35
|
## ✅ Completed Highlights
|
|
27
36
|
- [x] **JSON-LD Structured Data**: `BlogPosting`, `Book`, and `Article` schemas for Google rich results.
|
|
@@ -33,3 +42,4 @@
|
|
|
33
42
|
- [x] **Robust Engineering**: Zero hydration mismatches, Zod validation, and 64+ automated tests.
|
|
34
43
|
- [x] **Refined UI**: High-contrast typography, four color palettes, and horizontal scroll featured sections.
|
|
35
44
|
- [x] **Sub-features**: Newsletter/Subscribe page, Reading Progress, and Author Ecosystem.
|
|
45
|
+
- [x] **Series-scoped rST Support**: Strict rST series detection, README-based indexes, Unicode-safe static params, and legacy redirect handling.
|