Emacs + markdown으로 편안한 실시간 미리보기! (코드 하이라이트 편)

19032 단어 MarkdownEmacs
날마다, Emacs로 작업하고 있는 여러분은 당연, markdown도 Emacs로 쑥쑥 쓰고 계신다고 생각합니다 웃음. 여러 사람이 여러가지 방식으로 markdown 집필 환경을 만들고 있다고 생각합니다만, 코드의 하이라이트를 리얼타임 프리뷰 환경에서도 실현하고 싶다고 하는 것이 이번 동기입니다.

TL; DR



markdown-preview-mode 안에 들어있는 preview.htmlhighlight.js 이것만!

환경



emacs를 사용하여 markdown-preview-mode를 사용할 수 있다고 가정합니다. 이 기사 이 도움이 될 것입니다. 감사합니다.

코드 하이라이트



이 상태로 실시간 미리 보기는 가능하지만 코드 하이라이트가 되지 않는 상태입니다. 이런 느낌입니다.
이것은 힘들다. 어떻게든 코드 하이라이트시키고 싶네요. 인터넷에서 조사하면 여러가지 나오는데, 실시간 미리보기 환경에서 코드 하이라이트라는 것이 좀처럼 히트하지 않습니다. 어쩌면 HTML이므로 어떻게든 하이라이트 시키면 HTML에 highlight.js 맞을 수밖에 없다,라고 생각했습니다.

markdown-preview-mode의 작동 방식



markdown-preview-mode 을 보면 알 수 있지만 markdown에서 HTML을 생성 할 때 preview.html를 템플릿으로 만드는 것 같습니다. 로컬 환경이라고 어디에 격납되고 있을까는 사람 각각입니다만, 나는 지금은 Cask 를 사용하고 있으므로, 내 환경에서는 이하에 격납되고 있었습니다.


그래서, 이 preview.html 를 꼬집으면 코드 하이라이트도 될 것이다, 라는 발상입니다.

preview.html을 편집하자.



HTML을 살펴보면 WebSocket() 에서 데이터를 취하고 <p>Markdown preview</p> 를 실시간으로 업데이트하고 있음을 알 수 있습니다.

preview.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, minimal-ui">
    <title>Markdown preview</title>
    ${MD_STYLE}
    <script src="http://code.jquery.com/jquery-1.12.4.min.js"></script>
    ${MD_JS}
    <script>
     (function($, undefined) {
         var socket = new WebSocket("ws://${WS_HOST}:${WS_PORT}");
         socket.onopen = function() {
             console.log("Connection established.");
         socket.send("MDPM-Register-UUID: ${MD_UUID}");
         };
         socket.onclose = function(event) {
             if (event.wasClean) {
                 console.log('Connection closed gracefully.');
             } else {
                 console.log('Connection terminated.');
             }
             console.log('Code: ' + event.code + ' reason: ' + event.reason);
         };
         socket.onmessage = function(event) {
             $("#markdown-body").html($(event.data).find("#content").html()).trigger('mdContentChange');
             var scroll = $(document).height() * ($(event.data).find("#position-percentage").html() / 100);
             $("html, body").animate({ scrollTop: scroll }, 600);
         };
         socket.onerror = function(error) {
             console.log("Error: " + error.message);
         };
     })(jQuery);
    </script>
  </head>
  <body>
    <article id="markdown-body" class="markdown-body">
      <p>Markdown preview</p>
    </article>
  </body>
</html>


그래서, 이 HTML에 highlight.js 을 맞추고, WebSocket로부터 데이터 취득해 기입할 때마다 하이라이트 시키면, 리얼타임에 하이라이트가 될 것,,! 라고 하는 것으로, 조속합니다만 수정 후는 이쪽.

preview.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, minimal-ui">
    <title>Markdown preview</title>
    ${MD_STYLE}
    <script src="http://code.jquery.com/jquery-1.12.4.min.js"></script>
    ${MD_JS}

    <!-- ↓highlight.jsとCSSを当てましょう。CSSはいろんな種類があります。
         私はtomorrow.cssというものに落ち着きました。詳しくはhightlightのドキュメント見てください -->
    <link rel="stylesheet"
      href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.1/styles/tomorrow.min.css">
    <script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.1/highlight.min.js"></script>
    <!-- ネットでよく見る<script>hljs.initHighlightingOnLoad();</script>は今回は不要です。
         WebSocketでリアルタイムにレンダリングするので、OnLoadでhighlightしても意味がないですよね -->

    <script>
     (function($, undefined) {
         var socket = new WebSocket("ws://${WS_HOST}:${WS_PORT}");
         socket.onopen = function() {
             console.log("Connection established.");
         socket.send("MDPM-Register-UUID: ${MD_UUID}");
         };
         socket.onclose = function(event) {
             if (event.wasClean) {
                 console.log('Connection closed gracefully.');
             } else {
                 console.log('Connection terminated.');
             }
             console.log('Code: ' + event.code + ' reason: ' + event.reason);
         };
         socket.onmessage = function(event) {
             $("#markdown-body").html($(event.data).find("#content").html()).trigger('mdContentChange');
             var scroll = $(document).height() * ($(event.data).find("#position-percentage").html() / 100);
             $("html, body").animate({ scrollTop: scroll }, 600);

         // ここですね。pre codeタグを全て拾って、highlight処理をかけます。
         document.querySelectorAll('pre code').forEach((block) => {
         hljs.highlightBlock(block);
         });
     };
         socket.onerror = function(error) {
             console.log("Error: " + error.message);
         };
     })(jQuery);
    </script>
  </head>
  <body>
    <article id="markdown-body" class="markdown-body">
      <p>Markdown preview</p>
    </article>
  </body>
</html>


단지 이것뿐입니다. 이제 다시 코드 하이라이트가 효과가 있는지 확인해 보겠습니다.
좋아요! 실시간 미리보기 환경에서도 제대로 코드가 강조 표시되었습니다.

요약



이번은 markdown-preview-mode 환경하에서 코드 하이라이트를 실현하기 위한 방법의 하나를 제시했습니다. 여러분, 그 밖에 더 좋은 방법이 있습니다! 라든지, 지견이 있으면, 꼭 말해 주세요! !

좋은 웹페이지 즐겨찾기