mirror of
https://github.com/ChenQihan666/MyBlog-Next.git
synced 2026-08-13 23:31:07 +08:00
feat: add callout support (#655)
* feat: toggle .dark class on theme change * feat: add callouts with rehype-callouts plugin * docs: update blog posts with callouts
This commit is contained in:
@@ -10,6 +10,7 @@ import sitemap from "@astrojs/sitemap";
|
||||
import { unified } from "@astrojs/markdown-remark";
|
||||
import remarkToc from "remark-toc";
|
||||
import remarkCollapse from "remark-collapse";
|
||||
import rehypeCallouts from "rehype-callouts";
|
||||
import {
|
||||
transformerNotationDiff,
|
||||
transformerNotationHighlight,
|
||||
@@ -40,6 +41,7 @@ export default defineConfig({
|
||||
remarkToc,
|
||||
[remarkCollapse, { test: "Table of contents" }],
|
||||
],
|
||||
rehypePlugins: [rehypeCallouts],
|
||||
}),
|
||||
shikiConfig: {
|
||||
themes: { light: "min-light", dark: "night-owl" },
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
"astro": "^6.4.2",
|
||||
"dayjs": "^1.11.21",
|
||||
"lodash.kebabcase": "^4.1.1",
|
||||
"rehype-callouts": "^2.1.2",
|
||||
"remark-collapse": "^0.1.2",
|
||||
"remark-toc": "^9.0.0",
|
||||
"satori": "^0.26.0",
|
||||
|
||||
Generated
+15
@@ -29,6 +29,9 @@ importers:
|
||||
lodash.kebabcase:
|
||||
specifier: ^4.1.1
|
||||
version: 4.1.1
|
||||
rehype-callouts:
|
||||
specifier: ^2.1.2
|
||||
version: 2.1.2
|
||||
remark-collapse:
|
||||
specifier: ^0.1.2
|
||||
version: 0.1.2
|
||||
@@ -2263,6 +2266,10 @@ packages:
|
||||
regex@6.1.0:
|
||||
resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==}
|
||||
|
||||
rehype-callouts@2.1.2:
|
||||
resolution: {integrity: sha512-ZZWZ6EknUHiSzr4pQ88C7db3su4DElfJRmphZJbXpDdwW3urTwlYZpHckoC9pjEvBmUEEiJAM0uuc2uxyLdTfg==}
|
||||
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
|
||||
|
||||
rehype-parse@9.0.1:
|
||||
resolution: {integrity: sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==}
|
||||
|
||||
@@ -5341,6 +5348,14 @@ snapshots:
|
||||
dependencies:
|
||||
regex-utilities: 2.3.0
|
||||
|
||||
rehype-callouts@2.1.2:
|
||||
dependencies:
|
||||
'@types/hast': 3.0.4
|
||||
hast-util-from-html: 2.0.3
|
||||
hast-util-is-element: 3.0.0
|
||||
hastscript: 9.0.1
|
||||
unist-util-visit: 5.1.0
|
||||
|
||||
rehype-parse@9.0.1:
|
||||
dependencies:
|
||||
'@types/hast': 3.0.4
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
author: Sat Naing
|
||||
pubDatetime: 2022-09-23T15:22:00Z
|
||||
modDatetime: 2026-05-17T04:47:08.212Z
|
||||
modDatetime: 2026-06-03T00:00:00.000Z
|
||||
title: Adding new posts in AstroPaper theme
|
||||
slug: adding-new-posts-in-astropaper-theme
|
||||
featured: true
|
||||
@@ -44,6 +44,7 @@ src/content/posts/docs/_legacy/how-to.md -> mysite.com/posts/docs/how-to
|
||||
src/content/posts/Example Dir/Dummy Post.md -> mysite.com/posts/example-dir/dummy-post
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
> Files and directories prefixed with `_` are excluded from routing. Use them for drafts, shared assets, or internal-only content.
|
||||
|
||||
## Frontmatter
|
||||
@@ -71,7 +72,8 @@ Here is the list of frontmatter properties for each post:
|
||||
|
||||
</ResponsiveTable>
|
||||
|
||||
> Tip! You can get an ISO 8601 datetime by running `new Date().toISOString()` in the console.
|
||||
> [!TIP]
|
||||
> You can get an ISO 8601 datetime by running `new Date().toISOString()` in the console.
|
||||
|
||||
Only `title`, `description`, and `pubDatetime` fields in frontmatter must be specified.
|
||||
|
||||
@@ -116,6 +118,65 @@ AstroPaper includes workspace snippets to speed up creating new posts:
|
||||
|
||||
These snippets live in `.vscode/astro-paper.code-snippets`. If you use VS Code (or Cursor), they should be available automatically when you open the workspace.
|
||||
|
||||
## Callouts
|
||||
|
||||
AstroPaper started supporting callouts in AstroPaper v6.1. They use a simple blockquote syntax powered by `rehype-callouts` (Obsidian theme).
|
||||
|
||||
Here are the most commonly used types:
|
||||
|
||||
> [!NOTE]
|
||||
> Supplementary information the reader should be aware of.
|
||||
|
||||
> [!TIP]
|
||||
> Helpful advice, shortcuts, or best practices.
|
||||
|
||||
> [!WARNING]
|
||||
> Something that could go wrong or have unintended consequences.
|
||||
|
||||
> [!DANGER]
|
||||
> Serious risk of failure, data loss, or incorrect behavior.
|
||||
|
||||
> [!INFO]
|
||||
> Neutral informational context — less urgent than a note.
|
||||
|
||||
> [!SUCCESS]
|
||||
> Confirmation that something worked or is correct.
|
||||
|
||||
The full list of supported types includes: `NOTE`, `ABSTRACT`, `INFO`, `TODO`, `TIP`, `SUCCESS`, `QUESTION`, `WARNING`, `FAILURE`, `DANGER`, `BUG`, `EXAMPLE`, `QUOTE` — each with its own icon and color. Many types also accept aliases (e.g. `HINT` and `IMPORTANT` for `TIP`, `CAUTION` for `WARNING`). See the [rehype-callouts docs](https://github.com/lin-stephanie/rehype-callouts) for the complete reference.
|
||||
|
||||
### Collapsible callouts
|
||||
|
||||
Add `-` after the type to make the callout collapsed by default, or `+` to make it expanded but collapsible:
|
||||
|
||||
> [!WARNING]- Read before proceeding
|
||||
> This content is hidden until the reader expands it. Useful for long caveats that would otherwise interrupt the flow.
|
||||
|
||||
> [!TIP]+ Pro tip (expanded by default)
|
||||
> This starts open but can be collapsed. Great for optional detail you still want visible on first load.
|
||||
|
||||
### Custom titles
|
||||
|
||||
Replace the default type label with any title you like by adding text after the type:
|
||||
|
||||
> [!NOTE] Did you know?
|
||||
> The text after the type becomes the callout's heading. Leave it out and the type name is used automatically.
|
||||
|
||||
### Syntax summary
|
||||
|
||||
```md
|
||||
> [!NOTE]
|
||||
> Supplementary information.
|
||||
|
||||
> [!WARNING]- Collapsed by default
|
||||
> Hidden until expanded.
|
||||
|
||||
> [!TIP]+ Expanded, but collapsible
|
||||
> Starts open.
|
||||
|
||||
> [!DANGER] Custom title
|
||||
> Replaces the default heading.
|
||||
```
|
||||
|
||||
## Adding table of contents
|
||||
|
||||
By default, a post does not include any table of contents (TOC). To include one, write `Table of contents` as an h2 heading (`##` in Markdown) and place it where you want it to appear:
|
||||
@@ -181,7 +242,8 @@ export default defineConfig({
|
||||
|
||||
Here are two methods for storing images and using them inside a markdown file.
|
||||
|
||||
> Note: If you need to style optimized images in markdown, you should [use MDX](https://docs.astro.build/en/guides/images/#images-in-mdx-files).
|
||||
> [!IMPORTANT]
|
||||
> If you need to style optimized images in markdown, you should [use MDX](https://docs.astro.build/en/guides/images/#images-in-mdx-files).
|
||||
|
||||
### Inside `src/assets/` directory (recommended)
|
||||
|
||||
@@ -203,6 +265,7 @@ Example: suppose you want to display `example.jpg` whose path is `src/assets/ima
|
||||
<!-- ^^ This is wrong -->
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
> Technically, you can store images inside any directory under `src`. `src/assets` is just a recommendation.
|
||||
|
||||
### Inside `public/` directory
|
||||
@@ -225,7 +288,8 @@ Example: assume `example.jpg` is located at `public/assets/images/example.jpg`.
|
||||
|
||||
### Image compression
|
||||
|
||||
When putting images in a blog post (especially those in the `public/` directory), it is recommended to compress them. This will affect the overall performance of the website.
|
||||
> [!WARNING]
|
||||
> When putting images in a blog post (especially those in the `public/` directory), compress them first. Unoptimized images significantly hurt page performance.
|
||||
|
||||
Recommended image compression sites:
|
||||
|
||||
@@ -236,4 +300,5 @@ Recommended image compression sites:
|
||||
|
||||
The default OG image will be used if a post does not specify one. Though not required, an OG image relevant to the post should be specified in the frontmatter. The recommended size for OG images is **_1200 X 640_** px.
|
||||
|
||||
> [!TIP]
|
||||
> Since AstroPaper v1.4.0, OG images are generated automatically if not specified. Check out [the announcement](https://astro-paper.pages.dev/posts/dynamic-og-image-generation-in-astropaper-blog-posts/).
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
author: Sat Naing
|
||||
pubDatetime: 2022-12-28T04:59:04.866Z
|
||||
modDatetime: 2026-05-04T00:00:00Z
|
||||
modDatetime: 2026-06-03T00:00:00.000Z
|
||||
title: Dynamic OG image generation in AstroPaper blog posts
|
||||
slug: dynamic-og-image-generation-in-astropaper-blog-posts
|
||||
featured: false
|
||||
@@ -49,9 +49,8 @@ Dynamic OG images include _the blog post title_, _author name_, and _site title_
|
||||
|
||||
### Issue with Non-Latin Characters
|
||||
|
||||
Titles with non-latin characters won't display properly out of the box. In AstroPaper v6, dynamic OG images load font files from Astro's **Fonts** configuration (`astro.config.ts`) and register them with Satori.
|
||||
|
||||
To fix missing glyphs, switch the Google font family to one that covers your writing system, and make sure you include **both** `400` and `700` weights (Satori uses separate buffers for regular + bold).
|
||||
> [!CAUTION]
|
||||
> Titles with non-latin characters won't display properly out of the box. Switch the Google font family to one that covers your writing system, and include **both** `400` and `700` weights — Satori uses separate buffers for regular and bold, so missing either causes mismatched rendering.
|
||||
|
||||
```ts file="astro.config.ts"
|
||||
import { defineConfig, fontProviders } from "astro/config";
|
||||
@@ -79,15 +78,8 @@ If you change `cssVariable`, also update the matching key in:
|
||||
|
||||
> Check out [this PR](https://github.com/satnaing/astro-paper/pull/318) for more info.
|
||||
|
||||
## Trade-off
|
||||
|
||||
While this is a nice feature to have, there's still a trade-off: AstroPaper generates one PNG per eligible post at build time (when og image is not specified in the frontmatter), so total build time grows with content volume.
|
||||
|
||||
In AstroPaper v6, OG image generation is significantly faster (PR [#632](https://github.com/satnaing/astro-paper/pull/632)) than earlier implementations, so the per-image overhead is much lower in practice. If you still want to minimize build time on very large sites, you can disable it by setting `features.dynamicOgImage: false` in `astro-paper.config.ts` (and provide per-post `ogImage` files instead).
|
||||
|
||||
## Limitations
|
||||
|
||||
At the time of writing this, [Satori](https://github.com/vercel/satori) is fairly new and has not reached major release yet. So, there are still some limitations to this dynamic OG image feature.
|
||||
|
||||
- RTL languages are not supported yet.
|
||||
- [Using emoji](https://github.com/vercel/satori#emojis) in the title might be a little bit tricky.
|
||||
> [!WARNING] Caveats
|
||||
>
|
||||
> - **Build time** grows with content volume — one PNG per eligible post is generated at build time. Generation is faster in v6 (PR [#632](https://github.com/satnaing/astro-paper/pull/632)), but on very large sites you can disable it with `features.dynamicOgImage: false` in `astro-paper.config.ts`.
|
||||
> - **RTL languages** are not supported yet.
|
||||
> - **Emoji** in titles can be tricky — some may not render correctly.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
author: Sat Naing
|
||||
pubDatetime: 2022-09-23T04:58:53Z
|
||||
modDatetime: 2026-05-17T05:50:08.212Z
|
||||
modDatetime: 2026-06-03T00:00:00.000Z
|
||||
title: How to configure AstroPaper theme
|
||||
slug: how-to-configure-astropaper-theme
|
||||
featured: true
|
||||
@@ -296,7 +296,8 @@ import { Font } from "astro:assets";
|
||||
|
||||
The `--font-app` variable is used throughout the theme via the `font-app` Tailwind utility class, so updating this single variable applies your custom font everywhere.
|
||||
|
||||
> **Note**: Make sure the font name matches exactly as it appears on [Google Fonts](https://fonts.google.com). For other font providers or local fonts, refer to the [Astro Fonts documentation](https://docs.astro.build/en/guides/fonts/).
|
||||
> [!WARNING]
|
||||
> Make sure the font name matches exactly as it appears on [Google Fonts](https://fonts.google.com). For other font providers or local fonts, refer to the [Astro Fonts documentation](https://docs.astro.build/en/guides/fonts/).
|
||||
|
||||
## See also
|
||||
|
||||
|
||||
@@ -106,7 +106,9 @@ const rssHref = getRelativeLocaleUrl(
|
||||
"(prefers-color-scheme: dark)"
|
||||
).matches;
|
||||
const theme = stored ?? (prefersDark ? "dark" : "light");
|
||||
document.firstElementChild?.setAttribute("data-theme", theme);
|
||||
const root = document.firstElementChild;
|
||||
root?.setAttribute("data-theme", theme);
|
||||
root?.classList.toggle("dark", theme === "dark");
|
||||
// Expose value so theme.ts can skip re-detection.
|
||||
window.__theme = { value: theme };
|
||||
})();
|
||||
|
||||
@@ -21,7 +21,9 @@ function persist(): void {
|
||||
}
|
||||
|
||||
function reflect(): void {
|
||||
document.firstElementChild?.setAttribute("data-theme", themeValue);
|
||||
const root = document.firstElementChild;
|
||||
root?.setAttribute("data-theme", themeValue);
|
||||
root?.classList.toggle("dark", themeValue === DARK);
|
||||
document.querySelector("#theme-btn")?.setAttribute("aria-label", themeValue);
|
||||
|
||||
// Fill <meta name="theme-color"> with the computed background colour so
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
@import "tailwindcss";
|
||||
@import "./theme.css";
|
||||
@import "./typography.css";
|
||||
@import "rehype-callouts/theme/obsidian";
|
||||
|
||||
@custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *));
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
@apply border-s-accent/80 wrap-break-word opacity-80;
|
||||
}
|
||||
|
||||
details {
|
||||
details:not(.callout) {
|
||||
@apply text-foreground inline-block cursor-pointer select-none [&_p]:hidden [&_ul]:my-0!;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user