Org 문서
Org 문서는 이맥스 사용자들 사이에서 킬러앱 중 하나인 org-mode로써
유명하지만 일반 사용자에게 인지도는 현저하게 낮다. 최근에는 vscode나
vim에도 org 문서를 읽을 수 있도록 확장프로그램이 나왔다고 하지만
완전하게 org 문서를 지원하지도 못할 뿐더러 syntax highlighting 정도에
그치는 정도다.
낮은 인지도
개인적으로 생각하는 org 문서의 장점이자 단점은 메타 데이터를 이용하기
위한 문법이다. org 문서는 :CATEGORY:, :PROPERTIES:, :BLABLA: 와
같이 텍스트 문서에 추가적으로 속성을 정의할 수 있어 이맥스의 각종
패키지에서는 문서 메타 정보를 Elisp 함수 인자로써 활용한다. 마크다운이
간단한 문법으로 다양한 텍스트 렌더링에 초점을 맞췄다면 org 문서는
렌더링 정보 보다는 텍스트 정보에 추가되는 메타정보에 초점을 두고
있다는 것이 차이점이다.
낮은 가독성
하지만 이러한 기능적 장점은 가독성 문제를 낳았다. 정렬되지 않은
제목들과 문장들이 어떤 장절에 속해있는지 알 수 없을 정도로 장절 깊이가
많아지다보면 문서 형식 문법에 의해 문맥들이 분절돼 버린다. 더군다나
이맥스에서는 렌더링보다는 데이터를 어떻게 처리할 것인지에 초점을
맞추고 있어 가독성을 위한 패키지들 (org-bullet-mode,
org-modern-mode)은 그렇게 많지도 않고 그러한 패키지들도 불필요한
문법 요소들 (특히 aesterisk)을 제거해주지 않는다.
org-num-mode
org-num-mode는 장절 정보를 헤더 텍스트 앞쪽에 추가해준다. 하지만
이에 대한 정렬 문제는 해결해주지 못하기 때문에 가독성 측면에서 달라진
게 없다. 이를 해결하기 위해 왼쪽 여백 값(left-margin-width)을
이용한다.
(use-package org-num
:demand t
:preface
(defun my-org-num-margin-format (number)
"Customized org-num-mode's org-num-format-function to display the
number in left margin."
(let* ((num-str (mapconcat #'number-to-string number "."))
(margin-text (concat " " num-str)))
(propertize " " 'display
`((margin left-margin)
,(propertize margin-text 'face 'shadow)))))
:custom
(org-num-format-function #'my-org-num-margin-format)
:hook (org-mode))
그리고 font-lock 기능을 이용해 불필요한 aeterisk와 #+begin_ 들을 대체한다.
(defvar org-hide-stars-rule
'(("^\\*+[ \t]+" . (0 '(face nil display ""))))
"font-lock rule to hide heading stars in org-mode.")
(defvar org-replace-blocks-rule
'(("^[ \t]*\\(#\\+[bB][eE][gG][iI][nN]_[sS][rR][cC]\\)"
(1 '(face font-lock-comment-face display "[code]")))
("^[ \t]*\\(#\\+[eE][nN][dD]_[sS][rR][cC]\\)"
(1 '(face font-lock-comment-face display "[/code]")))
("^[ \t]*\\(#\\+[bB][eE][gG][iI][nN]_[qQ][uU][oO][tT][eE]\\)"
(1 '(face font-lock-comment-face display "[quote]")))
("^[ \t]*\\(#\\+[eE][nN][dD]_[qQ][uU][oO][tT][eE]\\)"
(1 '(face font-lock-comment-face display "[/quote]"))))
"font-lock rule to replace code/quote blocks in org-mode.")
(define-minor-mode org-view-mode
"My custom org-view-mode."
:init-value nil
:lighter " Org-View*"
(if org-view-mode
(progn
(add-to-list (make-local-variable 'font-lock-extra-managed-props) 'display)
(font-lock-add-keywords nil org-hide-stars-rule 'append)
(font-lock-add-keywords nil org-replace-blocks-rule 'append)
(setq-local left-margin-width 8)
(setq-local fringes-outside-margins 8))
(progn
(font-lock-remove-keywords nil org-hide-stars-rule)
(font-lock-remove-keywords nil org-replace-blocks-rule)
(setq-local left-margin-width 0)
(setq-local fringes-outside-margins 0)))
(when font-lock-mode
(if (fboundp 'font-lock-flush)
(font-lock-flush)
(with-no-warnings (font-lock-fontify-buffer)))))
이제 여백으로 정렬되고 불필요한 형식 문법 기호들이 사라진 상태로 문서가 렌더링 된 것을 확인할 수 있다. 문서 자체의 내용이 바뀌는 것이 아니라 렌더링만 바뀌는 것이므로 문서 파싱 자체에는 영향을 주지 않는다.