이번 포스팅에서는 Highlight.js 라이브러리와 약간의 CSS, JavaScript 코드를 활용하여, 자동 구문 강조(Syntax Highlighting), 줄 번호(Line Numbers), 코드 복사 버튼, 그리고 macOS 스타일의 헤더까지 갖춘 세련된 코드 블럭을 만드는 방법을 소개합니다.
구글 블로그 관리자 페이지에서 테마 > 맞춤설정 드롭다운 > HTML 편집으로 이동하여 아래 코드들을 지정된 위치에 추가합니다.
⚠️ 먼저, 자바스크립트 코드가 작동하기 위해서는 jQuery 3.6.0이 필요합니다. 이를 설치하기 위해 코드 한 줄만 삽입하면 됩니다. 다음 글에서 꼭 먼저 확인하고 오세요.
1단계: 구문 강조(Syntax Highlighting) 스타일 시트 추가
먼저 코드 블럭의 색상과 스타일을 정의하는 CSS 파일을 불러옵니다. Highlight.js에서 제공하는 다양한 테마 중 monokai-sublime 테마를 사용하는 예시입니다. 다른 테마를 원하시면 Highlight.js 데모 페이지에서 확인 후 링크를 교체할 수 있습니다.
▶ HTML 편집기에서 </head> 태그를 찾아서 그 바로 위에 아래 코드를 삽입하세요.
<!--코드블럭 구문 강조 시작-->
<link href='https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/monokai-sublime.min.css' rel='stylesheet'/>
<!--코드블럭 구문 강조 끝-->
- 설명: 외부 CSS 파일을 블로그에 연결하여 Highlight.js의
monokai-sublime테마 스타일을 적용합니다. 이 파일이 없으면 코드는 하얗게만 보일 것입니다.
2단계: 코드 블럭 커스텀 CSS 추가
이제 코드 블럭의 세부적인 디자인(줄 번호, 헤더, 복사 버튼, 스크롤바 등)을 꾸미는 CSS 코드입니다.
▶ HTML 편집기에서 ]]></b:skin> 태그를 찾아서 그 바로 위에 아래 코드를 삽입하세요.
/* 코드블럭 CSS 시작 */
pre {
position: relative;
counter-reset: line-idx;
}
pre::after {
content: attr(data-ke-language);
position: absolute;
bottom: 8px;
right: 12px;
color: #cfd2d1;
font-size: 12px;
font-family: Menlo, Courier, monospace;
}
.hljs {
display: flex !important;
flex-direction: column;
padding: 0 !important;
font-size: 14px;
border-radius: 8px;
box-shadow: 0 12px 24px rgb(0 0 0 / 40%);
color: #cfd2d1;
background-color: #343131;
font-family: Menlo, Courier, monospace;
}
.hljs .line {
counter-increment: line-idx;
line-height: 1.5;
white-space: pre;
}
.hljs .line:hover {
background-color: #262830;
}
.hljs .line:hover::before {
color: #cfd2d1;
}
.hljs .line::before {
content: counter(line-idx);
width: 24px;
display: inline-block;
text-align: right;
margin-right: 16px;
font-size: 0.8rem;
color: #747a7a;
}
.hljs .code-header {
display: flex;
align-items: center;
padding: 14px;
background-color: #434041;
border-radius: 8px 8px 0 0;
}
.hljs .code-header .btn {
border-radius: 50%;
width: 15px;
height: 15px;
margin: 0 5px;
}
.hljs .code-header .btn.red {
background-color: #f5655b;
}
.hljs .code-header .btn.yellow {
background-color: #f6bd3b;
}
.hljs .code-header .btn.green {
background-color: #43c645;
}
.hljs .code-body {
max-height: 600px;
margin: 32px 8px;
overflow: auto;
}
.hljs .code-body::-webkit-scrollbar {
width: 12px;
}
.hljs .code-body::-webkit-scrollbar-thumb {
background-color: rgb(1 2 3 / 80%);
border-radius: 4px;
}
.hljs .code-body::-webkit-scrollbar-corner {
display: none;
}
.hljs .copy-btn {
background-color: #ffffff17;
border: none;
cursor: pointer;
color: #fff;
border-radius: 4px;
width: 36px;
height: 28px;
margin-left: auto;
transition: 0.2s background-color;
font-size: 0;
}
.hljs .copy-btn:hover {
background-color: #ffffff30;
}
.post-body :not(pre) > code {
background-color: #343131;
color: #f8f8f2;
padding: 2px 6px;
border-radius: 4px;
font-family: Menlo, Courier, monospace;
font-size: 0.95em;
display: inline;
}
/* 코드블럭 CSS 끝 */
- 주요 기능 설명:
pre: 코드 블럭(pre태그)의 기본 설정을 합니다. 줄 번호를 위한counter-reset과 언어 표시를 위한position: relative를 포함합니다.pre::after:data-ke-language속성값을 가져와 코드 블럭 우측 하단에 코드 언어(예: javascript)를 표시합니다..hljs: Highlight.js가 적용된 요소의 메인 스타일입니다. 배경색, 폰트, 그림자 등을 정의하고flex레이아웃을 사용하여 헤더와 본문을 배치합니다..hljs .line: 코드 각 줄의 스타일입니다.counter-increment를 이용해 줄 번호를 생성합니다..hljs .line::before: 생성된 줄 번호의 스타일(정렬, 색상, 간격 등)을 지정합니다..hljs .line:hover: 마우스를 올렸을 때 해당 줄의 배경색과 줄 번호 색상을 변경하여 가독성을 높입니다..hljs .code-header: macOS 스타일의 창 헤더(빨강/노랑/초록 버튼 포함)를 만듭니다..hljs .code-body: 실제 코드가 표시되는 영역입니다. 최대 높이를 지정하고 내용이 길어지면 스크롤바가 나타나도록 합니다. 스크롤바 스타일도 꾸며줍니다..hljs .copy-btn: 코드 복사 버튼의 스타일과 마우스 오버 효과를 정의합니다..post-body :not(pre) > code:pre태그 안에 있지 않은 인라인code태그 (본문 중간에 짧게 들어가는 코드)의 스타일을 지정합니다.
3단계: 기능 활성화 JavaScript 추가
마지막으로 Highlight.js 라이브러리를 로드하고, 위에서 만든 CSS와 연동하여 코드 블럭을 동적으로 변환하고 복사 기능을 추가하는 JavaScript 코드입니다.
▶ HTML 편집기에서 </body> 태그를 찾아서 그 바로 위에 아래 코드를 삽입하세요.
<!--코드블럭 커스터마이징 시작-->
<script src='https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js'/>
<script>
//<![CDATA[
const COPY_TEXT_CHANGE_OFFSET=1e3,COPY_ERROR_MESSAGE="코드를 복사할 수 없습니다. 다시 시도해 주세요.",COPY_ICON=`
<svg width="14" height="14" fill="currentColor" class="icon" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M4 2a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2zm2-1a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1zM2 5a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1v-1h1v1a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h1v1z"/>
</svg>`,CHECK_ICON=`
<svg width="14" height="14" viewBox="0 0 14 15" fill="none">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.746.07a.5.5 0 0 1 .353.146l1.5 1.5a.5.5 0 0 1 0 .708l-7.5 7.5a.5.5 0 0 1-.708 0l-3-3a.5.5 0 0 1 0-.708l1.5-1.5a.5.5 0 0 1 .708 0L7 7.293l5.146-5.147a.5.5 0 0 1 .353-.146z" fill="currentColor"/>
</svg>`,copyBlockCode=async(e=null)=>{if(e)try{await navigator.clipboard.writeText(decodeURI(e.dataset.code)),e.innerHTML=CHECK_ICON,setTimeout(()=>{e.innerHTML=COPY_ICON},1e3)}catch(_){alert("코드를 복사할 수 없습니다. 다시 시도해 주세요."),console.error(_)}};document.addEventListener("DOMContentLoaded",()=>{let e=document.querySelectorAll("pre > code");for(let _ of e){let $=_.parentElement,a=_.className.match(/language-(\w+)/),t=a?a[1]:"";t&&$.setAttribute("data-ke-language",t);let l=_.textContent.trim().split("\n").map((e,_)=>`<div class="line">${e.trim()?hljs.highlight(e,{language:t||"plaintext"}).value:""}</div>`).join(""),n=`
<div class="code-header">
<span class="red btn"></span>
<span class="yellow btn"></span>
<span class="green btn"></span>
<button type="button" class="copy-btn" data-code="${encodeURI(_.textContent)}" onclick="copyBlockCode(this)">${COPY_ICON}</button>
</div>`,i=`<div class="code-body">${l}</div>`;hljs.highlightElement(_),_.innerHTML=n+i}});
//]]>
</script>
<!--코드블럭 커스터마이징 끝-->
- 주요 기능 설명:
- 첫 번째
<script>태그는 Highlight.js의 핵심 JavaScript 라이브러리를 불러옵니다. 이 파일이 구문 강조를 실제로 수행합니다. - 두 번째
<script>태그 안의 코드는 다음 작업을 수행합니다:COPY_ICON,CHECK_ICON: 복사 버튼과 복사 완료 시 표시될 아이콘(SVG)을 정의합니다.copyBlockCode함수: 복사 버튼 클릭 시 실행됩니다. 버튼의data-code속성에 저장된 코드를 클립보드에 복사합니다. 성공하면 아이콘을 체크 모양으로 바꾸고 1초 후에 다시 원래 복사 아이콘으로 돌려놓습니다. 실패하면 에러 메시지를 띄웁니다.DOMContentLoaded이벤트 리스너: 페이지 로딩이 완료되면 실행됩니다.querySelectorAll("pre > code"): 페이지 내의 모든 코드 블럭(pre태그 안의code태그)을 찾습니다.- 루프 실행: 찾은 각 코드 블럭에 대해 다음 작업을 반복합니다.
language-(\w+)정규식:code태그의 클래스에서language-xxx형식을 찾아 코드 언어(xxx부분)를 추출합니다. (예:class="language-javascript"->javascript추출)setAttribute("data-ke-language", a): 추출한 언어 정보를 부모pre태그의data-ke-language속성으로 설정합니다. (CSS에서 이 속성값을 사용해 언어를 표시)- 코드 분할 및 하이라이팅: 코드를 줄 단위로 나누고, 빈 줄은 제외한 후 각 줄에 대해
hljs.highlight함수를 호출하여 구문 강조 HTML을 생성합니다. - HTML 구조 생성: 각 줄을
<div class="line">으로 감싸고, 앞에서 정의한 헤더(code-header)와 코드 본문(code-body) HTML 구조를 만듭니다. 복사 버튼도 헤더 안에 포함시킵니다. 이때 원본 코드는encodeURI를 사용해data-code속성에 안전하게 저장합니다. _.innerHTML = o + s: 기존code태그의 내용을 새로 생성한 헤더 + 본문 HTML로 교체하여 화면에 표시합니다.
- 첫 번째
사용 방법
이제 포스트를 작성할 때 코드 블럭을 넣고 싶은 부분을 HTML 모드로 전환하여 다음과 같은 형식으로 작성하면 됩니다.
<pre><code class="language-javascript">
// 여기에 자바스크립트 코드를 입력하세요.
function greet(name) {
console.log('Hello, ' + name + '!');
}
greet('World');
</code></pre>
<pre><code class="language-css">
/* 여기에 CSS 코드를 입력하세요. */
body {
font-family: sans-serif;
line-height: 1.6;
}
</code></pre>
<pre><code class="language-python">
# 여기에 파이썬 코드를 입력하세요.
def add(a, b):
return a + b
print(add(5, 3))
</code></pre>
- 핵심:
<pre><code class="language-언어이름"> ... </code></pre>형태로 작성합니다. language-언어이름부분에 해당 코드의 언어(예:javascript,python,java,css,html,xml,bash등)를 소문자로 정확히 입력해야 구문 강조가 제대로 적용됩니다. 지원되는 언어 목록은 Highlight.js 문서에서 확인할 수 있습니다.- 언어를 지정하지 않거나 지원되지 않는 언어인 경우, 기본 텍스트 스타일로 표시됩니다 (
plaintext).
마무리
이제 여러분의 구글 블로그에서도 가독성 높고 세련된 코드 블럭을 사용할 수 있습니다! 코드를 공유하고 설명하는 것이 훨씬 즐거워질 것입니다.
주의: 테마 코드를 직접 수정하는 것은 예기치 않은 문제를 발생시킬 수 있습니다. 수정 전에는 반드시 기존 테마 코드를 백업해두시기 바랍니다. (테마 > 맞춤설정 드롭다운 > 백업)