Postprocessor

렌더링된 HTML을 후처리하는 모듈. 마크다운 렌더러(marked)가 생성한 표준 HTML에 위키 고유의 기능(private 링크, 이미지 경로, 접근성, 프레젠테이션 모드)을 입히는 역할이다.

ToC 해시 주입의 핵심 불변량은 인덱스 정합성이다: heading 배열의 i번째 원소가 toc 배열의 i번째 해시와 정확히 대응해야 한다. 길이가 다르면 잘못된 heading에 잘못된 id가 붙는다.

module postprocess

sig Heading {
  index: one Int
}

sig TocEntry {
  index: one Int,
  hash: one Hash
}

sig Hash {}

-- heading과 toc entry는 같은 인덱스로 1:1 매핑
fact indexAlignment {
  all h: Heading | one t: TocEntry | t.index = h.index
  all t: TocEntry | one h: Heading | h.index = t.index
}

-- 인덱스는 0부터 연속
fact contiguousIndices {
  all h: Heading | h.index >= 0
  all h: Heading | h.index < #Heading
}

-- 해시는 유일
fact uniqueHashes {
  all disj t1, t2: TocEntry | t1.hash != t2.hash
}

-- heading 수와 toc 수가 같으면 모든 heading에 정확히 하나의 해시가 대응
assert bijection {
  #Heading = #TocEntry implies
    all h: Heading | one t: TocEntry |
      t.index = h.index
}

-- 해시 충돌 없음
assert noHashCollision {
  all disj t1, t2: TocEntry | t1.hash != t2.hash
}

check bijection for 6 but 6 Int
check noHashCollision for 6

Private 링크 변환

Preprocessor가 존재하지 않는 페이지의 wikilink를 #private-link로 변환하면, postprocessor는 이를 클릭 불가능한 <span>으로 바꾼다. 이렇게 하면 방문자가 존재하지 않는 페이지로 이동하려다 404를 만나는 것을 방지하면서도, 해당 개념이 언급되었다는 맥락은 유지할 수 있다.

htmltocaddTocslideexpected
<a href="#private-link">Secret</a>
[]
false
false
<span data-link="private">Secret</span>

이미지 경로 보정

마크다운 원본에서 ![](photo.png) 형태로 참조된 로컬 이미지는 빌드 후 /data/ 디렉토리에서 서빙되므로, HTML의 src 경로에 /data/ 접두어를 추가한다. https://로 시작하는 외부 URL은 이미 절대 경로이므로 변환하지 않는다.

htmltocaddTocslideincludes
<img src="photo.png">
[]
false
false
/data/photo.png
htmltocaddTocslideexcludes
<img src="https://example.com/img.png">
[]
false
false
/data/https

테이블 래핑

모바일 화면에서 넓은 테이블이 레이아웃을 깨지 않도록 스크롤 가능한 wrapper로 감싼다. tabindex="0"은 키보드 사용자가 테이블 영역을 포커스하여 화살표 키로 스크롤할 수 있게 하는 접근성 속성이다.

htmltocaddTocslideincludes
<table><tr><td>cell</td></tr></table>
[]
false
false
class="table-wrapper"
<table><tr><td>cell</td></tr></table>
[]
false
false
tabindex="0"

Callout 변환

Obsidian 스타일의 callout 문법(> [!warning])을 data-callout 속성이 있는 HTML로 변환한다. CSS에서 callout 타입별 스타일링(아이콘, 배경색)을 적용하기 위해 blockquote 대신 구조화된 마크업을 생성한다.

htmltocaddTocslideincludes
<blockquote> <p>[!warning] Be careful</p></blockquote>
[]
false
false
data-callout="warning"

ToC 해시 주입

addToc이 true이면 H2~H6에 해시 기반 id를 추가한다. 이 id가 있어야 사이드바 목차에서 해당 섹션으로 스크롤 링크가 동작한다.

htmltocaddTocslideincludes
<h2>Hello</h2>
[{"level":2,"text":"Hello","hash":"hello-abc"}]
true
false
id="hello-abc"

슬라이드 모드

slide가 true이면 H2/H3 단위로 <section data-slide>를 삽입한다. 이 모드는 위키 문서를 프레젠테이션으로 사용할 때 활성화되며, CSS와 JavaScript가 각 section을 슬라이드로 렌더링한다.

htmltocaddTocslideincludes
<p>Intro</p><h2>S1</h2><p>C</p><h2>S2</h2>
[]
false
true
data-slide