效果

同样的思路,找到 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
        });
    });
})();

主题就用这三个足够

更多推荐