🚀 코드 블럭을 예쁘고 눈에 띄게 바꾸자!
블꾸 과정을 올리다 보니까 코드 블록이 굉장히 밋밋하다.
기본 코드 블록은 회색에 초록 글시라 가독성이 떨어지고 인용이랑 헷갈리기 쉽다.
그래서 좀 더 예쁘고 눈에 띄는 디자인을 적용하기로 했다.
가장 간단하게 코드블록을 바꾸는 방법은 플로그인 설정이다.
코드 문법 강조 플러그인만 써도 눈에 띄게 이뻐진다.
플러그인만 적용한 코드 블록 하지만 다른 블로그들을 보다보니까 특이한 스타일의 코드 블록을 적용하고 있는 게 보였다.
애플 유저가 아니라서 몰랐는데 맥 형식이라더라.
아무튼 이쁘니까 적용해보고 싶었는데 둉이님이 블로그에 자세한 설명과 코드를 알려주셔서 따라 해봤다.
🌟 맥 스타일 코드 블록의 장점
1. 깔끔한 UI로 가독성이 좋아진다.
2. 복사 버튼이 있어서 코드 복사가 쉬워진다.
3. 간접적으로 느껴보는 개발자 감성(?)
🔧 포트폴리오 스킨 수정하기
1️⃣ 스킨을 수정하기 전에 꼭 해야 할 일이 있다.
바로 코딩 문법 강조 플러그인을 설정해야 한다.
✔ 플러그인 → 코드문법 강조 → 테마 선택 → 적용
2️⃣ 플러그인 적용을 한 다음에 편집 화면으로 들어가면 된다.
✔ 티스토리 스킨을 편집하기 위해선 꾸미기 → 스킨 변경 → 변경 → 스킨 편집 → HTML 편집 → HTML 화면으로 들어가면 된다.
3️⃣ 기존의 hljs를 지운다.
✔ Ctrl+F로 찾아보니까 두 군데가 나왔다.
/*와 */ 사이에 넣어서 비활성화시키거나 지운다.
코드 수정이 끝났다면 적용을 누른다.
📝 MAC(맥) 스타일 코드 블록 만들기 JavaScript 설명
1️⃣ 상수 정의
const COPY_ICON_CHANGE_OFFSET = 1000;
const COPY_ICON = `
<svg xmlns=... width="15px" height="15px">
<path d="...">
</path>
</svg>`;
const CHECK_ICON = `
<svg xmlns=... width="15px" height="15px">
<path d="...">
</path>
</svg>`;
const COPY_ERROR_MESSAGE = 'ERROR';
✔ COPY_ICON_CHANGE_OFFSET = 1000; → 복사 버튼의 글자가 변하는 시간(1000ms = 1초)
✔ COPY_ICON = ...; → 복사 버튼 아이콘
✔ CHECK_ICON= ...; → 복사를 완료하면 표시될 아이콘
✔ COPY_ERROR_MESSAGE = "ERROR"; → 복사가 실패했을 때 표시할 경고 메시지
2️⃣ codeBlocks 변수
const codeBlocks = document.querySelectorAll('pre > code');
✔ document.querySelectorAll('pre > code') → HTML에서 <pre><code>...</code></pre> 태그 안의 태그를 모두 찾는다.
3️⃣ copyBlockCode 함수 (복사 버튼 클릭 시 클립보드에 코드 복사)
(1) copy-btn을 클릭하면 실행되는 함수
const copyBlockCode = async (target = null) => {
target은 버튼 요소를 의미한다.(<button class="copy-btn">)
✔ target = null → 기본값 null (아무 값도 들어오지 않으면, 즉 버튼이 눌리지 않으면 실행되지 않는다.)
✔ async → 비동기 함수 : 복사하는 과정이 끝날 때까지 기다려야 한다.
(2) target이 없으면 바로 종료
if (!target) return;
만약 target이 null이면 함수가 종료(return;)된다.
(3) 클립보드 복사 코드 실행
try {
try {...} 안에서 클립보드 복사 코드가 실행된다.
(4) 버튼이 눌린 코드 블록의 내용 가져오기 (복사 준비 완료)
const code = decodeURI(target.dataset.code);
✔ target.dataset.code → <button> 태그의 data-code 속성에서 코드 내용을 가져온다.
✔ decodeURI(...) → URI로 인코딩된 문자열을 원래대로 복원한다.
(5) 클립보드에 복사
await navigator.clipboard.writeText(code);
✔ navigator.clipboard.writeText(code) → 클립보드에 텍스트를 저장하는 기능.
✔ await → 비동기 함수 : 복사가 완료될 때까지 기다린다.
(6) 버튼을 체크 모양으로 변경
target.innerHTML = CHECK_ICON;
(7) 1초 후 버튼 텍스트 원래대로 돌리기
setTimeout(() => {
target.innerHTML = COPY_ICON;
}, COPY_ICON_CHANGE_OFFSET);
✔ setTimeout(..., ...); → 1초 동안 체크 모양을 보여준다.
✔ target.innerHTML = COPY_ICON; → 복사 아이콘으로 변경한다.
(8) catch 블록 (복사 실패 시)
} catch (error) {
alert(COPY_ERROR_MESSAGE);
console.error(error);
}
✔ catch (error) { ... } → 오류가 발생하면 여기서 처리한다.
✔ alert(COPY_ERROR_MESSAGE); → 복사가 실패하면 'ERROR' 메시지를 경고창으로 띄운다.
✔ console.error(error); → 개발자 도구(콘솔)에 오류 내용을 출력한다.
📂 여기까지 정리
사용자가 복사 버튼을 클릭하면 해당 코드 블록에서 코드를 가져와 클립보드에 복사한다.
복사 완료되면 체크 아이콘으로 변경되고 1초 후 다시 원래 복사 아이콘으로 복구된다.
에러가 발생하면 ERROR라고 경고 메시지가 출력된다.
4️⃣ func 함수 (코드 블록을 자동으로 수정)
(1) 코드 블록을 하나씩 처리하기 (for문)
for (const codeBlock of codeBlocks) {
for ... of 반복문을 사용해서 codeBlocks에 있는 코드 블록들(웹페이지에 있는 모든 코드 블록)을 하나씩 가져와 처리한다.
(2) 코드 블록을 줄 단위로 나누기
const codes = codeBlock.innerHTML.match(/(.*)(\n|.*$)/g).filter(Boolean);
✔ codeBlock.innerHTML → 현재 코드 블록의 HTML 내용을 가져온다.
✔ .match(/(.*)(\n|.*$)/g) → 정규 표현식(RegEx)을 사용해서 코드를 줄 단위로 나는다. 즉, 코드가 여러 줄이면 한 줄씩 분리해서 배열로 저장한다.
✔ filter(Boolean) → 값이 true인지 false인지 판별하는 함수 Boolean를 사용해 빈 줄("")을 제거한다.
(4) 코드를 한 줄씩 <div> 태그로 감싸기
const processedCodes = codes.reduce((prevCodes, curCode) => prevCodes + `<div class="line">${curCode}</div>`, '');
코드를 한 줄씩 <div class="line>...</div>에 감싸서 HTML로 변환한다.
✔ prevCodes는 누적된 HTML 문자열, curCode는 현재 줄의 코드.
(5) 복사 버튼 만들기
const copyButton = `<button type="button" class="copy-btn"
data-code="${encodeURI(codeBlock.textContent)}"
onclick="copyBlockCode(this)">
${COPY_ICON}
</button>`;
✔ data-code="${encodeURI(codeBlock.textContent)}" → data-code 속성에 코드 내용을 URI 형태로 저장한다.
✔ encodeURI(...) → 특수문자도 안전하게 저장할 수 있다.
✔ onclick="copyBlockCode(this)" → 버튼을 클릭하면 copyBlockCode(this)가 실행된다.
(6) 코드 블록의 내용이 들어가는 목록 만들기
const codeBody = `<div class="code-body">${processedCodes}</div>`;
코드 내용을 담는 <div class="code-body"> 생성한다.
(7) 코드 블록의 헤더 만들기 (Mac 스타일 UI)
const codeHeader = `<div class="code-header">
<span class="red dot"></span>
<span class="yellow dot"></span>
<span class="green dot"></span>
${copyButton}
</div>`;
✔ <span class="red dot"></span> → 빨간색 동그라미
✔ <span class="yellow dot"></span> → 노란색 동그라미
✔ <span class="green dot"></span> → 초록색 그라미
✔ ${copyButton} → 앞에서 만든 복사 버튼
(8) 최종적으로 코드 블록 변경
codeBlock.innerHTML = codeHeader + codeBody;
코드 블록을 header와 body 형태로 바꿔준다.
✔ codeBlock.innerHTML = → 원래 코드 블록의 내용을 새롭게 만든 코드로 덮어쓰기.
📂 여기까지 정리
기존 코드 블록을 맥 스타일의 코드 블록으로 바꾼다.
맥 스타일의 코드 블록에는 복사 버튼과 Mac 스타일 헤더(빨강/노랑/초록 점)가 추가된다.
버튼을 누르면 코드가 클립보드에 복사하는 기능도 넣는다.
이제 HTML & JavaScript 적용이 끝났다.
다음 글에서는 CSS로 맥 스타일의 코드 블록을 예쁘게 다듬어볼 예정이다.
"[Info🔍/HTML&CSS] - [Portfolio 스킨] 26. 코드 블록, 맥 스타일로 예쁘게 변신 (2탄 : CSS 디자인 편)"에서 계속 🚀
전체 코드가 필요하신 분은 둉이님 블로그를 참고해주세요.
💾 기존 코드
.article_view pre code.hljs {
padding: 20px;
}
#article-view pre code.hljs {
font-size: 14px;
padding: 20px;
font-family: SF Mono, Menlo, Consolas, Monaco, monospace;
border: solid 1px #ebebeb;
line-height: 1.71;
overflow: auto;
}