hexo-lilypond
v1.1.0
Published
Hexo plugin: render LilyPond sheet music in Markdown fences/tags as inline SVG
Maintainers
Readme
hexo-lilypond
在 Markdown 里直接写 LilyPond 乐谱,hexo generate 时调用本机 LilyPond CLI 编译成 SVG 嵌入页面。零 npm 运行依赖。
效果预览
单声部谱例(浅色主题):

多声部谱例 —— 左为浅色 + 背景染色,右为深色主题:
| 浅色 · 背景染色 | 深色 |
|:---:|:---:|
|
|
|
安装
npm install hexo-lilypond环境准备
brew install lilypond
lilypond --version # 记下版本号,对齐下面的 version 配置配置(_config.yml)
lilypond:
executable: lilypond # 裸名字走 PATH;可填绝对/相对路径
version: "2.26.0" # 与 `lilypond --version` 实际版本一致
output:
format: svg
padding: # 单位 mm;给 -dcrop 的紧边界增加安全留白
top: 1
right: 1
bottom: 2
left: 1
cache:
enable: true
dir: .cache/lilypond # 编译临时目录(.ps/.midi/日志隔离在此)
onError: auto # auto | embed | failoutput.padding 可写成单个数字(四边相同),也可按上例分别设置;写成 0 或 false 可关闭。插件会同时扩展 SVG 的物理尺寸和 viewBox,因此谱面字号、比例及字体不变,只增加透明安全边距。
重要:另在 _config.yml 的 exclude 里加 scores/**,防止 .ly 源文件被复制到 public/:
exclude:
- "scores/**"使用
1. 围栏代码块(lilypond 或简写 lily)
```lilypond
\relative c' {
c4 d e f |
g a b c |
}
```编译成:
<figure class="lilypond-score"><img class="lilypond-score-image" src="/lilypond/<hash>.svg"></figure>2. 独立 .ly 文件标签
把谱例文件放进 source/scores/,然后用标签引用(带不带引号均可):
{% lilypond "scores/demo.ly" %}
{% lilypond scores/demo.ly %}错误处理(onError)
| 值 | 行为 |
|---|---|
| embed | 页面内嵌 <pre class="lilypond-error">…</pre>,不中断构建 |
| fail | 抛错使构建失败,避免发布缺谱网站 |
| auto | hexo server 时 embed,generate/deploy 时 fail |
报错统一格式,含 Post / Score / line 三要素(行号已指回用户源码):
LilyPond compilation failed
Post: _posts/xxx.md
Score: lilypond block #3
LilyPond: line 7: syntax error, unexpected '}'缓存
- SVG 直接缓存到
public/lilypond/<hash>.svg,命中即复用、不重跑 LilyPond。 - 缓存键 =
SHA256(谱例源码 + LilyPond 版本 + 渲染器版本 + 渲染选项),任一变化即重编译。
目录结构
index.js # Hexo 感知层(唯一入口,注册 filter + tag)
lib/
├── config.js # 读配置 + 默认值
├── parser.js # 标签参数解析(caption/width 接口已留,未接入输出)
├── wrapper.js # 包装源码(去 \version、注入 \pointAndClickOff、行偏移)
├── compiler.js # spawn lilypond → SVG;错误行解析
├── svg.js # 扩展 -dcrop SVG 的物理尺寸与 viewBox
├── cache.js # SHA256 键 + public 缓存
└── renderer.js # 编排,输出 <figure>
test/ # node:test 单测(零依赖)lib/ 不依赖全局 hexo(依赖注入),index.js 是唯一碰 hexo 的层。
主题样式
插件只输出稳定 HTML,样式由主题负责。参考:
.lilypond-score { text-align: center; margin: 2em auto; }
.lilypond-score-image { max-width: 100%; height: auto; }
/* 深色模式反色:SVG 以 currentColor 上色,经 <img> 引入固定为黑,需 filter 反相;hue-rotate 保留彩色色相 */
.mdui-theme-dark .lilypond-score-image { filter: invert(1) hue-rotate(180deg); }
@media (prefers-color-scheme: dark) { .mdui-theme-auto .lilypond-score-image { filter: invert(1) hue-rotate(180deg); } }开发
npm test # node --test,零依赖本地开发推荐用
npm linkLicense
MIT
