mirror of
https://github.com/jerryc127/hexo-theme-butterfly.git
synced 2026-04-08 12:07:06 +08:00
feat(score tag): support RenderAbc options
Modified the score tag to pass custom options to the abcjs RenderAbc interface. This enhancement enables proper rendering of guitar tablature with custom settings such as instrument tuning, labels, and formatting options.
This commit is contained in:
64
layout/includes/third-party/abcjs/abcjs.pug
vendored
64
layout/includes/third-party/abcjs/abcjs.pug
vendored
@@ -1,17 +1,51 @@
|
||||
script.
|
||||
(() => {
|
||||
const abcjsInit = () => {
|
||||
const abcjsFn = () => setTimeout(() => {
|
||||
document.querySelectorAll(".abc-music-sheet").forEach(ele => {
|
||||
if (ele.children.length > 0) return
|
||||
ABCJS.renderAbc(ele, ele.innerHTML, {responsive: 'resize'})
|
||||
})
|
||||
}, 100)
|
||||
|
||||
typeof ABCJS === 'object' ? abcjsFn()
|
||||
: btf.getScript('!{url_for(theme.asset.abcjs_basic_js)}').then(abcjsFn)
|
||||
}
|
||||
(function() {
|
||||
var abcjsInit = function() {
|
||||
var abcjsFn = function() {
|
||||
setTimeout(function() {
|
||||
var sheets = document.querySelectorAll(".abc-music-sheet");
|
||||
for (var i = 0; i < sheets.length; i++) {
|
||||
var ele = sheets[i];
|
||||
if (ele.children.length > 0) continue;
|
||||
|
||||
// 从 data-params 属性中解析参数
|
||||
var params = {};
|
||||
var dp = ele.getAttribute("data-params");
|
||||
if (dp) {
|
||||
try {
|
||||
params = JSON.parse(dp);
|
||||
} catch (e) {
|
||||
console.error("解析 data-params 失败:", e);
|
||||
}
|
||||
}
|
||||
|
||||
// 将解析出的参数与 responsive 参数合并,
|
||||
// 保证 params 中的内容在 responsive 之前
|
||||
var options = {};
|
||||
for (var key in params) {
|
||||
if (params.hasOwnProperty(key)) {
|
||||
options[key] = params[key];
|
||||
}
|
||||
}
|
||||
options.responsive = "resize";
|
||||
|
||||
// 使用 ABCJS.renderAbc 渲染乐谱
|
||||
ABCJS.renderAbc(ele, ele.innerHTML, options);
|
||||
}
|
||||
}, 100);
|
||||
};
|
||||
|
||||
window.pjax ? abcjsInit() : window.addEventListener('load', abcjsInit)
|
||||
btf.addGlobalFn('encrypt', abcjsInit, 'abcjs')
|
||||
})()
|
||||
if (typeof ABCJS === "object") {
|
||||
abcjsFn();
|
||||
} else {
|
||||
btf.getScript("!{url_for(theme.asset.abcjs_basic_js)}").then(abcjsFn);
|
||||
}
|
||||
};
|
||||
|
||||
if (window.pjax) {
|
||||
abcjsInit();
|
||||
} else {
|
||||
window.addEventListener("load", abcjsInit);
|
||||
}
|
||||
btf.addGlobalFn("encrypt", abcjsInit, "abcjs");
|
||||
})();
|
||||
@@ -6,17 +6,45 @@
|
||||
'use strict'
|
||||
|
||||
const score = (args, content) => {
|
||||
// 转义 HTML 标签和部分特殊字符,包括花括号
|
||||
const escapeHtmlTags = s => {
|
||||
const lookup = {
|
||||
'&': '&',
|
||||
'"': '"',
|
||||
'\'': ''',
|
||||
'<': '<',
|
||||
'>': '>'
|
||||
'>': '>',
|
||||
'{': '{',
|
||||
'}': '}'
|
||||
}
|
||||
return s.replace(/[&"'<>]/g, c => lookup[c])
|
||||
return s.replace(/[&"'<>{}]/g, c => lookup[c])
|
||||
}
|
||||
return `<div class="abc-music-sheet">${escapeHtmlTags(content)}</div>`
|
||||
|
||||
const trimmed = content.trim()
|
||||
// 使用六个横线作为分隔符拆分内容
|
||||
const parts = trimmed.split('------')
|
||||
|
||||
if (parts.length < 2) {
|
||||
// 如果没有分隔符,直接将整个内容作为乐谱内容处理
|
||||
return `<div class="abc-music-sheet">${escapeHtmlTags(trimmed)}</div>`
|
||||
}
|
||||
|
||||
// 第一部分为参数(JSON 字符串),其余部分作为乐谱内容
|
||||
const paramPart = parts[0].trim()
|
||||
const scorePart = parts.slice(1).join('------').trim()
|
||||
|
||||
let paramsObj = {}
|
||||
try {
|
||||
paramsObj = JSON.parse(paramPart)
|
||||
} catch (e) {
|
||||
console.error('解析 score 标签中的参数 JSON 失败:', e)
|
||||
}
|
||||
|
||||
// 使用双引号包裹 data-params 的属性值,确保 JSON 内部的双引号已被转义
|
||||
return `<div class="abc-music-sheet" data-params="${escapeHtmlTags(JSON.stringify(paramsObj))}">
|
||||
${escapeHtmlTags(scorePart)}
|
||||
</div>`
|
||||
}
|
||||
|
||||
hexo.extend.tag.register('score', score, { ends: true })
|
||||
|
||||
|
||||
Reference in New Issue
Block a user