EGO icon indicating copy to clipboard operation
EGO copied to clipboard

EGO is a static site generator that depends on Emacs, Git and Org-mode.

#+TITLE: README of EGO-lite #+AUTHOR: Feng Shu, Kuangdash, Darksun #+EMAIL: [email protected] #+DATE: 2015-07-02

[[https://melpa.org/#/ego][file:https://melpa.org/packages/ego-badge.svg]]

  • 介绍 :PROPERTIES: :ID: efd66v31lbi0 :END:

EGO 的简化版本,去掉了很多感觉不必要的东西,跟之前的版本比有如下改动

** 不保存上一次发布的项目 合并了 =ego-current-project-name= 和 =ego-default-project-name= 这两个变量,目前 =ego-current-project-name= 的作用就是以前的 =ego-default-project-name=.

而ego不再保存上一次发布的项目是什么,因为上一次发布的项目不见得就是这次要发布的项目,我觉得保存上一次发布项目反而使代码变得复杂。 ** 用另一个单独的目录存储html结果 在同一个目录里面通过不同分支存储html和org文件,意味着要使用一个临时目录保存html再拷贝回原目录,我觉得这个拷贝的操作完全是费操作,而且当博客内容很多的时候拷贝速度也不快。

另外在目录中切换分支也容易把仓库搞乱,索性简单点使用单独的一个目录来存储html,该目录和原目录分别对应远程仓库中的不同分支。这样不仅节省了拷贝操作,而且无需在进行分支的切换了。 ** 发布前先git pull同步一次上游仓库 有的时候会在另一台机器上写博客,而在本机上忘了同步上游仓库导致合并仓库时出现冲突 ** 去掉Emacs中的静态web服务 根据UNIX哲学,只做一件事情,把这件事情做好。我觉得EGO只需要实现把org文件转换成html博客就好,预览功能作用不大。

而且Emacs上实现的web静态服务器太过简陋,如果真的想要预览,可以用专业的web服务器来实现,比如 #+begin_src shell docker run -dit --name my-apache-app -p 8080:80 -v "${STORE-DIR}":/usr/local/apache2/htdocs/ httpd:2.4 #+end_src ** 根据修改的内容增量更新tag文件 ** 尝试用vc库代替git vc-git本身实现了很多git操作,可以复用这些操作而无需自己实现。 ** gitalk替换评论系统 ** water.css改配色 ** 实现delete org file处理 ** repo-dir切换到org branch前先用stash保存未提交内容,切回原branch后再unstash,这要比直接commit好

  • 使用方法

** 安装 可以从 [[http://melpa.milkbox.net/][melpa]] 安装,或者用 =git clone= 后处理。

** 设置

下面是 emacs-china 的设置,安装好 [[https://github.com/emacs-china/EGO][EGO]] 后,将该设置写入配置即可管理 emacs-china。

CAUTION: 直接 clone emacs-china 后,需要 checkout master 和 source 后才能使用 emacs-china,否则会导致意外情况。

#+BEGIN_SRC emacs-lisp ;; the following is only needed if you install EGO manually (add-to-list 'load-path "path/to/EGO")

(require 'ego)

(ego-add-to-alist 'ego-project-config-alist `(("emacs-china" ; 站点工程的名字 :repository-directory "~/github/emacs-china.github.io" ; 站点的本地目录 :site-domain "http://emacs-china.github.io/" ; 站点的网址 :site-main-title "EMACS-CHINA" ; 站点的标题 :site-sub-title "=============>集思广益" ; 站点的副标题 :theme (default) ; 使用的主题 :summary (("years" :year :updates 10) ("authors" :authors) ("tags" :tags)) ; 导航栏的设置,有 category 和 summary 两种 :source-browse-url ("Github" "https://github.com/emacs-china") ; 你的工程源代码所在的位置 :personal-disqus-shortname "emacs-china" ; 使用 disqus 评论功能的话,它的短名称 ;; :personal-duoshuo-shortname "emacs-china" ; 使用 多说 评论功能的话,它的短名称(由于多说已经关闭,这里就此废置) :confound-email nil ; 是否保护邮件名称呢?t 是保护,nil 是不保护,默认是保护 :ignore-file-name-regexp "readme.org" ; 有些不想发布成 html 的 org 文件(但是又想被导入 git 进行管理),可以用这种正则表达的方式排除 :store-dir "~/webRoot/emacs-china.github.io" ; 本地测试的目录 )

               ;; 你可以在此添加更多的站点设置
             ))

#+END_SRC

TIP: 你可以仿照上面来设置自己的站点。

你可以通过以下方式发现 EGO 的设置方法(英文)

#+BEGIN_EXAMPLE C-h v ego-project-config-alist C-h v ego-config-fallback #+END_EXAMPLE

** 新建 Repository 通过以下方式创建新的 Repository(也就是一个新站点了):

#+BEGIN_EXAMPLE M-x ego-new-repository #+END_EXAMPLE

这种方式只能进行一个初级的设置,要想让它正常工作,还是需要设置 =ego-project-config-alist= 变量。

** 新建文章 用以下方式创建新文章:

#+BEGIN_EXAMPLE M-x ego-new-post #+END_EXAMPLE

** 测试单独文章的 html 页面 使用以下命令可以生成当前 org 文件所对应的 html 文件,并浏览:

#+BEGIN_EXAMPLE M-x ego-test-current-page #+END_EXAMPLE

** 发布 用以下命令生成 html 文件,并按需传送到远程端:

#+BEGIN_EXAMPLE M-x ego-do-publication #+END_EXAMPLE

这条命令会问你如下几个问题:

  1. Which project do you want to publish? \ ~ 发布哪个站点?
  2. Choose a job from the jobs below: \ ~ "1. Test partial publish" \ ~ "2. Partial publish" \ ~ "3. Test full publish" \ ~ "4. Full publish" \ ~ 从以下四个选项里选择一种发布方式: \ ~ "1. 增量发布测试" \ ~ "2. 增量发布" \ ~ "3. 完全发布测试" \ ~ "4. 完全发布" \ ~ 测试即意味着发布到 store-dir 文件夹下用 emacs 自带的 web server 查看,是本地的并不传送到远端。
  3. (when (2) is partial) Base git commit: HEAD~1 ? \ ~ 将哪些提交视为改变文件?(当第三项选了带了 “partial” 字符串时出现的选项,不懂得话回车即可)
  4. Input checkin messages. (The message won't be inputted if you have checkined before.) \ ~ 输入 checkin 信息,了解 git 的话应该知道
  5. (when (2) is not "test") There will be some questions for "publish-config" \ ~ 对发布到远端的设置进行具体询问(在第二项没有 “test” 字符串时出现)

注意: 当进行没测试过的发布时,任何未经测试的内容变化都不会被发布。也即,任何内容变化在真正发布之前必须经过测试发布。

你可以在 message buffer 和 EGO OUTPUT buffer 里跟踪整个过程。

** 异步发布 你可以使用 =async.el= 包来包裹 =ego-do-publication= 命令,使得该命令异步执行。

关于 =async.el= 包的用法可以参看这里(英文) : [[https://github.com/jwiegley/emacs-async][Async]].

这里是一个例子: (你当然不能直接使用它,但是可以参考它进行自己的设置,就当是一个使用 async 的作业吧)

#+BEGIN_SRC emacs-lisp (require 'ego) (require 'async) (defun ego-async-do-publish (&optional project-name test-and-not-publish force-all base-git-commit checkin-all publish-config) (interactive (let* ((j (or ego--default-project-name (completing-read "Which project do you want to publish? " (delete-dups (mapcar 'car ego-project-config-alist)) nil t nil nil ego--last-project-name))) (p (y-or-n-p "Action: [Yes] Test, [No] Tested Publish. ")) (f (y-or-n-p (format "Publish all org files of "%s" project? " j))) (b (unless f (read-string "Base git commit: " "HEAD~1"))) (c (read-string "checkin message (won't show in 'git log' if you have committed all): ")) (a nil)) (list j p f b c a))) ;; set ego remote push (publish-config) (unless test-and-not-publish (setq ego--current-project-name project-name) (setq ego--last-project-name project-name) (setq publish-config (ego--git-get-publish-config (ego--get-repository-directory) (ego--get-config-option :repository-org-branch) (ego--get-config-option :repository-html-branch))))

(message "See *EGO OUTPUT* buffer and *emacs* buffer for information")
(async-start
 `(lambda ()
    ;; load packages and set load-path
    (setq package-user-dir ,(expand-file-name "~/.emacs.d/elpa/"))
    (package-initialize)
    (add-to-list 'load-path ,(expand-file-name "~/github/org-mode/lisp"))
    (add-to-list 'load-path ,(expand-file-name "~/github/org-mode/contrib/lisp" t))
    (add-to-list 'load-path ,ego-load-directory)

    ;;set color-theme
    (add-to-list 'load-path ,(expand-file-name "~/.emacs.d/color-theme-6.6.0"))
    (require 'color-theme-autoloads "color-theme-autoloads")
    (color-theme-initialize)
    (color-theme-dark-blue2)

    ;; set coding-system
    (set-terminal-coding-system 'utf-8-unix)
    (set-keyboard-coding-system 'utf-8-unix)
    (prefer-coding-system 'utf-8-unix)
    (setq save-buffer-coding-system 'utf-8-unix
          coding-system-for-write 'utf-8-unix)

    ;; pre-set ego configurations
    (require 'cl-lib)
    (require 'ego)
    (setq ego-project-config-alist ',ego-project-config-alist)

    ;; Make EGO show svg images
    (require 'ox-html)
    (defun kd/org-html--format-image (source attributes info)
      "Return \"img\" tag with given SOURCE and ATTRIBUTES.
SOURCE is a string specifying the location of the image.
ATTRIBUTES is a plist, as returned by
`org-export-read-attribute'.  INFO is a plist used as
a communication channel."
      (org-html-close-tag
       "img"
       (org-html--make-attribute-string
        (org-combine-plists
         (list :src source
               :alt (if (string-match-p "^ltxpng/" source)
                        (org-html-encode-plain-text
                         (org-find-text-property-in-string 'org-latex-src source))
                      (file-name-nondirectory source)))
         attributes))
       info))
    (advice-add 'org-html--format-image :override #'kd/org-html--format-image)

    ;; without org-to-html if possible
    (unless ,test-and-not-publish
      (if ,base-git-commit
          (setq ego--publish-without-org-to-html 1)
        (setq ego--publish-without-org-to-html 2)))

    ;; ego-do-publication here
    (ego-do-publication ,project-name
                        ,test-and-not-publish
                        ,force-all
                        ,base-git-commit
                        ,checkin-all
                        ',publish-config)

    ;; waiting for push remote success or just wait http-server in which case you have to close *emacs* buffer manually
    (while (not ego--async-publish-success)
      (sit-for 1))

    ;; return the result
    (with-current-buffer (get-buffer-create ,ego--temp-buffer-name)
      (buffer-string))
    )
 `(lambda (result)
    (with-current-buffer (get-buffer-create ego--temp-buffer-name)
      (insert (format "*EGO output* should be :\n %s \nego-async-do-publish done!" result))))))

#+END_SRC

你可以在 emacs buffer 和 EGO OUTPUT buffer 里跟踪整个过程。

  • 依赖
  1. [[http://www.gnu.org/software/emacs/][emacs]]: this is an "of-course" dependency, "version >= 24.5" is required.
  2. [[http://orgmode.org/][org mode]]: v8.0 is required, please use =M-x org-version <RET>= to make sure you org mode version is not less than 8.0
  3. [[http://git-scm.com][git]]: a free and open source version control system
  4. [[https://github.com/Wilfred/mustache.el][mustache.el]]: a mustache templating library for Emacs
  5. [[http://fly.srk.fer.hr/~hniksic/emacs/htmlize.el.cgi][htmlize.el]]: a library for syntax highlighting (usually this library is shipped with emacs)
  6. [[https://github.com/magnars/dash.el][dash.el]]: a modern list library for Emacs
  7. [[https://github.com/Wilfred/ht.el][ht.el]]: a modern hash-table library for Emacs
  • Known issues
  • CAUTION when there are opened directories in the repository (which don't contain the repository itself), =ego--git-change-branch= will mess up the files in the repository. So, close all opened directories in the repository before =ego-do-publication= .
  • Roadmap [7/10]

    • [X] 不保存上一次发布的项目
    • [X] 用另一个单独的目录存储html结果
    • [X] 发布前先git pull同步一次上游仓库
    • [X] 去掉Emacs中的静态web服务
    • [ ] 根据修改的内容增量更新tag文件
    • [ ] 尝试用vc库代替git
    • [X] gitalk替换评论系统
    • [ ] water.css改配色
    • [X] 实现delete org file处理
    • [X] repo-dir切换到org branch前先用stash保存未提交内容,切回原branch后再unstash,这要比直接commit好
  • FAQ ** 为什么没有发布那些包含中文的 org 文件? 请在 repo 目录下手工执行 src_sh{git ls-tree -r --name-only HEAD}, 若发现所有的中文都显示成乱码,那么请执行 #+BEGIN_SRC sh git config --global core.quotepath false #+END_SRC 之后,再重新发布。