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 6Private 링크 변환
Preprocessor가 존재하지 않는 페이지의 wikilink를 #private-link로 변환하면,
postprocessor는 이를 클릭 불가능한 <span>으로 바꾼다.
이렇게 하면 방문자가 존재하지 않는 페이지로 이동하려다 404를 만나는 것을 방지하면서도,
해당 개념이 언급되었다는 맥락은 유지할 수 있다.
| html | toc | addToc | slide | expected |
|---|---|---|---|---|
<a href="#private-link">Secret</a> | [] | false | false | <span data-link="private">Secret</span> |
이미지 경로 보정
마크다운 원본에서  형태로 참조된 로컬 이미지는
빌드 후 /data/ 디렉토리에서 서빙되므로, HTML의 src 경로에 /data/ 접두어를 추가한다.
https://로 시작하는 외부 URL은 이미 절대 경로이므로 변환하지 않는다.
| html | toc | addToc | slide | includes |
|---|---|---|---|---|
<img src="photo.png"> | [] | false | false | /data/photo.png |
| html | toc | addToc | slide | excludes |
|---|---|---|---|---|
<img src="https://example.com/img.png"> | [] | false | false | /data/https |
테이블 래핑
모바일 화면에서 넓은 테이블이 레이아웃을 깨지 않도록
스크롤 가능한 wrapper로 감싼다. tabindex="0"은 키보드 사용자가
테이블 영역을 포커스하여 화살표 키로 스크롤할 수 있게 하는 접근성 속성이다.
| html | toc | addToc | slide | includes |
|---|---|---|---|---|
<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 대신 구조화된 마크업을 생성한다.
| html | toc | addToc | slide | includes |
|---|---|---|---|---|
<blockquote>
<p>[!warning] Be careful</p></blockquote> | [] | false | false | data-callout="warning" |
ToC 해시 주입
addToc이 true이면 H2~H6에 해시 기반 id를 추가한다.
이 id가 있어야 사이드바 목차에서 해당 섹션으로 스크롤 링크가 동작한다.
| html | toc | addToc | slide | includes |
|---|---|---|---|---|
<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을 슬라이드로 렌더링한다.
| html | toc | addToc | slide | includes |
|---|---|---|---|---|
<p>Intro</p><h2>S1</h2><p>C</p><h2>S2</h2> | [] | false | true | data-slide |