11690 字
58 分钟
XiaoMai Markdown 增强功能
XiaoMai 提供了一系列主题专属的 Markdown 扩展与自定义语法容器。基于我们原生的 unified AST 处理管线构建,所有扩展在站点构建时即渲染为无障碍、语义化的 HTML,具备零客户端 JavaScript 水合开销与 100% M3E 设计令牌对齐。
文件树
文件树可将多层项目结构、源码层级与终端目录输出,转换为紧凑、可交互的树状视图,带有自动扩展名图标、差异高亮与可折叠分支。
1. 嵌套列表语法(:::file-tree)
当直接以 Markdown 嵌套列表的形式书写文件层级时,使用 :::file-tree 块指令。
:::file-tree{title="XiaoMai source tree"}- src - components/ - ++ Navigation.svelte # added component - -- Button.astro # removed component - content - posts/ - markdown-增强功能.md - layouts/ - PostLayout.astro - plugins - markdown/ - rehype-file-tree.mjs - styles - markdown/ - trees.css - **content.config.ts** # important file- public/ - favicon.svg- package.json:::XiaoMai 源码树
src
components
- +Navigation.svelteadded component
- -Button.astroremoved component
content
posts
- markdown-增强功能.md
layouts
- PostLayout.astro
plugins
markdown
- rehype-file-tree.mjs
styles
markdown
- trees.css
- content.config.tsimportant file
public
- favicon.svg
- package.json
写作规则与标记
- 差异状态:在条目前加
++(绿色背景与徽标)或--(红色背景与删除线)以突出改动。 - 注释:
#之后的任意文本会渲染为弱化的、右对齐行内注释。 - 强调:用
**粗体**包裹名称,让关键文件获得醒目的视觉权重。 - 可折叠文件夹:由嵌套列表项推断出的目录默认展开。添加末尾斜杠(例如
components/)可创建一个折叠目录,读者可通过点击或键盘导航展开。
2. 终端输出语法(```file-tree)
当你已经有用 tree 等命令行工具生成的目录树文本时,可直接粘贴进 file-tree 围栏代码块。Unicode 分支字符(├──、└──、│)与 ASCII 分支都会被自动解析。
```file-tree title="Build output" icon="simple"dist├── _astro/│ ├── index.css│ └── page.js└── favicon.ico```构建输出
dist
_astro
- index.css
- page.js
- favicon.ico
配置选项
title="string":为树设置自定义标题与无障碍标签。icon="colored" | "simple":在多彩扩展图标(colored,默认)与极简单色图标(simple)之间选择。
代码树
交互式代码树将左侧的多级文件层级导航面板与右侧的即时代码面板切换配对。它们为多文件示例、模块或整个目录的导读提供了类似 IDE 的阅读体验。
1. 容器语法(:::code-tree)
在 :::code-tree 块指令中组合多个围栏代码块。每个代码块通过 title="path/to/file" 指定其路径。
:::code-tree{title="XiaoMai Component Demo" height="380px" entry="src/Button.svelte"}```svelte title="src/Button.svelte"<script lang="ts"> let { label = "Click me" } = $props();</script>
<button class="m3-btn">{label}</button>```
```stylus title="src/styles/button.styl".m3-btn background: var(--primary) color: var(--on-primary) border-radius: var(--shape-corner-m)```
```json title="package.json"{ "name": "button-demo", "version": "1.0.0"}```:::XiaoMai 组件演示
<script lang="ts"> let { label = "Click me" } = $props();</script>
<button class="m3-btn">{label}</button>配置与标记
title="string":为代码树设置标题与无障碍标签。height="string":设置桌面视图的高度(默认420px,例如380px、26rem)。entry="filepath":指定首次加载时处于激活状态的文件。icon="colored" | "simple":在彩色或极简单色文件图标之间切换。:active:在任意围栏代码块上放置:active,将其指定为默认激活标签页。
2. 本地目录自动导入(@[code-tree])
直接指向工作区中的任意本地目录路径,即可在构建时自动扫描并生成交互式代码树,无需手动复制文件内容。
@[code-tree title="代码树工具" entry="code-tree.ts"](/src/utils)站点配置
import type { SiteConfig } from "@/types/config";import type { ResolvedTextureOptions, TextureConfig,} from "@/types/textureConfig";import { withUserConfig } from "../utils/config-overlay.ts";
/** * 站点核心配置:标题 / 语言 / 主题色(HCT 动态配色)/ 横幅 / 目录 / 进度条 / favicon。 * 类型见 src/types/config.ts。 */export const siteConfig: SiteConfig = withUserConfig("site", { site: " https://xiaomai.l.cd/", base: "/", title: "XiaoMai", subtitle: "博客", // 电脑端顶栏标题与导航内容区域:"left" 左对齐,"center" 居中。 topAppBar: { contentAlign: "center", }, // 显示设置面板控制:配置各项前端切换项的可见性(默认全部开启)。 displaySettings: { colorStyle: true, // 是否展示配色风格 9 宫格 colorSpec: true, // 是否展示 Color Spec 调色规范切换 wallpaperMode: true, // 是否展示页面背景(纯色/横幅)切换 layoutMode: true, // 是否展示文章列表布局(列表/网格)切换 reduceMotion: true, // 是否展示减少动效切换 texture: true, // 是否展示背景纹理选择 }, lang: "zh_CN", // Language code, e.g. 'en', 'zh_CN', 'ja', etc. // IANA time zone for precise post and moment timestamps. It is independent of lang. timeZone: "Asia/Shanghai", themeColor: { hue: 315, // Default hue 0-360. 站点设计默认粉紫(偏二次元);262 紫 / 345 粉 也可选 fixed: false, // Hide the theme color picker for visitors // Dynamic Material 3 palette style (TonalSpot/Vibrant/Content/Expressive/Rainbow/FruitSalad/Monochrome/Neutral/Fidelity) style: "tonalSpot", // Design spec version: "2021" (MD3) or "2025" (M3 Expressive)。角色集一致, // 差异仅在调色板派生(库的 colorSpec 静态为 2025 委托) spec: "2025", }, // 默认页面背景模式:"banner" 使用壁纸横幅,"none" 使用主题纯色。 // 访客在“显示设置”中的选择会保存在浏览器中,并覆盖这里的默认值。 wallpaperMode: { defaultMode: "none", }, // 页面背景纹理系统配置(5 大精美预设 + 零开销 HCT 动态取色) texture: { enable: true, // 是否启用背景纹理系统 defaultPreset: "starlight", // 默认纹理预设:"none" | "starlight" | "cyber-dots" | "topography" | "geometric" | "sakura" defaultOpacity: 0.12, // 默认纹理浓度 (0.05 ~ 0.25) allowMotion: true, // 是否允许背景微动效(开启 reduced-motion 时自动静止) }, banner: { // 推荐将图片放入 src/assets,并填写相对 src 的路径,以启用构建期 AVIF/WebP 响应式优化。 // 以 "/" 开头的 public 路径与远程 URL 仍可用,但会保留原图、不生成候选。 // desktop 用于 >= 1024px;mobile 仅用于 < 1024px 的首页,手机非首页不显示壁纸。 // 数组顺序就是轮播顺序;只需要静态 Banner 时,每组保留一张图片即可。 src: { desktop: ["assets/images/banner/desktop/1.webp"], mobile: ["assets/images/banner/mobile/1.webp"], }, // 图片裁切焦点:"top"、"center" 或 "bottom"。 position: "center", dim: { // 在图片上覆盖黑色遮罩以提高标题和顶部栏的对比度;opacity 范围为 0-1。 enable: true, opacity: 0.24, }, homeText: { // 仅在首页 Banner 中显示,标题与副标题会上下居中排列。 enable: false, title: "XiaoMai", subtitle: [ "欢迎来到我的博客", "Welcome to my blog", "僕のブログへようこそ", "내 블로그에 오신 것을 환영해", ], typewriter: { // 副标题逐字显示;关闭后直接显示完整副标题。 enable: true, // 打字速度(每个字符间隔,毫秒)。 speed: 100, // 回退反向删除速度(每个字符间隔,毫秒)。 deleteSpeed: 50, // 打字完成后停顿时间,单位为毫秒。 pauseTime: 2000, // 完成后是否循环播放;关闭表示只播放一次。 loop: true, }, }, carousel: { // 是否开启多张图片自动轮播;多张图片时生效,单张图片时自动降级为静态展示。 enable: false, // 轮播切换间隔时间(毫秒),运行时最小值限制为 3000ms。 interval: 6000, // 交叉淡入淡出(Crossfade)过渡时长(毫秒,默认 1200ms)。 fadeDuration: 1200, // 运镜呼吸动画模式:"ken-burns"(默认,循环运镜)| "zoom-in"(推进)| "zoom-out"(拉远)| "pan-left"(左移)| "pan-right"(右移)| "none"(无运镜)。 animation: "ken-burns", }, waves: { // 在 Banner 底部渲染页面背景色水波纹;关闭后不输出波浪 DOM。 enable: false, }, }, // Markdown 正文图片处理;仅匹配远程图片,不会产生额外网络请求或客户端代码。 imageOptimization: { // 为需要防盗链兼容的图片 CDN 添加 referrerpolicy="no-referrer",支持通配符。 noReferrerDomains: ["*.hdslb.com"], }, toc: { enable: true, // Display the table of contents on the right side of the post depth: 2, // Maximum heading depth to show in the table, from 1 to 3 }, progressIndicator: { // 进度条预设样式:dual 双向扫描(官方默认双线)/ single 单向扫描(单线) style: "dual", }, favicon: [ // 浏览器标签页图标,路径相对于 public 目录。 { src: "/logo/icon.webp" }, ],});
/** * 解析并返回背景纹理配置选项(包含关闭短路与 0 开销优化判定) */export function resolveTextureOptions( config: boolean | TextureConfig | undefined = siteConfig.texture, displaySettingsTexture: boolean = siteConfig.displaySettings?.texture ?? true,): ResolvedTextureOptions { if (config === false || config === undefined) { return { enable: false, defaultPreset: "none", defaultOpacity: 0.12, allowMotion: false, }; }
if (config === true) { return { enable: true, defaultPreset: "starlight", defaultOpacity: 0.12, allowMotion: true, }; }
const enable = config.enable ?? true; const defaultPreset = config.defaultPreset ?? "starlight"; const defaultOpacity = config.defaultOpacity ?? 0.12; const allowMotion = config.allowMotion ?? true;
// 性能短路优化: // 如果配置 enable: false,或者 defaultPreset: "none" 且显示设置面板未允许切换(访客也无法开启), // 则自动视为完全关闭以达成零 DOM、零 CSS、零运行时代价。 const effectiveEnable = enable && (defaultPreset !== "none" || displaySettingsTexture);
return { enable: effectiveEnable, defaultPreset, defaultOpacity, allowMotion, };}
/** 站点默认配色风格(访客未做选择时的回退值) */export function getDefaultStyle(): string { return siteConfig.themeColor.style;}
/** 站点默认 Color Spec(2021 / 2025) */export function getDefaultSpec(): string { return siteConfig.themeColor.spec;}
/** 解析并返回显示设置面板各项开关(未配置时默认 true) */export function resolveDisplaySettings(): { colorStyle: boolean; colorSpec: boolean; wallpaperMode: boolean; layoutMode: boolean; reduceMotion: boolean; texture: boolean;} { const cfg = siteConfig.displaySettings; const textureOpts = resolveTextureOptions( siteConfig.texture, cfg?.texture ?? true, ); return { colorStyle: cfg?.colorStyle ?? true, colorSpec: cfg?.colorSpec ?? true, wallpaperMode: cfg?.wallpaperMode ?? true, layoutMode: cfg?.layoutMode ?? true, reduceMotion: cfg?.reduceMotion ?? true, texture: textureOpts.enable && (cfg?.texture ?? true), };}XiaoMai Markdown 增强功能
https://xiaomai.l.cd/posts/markdown-增强功能/分享文章
生成精美分享图或复制链接,与更多人分享本文。
继续阅读
换条路线
从其他文章中稳定抽取
最后更新于 ,距今已过 28 天
部分内容可能已过时