Org Publish로 익스포트 자동화하기
≡ 목차 (Table of Contents)
Org Publish는 Emacs에서 Org Mode로 작성된 .org 문서들로 정적 웹사이트를 만들 수 있게 자동화 해주는 도구다. 특정 디렉토리 안의 .org
파일들을 .html
파일로 익스포트 해서 원하는 디렉터리로 복사해 준다. 그리고 각종 CSS나 스크립트, 이미지 등의 파일도 자동으로 복사해 준다.
시작하기
설명을 시작하기에 앞서 아래와 같은 디렉터리에서 글을 쓴다고 가정하자.
~/org/ static/ style.css img/ someimage.jpg index.org foobar.org ...
위 구조는 .org
파일로 글을 쓸 ~/org
디렉터리, CSS나 Javascript 파일을 넣기 위핸 ~/org/static
디렉터리, 그리고 이미지를 넣기 위핸 ~/org/img
디렉터리로 구성되어 있다고 치자.
이제 위의 디렉터리 구조를 아래와 같은 디렉터리 구조로 익스포트 하는 것을 목적으로 삼자.
~/web/ static/ style.css img/ someimage.jpg index.html foobar.html ...
.org
파일 확장자가 .html
로 바뀐 거 빼곤 이름과 배치가 동일하다. 즉 이대로 원하는 서버에 올리면 그대로 정적 웹사이트가 서빙될 수 있는 형태다.
이제 이 목적에 맞게 Org Publish를 설정해보자.
필요한 모듈들
Org Publish는 다행히도 별도로 설치할 필요가 없다. Emacs이맥스에 이미 빌트인 되어있는 Org Mode의 모듈이기 때문이다. 다만 필요한 몇몇 모듈은 자동으로 로딩되지 않기 때문에 명시적으로 로드해야 할 수도 있다.
(require 'ox-publish) (require 'ox-html) (require 'ox-rss)
참고로 마지막의 ox-rss
모듈은 RSS를 만들기 위한 것이 아니면 필요가 없는데 나중에 필요할지도 몰라서 일단 넣어둔 상태다. 따라서 이 글에서는 꼭 필요하진 않다.
이제 본격적으로 설정 스크립트를 작성해보자.
기본 설정
Org Publish의 프로젝트 설정은 org-publish-project-alist
라는 리스트로 대부분 설정할 수 있다. 아래는 위의 목적대로 작성한 스크립트다.
(setq org-publish-project-alist '(("doc" :base-directory "~/org" :base-extension "org" :publishing-directory "~/web/" :recursive t :with-toc nil :with-title t :with-date t :section-numbers nil :html-doctype "html5" :html-html5-fancy t :html-head-include-default-style nil :html-head-include-scripts nil :htmlized-source t) ("static" :base-directory "~/org/static" :base-extension "css\\|js\\|png\\|jpg\\|jpeg\\|gif" :publishing-directory "~/web/static" :recursive t :publishing-function org-publish-attachment) ("img" :base-directory "~/org/img" :base-extension "png\\|jpg\\|jpeg\\|gif" :publishing-directory "~/web/img" :recursive t :publishing-function org-publish-attachment)))
위 설정에는 doc
, static
, img
의 세 가지 프로젝트가 정의되어 있다. 일단 이름은 마음대로 지을 수 있지만 가급적 디렉터리 이름과 동일하게 지었다.
doc
프로젝트의 내용은 .org
파일들이 위치하는 디렉터리에 대한 설정이다.
base-extension
에 명시된 확장자의 파일들을publishing-directory
에 익스포트한다.htmlized-source
가nil
이 아니기 때문에 익스포트는 HTML 형식으로 한다.
그 외에 여러 옵션이 있는데 이는 Org Mode의 Export 옵션 그 자체이기도 하니 일단 생략한다.
나머지 static
과 img
프로젝트의 내용은 특정한 확장자의 파일들을 그대로 복사하도록 하기 위한 규칙이다. publishing-function
에 명시한 org-publish-attachment
함수는 말 그대로 첨부용 파일을 그대로 복사하는 용도다.
Publish 해보기
이제 실제로 편찬(publish)을 해보자. 단순하게 org-publish-all
함수를 실행시키면 된다.
M-x org-publish-all
참고로 Doom Emacs의 경우 M-x
대신 SPC :
단축키를 이용해도 동일하다.
어쨌거나 이 함수는 등록된 모든 프로젝트의 설정에 맞게 익스포트 하거나 추가하거나 수정한 파일을 자동으로 복사한다.
별 문제가 없다면 이 명령 만으로 목적대로 원하는 디렉터리에 HTML 파일들과 함께 이미지 등의 정적 파일들도 복사된다.
당연하겠지만 org-publish-all
함수나 혹은 아래에 소개할 org-publish
함수는 새로 추가된 파일이나 변경된 파일만 작업을 수행한다.
프로젝트 그룹화하기
org-publish-all
함수의 경우 등록된 모든 프로젝트를 대상으로 익스포트 및 복사 작업을 수행한다. 하지만 만약 필요한 일부 프로젝트만 골라서 익스포트 하려면 org-publish
함수를 이용할 수 있다. 예를 들어 아래 커맨드를 실행시키면 doc
프로젝트만 publish 된다.
(org-publish "doc")
참고로 Doom Emacs의 경우는 SPC ;
를 누르면 Emacs Lisp 코드를 즉석에서 입력해서 실행시킬 수 있는 프롬프트가 뜨니 여기서 위 코드를 입력해보자.
이렇게 개별 프로젝트를 출력할 수도 있는데, 프로젝트를 그룹으로 묶으면 한 프로젝트의 연관 프로젝트도 모조리 자동으로 출력되게 할 수 있다.
(setq org-publish-project-alist '(("doc" :base-directory "~/org" ;; ... ) ("static" :base-directory "~/org/static" ;; ... ) ("img" :base-directory "~/org/img" ;; ... ) ("web" :components ("doc" "static" "img"))))
생략한 코드가 많은데, 그냥 앞서 설정했던 내용에서 마지막 web
을 정의하는 한 줄이 더 추가되었다고 치자. 이 코드의 의미는 web
프로젝트는 doc
, static
, img
라는 세 가지 컴포넌트로 구성되어 있다라는 것이다.
이제 아래 커맨드 한 줄이면 doc
, static
, img
세 프로젝트 모두 publish 된다.
(org-publish "web")
이런 식으로 그룹화를 할 수 있다. 하지만 꼭 할 필요 없이 위의 org-publish-all
함수를 사용하는 게 더 편할 수 있다.
전부 새로 퍼블리시 하기
굳이 그룹화를 소개한 것은 이 항목 때문이다. org-publish-all
함수는 변경되거나 새로 추가된 파일만 업데이트를 하는데, 만약 설정을 바꾸는 바람에 모든 파일을 다시 익스포트해야 한다면 이 함수가 좀 불만스러울 수 있다.
대신 이 경우 다음 명령어 한 방에 해결이 될 수도 있다.
(org-publish "PROJECT_NAME" t)
org-publish
함수의 두 번째 매개변수로 nil
이 아닌 값이 들어오게 되면 파일의 변동 여부를 검사하지 않고 지정된 퍼블리시 함수를 이용해 퍼블리시를 하게 된다.
만약 프로젝트를 그룹으로 묶어뒀다면 이 커맨드 하나로 모든 것을 강제로 새로 익스포트 할 수 있게 된다.
물론 이 기능을 자주 쓸 일은 없을지도 모르고, 또 .org
파일을 HTML로 출력하는 작업이 가장 자주 필요할거라 그룹화가 꼭 필요한 건 아니다. 편한대로 사용하자.