Katex
: ์น ๋ธ๋ผ์ฐ์ ์์ ์ํ ํ๊ธฐ๋ฒ์ ํ์ํ๋ ๋ธ๋ผ์ฐ์ ๊ฐ JavaScript ๋ผ์ด๋ธ๋ฌ๋ฆฌ
- ๋น ๋ฅด๊ณ ์ฌ์ฉํ๊ธฐ ์ฌ์ด ๊ฒ์ ํนํ ์ค์ ์ ๋
PlantUML
: ๋ค์ด์ด๊ทธ๋จ์ ๋น ๋ฅด๊ฒ ์์ฑํ๊ธฐ ์ํ ์คํ ์์ค ํ๋ก์ ํธ
๐๐ป ๋งํฌ
์ฝ๋
HTML
<script src="https://uicdn.toast.com/editor/latest/toastui-editor-all.min.js"></script>
<link rel="stylesheet" href="https://uicdn.toast.com/editor/latest/toastui-editor.min.css" />
<!-- ์ ํ์ค ํ์ด๋ผ์ดํฐ ํ๋ฌ๊ทธ์ธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์ -->
<link rel="stylesheet" href="https://uicdn.toast.com/editor-plugin-code-syntax-highlight/latest/toastui-editor-plugin-code-syntax-highlight.min.css">
<script src="https://uicdn.toast.com/editor-plugin-code-syntax-highlight/latest/toastui-editor-plugin-code-syntax-highlight-all.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism.min.css">
<!-- ์ ํ์ค ํ์ด๋ผ์ดํฐ ํ๋ฌ๊ทธ์ธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ -->
<!-- katex ํ๋ฌ๊ทธ์ธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์ -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.13.13/katex.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.13.13/katex.min.css">
<!-- katex ํ๋ฌ๊ทธ์ธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ -->
<!-- uml ํ๋ฌ๊ทธ์ธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์ -->
<script src="https://uicdn.toast.com/editor-plugin-uml/latest/toastui-editor-plugin-uml.min.js"></script>
<!-- uml ํ๋ฌ๊ทธ์ธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ -->
<template id="viewer-1-template">
# ์๋
ํ์ธ์.
## ๋ฐ๊ฐ์์.
- ํํ
- ํธํธ
- ํํ
# ์๋ฐ
```java
// ์ฃผ์์
๋๋ค.
int a = 10;
int b = 20;
System.out.println(a + b);
```
$$katex
x^2 + y^2 = 1
$$
```html
<script src="๊ฒฝ๋ก"></script>
```
$$uml
(First usecase)
(Another usecase) as (UC2)
usecase UC3
usecase (Last\nusecase) as UC4
$$
</template>
<div id="viewer-1"></div>
CSS
body {
margin: 0;
}
@font-face {
font-family: "GmarketSansMedium";
src: url("https://cdn.jsdelivr.net/gh/projectnoonnu/noonfonts_2001@1.1/GmarketSansMedium.woff")
format("woff");
font-weight: normal;
font-style: normal;
}
#viewer-1 {
padding: 0 10px;
}
html > body,
html > body .toastui-editor-contents,
html > body .toastui-editor-contents code,
html > body .toastui-editor-contents pre {
font-family: "GmarketSansMedium";
}
JS
console.clear();
function stripIndent(str) {
const lines = str.split("\n");
let minIndent = Infinity;
// ์ฒซ ๋ฒ์งธ ์ค ์ดํ์ ๊ฐ ์ค์์ ๊ฐ์ฅ ์์ ๋ค์ฌ์ฐ๊ธฐ ๊ฐ์ ์ฐพ์ต๋๋ค.
for (let i = 1; i < lines.length; i++) {
const line = lines[i];
const indent = line.search(/\S/); // ์ฒซ ๋ฒ์งธ ๋น๊ณต๋ฐฑ ๋ฌธ์์ ์ธ๋ฑ์ค๋ฅผ ์ฐพ์ต๋๋ค.
if (indent !== -1 && indent < minIndent) {
minIndent = indent;
}
}
// ๋ชจ๋ ์ค์์ ๊ฐ์ฅ ์์ ๋ค์ฌ์ฐ๊ธฐ ๊ฐ์ ๋บ๋๋ค.
if (minIndent !== Infinity) {
for (let i = 0; i < lines.length; i++) {
lines[i] = lines[i].slice(minIndent);
}
}
// ๊ฒฐ๊ณผ ๋ฌธ์์ด์ ๋ฐํํฉ๋๋ค.
return lines.join("\n");
}
const Editor = toastui.Editor;
function katexPlugin() {
const toHTMLRenderers = {
katex(node) {
console.log("HI");
let html = katex.renderToString(node.literal, {
throwOnError: false
});
return [
{ type: "openTag", tagName: "div", outerNewLine: true },
{ type: "html", content: html },
{ type: "closeTag", tagName: "div", outerNewLine: true }
];
}
};
return { toHTMLRenderers };
}
// id๊ฐ 'viewer-1-template' ์ธ ์๋ฆฌ๋จผํธ๋ฅผ ์ฐพ๋๋ค.
const viewer1TemplateEl = document.querySelector("#viewer-1-template");
const viewer1MarkdownSource = stripIndent(viewer1TemplateEl.innerHTML); // ํฌํจํ๊ณ ์๋ ๋ด์ฉ
console.log("viewer1MarkdownSource : " + viewer1MarkdownSource);
const viewer1 = Editor.factory({
el: document.querySelector("#viewer-1"),
viewer: true,
initialValue: viewer1MarkdownSource,
plugins: [
[toastui.Editor.plugin.codeSyntaxHighlight, { highlighter: Prism }],
katexPlugin,
[
toastui.Editor.plugin.uml,
{ rendererURL: "http://www.plantuml.com/plantuml/svg/" }
]
]
});
์คํ ๊ฒฐ๊ณผ