最終更新日 2025-06-27

HmMarkdownSimpleRender の作成

では、

に対応したものを作成してみましょう。

このようなものは、まさに2025年現代の、Githubあるいは、対話AIが返すフォーマットそのものだと言えます。

HmMarkdownSimpleRender.mac

マクロのエントリーポイントとなる.macですが、
「ブラウザ枠」に対して「エディタ上のテキストを返す」だけでなく
「秀丸がタブで隠れていたら(一番手前にないなら)、ブラウザ枠は更新しなくていいよ」、といった情報を送りましょう。
「見えるハズもないのにレンダリング更新する」といった意味のない処理の負担が無くなります。

また、URLを工夫して、利用するのを「HmMarkdownSimpleRender.html」としてみましょう。
自分で制作したファイルだ、というのがより明確にわかるようになりますね。

HmMarkdownSimpleRender.mac
// HmMarkdownSimpleRender 1.0.0.5
hidemaruversion "9.43.99";

jsmode "WebView2\\" + currentmacrofilename;

execjs currentmacrodirectory + "\\HmCustomRenderServer.WebView2.js";

js {

function onRequestObject() {

    // タブモードで裏にある状態は、見えるハズがないので、ブラウザ側は更新する必要はないよ、という情報を付与
    const isNoNeedUpdate = inputstates() & 0x00000800;

    const obj = {
        text: gettotaltext(),
        noNeedUpdate : isNoNeedUpdate
    };

    return obj;
}

function addBaseUrlParameter(url) {
    // 開いているファイルが名前が付いているならば、そこをbaseのurlとするため、クエリーとして伝達する
    if (filename2()) {
        const currentDir = directory2();
        const currentHref = new URL (currentDir + "\\").href;
        let urlObj = new URL(url);
        urlObj.searchParams.set('base', currentHref);
        url = urlObj.href;
    }
    
    return url;
}

function showCustomRenderPane(url) {

    url = url.replace("HmCustomRenderBrowser.html", "HmMarkdownSimpleRender.html");
    url = addBaseUrlParameter(url);
    
    browserpanecommand({
        target: "_each", // "HmMarkdownSimpleRender",
        url: url,
        show: 1,
        size: 500,
        initialize: "async"
    });
}

} // js

HmMarkdownSimpleRender.html

HTML側に特別な処理はありません。
全部 marked.js mathjax.js mermaid.js の使い方の代表格であり、
「よくわからん」という人が大半(私もそうですが)でしょうが、これらはまさにAIが詳しく答えてくれます。

これらは「バージョン」によっても記述方法が全く変化してしまっているため、
可能ならば「VSCode」や「Cursur」などの「AI Agentモード」でファイルそれ自体をAIに直接編集してもらうのが良いです。
そこまでの環境が整っていないのであれば、Web版の対話AIで複数回やりとりしていけば、正しいHTML/JSが得られるしょう。

HmMarkdownSimpleRender.html
<!DOCTYPE html>
<!-- HmMarkkdownSimpleRender 1.0.0.5 -->
<html lang="ja">

    <head>
        <title>HmMarkdownSimpleRender</title>
        <script src="https://cdn.jsdelivr.net/gh/komiyamma/hm_custom_render_browser@2.4.4.2/HmCustomRenderBrowser.min.js"></script>
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/5.8.1/github-markdown.min.css">
        <script src="https://cdn.jsdelivr.net/npm/marked@15.0.12/marked.min.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/mermaid@11.7.0/dist/mermaid.min.js"></script>

        <script>
            window.MathJax = {
                tex: {
                    inlineMath: [['$', '$'], ['\\(', '\\)']],
                    displayMath: [['$$', '$$'], ['\\[', '\\]']],
                    processEscapes: true
                },
                svg: { fontCache: 'global' }
            };
        </script>

        <script src="https://cdn.jsdelivr.net/npm/mathjax@3.2.2/es5/tex-mml-chtml.js"></script>

        <script>
            const params = new URLSearchParams(window.location.search);
            const baseValue = params.get("base");
            let baseTag = document.querySelector("base");
            if (!baseTag) {
                baseTag = document.createElement("base");
                document.head.prepend(baseTag);
            }
            baseTag.setAttribute("href", baseValue);
        </script>
    </head>
    <style>
        .markdown-body {
            margin: 10px;
        }
    </style>

    <body class="markdown-body">
        <div id="content"></div>
        <script>
            mermaid.initialize({ startOnLoad: false, securityLevel: "loose" });

            const renderer = {
                code(token) {
                    return token.lang === 'mermaid'
                        ? '<div class="mermaid">' + token.text + '</div>'
                        : '<pre><code>' + token.text + '</code></pre>';
                }
            };

            marked.use({ renderer });

            let prevText = "";

            function onReceiveObject(obj, error) {
                if (obj.error || obj.noNeedUpdate || prevText == obj.text) return;
                prevText = obj.text;

                content.innerHTML = marked.parse(obj.text);

                MathJax.startup.promise.then(() => {
                    if (MathJax.typesetClear) MathJax.typesetClear([content]);
                    return MathJax.typesetPromise([content]);
                });

                const mermaidElements = content.querySelectorAll('.mermaid');
                if (mermaidElements.length > 0) {
                    mermaid.run({ nodes: mermaidElements });
                }
            }

            document.addEventListener('DOMContentLoaded', () => {
                HmCustomRenderBrowser.setInterval(onReceiveObject, 2000);
            });
        </script>
    </body>

</html>
        

ライセンス

CC0 (パブリックドメイン)となります。

Githubにソースがあります。