심심한 개발자의 취미생활

2. 블로그 만들기 - 마크다운 변환

블로그 만들기 핵심 기능 2번째 마크다운 변환 관련 이다. 정확하게 말하자면 마크다운으로 작성된 포스팅을 HTML 코드로 변환하며 HTML 페이지를 생성하는 과정을 의미한다.

작업 내용

작업 내용은 다음과 같이 3단계를 거치게 된다. 그중 이 포스팅에서는 두번째 과정만을 다루고 더 상세한 내용은 다음 포스팅에서 다룬다.

  1. 첫번째는 앞서 포스팅한 트리 탐색을 통한 네비게이션 코드의 생성이다.
  2. 두번째는 탐색을 진행하는 과정에서 얻어진 포스팅 파일의 마크다운 데이터를 HTML 코드로의 변환이다
    • 해당 과정에서는 컨텐츠 내부에 작성되어 있는 메타 데이터를 통해 prev/next page의 이동과 페이지별 css 변경을 위한 메타 데이터가 생성된다.
  3. 마지막으로 제작된 네비게이션과 포스팅 내용을 통합하여 완성된 HTML 페이지 코드의 제작과 CSS 변경, .html 파일 생성 작업이다.

마크다운과 HTML의 변환

마크다운이란?

우선 마크다운은 텍스트 기반의 마크업 언어로 쉬운 읽기과 쓰기를 지원하며 HTML과 대응하여 변환 가능한 문법이 특징이다. 특수기호와 문자를 이용한 매우 간단하고 직관적인 문법을 사용하여 빠르게 컨텐츠를 작성할 수 있다. 다만 마크다운 언어는 국제적인 표준이 없기 때문에 변환 툴이나 사이트에 따라 결과물이 달라 질 수 있으며 HTML 보다는 세부적인 부분에 대해서는 표현이 불가능 하다.

변환 모듈

나는 다양한 마크다운 변환 모듈를 사용해 본 결과 최종적으로 'marked' 모듈를 사용하고 있다. 대부분의 모듈이 비슷한 성능을 제공하지만 선택한 이유는 우선 사용법이 간단하고, 마크다운 문서 내부에서 HTML 코드를 지원한다는 점이다. 마크다운은 HTML과 대응하여 변환이 가능하지만 앞서 말한것과 같이 HTML 처럼 세부적인 디자인은 어려운 부분이 많기에 마크다운 문서에서 HTML 코드를 작성하는 경우가 종종 있다. 타 모듈에서는 HTML 태그의 '<', '>'를 특수기호로 인식해 HTML 문자 엔티티로 변환해버려 HTML 태그를 사용할 수 없었으나 'marked'에서는 정상적으로 변환이 가능하여 선택하게 되었다.

변환 코드

  • 사실 변환 코드는 너무나 간단하다. 'fs.readFile()'함수를 이용하여 마크다운 파일의 내용을 읽어와 'marked.parse()'를 사용하여 html 코드를 생성한다.
const markdown = fs.readFileSync('index.md', 'utf8')
const html = marked.parse(markdown)
  • 하지만 마크다운 만으로는 포스팅은 가능하지만 블로그의 기능을 구현하기 위해서는 다양한 이벤트와 기능적인 코드가 필요하다. 그러한 작업을 위한 메타데이터와 일부 코드의 수정이 위 코드에서 함께 이루어진다.
let markdown = fs.readFileSync(`${root}/${v}`, 'utf8').trim()

// 마크다운에서 코드 작성 문법인 '```' 문자열의 모든 위치를 리스트화
const point = [...markdown.matchAll(/```/g)].map((v) => { return v.index })

// 찾아낸 '```' 문자열 위치를 활용하여 내부 코드 추출
const tempData = markdown.substring(point[0], point[1] + 3)

// JSON으로 작성된 추출한 코드 데이터를 이후 블로그 페이지 생성을 위한 메타 데이터로 활용
convertData['metaData'] = JSON.parse(tempData.replaceAll('```json', '').replaceAll('```', ''))

// 변환된 HTML 코드에서 이미지와 같이 외부 파일을 참조하는 경우 배포/개발환경에 따른 알맞은 위치의 폴더를 참조하도록 코드 수정
convertData['mdFile'] = marked.parse(markdown.replace(tempData, '')).replaceAll(/(?<=")[^"]*(?=image)/g, `${json[process.env.NODE_ENV].url}/`)

개선될 변환 코드

사실 나의 블로그를 만드는데 가능한 외부 라이브러리를 사용하는 것을 지양하고 싶다. 차후 마크다운의 변환 모듈을 직접 개발할 계획이며 위코드에서 덕지덕지 붙어 있는 'replaceAll' 코드들을 조금 유지보수가 간편한 모듈화를 이루고자 한다.