typora复制和折叠代码块或者表格的插件和主题
·
效果
同样的思路,找到 Windows 上的 window.html,注入脚本。
第一步:找到 window.html
一般在:
Windows
C:\sofe\Typora\resources\window.html linux /usr/share/typora/resources/
第二步:备份
用管理员权限复制一份 window.html 改名为 window.html.bak
用管理员权限打开 C:\Program Files\Typora\resources\window.html,找到 </body>,在前面替换成这段完整的:
如图:

用插件
<script src="./my_plugin/fence_enhance_standalone.js"></script> <script src="./my_plugin/collapse_extra_standalone.js"></script>
sudo cp -r my_plugin /usr/share/typora/resources/
或者复制粘贴
折叠插件
my_plugin/collapse_extra_standalone.js
(function () {
var CONFIG = {
autoHide: true,
collapsedClass: "ce-collapsed",
hiddenClass: "ce-hidden",
btnClass: "ce-collapse-btn",
listBtnClass: "ce-list-btn",
tableBtnClass: "ce-table-btn",
expandedIcon: "-",
collapsedIcon: "+"
};
function addStyle() {
if (document.querySelector("#collapse-extra-standalone-style")) return;
var style = document.createElement("style");
style.id = "collapse-extra-standalone-style";
style.innerHTML =
".ce-hidden{" +
"display:none!important;" +
"}" +
".ce-collapse-btn{" +
"width:28px;" +
"height:28px;" +
"padding:0;" +
"display:inline-flex;" +
"align-items:center;" +
"justify-content:center;" +
"cursor:pointer;" +
"border:none!important;" +
"border-radius:999px;" +
"background:rgba(0,0,0,.32)!important;" +
"box-shadow:none!important;" +
"backdrop-filter:blur(8px);" +
"-webkit-backdrop-filter:blur(8px);" +
"color:#fff!important;" +
"font-size:18px;" +
"font-weight:700;" +
"line-height:1;" +
"user-select:none;" +
"outline:none;" +
"transition:background .2s ease, transform .15s ease, opacity .2s ease;" +
"}" +
".ce-collapse-btn:hover{" +
"background:rgba(0,0,0,.42)!important;" +
"transform:scale(1.05);" +
"}" +
".ce-collapse-btn:active{" +
"transform:scale(.96);" +
"}" +
".ce-list-btn{" +
"width:22px;" +
"height:22px;" +
"min-width:22px;" +
"margin-right:6px;" +
"font-size:15px;" +
"vertical-align:middle;" +
"opacity:.75;" +
"}" +
"li:hover > .ce-list-btn{" +
"opacity:1;" +
"}" +
".ce-table-wrap{" +
"position:relative!important;" +
"}" +
".ce-table-btn{" +
"position:absolute;" +
"right:8px;" +
"top:8px;" +
"width:32px;" +
"height:32px;" +
"font-size:20px;" +
"z-index:999;" +
"opacity:" + (CONFIG.autoHide ? "0" : "1") + ";" +
"}" +
".ce-table-wrap:hover .ce-table-btn{" +
"opacity:1;" +
"}" +
".ce-table-folded tbody," +
".ce-table-folded tr:nth-child(n+2){" +
"display:none!important;" +
"}";
document.head.appendChild(style);
}
function makeBtn(className, title) {
var btn = document.createElement("button");
btn.className = CONFIG.btnClass + " " + className;
btn.type = "button";
btn.title = title || "折叠 / 展开";
btn.textContent = CONFIG.expandedIcon;
return btn;
}
function stopEvent(e) {
e.preventDefault();
e.stopPropagation();
}
function getDirectChildLists(li) {
var result = [];
Array.prototype.forEach.call(li.children, function (child) {
if (child.tagName === "UL" || child.tagName === "OL") {
result.push(child);
}
});
return result;
}
function toggleList(li, btn) {
var childLists = getDirectChildLists(li);
if (!childLists.length) return;
var collapsed = li.classList.contains(CONFIG.collapsedClass);
if (collapsed) {
li.classList.remove(CONFIG.collapsedClass);
btn.textContent = CONFIG.expandedIcon;
childLists.forEach(function (list) {
list.classList.remove(CONFIG.hiddenClass);
});
} else {
li.classList.add(CONFIG.collapsedClass);
btn.textContent = CONFIG.collapsedIcon;
childLists.forEach(function (list) {
list.classList.add(CONFIG.hiddenClass);
});
}
}
function initListCollapse() {
var root = document.querySelector("#write") || document.body;
var items = root.querySelectorAll("li");
Array.prototype.forEach.call(items, function (li) {
if (li.querySelector(":scope > ." + CONFIG.listBtnClass)) return;
var childLists = getDirectChildLists(li);
if (!childLists.length) return;
var btn = makeBtn(CONFIG.listBtnClass, "折叠 / 展开列表");
li.insertBefore(btn, li.firstChild);
btn.addEventListener("click", function (e) {
stopEvent(e);
toggleList(li, btn);
});
});
}
function getTableWrap(table) {
var p = table.parentElement;
if (
p &&
(
p.classList.contains("md-table") ||
p.classList.contains("table-figure") ||
p.tagName === "FIGURE"
)
) {
return p;
}
return table;
}
function toggleTable(table, wrap, btn) {
var collapsed = wrap.classList.contains("ce-table-folded");
if (collapsed) {
wrap.classList.remove("ce-table-folded");
table.classList.remove("ce-table-folded");
btn.textContent = CONFIG.expandedIcon;
} else {
wrap.classList.add("ce-table-folded");
table.classList.add("ce-table-folded");
btn.textContent = CONFIG.collapsedIcon;
}
}
function initTableCollapse() {
var root = document.querySelector("#write") || document.body;
var tables = root.querySelectorAll("table");
Array.prototype.forEach.call(tables, function (table) {
var wrap = getTableWrap(table);
if (wrap.querySelector(":scope > ." + CONFIG.tableBtnClass)) return;
wrap.classList.add("ce-table-wrap");
var btn = makeBtn(CONFIG.tableBtnClass, "折叠 / 展开表格");
wrap.appendChild(btn);
btn.addEventListener("click", function (e) {
stopEvent(e);
toggleTable(table, wrap, btn);
});
});
}
function init() {
addStyle();
initListCollapse();
initTableCollapse();
}
window.addEventListener("load", function () {
init();
new MutationObserver(function () {
init();
}).observe(document.body, {
childList: true,
subtree: true
});
});
})();
复制按钮:
my_plugin/fence_enhance_standalone.js
(function () {
var CONFIG = {
autoHide: true,
trimOnCopy: false,
foldHeight: 84,
foldIcon: "+",
expandIcon: "-"
};
function addStyle() {
if (document.querySelector("#fence-enhance-standalone-style")) return;
var style = document.createElement("style");
style.id = "fence-enhance-standalone-style";
style.innerHTML =
".md-fences.fe-standalone{" +
"position:relative!important;" +
"}" +
".fe-standalone-bar{" +
"position:absolute;" +
"top:10px;" +
"right:12px;" +
"display:flex;" +
"align-items:center;" +
"gap:10px;" +
"z-index:999;" +
"opacity:" + (CONFIG.autoHide ? "0" : "1") + ";" +
"transition:opacity .2s ease;" +
"}" +
".md-fences.fe-standalone:hover .fe-standalone-bar{" +
"opacity:1;" +
"}" +
".fe-standalone-btn{" +
"width:40px;" +
"height:40px;" +
"padding:0;" +
"display:inline-flex;" +
"align-items:center;" +
"justify-content:center;" +
"cursor:pointer;" +
"border:none!important;" +
"border-radius:999px;" +
"background:rgba(0,0,0,.32)!important;" +
"box-shadow:none!important;" +
"backdrop-filter:blur(8px);" +
"-webkit-backdrop-filter:blur(8px);" +
"color:#fff!important;" +
"user-select:none;" +
"outline:none;" +
"transition:background .2s ease, transform .15s ease, opacity .2s ease;" +
"}" +
".fe-standalone-btn:hover{" +
"background:rgba(0,0,0,.42)!important;" +
"transform:scale(1.05);" +
"}" +
".fe-standalone-btn:active{" +
"transform:scale(.96);" +
"}" +
".fe-standalone-btn svg{" +
"width:20px;" +
"height:20px;" +
"stroke:currentColor;" +
"fill:none;" +
"stroke-width:2;" +
"stroke-linecap:round;" +
"stroke-linejoin:round;" +
"pointer-events:none;" +
"}" +
".fe-copy-btn{" +
"font-size:0;" +
"}" +
".fe-fold-btn{" +
"font-size:22px;" +
"font-weight:700;" +
"line-height:1;" +
"}" +
".md-fences.fe-folded .CodeMirror-scroll{" +
"max-height:" + CONFIG.foldHeight + "px!important;" +
"overflow:hidden!important;" +
"}" +
".md-fences.fe-folded pre," +
".md-fences.fe-folded code{" +
"max-height:" + CONFIG.foldHeight + "px!important;" +
"overflow:hidden!important;" +
"display:block;" +
"}";
document.head.appendChild(style);
}
function getCodeMirror(fence) {
if (fence.CodeMirror) return fence.CodeMirror;
var cmWrap = fence.querySelector(".CodeMirror");
if (cmWrap && cmWrap.CodeMirror) return cmWrap.CodeMirror;
return null;
}
function getCodeText(fence) {
var cm = getCodeMirror(fence);
if (cm && typeof cm.getValue === "function") {
var value = cm.getValue();
return CONFIG.trimOnCopy ? value.trim() : value;
}
var lines = fence.querySelectorAll(".CodeMirror-line");
if (lines.length) {
var text = Array.prototype.map.call(lines, function (line) {
return line.innerText || line.textContent || "";
}).join("\n");
return CONFIG.trimOnCopy ? text.trim() : text;
}
var code = fence.querySelector("pre code, pre, code");
var fallback = code
? (code.innerText || code.textContent || "")
: (fence.innerText || fence.textContent || "");
fallback = fallback
.replace(/\n?\+\s*$/g, "")
.replace(/\n?-\s*$/g, "")
.replace(/\n?✓\s*$/g, "");
return CONFIG.trimOnCopy ? fallback.trim() : fallback;
}
function makeCopyIcon() {
return (
'<svg viewBox="0 0 24 24" aria-hidden="true">' +
'<rect x="9" y="9" width="10" height="10" rx="2"></rect>' +
'<rect x="5" y="5" width="10" height="10" rx="2"></rect>' +
"</svg>"
);
}
function makeCheckIcon() {
return (
'<svg viewBox="0 0 24 24" aria-hidden="true">' +
'<path d="M20 6L9 17l-5-5"></path>' +
"</svg>"
);
}
function writeClipboard(text, btn, restoreFn) {
navigator.clipboard.writeText(text).then(function () {
btn.innerHTML = makeCheckIcon();
setTimeout(function () {
if (typeof restoreFn === "function") {
restoreFn();
}
}, 1200);
});
}
function makeButton(type, title, className) {
var btn = document.createElement("button");
btn.className = "fe-standalone-btn " + className;
btn.type = "button";
btn.title = title;
if (type === "copy") {
btn.innerHTML = makeCopyIcon();
} else if (type === "fold") {
btn.textContent = CONFIG.foldIcon;
}
return btn;
}
function addToolbar(fence) {
if (fence.querySelector(".fe-standalone-bar")) return;
fence.classList.add("fe-standalone");
var bar = document.createElement("div");
bar.className = "fe-standalone-bar";
var foldBtn = makeButton("fold", "折叠 / 展开", "fe-fold-btn");
var copyBtn = makeButton("copy", "复制", "fe-copy-btn");
bar.appendChild(foldBtn);
bar.appendChild(copyBtn);
fence.appendChild(bar);
copyBtn.addEventListener("click", function (e) {
e.preventDefault();
e.stopPropagation();
var text = getCodeText(fence);
writeClipboard(text, copyBtn, function () {
copyBtn.innerHTML = makeCopyIcon();
});
});
foldBtn.addEventListener("click", function (e) {
e.preventDefault();
e.stopPropagation();
if (fence.classList.contains("fe-folded")) {
fence.classList.remove("fe-folded");
foldBtn.textContent = CONFIG.foldIcon;
} else {
fence.classList.add("fe-folded");
foldBtn.textContent = CONFIG.expandIcon;
}
});
}
function init() {
addStyle();
document.querySelectorAll(".md-fences").forEach(function (fence) {
addToolbar(fence);
});
}
window.addEventListener("load", function () {
init();
new MutationObserver(function () {
init();
}).observe(document.body, {
childList: true,
subtree: true
});
});
})();
主题就用这三个足够

更多推荐


所有评论(0)