使用elisp编写脚本
2013-10-09起因
我通过Github Pages有了自己的一个静态博客,并且开始正儿八经地写博客。
但我碰到了一个问题:每次我需要写博客,我要先打开emacs,按下C-x C-f,然后输入一长串路径名和文件名(org文件),然后手动输入YAML Front Matter[1]。路径名每次都是一样的,YAML Front Matter也是一样的,这都是重复性的工作,并且我又是一个很懒的人,所以我就想偷懒了。
起初是想写个shell脚本来简化步骤而已,开始写脚本后,我就想,应该把publish的步骤也通过脚本进行简化(虽然这并不是很复杂的步骤),然后我发现shell不能做到这一点,唯一的选择是elisp。
过程
用elisp写脚本?这事我听说过,但我没做过,也就是说我也是大姑娘上轿头一回了。
照例google。
基本形式没太大问题,将shell脚本Shebang[2]后面的 /bin/bash 改成 /usr/bin/emacs –script ,其他的东西嘛,随便就行不是么?(想当年某次实习招聘的时候我跟面试官说我会shell脚本,结果只会堆命令的真相还是被不留情面地揭穿了(╯‵□′)╯︵┴─┴ )
不过碰到了不少问题。
之所以用elisp,就是想简化publish么,但是在elisp script里写上的
(org-publish-project "blog-linusp")
完全不起作用。细想一下应该是shell脚本没有加载我的emacs相关配置。当时真是一筹莫展啊,后来发现其实这是一件不复杂的事情,在之前加上一句
(load-file "~/.emacs")
不过这样做太凶残了,什么auto-complete、yasnippet、slime、org2blog、metablog全被加载了(╯‵□′)╯︵┴─┴ 。
好在我有将配置文件分类的习惯,org-mode的相关配置被我写在一个名为 org.el 的文件里,于是加载它就OK了,不过这个文件里还有引用其他的一些emacs插件,于是也都加载了——好吧至少比之前更好是吧。
如何传递参数给脚本?shell脚本接受参数的话还是懂的怎么做的,可是elisp脚本……
照例google,然后发现Xah Lee[3]的博客上就有这个内容,原文点我。
运行脚本后,发现总会有一堆的Loading message,就像下面这样:
(╯‵□′)╯︵┴─┴
经google,该问题没有太好的解决问题,凑合吧。
成果
嘛,虽然代码写得比较丑陋,至少能用,功能上达到了我的预期目标,所以代码的问题,以后再说吧。
附脚本代码
#!/usr/bin/emacs --script (require 'calendar) (defun blog (action &rest rst) (cond ((string-equal action "post") (if (equal rst nil) (print "Please input title") (let ((post-file (concat (format-time-string "%Y-%m-%d") "-" (car rst) ".org"))) (progn (with-temp-file (concat "~/blog/org/_posts/" post-file) (insert (concat "#+begin_html\n" "---\n" "layout : post\n" "title : \n" "categories : \n" "tags : \n" "excerpt : \n" "---\n" "#+end_html\n"))) (print (format "Create post file %s in post directory" post-file)) (shell-command (concat "emacs " "~/blog/org/_posts/" post-file)))))) ((string-equal action "publish") (progn (org-publish-project "blog-linusp") (print "Project has been published!"))) (t (print "Action: post/publish")))) (load-file "~/.emacs.d/site-lisp/xml-rpc.el") (load-file "~/.emacs.d/site-lisp/wc-mode.el") (load-file "~/.emacs.d/myplugins/org.el") (blog (elt argv 0) (elt argv 1))
[1] YAML Front Matter是用来告诉Jekyll使用什么模板并可以附带一些其他信息的文件头
[2] Shebang是一个由'#'和'!'构成的字符串,在文件中存在Shebang的情况下,类Unix操作系统的程序载入器会分析Shebang后的内容,将这些内容作为解释器指令,并调用该指令,并将载有Shebang的文件路径作为该解释器的参数——来自维基百科
[3] Xah Lee是一位emacs大牛,emacs wiki上可是都有他的专门的页面哦