본문 바로가기

Org Publish로 익스포트 자동화하기

기술적인 이야기/이맥스 2020. 1. 9.
반응형

Org Publish는 이맥스(Emacs)에서 Org Mode로 작성된 .org 문서들로 정적 웹사이트를 만들 수 있게 해주는 도구입니다. 쉽게 말해서 특정 디렉터리 안의 .org 파일들을 .html 파일로 익스포트 해서 원하는 디렉터리로 복사해 줍니다. 그리고 각종 css나 스크립트, 이미지 등의 파일도 자동으로 복사하는 등의 기능을 제공합니다. 제 관리가 안 되는 😭 깃헙 페이지도 이 Org Publish를 이용해 만들었습니다.

넣을 이미지가 마땅치 않아서 넣어보는 "실제로 퍼블리시한 결과물" :D

시작하기

설명을 시작하기에 앞서 아래와 같은 디렉터리에서 글을 쓴다고 가정합니다.

~/org/
    static/
        style.css
    img/
        someimage.jpg
    index.org
    foobar.org
    ...

이 가정에서는 ~/org 라는 디렉토리에서 .org 파일로 글을 작성합니다. 그리고 ~/org/static 에는 스타일 파일과 미래에 사용할지도 모를 자바스크립트 파일 등을 넣을 예정입니다. 그 외에 ~/org/img 디렉터리는 이름처럼 이미지만 넣을 예정입니다.

이 상태로 쓴 글을 아래와 같은 디렉터리 구조로 익스포트 하려는 것을 목적입니다.

~/web/
    static/
        style.css
    img/
        someimage.jpg
    index.html
    foobar.html
    ...

그냥 .org 파일이 .html로 바뀐 거 빼곤 이름과 배치가 동일합니다. 이대로 원하는 서버에 올리면 그대로 정적 웹사이트가 서빙되겠네요.

위의 목적에 맞게 설정을 해 봅시다.

 

필요한 모듈들

Org Publish는 다행히도 별도로 설치할 필요가 없는 확장입니다. 이맥스에 이미 빌트인 되어있기 때문입니다. 단지 몇 가지 모듈은 자동으로 로딩되지 않기 때문에 명시적으로 로드해야 됩니다.

(require 'ox-publish)
(require 'ox-html)
(require 'ox-rss)

여기서 마지막의 ox-rss 모듈은 RSS를 만들기 위한 것이 아니면 필요가 없는데 나중에 필요할지도 몰라서 일단 넣어둔 상태입니다.

이제 본격적으로 설정 스크립트를 작성해야 합니다.

기본 설정

org-publish-project-alist 라는 리스트가 Org Publish의 핵심입니다. 아래는 위의 목적대로 동작하도록 설정하는 스크립트입니다.

(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-sourcenil 이 아니기 때문에 익스포트는 html 형식으로 하게 됩니다.

위 두 부분이 중요합니다. 그 외에 여러 옵션이 있는데 이는 Org Mode의 Export 옵션입니다.

나머지 static과 img 프로젝트의 내용은 특정한 확장자의 파일들을 그대로 복사하도록 하기 위한 규칙들입니다. 특별하게 publishing-function 이 사용되었는데 여기서 사용된 org-publish-attachment 는 말 그대로 첨부용 파일을 그대로 복사하는 용도입니다.

 

Publish 해보기

편찬(publish)을 하기 위해서는 org-publish-all 함수를 호출하면 됩니다.

M-x org-publish-all

이 함수는 등록된 모든 프로젝트의 설정에 맞게 익스포트 하거나 추가하거나 수정한 파일을 복사합니다. 기본적으로 이 함수는 따로 단축키가 정의되어 있지 않으므로 별도로 정의하거나 위처럼 M-x 키를 누른 후 위 함수를 입력하면 실행시킬 수 있습니다. 만약 Doom Emacs라면 M-x 대신 SPC : 키를 사용하면 좀 더 편하게 커맨드를 검색해서 실행시킬 수 있습니다.

별 문제가 없다면 이 명령 만으로 목적대로 원하는 디렉터리에 html과 함께 이미지 등의 정적 파일들도 복사될 것입니다. 문제가 있다면... 그건 각 에러에 맞게 대응을 해야겠지요.

당연하겠지만 org-publish-all 함수나 혹은 아래에 소개할 org-publish 함수는 새로 추가된 파일이나 변경된 파일만 작업을 수행합니다.

프로젝트 그룹화하기

org-publish-all 함수의 경우 등록된 모든 프로젝트를 대상으로 익스포트 및 복사 작업을 수행합니다. 하지만 만약 필요에 의해 모든 것이 한 번에 가 아니라 필요한 것만 골라서 익스포트 하려면 org-publish 함수를 이용할 수 있습니다. 예를 들어 아래 커맨드를 실행시키면 doc라는 프로젝트만 publish 합니다.

(org-publish "doc")

다만 이렇게 하나하나 하기는 귀찮으니 이 항목의 제목처럼 몇몇 프로젝트를 그룹으로 묶어봅시다. 방법은 간단합니다. 지금까지 작성한 방식과 동일하게 역시 프로젝트를 만들되 아래처럼 만들 수 있습니다.

(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이라는 이름의 프로젝트는 doc, static, img라는 세 가지 컴포넌트로 구성되어 있다고 정의한 것입니다. 따라서 이 경우 아래 커맨드 한 줄이면 doc, static, img 세 프로젝트 모두 publish가 됩니다.

(org-publish "web")

참고로 Doom Emacs의 경우 SPC ; 단축키를 이용하면 위 커맨드를 쉽게 입력해서 실행시킬 수 있습니다. 이 단축키는 간단한 한 줄의 Lisp 코드를 입력하기 좋은 기능을 제공합니다.

전부 새로 퍼블리시 하기

org-publish 함수는 기본적으로 변경되거나 새로 추가된 파일만 업데이트를 하는데, 만약 설정을 바꾸는 바람에 모든 파일을 다시 익스포트 해야 한다면 다음 명령어 한 방에 해결이 될 수도 있습니다.

(org-publish "PROJECT_NAME" t)

첫 옵션으로 nil이 아닌 값이 들어오게 되면 파일의 변동 여부를 검사하지 않고 지정된 퍼블리시 함수를 이용해 퍼블리시를 하게 됩니다.

728x90
반응형

댓글