
티스토리에 개발 관련 글을 올릴 때 코드가 평범한 텍스트처럼 보이면 글의 완성도가 많이 떨어집니다. 특히 HTML, CSS, JavaScript처럼 구조와 문법이 중요한 코드는 색상 구분이 있어야 읽기 훨씬 편합니다.
이럴 때 많이 사용하는 방식이 코드 하이라이팅 라이브러리 적용입니다. 티스토리에서는 별도의 빌드 환경 없이도 스킨 편집만으로 적용할 수 있고, 그중에서 가장 무난한 선택지가 Prism.js입니다.
이번 글에서는 티스토리에 Prism.js를 적용하는 방법부터, 실제로 하이라이팅이 안 될 때 확인해야 할 핵심 원인까지 정리해보겠습니다.
왜 Prism.js를 많이 사용할까
Prism.js는 가볍고 구조가 단순합니다. CSS 파일로 테마를 불러오고, JS 파일로 문법 하이라이팅을 활성화한 뒤, 코드 블록에 언어 클래스를 붙이면 됩니다.
즉, 기본 구조는 아래 세 가지입니다.
- Prism 테마 CSS 불러오기
- Prism JS와 필요한 언어 컴포넌트 불러오기
- 본문 코드 블록에 올바른 언어 클래스 적용하기
설정 방식이 복잡하지 않아서 티스토리 같은 블로그 환경에도 잘 맞습니다.
티스토리에 Prism.js 적용하는 기본 방법
티스토리 관리자에서 아래 경로로 들어갑니다.
티스토리 관리자 → 꾸미기 → 스킨 편집 → HTML 편집
여기서 스킨의 HTML에 Prism 관련 코드를 추가하면 됩니다.
1. <head> 안에 Prism 테마 CSS 추가
먼저 코드 블록 디자인에 필요한 테마 CSS를 넣습니다.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/themes/prism-tomorrow.min.css">
이 코드는 <head> 태그 안에 넣으면 됩니다.
prism-tomorrow.min.css는 어두운 배경 기반이라 코드 가독성이 좋은 편입니다. 다른 테마를 쓰고 싶다면 해당 파일만 바꾸면 됩니다.
2. </body> 바로 위에 Prism JS 추가
이제 문법 하이라이팅을 실제로 동작시키기 위한 JS 파일을 넣습니다.
<script>
window.Prism = window.Prism || {};
Prism.manual = true;
</script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/prism.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-javascript.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-css.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-markup.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-bash.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
Prism.highlightAll();
});
</script>
이 코드는 </body> 태그 바로 위에 넣으면 됩니다.
여기서 중요한 점은 prism.min.js만 넣는다고 모든 언어가 자동으로 하이라이팅되는 것은 아니라는 점입니다. 자주 쓰는 언어별 컴포넌트도 함께 불러와야 합니다.
글 본문에서 코드 블록 작성하는 방법
Prism.js를 연결했더라도, 글 본문 코드 블록의 HTML 구조가 맞지 않으면 하이라이팅은 적용되지 않습니다.
가장 기본적인 형태는 아래와 같습니다.
<pre><code class="language-javascript">
const hello = "world";
console.log(hello);
</code></pre>
HTML 예제는 이렇게 작성합니다.
<pre><code class="language-html">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/themes/prism-tomorrow.min.css">
</code></pre>
CSS 예제는 이렇게 작성합니다.
<pre><code class="language-css">
body {
background: #111;
color: #fff;
}
</code></pre>
즉, 핵심은 language-언어명 클래스를 정확하게 붙이는 것입니다.
티스토리에서 하이라이팅이 안 되는 가장 흔한 이유
여기서 많은 분들이 헷갈리는 부분이 있습니다. Prism 파일을 연결했는데도 코드 하이라이팅이 안 되는 경우, 실제 원인은 보통 아래 둘 중 하나입니다.
1. 코드 블록이 Prism 형식으로 출력되지 않는 경우
Prism은 아래 같은 구조를 기대합니다.
<pre class="language-html"><code class="language-html">...</code></pre>
그런데 티스토리 에디터나 일부 스킨에서는 이런 식으로 출력되는 경우가 있습니다.
<pre class="xml"><code>...</code></pre>
또는
<pre class="routeros"><code>...</code></pre>
또는
<pre class="typescript"><code>...</code></pre>
이 경우 Prism은 제대로 인식하지 못할 수 있습니다.
이유는 Prism이 xml, routeros, typescript 같은 단순 클래스가 아니라, language-html, language-css, language-javascript 같은 형식을 기준으로 동작하기 때문입니다.
2. 코드 종류와 클래스명이 맞지 않는 경우
예를 들어 아래 코드는 HTML 코드입니다.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/themes/prism-tomorrow.min.css">
그런데 이 코드를 아래처럼 감싸면 맞지 않습니다.
<pre class="routeros"><code>...</code></pre>
이 코드는 RouterOS 문법이 아니라 HTML 마크업이기 때문에, routeros로 지정하면 하이라이팅이 제대로 되지 않는 것이 정상입니다.
이럴 때는 아래처럼 바꿔야 합니다.
<pre class="language-html"><code class="language-html"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/themes/prism-tomorrow.min.css"></code></pre>
또는 이렇게 작성해도 됩니다.
<pre class="language-markup"><code class="language-markup"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/themes/prism-tomorrow.min.css"></code></pre>
실제로 자주 틀리는 예시
아래처럼 작성하면 하이라이팅이 안 될 수 있습니다.
<pre class="xml"><code><script src="https://cdn.jsdelivr.net/npm/prismjs/prism.min.js"></script></code></pre>
이유는 xml 클래스만 붙어 있고, Prism이 기대하는 language-html 또는 language-markup 형식이 아니기 때문입니다.
수정된 예시는 아래와 같습니다.
<pre class="language-html"><code class="language-html"><script src="https://cdn.jsdelivr.net/npm/prismjs/prism.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-javascript.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-css.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-markup.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-bash.min.js"></script></code></pre>
또 아래처럼 되어 있어도 문제가 됩니다.
<pre class="routeros"><code><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/themes/prism-tomorrow.min.css"></code></pre>
이 코드의 실제 내용은 RouterOS가 아니라 HTML이므로, 아래처럼 바꿔야 맞습니다.
<pre class="language-html"><code class="language-html"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/themes/prism-tomorrow.min.css"></code></pre>
코드 예시를 감싼 코드도 클래스가 맞아야 한다
이 부분도 자주 놓치는 문제입니다. 아래 코드는 겉보기에는 typescript 클래스로 감싸져 있습니다.
<pre class="typescript"><code><pre><code class="language-javascript">
const hello = "world";
console.log(hello);
</code></pre></code></pre>
하지만 이 안의 실제 내용은 TypeScript 문법이 아닙니다.
이 코드는 “자바스크립트 코드 블록을 작성하는 HTML 예시”를 보여주는 문자열입니다.
즉, 이 경우에도 typescript보다는 language-html 또는 language-markup이 더 맞습니다.
수정 예시는 아래처럼 쓰는 편이 정확합니다.
<pre class="language-html"><code class="language-html"><pre><code class="language-javascript">
const hello = "world";
console.log(hello);
</code></pre></code></pre>
핵심은 코드 블록 안에 JavaScript 코드가 들어 있다고 해서 바깥 블록까지 JavaScript나 TypeScript로 분류하는 것이 아니라, 현재 화면에 출력하려는 코드 문자열 자체가 어떤 문법인지 기준으로 클래스명을 정해야 한다는 점입니다.
즉:
- 실제 JavaScript 코드 자체를 보여주면
language-javascript - JavaScript 코드 블록을 만드는 HTML 예시를 보여주면
language-html또는language-markup
이 기준을 혼동하면 하이라이팅이 어색해지거나 적용되지 않을 수 있습니다.
티스토리 에디터가 예전 클래스명을 출력할 때 해결하는 방법
문제는 티스토리에서 글을 작성할 때 자동으로 pre.xml, pre.css, pre.javascript, pre.typescript 같은 예전 스타일 클래스를 출력하는 경우가 있다는 점입니다.
이럴 때는 Prism이 인식할 수 있도록 클래스를 변환하는 스크립트를 추가하면 됩니다.
아래 코드를 </body> 바로 위, Prism 스크립트 아래쪽에 넣으면 됩니다.
<script>
document.addEventListener('DOMContentLoaded', function () {
const map = {
xml: 'language-html',
html: 'language-html',
markup: 'language-markup',
css: 'language-css',
javascript: 'language-javascript',
js: 'language-javascript',
bash: 'language-bash',
shell: 'language-bash',
routeros: 'language-html',
typescript: 'language-html'
};
document.querySelectorAll('pre').forEach(function(pre) {
Object.keys(map).forEach(function(oldClass) {
if (pre.classList.contains(oldClass)) {
pre.classList.remove(oldClass);
pre.classList.add(map[oldClass]);
const code = pre.querySelector('code');
if (code) {
code.classList.add(map[oldClass]);
}
}
});
});
Prism.highlightAll();
});
</script>
여기서 typescript를 language-html로 연결한 이유는, 위 예시처럼 실제 내용이 TypeScript가 아니라 HTML 마크업 예시였기 때문입니다.
단, 정말 TypeScript 코드를 올리는 경우라면 이 매핑은 다르게 봐야 합니다. 예를 들어 실제 TypeScript 코드를 자주 올릴 예정이라면 typescript를 language-typescript로 연결하고, Prism의 TypeScript 컴포넌트도 추가로 불러와야 합니다.
예를 들면 이런 식입니다.
<script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-typescript.min.js"></script>
즉, typescript라는 클래스가 붙어 있다고 해서 무조건 TypeScript로 처리하는 것이 아니라, 그 안에 들어 있는 실제 코드 내용이 무엇인지 보고 판단해야 합니다.
스킨 CSS와 충돌하는 경우도 있다
Prism이 적용되었는데도 디자인이 어색하거나 색상이 안 보이는 경우는 스킨 CSS가 pre, code 태그를 덮어쓰고 있을 가능성이 큽니다.
그럴 때는 아래처럼 보정 스타일을 추가하는 것이 좋습니다.
.article-view pre[class*="language-"] {
background: #2d2d2d;
padding: 1.2em;
border-radius: 12px;
overflow: auto;
margin: 1.5em 0;
}
.article-view code[class*="language-"] {
font-family: Consolas, Monaco, monospace;
text-shadow: none;
}
.article-view :not(pre) > code[class*="language-"],
.article-view pre[class*="language-"] {
background: #2d2d2d;
}
이렇게 하면 티스토리 기본 스킨 스타일과 충돌할 때도 코드 블록 모양이 더 안정적으로 보입니다.
티스토리에서 Prism.js 적용할 때 정리해야 할 핵심
결국 중요한 것은 아래 네 가지입니다.
<head>에 Prism 테마 CSS 추가</body>위에 Prism JS와 언어 파일 추가- 본문 코드 블록을
language-언어명형식으로 작성 - 티스토리가
xml,routeros,typescript같은 클래스를 뱉는 경우 변환 스크립트 추가
특히 아래처럼 잘못된 클래스는 바로 수정해야 합니다.
<pre class="xml"><code>...</code></pre>
<pre class="routeros"><code>...</code></pre>
<pre class="typescript"><code>...</code></pre>
이런 구조보다 아래처럼 맞추는 것이 정확합니다.
<pre class="language-html"><code class="language-html">...</code></pre>
마무리
티스토리에 코드 하이라이팅을 적용하는 작업 자체는 어렵지 않습니다.
하지만 실제로는 Prism 파일을 넣는 것보다, 글 본문에서 출력되는 코드 블록 HTML 구조가 더 중요합니다.
파일을 잘 연결했는데 하이라이팅이 안 된다면, 대개 아래 둘 중 하나입니다.
- 코드 블록 클래스가
language-...형식이 아님 - 코드 내용과 언어 클래스가 서로 맞지 않음
즉, Prism.js를 붙였는데도 동작하지 않는다면 라이브러리 문제보다 코드 블록 마크업 문제를 먼저 의심하는 편이 맞습니다.
원래 적용 방법만 보면 단순해 보이지만, 티스토리에서는 pre.xml, pre.routeros, pre.typescript처럼 출력되는 경우가 생각보다 흔해서 이 부분까지 같이 잡아줘야 실제로 제대로 작동합니다.
'UX 개발 > 티스토리' 카테고리의 다른 글
| 블로그 빌더로서의 티스토리 플랫폼 특단점 (0) | 2019.06.29 |
|---|