一鳞半甲

醉心、探索与收获
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

增强org-mode的发布功能

Posted on 2012-09-29 22:54  麦满屯  阅读(3565)  评论(0编辑  收藏  举报

org-mode是极佳的个人事务记录工具,但在目前org-mode中集成的org-publish功能在实现发布功能主要针对每一个独立的ORG文件进行。使用org-mode来组织个人blog或wiki显得相对离散。然而org-mode中提供的各种书写链接的语法,也让手工组织blog或wiki存在那么一种可能性。通过恰当的CSS,可以塑造优美而易于阅读的网站。因此,增强org-mode的发布功能成为我近一段时间关注的一个问题。

要解决这个问题通常来说有一下两个途径:

  1. 自己写emacs-lisp脚本

    这种方式对于已经了解甚至精通了emacs-lisp的朋友来说可能不是什么大事,但是对于现阶段的我来说,还只能混乱的阅读一些代码,距离自己编写代码差的还很远。此外,难道这个问题世界上没有其他人想到吗?还是应该尽可能的避免“重新发明轮子”吧。

  2. 寻找已经发明了的“轮子”

    泡在stackoverflow几天之后,我找到了三只轮子:

    • 使用org与ruby的结合体

      目前org可以喝Octopress等相结合实现blog功能。对于我来说,由于我日常使用的操作系统在Windows上,而在Windows上搭建Ruby环境是一件让人痛苦的事情,此外要使用好这种结合体,不可避免要多少了解一些Ruby的概念,短期内我还不想考虑这种技术组合。

    • o-blog

      o-blog1是一套emacs-lisp开发的将org-mode发布为静态HTML文件的Emacs扩展功能。emacs通过简单配置可以实现将org文件发布为一套完整的博客。从o-blog的官方网站可以看到,o-blog支持大多数现代浏览器技术,包括:

      • Bootstrap 2
      • Font-Awesome support
      • LESS CSS support
      • jQuery support
      • HTML5 / CSS3 ready
      • Custom Google web fonts support
      • Responsive design for many devices

      在博客功能方面,也支持生成Tag云、归档等。o-blog的功能全面,看上去很美——哦,这就是我想要的!

    • 自组织org文件实现功能

      自己组织org文件,手工实现各个页面的链接关系的组织,在一些情况下(特别是在内容比较少的时候)会让人获得更大的控制力。有人通过组织org文件,利用org-publish功能实现了搭建个人网站的目标2。通过他贡献的org文件,我看到了另一种可能——通过组织org文件以及相应的css文件构建完整个人网站的目标。由于很多内容需要手工处理,因此可以说是一种“刀耕火种”的方法,但也透露着一分“原始的”粗犷美。

1 功能完备的o-blog不是我的菜

看完o-blog的功能特性列表,感觉真的很好。下载1了源代码后,按照手册很快就完成了配置。emacs这时可以使用新的命令“org-publish-blog”来生成页面。使用Example目录中的simple.org文件生成了一个完整的意义上的网站。生成的页面很华丽,但我很快发现了问题:

  1. o-blog使用单一org文件生成blog网站

    o-blog没有利用org-mode的Publish机制,仅针对单一文件进行处理。那这样的话,当存储的blog多了该怎么办?使用单一文件组织整个网站,在我看来不是一个很好的方式。是不是我还有什么问题没有弄清楚呢?

  2. o-blog对我有进一步的web开发技能要求

    o-blog引入了bootstrap、LESS等较新的WEB开发技术。要充分利用o-blog的功能,设计一套全新的页面模板,需要了解Bootstrap、LESS等技术,这对于我来说门槛有些高。如果抛弃这些特性重头书写页面,也让我感觉浪费。也许,过不了多久,当我充分了解了Bootstrap和LESS后,重新再看o-blog会有完全不一样的感觉。

  3. o-blog增加了页面生成控制属性

    o-blog为能够实现blog中诸如独立页面(Page)、Bootstrap的栅格控制、Blog记录等在org文档中增加了很多的控制属性。从样例中可以看出来,文档内容和控制属性混杂在一起。没有实现内容与表现的区隔。这种实现让我感觉到了一种“bad smell”,o-blog的这种设计我不喜欢。

  4. o-blog的文档还有待进一步增强

    目前o-blog的文档还不是很全面。现有的样例和文档可以解决简单的使用问题,但是如果想进行深入的调整和使用将不得不阅读emacs-lisp代码。这无形中提升了使用o-blog的使用门槛。

o-blog在最初看见的一刹那,给了我一种“惊艳”的感觉,但是我觉得她不是我的菜。也许当我有了更多的知识积淀,重新审视这段文字的时候,会有新的认识。

2 自组织org文件更自由,但需要按照自己的需求调整

其实org-mode已经含有了一套相对完整的发布指令。充分使用org-mode内置的功能,应该可以生成一个完整的网站。所需要的就是一套经过良好设计的“网站组织结构”。一些使用org-mode的Fans共享了自己的一些解决方案,其中就有一套网站组织结构模板2可供借鉴。

在这个模板中,包含如下内容(具体内容请参看本文附录):

Makefile
用于简化org发布流程,提升发布速度
CSS文件
用于控制生成的网站显示
header.org
生成通用的头文件,此文件可以用于生成网页的导航菜单、固定显示的网页标题等。
publish-config.el
利用org-mode的内置org-publish-project-alist变量控制生成网站。

这套模板让我有了一个新的思路,利用这套组织结构,完成一个网站是非常有可能的。从org-mode的官方网站,我们可以看到由全世界诸多org-mode的粉丝共同创造书写的worg就是采用类似这种方式来实现的。

通过访问org-mode的Git repo,可以得到worg的org源文件。目前worg的org源文件已经达到了惊人的26MB大小,这足以显示这种组织方式的在支持大量数据显示上的优越性。研究这些源文件,就可以了解别人是如何通过组织org文件,并生成一个组织良好的网站的。

3 结论

自组织org文件能够给人更多的控制空间。通过将内容组织进入不同的org文件,可以在大数据量的情况下保持网站整体的有效维护。因此,o-blog暂时还是小微型项目的可选发布方案。对于我希望使用HTML格式组织自己的知识库来说,自组织org文件应该更加符合我的需求。

4 附录

  • Makefile源代码
    EMACS=emacs
    ORG_CONFIG_FILE=publish_config.el
    EMACS_OPTS=--batch --eval "(load-file \"$(ORG_CONFIG_FILE)\")" -f myweb-publish
    
    DEST_HOST='myhost.com:public_html/'
    OUTPUT_DIR=output
    
    all: html upload
    
    html:
            @echo "Generating HTML..."
            @mkdir -p $(OUTPUT_DIR)
            @$(EMACS) $(EMACS_OPTS)
            @echo "HTML generation done"
    
    upload: clean_bak
    
            @cd $(OUTPUT_DIR) && scp -r . $(DEST_HOST) && cd ..
    
    clean: clean_output clean_bak
    
    clean_output:
            @rm -rf $(OUTPUT_DIR)
    
    clean_bak:
            @find . | grep ~$$ | while read l; do rm $$l; done     
    
  • header.org
    Main | Add here more links or any other stuff
    
    
    #+BEGIN_HTML
    
    <p>Write here whatever HTML code you need to include in every
    page. For instance, Javascript stuff to count visits.</p>
    
    #+END_HTML 
    
    
  • publish-config.el
         (add-to-list 'load-path "~/.emacs.d/utils")
    (add-to-list 'custom-theme-load-path "~/.emacs.d/themes")
    
    (require 'org-publish)
    (require 'htmlize)                      
    
    (setq org-publish-project-alist
                '(
    
                  ;; These are the main web files
                  ("org-notes"
                    :base-directory "/cygdrive/d/HOME/web/" ;; Change this to your local dir
                    :base-extension "org"
                    :publishing-directory "output"
                    :recursive t
                    :publishing-function org-publish-org-to-html
                    :headline-levels 4             ; Just the default for this project.
                    :auto-preamble t
                    :section-numbers nil
                    :headline-levels 3
                    :table-of-contents nil
                    :style "<link rel='stylesheet' type='text/css' href='css/style.css' />"
                    :style-include-default nil
                    )
    
                  ;; These are static files (images, pdf, etc)
                  ("org-static"
                    :base-directory "/cygdrive/d/HOME//web/" ;; Change this to your local dir
                    :base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg\\|swf\\|txt\\|asc"
                    :publishing-directory "output"
                    :recursive t
                    :publishing-function org-publish-attachment
                    )
    
                  ("org" :components ("org-notes" "org-static"))
                  )
                )
    
    (defun myweb-publish nil
         "Publish myweb."
         (interactive)
         (org-publish-all))