Microsoft 社는 2022년 6월 15일 Internet Explorer 11의 지원을 종료했습니다.

Javascript 로 MarkDown 문서를 HTML 로 변환하기

제목

Javascript 로 MarkDown 문서를 HTML 로 변환하기

1. 원하는 것

  • MarkDown 문서를 HTML 형식으로 변환한다.
  • 소스코드는 highlight.js 를 이용해서 보기 좋게 만든다.
  • 소스코드는 highlightjs-line-numbers.js 를 이용해서 line number 를 표시한다.
  • onsubmit 에서 위의 작업을 수행하고, 결과를 Javascript 변수에 할당한다.

2. 라이브러리

2.1. marked.js (https://marked.js.org/)

2.2. highlight.js (https://highlightjs.org/)

지원하는 프로그래밍 언어는 SUPPORTED_LANGUAGES.md 문서를 참조한다.

2.3. highlightjs-line-numbers.js (https://wcoder.github.io/highlightjs-line-numbers.js/)

3. 구현

memo.detail.js 의 mark 함수를 참조한다.

highlightjs-line-numbers.js 까지 적용된 html 을 Javascript 변수로 할당받는 것은 memo.detail.js 에는 포함되어 있지 않다.

3.1. marked.js + highlight.js 까지 적용

marked.js + highlight.js 까지 적용된 HTML 소스를 얻기 위해서 다음과 같이 한다.

var markedText = "# 제목";
marked.setOptions({
renderer: new marked.Renderer(),
highlight: function(code, language) {
let validLanguage = hljs.getLanguage(language) ? language : 'plaintext';
return hljs.highlight(validLanguage, code).value;
},
pedantic: false,
gfm: true,
breaks: false,
sanitize: false,
smartLists: true,
smartypants: false,
xhtml: false
});
var htmlText = marked.parse(markedText);

다음과 같이 (jquery 를 이용해서) htmlText 를 화면에 표시한다.

var selectedContents2 = $("table#memo td.contents2");
selectedContents2.html(htmlText);

위의 Javascript 는 다음과 같은 HTML 을 필요로 한다.

<table id="memo">
<tr>
<td class="contents2"></td>
</tr>
</table>

주석으로 막힌 부분을 제거하려면 다음음 추가한다.

selectedContents2.contents().filter(function() {
if(this.nodeType == 8) {
return true;
}
return false;
}).each(function(index, node) {
$(node).remove();
});

3.2. highlightjs-line-numbers.js 적용

highlightjs-line-numbers.js 를 적용하기 위해서 (위의 소스들에 덧붙여) 다음을 추가한다.

selectedContents2.find("code").each(function(i, block) {
hljs.lineNumbersBlock(block);
});

highlightjs-line-numbers.js 는 htmlText 를 화면에 표시한 후에 적용할 수 있다.

3.3. 문제해결

3.3.1. highlightjs-line-numbers.js

위의 소스들에 덧붙여 다음을 추가하면, (화면은 정상적으로 표시되지만,) 경고창에는 highlightjs-line-numbers.js 적용 전의 html이 표시된다.

alert(selectedContents2.html());

위의 문제는 다음과 같이 해결할 수 있다.

window.setTimeout(function() {
alert(selectedContents2.html());
}, 0);

최신 버전의 Firefox 와 Chrome 그리고 IE 11 에서 테스트했고, 끝이 보이지 않던 삽질 끝에 우연히 답을 얻었다.

(예를 들어 서버로 전송하기 위해서 HTML 로 변환된 결과를 textarea 에 채우는 등) submit 직전에 무엇인가 처리하려면, onsubmit 이벤트 함수는 다음과 같은 형태가 될 것이다.

function check_submit(form, msg) {
window.setTimeout(function() {
$("form#insert textarea.html_contents").val($("div#preview_area").html());
$("form#insert").removeAttr("onsubmit");
$("form#insert").submit();
}, 0);
return false;
}

3.3.2. IE 관련

IE 를 지원하는 마지막 버전은 각각 다음과 같다.

  • marked.js : 5.0.5
  • highlight.js : 9.18.5

폴리필(Polyfill)도 추가해야 한다.

폴리필(Polyfill)을 추가하지 않는다면, 객체가 무슨 함수를 지원하지 않는다는 runtime 에러가 발생할 것인데, 구체적으로 필요한 함수는 markdown 원문에 따라 다르다.

지원이 종료된 IE 를 지원할 것인지는 전적으로 서비스 운영자의 선택이다.

제목

첨부파일