aardio 文档

aardio 范例: HTML 通用代码块复制工具

原理

//通用代码块
//原理: https://mp.weixin.qq.com/s/BhFTemG3D3i6Ttvzag25XQ
import win.ui;
import win.clip.html;
import web.view;
import web.prism;
import wsock.tcp.asyncHttpServer;
/*DSG{{*/
var winform = win.form(text="HTML 通用代码块复制工具";right=1055;bottom=674;bgcolor=0xFFFFFF)
winform.add(
button={cls="button";text="复制高亮代码块";left=782;top=609;right=1050;bottom=665;bgcolor=0xFFFFFF;color=0xD77800;db=1;dr=1;font=LOGFONT(h=-14);note="可在所有在线编辑器内直接粘贴";z=4};
cmbLangs={cls="combobox";left=561;top=625;right=745;bottom=651;db=1;dl=1;dr=1;edge=1;items={"javascript"};mode="dropdown";vscroll=1;z=2};
custom={cls="syslink";text='<a href="https://mp.weixin.qq.com/s/BhFTemG3D3i6Ttvzag25XQ">原理</a>';left=373;top=627;right=433;bottom=647;bgcolor=0xFFFFFF;db=1;dl=1;z=6};
editCode={cls="edit";left=1;top=4;right=1052;bottom=599;db=1;dl=1;dr=1;dt=1;edge=1;hscroll=1;multiline=1;vscroll=1;z=5};
static={cls="static";text="请选择语言:";left=443;top=627;right=547;bottom=647;align="right";db=1;dl=1;transparent=1;z=3};
static2={cls="static";text="aardio 可在编辑器右键直接点「复制全部到 HTML 代码块」";left=13;top=627;right=368;bottom=647;db=1;dl=1;dr=1;transparent=1;z=7};
webCtrl={cls="custom";text="自定义控件";left=8;top=10;right=1048;bottom=604;db=1;dl=1;dr=1;dt=1;hide=1;z=1}
)
/*}}*/

var appTitle = "HTML 通用代码块复制工具";
var isReady = false;

// 常用语言别名映射
var langAlias = {
    ["c#"] = "csharp";
    ["c++"] = "cpp";
    ["py"] = "python";
    ["js"] = "javascript";
    ["ts"] = "typescript";
};

// 初始化 WebView
var wb = web.view(winform.webCtrl);

// 导出 aardio 函数给 JS 调用
wb.export({ 
    onHighlight = function(html, background, foreground){
        html = `<pre class="code" style="overflow-x:auto;text-align:left;box-shadow: rgba(216, 216, 216, 0.5) 0px 0px 0px 1px inset;padding:10px;border-radius:3px;background-color:` + background + `;color:` + foreground + `;white-space:pre;word-break:break-all;display:block;font-size:14px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-family: 'Consolas', 'Liberation Mono', Menlo, Courier, monospace"><code>`
            + html + `</code></pre>`;

        html, count = string.replace(html, '\n', "<br>");
        if(!count){
            html = string.replace(html,`\</code\>\</pre\>$`,`<br></code></pre>`);
        }

        var cb = win.clip.html();
        cb.write(html); 

        winform.setTimeout(function(){
            winform.editCode.show(true);
            winform.webCtrl.show(false);
            winform.text = appTitle + " - 已复制到剪贴板";
        }, 500);
    };

    setLanguages = function(langs){
        winform.languages = langs;

        // 排序并更新下拉框
        table.sort(winform.languages);
        winform.cmbLangs.items = winform.languages;
        winform.cmbLangs.selIndex = table.find(winform.languages, "javascript") : 1;

        isReady = true;
    }  
});

winform.cmbLangs.onEditChange = function(){
    if(!winform.languages) return;

    var text = string.lower(winform.cmbLangs.text);
    var items = table.filter(winform.languages, lambda(v) string.startsWith(v, text)); 
    winform.cmbLangs.autoComplete(items);  
}
winform.cmbLangs.editBox.disableInputMethod();

// 启动本地 HTTP 服务器渲染高亮代码块
var httpServer = wsock.tcp.asyncHttpServer(); 
httpServer.run(web.prism, {
    ["/index.html"] = /*****
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" /> 
    <link href="prism.css" rel="stylesheet" />
  </head>
  <body>
    <pre id="code-pre"><code id="code" class="lang-javascript"></code></pre>
    <script src="prism.js"></script>
    <script>
    // [重点改进] 递归计算并内联样式
    function computedColorStyle(element) {
        // 递归处理子元素
        Array.prototype.forEach.call(element.children, child => {
            computedColorStyle(child);
        });

        const computedStyle = getComputedStyle(element);

        // [修复] 复制完整样式:颜色、粗体、斜体、装饰线
        element.style.color = computedStyle.color;
        element.style.fontWeight = computedStyle.fontWeight;
        element.style.fontStyle = computedStyle.fontStyle;
        element.style.textDecoration = computedStyle.textDecoration;
    }

    highlight = function(code, language){
        var html = Prism.highlight(code, Prism.languages[language], language);

        var codeEle = document.getElementById("code");
        codeEle.innerHTML = html;
        computedColorStyle(codeEle);

        const preStyle = getComputedStyle(document.getElementById("code-pre"));
        const codeStyle = getComputedStyle(codeEle);

        onHighlight(codeEle.innerHTML, preStyle.backgroundColor, codeStyle.color);
    }

    // 过滤掉 Prism 的内置方法,只保留语言
    var languages = Object.keys(Prism.languages).filter(function(key){
        return typeof Prism.languages[key] === 'object';
    });
    setLanguages(languages);
    </script>
  </body> 
</html> 
    *****/
});

wb.go(httpServer.getUrl("/index.html"));

winform.button.oncommand = function(id, event){
    if(!isReady){
        return win.msgboxErr("请等待初始化完成");
    }

    var code = winform.editCode.text;
    if(!#code){
        return win.msgboxErr("请输入要高亮的代码");
    }

    var lang = string.lower(winform.cmbLangs.text);
    lang = langAlias[lang] : lang;

    if(!table.find(winform.languages, lang)){
        return win.msgboxErr("请指定正确的语言名称,支持自动补全");
    } 

    winform.text = "正在生成高亮代码...";
    winform.editCode.show(false);
    winform.webCtrl.show(true);

    wb.xcall("highlight", code, lang);
}

winform.show();
win.loopMessage();
Markdown 格式