hogashi.*

日記から何から

Monaco Editorをシンタックスハイライトされたコードブロックとして使う

 昨日*1の続き。寝る前にぼんやりしながら glitch.me で頑張っていたのをやめて、机に座ってよく調べると、ちゃんと npm install とかをすっ飛ばして script タグだけで Monaco Editor が出せるらしい (How to run the Monaco editor from a CDN like cdnjs? - Stack Overflow)。
 が、これをブログ記事内に雑に貼ってもどうしてもうまくいかなさそう*2だったので、諦めて Netlify にデプロイして爆速 iframe 版 Monaco Editor を出せるようにした*3

 こういう感じで iframe で読み込む。

<iframe
  class="hogashi-iframe-monaco"
  src="https://amazing-dijkstra-3764b5.netlify.app/?value=function%20isLongString(hoge%3A%20string)%3A%20boolean%20%7B%0A%20%20console.log(hoge)%3B%0A%20%20return%20hoge.length%20%3E%2010%3B%0A%7D%0A">
</iframe>

 こう出る。すすっと書き換えてみて、型で怒られたりできて便利。

 ちょっと頑張って、例えば pre に入れてある内容をバリッと渡して表示することもできる*4。カーソルを合わせると型が出たり、ただの querySelector で引いてきたものは Element 型なので dataset は引けませんということがわかったりして便利。

const entryIdentifier = 'hogashi-iframe-monaco-entry';
const iframeClassName = 'hogashi-iframe-monaco';
const doneClassName = 'hogashi-iframe-monaco-inserted';
const entryContent = document.querySelector(`.entry-content #${entryIdentifier}`).parentElement;
if (entryContent && !entryContent.classList.contains(doneClassName)) {
  Array.from(entryContent.querySelectorAll('pre.code')).map(pre => {
    if (pre.classList.contains(doneClassName) || pre.parentElement.classList.contains(doneClassName)) {
      return;
    }

    const url = new URL('https://amazing-dijkstra-3764b5.netlify.app/');
    const value = encodeURIComponent(pre.textContent);
    const language = encodeURIComponent(pre.dataset.lang || '');
    url.search = `?language=${language}&value=${value}`;

    const iframe = document.createElement('iframe');
    iframe.src = url.href;
    pre.insertAdjacentElement('afterend', iframe);
    iframe.classList.add(iframeClassName);
    iframe.style.height = `${24 * (pre.textContent.split('\n').length + 1)}px`;

    pre.classList.add(doneClassName);
  });
  entryContent.classList.add(doneClassName);
}

 たまに自分の必殺技はブックマークレット正規表現ですって言うことがあるけど、ずっとそういう感じで、ブックマーク編集の input 内とか、ブログの編集画面とかに、生の JavaScript をバリバリ書いたりして、楽しんで暮らしている。そういう素朴な技でも、こういう高級なものが繰り出せるのは便利。

 どうでもいいけど amazing-dijkstra かっこいい。

*1:https://blog.hog.as/entry/2021/12/03/032619

*2:なぜうまくいかないかは丁寧に見てみたいけどいったん置いておく

*3:↑の Stack Overflow の HTML をこういう感じに書き換えて Netlify でデプロイ https://github.com/hogashi/20211204-monaco-editor-iframe

*4:16px に設定していると行の高さは 24px っぽいので雑に決め打ちで iframe の高さを決めてる