# iJipu(爱记谱)—— Obsidian 插件 在 Obsidian 笔记里写 ` ```jps ` 代码块(**适合单行 / 片段乐谱**),或把 `.jps` 存成文件再链接 / 内联嵌入, 都能把 **.jps 简谱脚本渲染为可视化简谱(SVG)**,并可**试听**; 也可以点左侧栏图标(或在库里打开 `.jps`)用插件内嵌的**完整 iJipu 编辑器**编辑谱面。 渲染引擎复用 `@ijipu/engine`(与 iJipu 应用一致),设置项与 iJipu 一脉传承。 官网: > 码即成,谱自现。 ## 安装 / Installation > **桌面端与手机端都支持**(Windows / macOS / Linux / Android / iOS;`manifest.json` 的 `isDesktopOnly: false`)。 > > 两端的差别只在"**内嵌的完整 iJipu 编辑器**": > 它需要一个本机服务(用到只有桌面版 Obsidian 才提供的 Node.js 接口),因此**桌面端**才提供; > **手机端**改为用宿主自己的编辑器打开 `.jps` 源码(带 iJipu 那套语法着色与语法错误提示), > 点「看谱」即回到谱面预览 —— 渲染、试听、格式化、` ```jps ` 代码块在两端**完全一致**。 **从社区目录安装(推荐)** 1. 打开 Obsidian → **设置 → 第三方插件 → 浏览**; 2. 搜索 **iJipu**,点安装 → 启用。 **手动安装** 1. 到 [Releases](https://github.com/snailhome/obsidian-ijipu/releases) 下载 `main.js`、`manifest.json`、`styles.css`; 2. 放到 `<你的库>/.obsidian/plugins/ijipu/`(目录名必须是 `ijipu`,与 `manifest.json` 的 `id` 一致); 3. 在 **设置 → 第三方插件** 里启用 **iJipu**(看不到就重开 Obsidian)。 ## 用法 / Usage 在任意笔记里写一个 `jps` 代码块(**这仍是推荐用法之一**,尤其适合**单行 / 片段乐谱** —— 几句谱直接写在笔记里,不必为它单独建一个 `.jps` 文件;两种用法的取舍见下文「代码块还是 `.jps` 文件?」): ````markdown ```jps V: 1.0 B: 两只老虎 Z: 法国童谣 词曲 D: C P: 4/4 J: 120 Q: 1 2 3 1 | 1 2 3 1 | 3 4 5 - | 3 4 5 - | C: 两只老虎 两只老虎 跑得快 跑得快 ``` ```` - 渲染区显示简谱(多页自动分页),右上角有 **▶ 试听 / ⏹ 停止**(Web Audio 合成,无需音频文件)。 - 语法解析失败会显示错误信息,不阻断正文。 - **默认「无空白」显示**:默认的「谱面」视图裁到**真实内容包围盒**——只显示有墨迹的部分(整页白底、页边距内的空白都不显示),四周只留 **2px**。 - **操作按钮默认隐藏**:工具条浮在谱面块**外侧左上角**(块正上方、左缘对齐,不压谱面),鼠标移到谱面块上才淡入 —— 于是 Obsidian「导出为 PDF / 打印」不会把操作界面带进成果;触屏设备常显。 - **编辑源码**:谱面块**右上角的 ``**(与 Obsidian 自己给块挂的「编辑此块」同款位置与外观)—— 点它**切回笔记源码**(阅读视图会先切到实时预览)并把光标放进这个代码块,用 Obsidian 自带编辑器改(原生语法高亮、撤销栈、与其它代码块一致);光标移出该块即回到谱面。**不再**在预览里另开一个 textarea。 - **显示模式**(三个图标按钮):**整页**(完整一页含页边距)/ **满宽**(撑满笔记宽度)/ **谱面**(裁掉页边距、只显示有墨迹的部分,默认);悬停有文字说明。 - **排版**(田字格图标,与 iJipu 应用顶栏同一形状):**显示/隐藏排版辅助虚线**——显示后**直接拖动虚线**即可调整版面,**松手即写入该谱源码的 `# jps-config` 行**(与 iJipu 一致,拖动过程只预览不落盘)。为能看见页边距,开启时会自动切到「整页」视图,关闭时恢复原视图。 - **设置**(滑杆图标):打开对话框按字段精确设值(字体/字号/行距/渲染开关等**不可拖动项**),可按**页签**逐组改(页面 / 字体 / 行距 / 渲染 + 说明,与「设置 → iJipu」同款),并有「保存到谱面」(写 `# jps-config`)、「随谱固化(分享用)」、「保存为插件默认」三个去向。 对话框顶部会列出**谱面自带设置 N 项**(来自源码 `# jps-config`)——一眼看出这份谱自己写了哪些设置。 ### 可拖动的辅助虚线 | 虚线 | 拖动调整的字段 | |---|---| | 上 / 下 / 左 / 右 页边距 | `margin_top` / `margin_bottom` / `margin_left` / `margin_right` | | 描述头区下沿线 | `descAreaH`(描述头内容区高;另有浅色中线为纯标注) | | 第 1 行曲部线 | `body_margin_top`(曲部与描述头间距) | | 多声部块内第 2+ 声部行线 | `height_shengbu`(声部行间距) | | 其他曲部行线 | 上一行有歌词 → `height_ciqu_lyric`;否则 → `height_ciqu` | | 歌词行线 | 第 1 行 → `height_quci`(曲-词间距);后续行 → `height_cici`(词-词间距) | ## `.jps` 文件与嵌入 插件启用后,Obsidian 会把 **`.jps` 识别为简谱文件**: | 用法 | 效果 | |---|---| | `[[我的谱.jps]]` | 链接可直接点开 → 用**简谱视图**打开(试听 / 显示模式 / 排版 / ⇄ 源码编辑),不再提示"无法打开" | | `![[我的谱.jps]]` | 在笔记里**内联渲染**该谱(紧凑工具条,可试听);排版保存直接改写该 `.jps` 文件 | | 文件树里双击 `xxx.jps` | 同上打开简谱视图;工具栏「✎ 源码」可切到纯文本编辑(改动自动保存,`Ctrl+S` 立即保存) | | 文件树里**右键文件夹** → 「新建 JPS 文件」 | 在该文件夹内新建一份 **`.jps`(默认模板内容)**并直接打开;重名时自动取 `未命名.jps` → `未命名 1.jps` → …(与 Obsidian 自带「新建笔记」同款命名) | | 点击 `[[谱名.jps]]`(**文件还不存在**) | 按默认模板**自动创建 `谱名.jps`**(不是 `谱名.jps.md`)并打开:建在**链接所在笔记的同级目录**下;`[[子/谱.jps]]` 会连子目录一起建,`[[/谱库/我的谱.jps]]` 从库根算 | 链接支持 `#子标题` 与 `|别名` 写法(`![[谱.jps|我的谱]]`、`![[谱.jps#第2段]]`);找不到文件时会在原位给出提示而不是留空白。 ### 代码块还是 `.jps` 文件?(两者都**长期保留**) **` ```jps ` 代码块不是过渡用法,它有一个 `.jps` 文件做不到的场景:** | 场景 | 该用哪个 | 原因 | |---|---|---| | **单行 / 片段乐谱**(例:笔记里只想展示 `1 2 3 1 \| 3 4 5 - \|` 这一句) | **代码块** | 十几字节的源码**直接写在笔记里**,不用为一句谱单独建个文件 | | 讲解 / 教程:一句谱 + 一段说明穿插 | **代码块** | 源码与讲解同处一篇笔记,复制、改写、对照都顺手 | | 一个笔记里**多个片段**、各自调排版试效果 | **代码块** | 同一份源码可复制多份;嵌 `.jps` 只能"多个文件" | | **完整的一首曲子**(要长期维护、反复编辑) | **`.jps` 文件** | 有独立文件、**桌面端点开就进完整编辑器**(内嵌 iJipu;手机端先看**谱面预览**,点工具条最右的「编辑」进)、可被多篇笔记引用 | | 一处维护、多处引用 | **`.jps` 文件** | 改文件即处处生效;代码块是各笔记各一份 | | 库里已有大量 ` ```jps ` 笔记 | **保持不动** | 代码块路径**继续维护**,不会失效 | > 两者**互不影响**:`.jps` 文件与 ` ```jps ` 代码块**都只读谱面自带的 `# jps-config`**(见下节)。 ## 设置优先级 ``` 引擎默认(defaultPageConfig) < 插件设置(设置面板里的全局默认) < 谱面源码内的 # jps-config 行 ``` > **设置写在哪:就写在谱面里** —— 用一行 `# jps-config:{…}` 携带这份谱的设置(点工具条的「设置」按钮改,插件会自动写回这一行)。 > 这样**每一份谱都是自包含的**:把源码(或整个 `.jps` 文件)复制给别人,看到的排版一致。 > ⚠ **笔记 frontmatter(`ijipu_*`)那一层已删除**(0.32.0,用户决定):它对 `.jps` 文件用不上、 > 对"一个笔记里多个 ` ```jps ` 块"又太粗(笔记级),且**不随谱走**;谱内 `# jps-config` 可**逐块**写。 - **谱面源码内的 `# jps-config:{...}` 优先级最高**(与 iJipu 应用一致:"每首谱用自己的设置")。iJipu 点「保存设置」时会把配置写进源码那一行,所以**把 iJipu 里的 .jps 直接复制进 Obsidian,渲染结果与 iJipu 一致**;插件设置只对**源内没写的键**生效。 - **差量写入**:设置行只记录与「引擎默认值」不同的项(全部为默认时该行不写);想"到哪都一样"可在「设置」对话框点「**随谱固化(分享用)**」写入全部非默认项。 - **字体**:候选项都是跨平台字体栈(末尾带兜底字体,如 `'SimHei', sans-serif`),换设备不会掉到不合适的默认字体;旧谱里的裸字体名读取时会自动补 fallback。 - **编辑器字体/字号不属于谱面设置**(属本机偏好,在插件设置里调)——别人打开你的 .jps 不会被改;写进源码的 `editorFont*` 旧键会被识别出来并提示"已不再随谱保存"。 - 预览工具条的「⚙ 设置」对话框里会列出「**谱面自带设置 N 项**」(源码 `# jps-config` 写了哪几项、值是什么)。 - **插件设置的默认值体系与应用一致**:本库默认层(`代码默认 ← 插件设置`)被当作"应用里的代码默认值"看待 ⇒ 它**不算"没随谱携带"**(不会无端提示)。 - 插件设置面板每项即**全局默认**(谱面未自带设置时生效);改设置后打开中的谱面立刻重渲染。 - **设置面板按页签分组**(`页面 / 字体 / 行距 / 渲染 / 音色库 / 说明`),一屏只看一组、不必长距离滚动; 「说明」页签里写了"**设置写在哪**":谱面里的 `# jps-config`(跟着谱走、**可逐块写**),以及用工具条「设置」按钮可视化改、自动写回。 - **收藏音色是分类流式列表**(与 iJipu 应用「音色库」同一套 GM 14 类分类):按类折叠、每类可「选本组 / 消本组」, 顶部「全选 / 全消 / 反选 + 搜索」,右上角实时显示「已选 N / 128」。 - **注意「生效值」与「全局默认」是两层**:谱面工具栏「⚙ 设置」里显示的是**这一份谱的生效值** (含源码 `# jps-config`),与「设置 → iJipu」里的**全局默认**值不同是正常的; 在对话框里点「保存为插件默认」**只记录你那次真正改动过的项**(不会把某一份谱的源内值变成全库默认)。 - **改动即时生效**:改谱面里的设置行、或改设置面板后,谱面**立刻重渲染**(无需重开笔记)。 ### 谱内设置示例 ```text D: C P: 4/4 # jps-config:{"page":"A4_horizontal","note_size":15,"lianyinxian_type":1,"showInstrument":true} Q: 1 2 3 4 | ``` > 手写时只需记住一条:**键名 = 引擎 `PageConfig` 的字段名**(下表第三列那些名字,去掉反引号即可)。 > 数字与布尔可以写成字符串(`"15"`、`是/否`、`1/0`);嵌套字段(`segmentRowGap`)写成一行映射 `{bz: 22, dsb: 22, tp: 14}`。 ## 设置键对照表(写进 `# jps-config` 用) > 键 = iJipu 引擎 `PageConfig` 字段名。`boolean` 用 `true/false`(也可写 `是/否`、`1/0`),`枚举` 用所给值。 > 一般不必手写:点工具条的「设置」按钮用图形界面改,插件会自动把差量写回那一行。 ### 页面 | 设置项 | `# jps-config` 键 | 类型 | 取值 / 默认 | |---|---|---|---| | 纸张 | `page` | 枚举 | A4 / A5 / A4_horizontal / A5_horizontal(默认 A4) | | 上边距 | `margin_top` | 数字 | 默认 40 | | 下边距 | `margin_bottom` | 数字 | 默认 40 | | 左边距 | `margin_left` | 数字 | 默认 50 | | 右边距 | `margin_right` | 数字 | 默认 50 | | 正文上间距 | `body_margin_top` | 数字 | 默认 20 | | 描述头区高 | `descAreaH` | 数字 | 默认 80 | | 小节间距 | `bar_gap` | 数字 | 默认 0(设置面板未提供控件,仍可手写进 `# jps-config`) | | 两端对齐最小小节数 | `align_min_bars` | 数字 | 默认 4 | | 音符布局模式 | `noteSpaceLayout` | 枚举 | space(空间优先)/ duration(时值优先),默认 space | | 显示小节计数 | `showBarCount` | boolean | true / false(默认 true) | | 序号间隔 | `barCountInterval` | 数字 | 默认 4(每隔几个小节显示一个方框序号) | ### 字体 | 设置项 | `# jps-config` 键 | 类型 | 默认 | |---|---|---|---| | 标题字体 | `biaoti_font` | 字体名 | 微软雅黑/PingFang/Noto 系统栈 | | 标题字号 | `biaoti_size` | 数字 | 20 | | 副标题字体 | `fubiaoti_font` | 字体名 | 系统栈 | | 副标题字号 | `fubiaoti_size` | 数字 | 15 | | 描述头字体 | `miaoshu_font` | 字体名 | 系统栈 | | 描述头字号 | `miaoshu_size` | 数字 | 13 | | 说明文字字体 | `notes_font` | 字体名 | 系统栈 | | 说明文字字号 | `notes_size` | 数字 | 12 | | 歌词字体 | `geci_font` | 字体名 | 系统栈 | | 歌词字号 | `geci_size` | 数字 | 11 | | 音符字号 | `note_size` | 数字 | 13 | | 音符(数字)字体 | `shuzi_font` | 字体名 | 系统栈 | ### 行距 | 设置项 | `# jps-config` 键 | 类型 | 默认 | |---|---|---|---| | 曲-词间距 | `height_quci` | 数字 | 20 | | 词-词间距 | `height_cici` | 数字 | 10 | | 曲-曲间距 | `height_ciqu` | 数字 | 20 | | 曲-上词间距 | `height_ciqu_lyric` | 数字 | -5 | | 声部间距 | `height_shengbu` | 数字 | 0 | | 临时段上下间距 | `segmentRowGap` | 映射 | `{bz: 22, dsb: 22, tp: 14}`(bz/dsb 段上下层、替谱层与歌词行的纵向间距;可只写其中一项) | ### 渲染 | 设置项 | `# jps-config` 键 | 类型 | 取值 / 默认 | |---|---|---|---| | 歌词压缩(避免重叠) | `lyricShrink` | boolean | true / false(默认 false) | | 显示乐器名 | `showInstrument` | boolean | true / false(默认 false) | | 连音线样式 | `lianyinxian_type` | 数字 | 0 自动 / 1 圆弧 / 2 平顶(默认 0) | ## 网络使用与权限(披露) Obsidian 的开发者政策要求**明确披露网络访问**,这里一次说清: - **下载音源(唯一的外部网络请求)**:高保真试听需要一个 SoundFont 音源文件 (GeneralUser GS,约 32 MB,**不随插件分发**)。首次试听时,插件会从这个直链下载: `https://raw.githubusercontent.com/mrbumpy409/GeneralUser-GS/main/GeneralUser-GS.sf2` (该地址由上游项目 [GeneralUser-GS](https://github.com/mrbumpy409/GeneralUser-GS) 提供)。 下载后**缓存在本机**(IndexedDB),之后试听**不再联网**。 该地址在部分网络下可能不可达(例如 `raw.githubusercontent.com` 被拦截)——此时会提示, 你可以在「设置 → iJipu」里**手动导入**本地 `.sf2` 文件,导入后同样只走本地缓存。 - **没有任何遥测 / 统计 / 账号**:插件不收集、不上传任何数据,也不需要登录。 - **内嵌编辑器用一个"仅本机"的本地服务**:`127.0.0.1` 上的临时 HTTP 服务 (端口固定优先 `47821`,被占用则回退随机端口;URL 带一次性随机令牌)。 它**只监听本机回环地址、不对外**,仅用于把打包进 `main.js` 的网页交给内部 iframe 显示。 该服务只提供两样东西:那份单文件页面、以及页面用到的图标资源(白名单查表,不接受任意路径)。 - **文件访问范围**:只读写你的 Obsidian **文库内**的文件(通过 Obsidian 的文库接口), 不访问文库之外的任何路径;「默认应用」打开方式会把该 `.jps` 交给系统关联程序(仅在你主动点击时)。 ## 支持作者 喜欢这个插件?可在插件的**设置页**点「**支持作者 ❤**」扫码支持(与 iJipu 应用一致的微信赞赏码,`https://ijipu.pages.dev/good.png`)。也可访问 [iJipu 官网](https://ijipu.pages.dev)。 ## 标注 - 引擎:`@ijipu/engine`(.jps 解析 → 排版 → SVG 渲染 → 播放序列 → Web Audio 试听)。 - 许可证:**AGPL-3.0-or-later**(全文见 [`LICENSE.md`](./LICENSE.md),版权与 SPDX 标识见 [`NOTICE.md`](./NOTICE.md),与引擎一致)。 特别致谢「番茄简谱」原作与社区;音源 [GeneralUser GS](https://github.com/mrbumpy409/GeneralUser-GS)(其自带许可)。