- Sphinx의 reStructured Text(rST) 는 Markdown보다 배우기 어렵지만, 책처럼 규모가 큰 문서에서 구조와 출력 형식을 세밀하게 제어하기 쉬움
- Markdown은 HTML을 가볍게 쓰는 표기에 가깝고, rST는 추상 문서 트리를 중심으로 지시자, 노드, 렌더러를 조합해 새 문서 객체를 추가할 수 있음
- Sphinx는 렌더링 전에 doctree를 변환하므로 교차 참조, 출력 형식별 처리, 특정 빌드 단계의 변환 같은 작업을 문서 시스템 안에서 다룰 수 있음
- Logic for Programmers에서는 연습문제와 해설을 원문 가까이에 작성한 뒤, EPUB와 LaTeX 출력에서 위치와 표시 방식을 바꾸는 커스텀 확장을 사용함
- 단순 Markdown은 통일된 확장 문법과 렌더링 전 변환 지원이 부족해, 문서 생성기가 별도 전처리로 우회할수록 도구 지원과 확장성이 약해짐
rST를 선택한 이유
- Logic for Programmers 새 버전은 Sphinx로 작성한 두 번째 책이며, 이전 작업인 새 Learn TLA+도 Sphinx를 사용함
- Sphinx는 reStructured Text를 사용하고, rST는 Markdown보다 학습 곡선이 가파름
- Markdown으로 여러 권의 책을 쓴 뒤 더 나은 도구가 필요해 rST로 전환함
- rST 자체는 Sphinx와 독립적이지만, 실제로는 Sphinx 때문에 rST를 쓰는 경우가 많아 둘을 함께 다룸
Markdown과 rST의 구조 차이
- 가장 큰 차이는 Markdown이 HTML 경량 표기에 가깝고, rST는 추상 문서 트리를 만드는 중간 규모 표기라는 점임
- Markdown의 이미지 문법은 간단한 변환만으로
<img alt="alttext" src="example.jpg"/>같은 HTML로 바뀔 수 있음- 최신 Markdown 엔진도 중간 표현으로 파싱하는 경우가 많지만, 기본 성격은 가벼운 HTML 표기에 가까움
- rST의 이미지는
.. image::지시자로 표현됨- Sphinx는 등록된 지시자 핸들러를 찾아
ImageDirective.run을 실행함 - 실행 결과는
alt필드를 가진image_node같은 노드 객체가 됨 - 전체 doctree 처리가 끝나면 HTML Writer가
image_node렌더링 함수를 찾아 HTML 태그를 출력함
- Sphinx는 등록된 지시자 핸들러를 찾아
- rST 방식은 구현과 문법이 더 복잡하고 Markdown보다 보일러플레이트가 많지만, 이미지도 다른 지시자와 같은 확장 메커니즘으로 다뤄짐
새 문서 객체를 추가하는 방식
- rST/Sphinx에서는 새 텍스트 객체를 확장으로 추가할 수 있음
- 예를 들어
<image>대신<figure>와<figcaption>을 만들고 싶다면, 기본 Markdown에서는 HTML을 직접 삽입해야 함 - Sphinx에서는 새
figure지시자를 등록하는 방식으로 처리함FigureDirective가ImageDirective를 상속해 이미지 처리 대부분을 재사용할 수도 있음
- 지시자 등록, 노드 생성, 빌더별 렌더러 등록이라는 패턴이 모든 확장에 동일하게 적용됨
렌더링 전 doctree 변환
- Sphinx는 렌더링 전에 doctree 변환을 수행할 수 있음
- 문서 간 교차 참조도 이 기능으로 처리됨
- 한 문서에
foo앵커가 있고 다른 문서에:ref:\image <foo>``가 있으면, Sphinx가 후처리 단계에서 올바른 URL을 삽입함
- 한 문서에
- 변환 코드는 빌드 과정 안의 일급 기능처럼 다뤄짐
- HTML 출력일 때만 특정 변환을 적용할 수 있음
- 특정 빌드 단계에서 변환을 실행할 수 있음
- 실행하고 싶지 않은 내장 변환을 제거할 수도 있음
- 모든 문서에 이런 강력함이 필요한 것은 아니며, Markdown은 가볍고 이식성이 좋아 널리 쓰임
연습문제와 해설 확장 사례
- Logic for Programmers는 수학에 가까운 책이라 독자용 연습문제가 필요함
- 작성할 때는 연습문제와 해설을 문서 안에서 가까이 두는 편이 쉽지만, 독자에게는 해설이 책 뒤쪽에 나타나야 함
- 요구사항은 출력 형식마다 달랐음
- 연습문제와 해설을 서로 링크해야 함
- 인쇄 가능성을 고려해 PDF에는 페이지 참조도 필요함
- LaTeX/PDF 출력과 EPUB 출력에서 렌더링 방식이 달라야 함
- 이를 위해
exercise,solution,solutionlist를 처리하는 커스텀 Sphinx 확장을 작성함 - HTML 디버깅 출력에서는 연습문제와 해설을 인라인으로 렌더링함
- EPUB와 LaTeX 생성에서는 전체 doctree를 만든 뒤 변환을 실행함
- 원래 위치에 있던 모든
solution_node를solutionlist아래로 이동함 - 각 연습문제에는 새 해설 위치로 가는 참조 노드를 붙임
- 각 해설에는 원래 연습문제로 돌아가는 참조 노드를 붙임
- 원래 위치에 있던 모든
- LaTeX 빌더는 연습문제와 해설을 answers environment로 감쌈
- EPUB 빌더는 해설을 popup footnote로 렌더링함
- 이 구조는 책의 무료 샘플을 만들 때도 도움이 됨
- 무료 샘플 뒤쪽에는 전체 책의 해설이 아니라 샘플에 포함된 부분의 해설만 들어감
문법 취향과 대안
- rST에 대한 가장 흔한 반대는 문법이 못생겼다는 점임
- 도구가 보기 싫어서 쓰지 않는 것도 충분히 가능한 선택이며, Lisp를 받아들이기 어려운 이유도 같은 취향 문제로 볼 수 있음
- 대안으로 asciidoc, MyST, Typst, Pollen, pandoc-extended markdown이 있음
- 요지는 Sphinx/rST가 대규모 문서화에 예외적으로 좋다는 것이 아니라, 단순 Markdown이 대규모 문서화에 예외적으로 부적합하다는 점임
Markdown 기반 생성기의 한계
- 단순 Markdown에는 통일된 확장 문법이나 렌더링 전 변환에 대한 네이티브 지원이 없음
- 많은 Markdown 기반 문서 생성기는 새 사용 사례를 지원하려고 자체 전처리 단계를 덧붙임
- 이런 방식은 대체로 동작하지만, Markdown 안에서 처리하는 것이 아니라 Markdown 주변에서 우회하는 구조가 됨
- 그 결과 기능의 강력함에 한계가 생기고, 프로그래머용 도구가 그 변형을 잘 이해하기 어려움
- Markdown과 rST용 LSP 및 treesitter는 있지만, gitbook-markdown, md-markdown, leanpub-markdown용으로 같은 수준의 도구를 기대하기 어려움
- rST의 못생긴 문법은 오히려 구문 트리가 풍부하다는 장점으로 작용할 수 있음
- 특정
todo지시자의 본문만 바꾸는 treesitter 쿼리가 가능함 - 이는 rST 구문 트리가 Markdown 구문 트리보다 더 풍부하기 때문에 가능함
- 특정
Logic for Programmers 업데이트
- Logic for Programmers는 형식 논리가 일상적인 소프트웨어 엔지니어링에 어떻게 유용한지 다루는 책임
- 책은 기본적인 수학 개요로 시작해 속성 테스트, 데이터베이스 제약, 결정표 등 8가지 응용으로 이어짐
- 아직 알파 단계지만 20,000단어 규모이며, 독자 피드백을 받고 있음