4. 블로그 만들기 - 목차
나만의 블로그가 어느 정도 궤도에 올라왔다는 생각이 든다. 꾸준히 글을 올리고 있고 개인 취향이지만 디자인도 개선 되고 있고 계속 해서 추가적인 기능도 개속 탑제 되고 개선 되고 있다. 이번에는 포스트에서의 글의 빠른 이동을 위한 목차 기능을 만들었다.
기획
- a 태그와 태그의 id 설정을 통해 페이지 위치 이동 기능 사용
- 마크다운 포스팅 글에서 목차 타이틀 선택 및 리스트 저장
- 저장된 리스트 기반으로 목차 제작
- 타이틀 변환시 id값 설정
목차 타이틀 선택
- 먼저 목차로 이동할 타이틀, 즉 헤더를 선택해야 한다. 나는 마크다운 헤더 중 '#', '##', '###' 이 3가지 헤더를 목차로 지정하기로 했다.
- 기존에는 마크다운 파일을 읽어 마크 다운 텍스트를 기초 json 데이터로 저장 후 텍스트를 곧 바로 HTML 코드로 변환하는 프로세스를 거쳤다.
- 이번에 개선된 방식은 마크다운 텍스트와 HTML 코드 변환 과정 사이에 토큰 이라는 데이터 생성 과정이 추가가 되었다. 마크다운 텍스트를 읽어 HTML 변환을 위한 데이터 Object인 token 데이터를 생성하여 저장하고 추후 저장된 token을 활용하여 HTML 코드를 제작 하는 방식이다.
- 이러한 방식을 채택한 이유는 마크 다운 코드에서 token을 생성할때 타이틀에 들어갈 id값 생성에 필요한 데이터 값이다 추가 적인 데이터를 함께 탑재해 HTML 코드 변환에 활용 할 수 있기 때문이다.
타이틀 선택 코드 분석
// (1)
const token = marked.lexer(mdFile.content).map((v, i) => { return { index: i, ...v } })
...
const item = {
...,
// (2)
bookmark: token.filter((v) => { return v.type === 'heading' })
}
(1)
- 마크다운 텍스트 데이터를 분해하여 token 데이터로 변환하고 token 데이터 중 최상위 데이터에 index 값은 부여 한다.
(2)
- 생성된 최상위 토큰 중 type이 heading, 즉 '#', '##', '###' 로 작성된 내용을 걸러 내어 bookmark라는 데이터로 뽑아 낸다.
커스텀 변환 코드
const renderer = new marked.Renderer()
renderer.heading = (token) => {
return `<h${token.depth} id="bm-${token.index}">${token.text}</h${token.depth}>`
}
/*
{
index: 15,
type: 'heading',
raw: '### 커스텀 변환 코드\n',
depth: 3,
text: '커스텀 변환 코드',
tokens: [
{
type: 'text',
raw: '커스텀 변환 코드',
text: '커스텀 변환 코드',
escaped: false
}
]
}
*/
- 기본적으로 h태그 변환 코드는 동일하지만 이전에 추가 되었던 index 값으로 id 값을 생성한다.
Bookmark 코드
const bookmark = (param) => {
const html = param.reduce((a, b) => {
return `${a}\n${`
<div class="title t${b.depth}">
<div><a href="#bm-${b.index}">${b.raw.replace('\n', '')}</a></div>
<p>•</p>
</div>`}`
}, '')
return `<div class="bookmark">${html}</div>`
}
- 기존에 생성되었던 item.bookmark 리스트 데이터를 기반으로 북마크 코드를 생성한다.