구글 블로그(블로그스팟) 코드 블럭 커스터마이징 (Highlight.js + CSS/JS)

이번 포스팅에서는 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).

마무리

이제 여러분의 구글 블로그에서도 가독성 높고 세련된 코드 블럭을 사용할 수 있습니다! 코드를 공유하고 설명하는 것이 훨씬 즐거워질 것입니다.

주의: 테마 코드를 직접 수정하는 것은 예기치 않은 문제를 발생시킬 수 있습니다. 수정 전에는 반드시 기존 테마 코드를 백업해두시기 바랍니다. (테마 > 맞춤설정 드롭다운 > 백업)

출처

https://guiyomi.tistory.com/132 이 티스토리 블로그의 코드를 블로그스팟에 적용 가능하게 코드를 수정하였습니다.
이 글의 목차
    면책: 이 글은 개인적 의견을 담은 정보 제공용 기록이며 투자 조언 또는 투자 권유가 아닙니다.
    링크가 복사되었습니다.