本博客后台使用的文本编辑器为TinyMCE,因为是技术博客,常常会有一些很特别的需求, 比如点击图片要能生成一个显示图片的浮层,例子代码要能用一个代码框包围起来。 时常需要直接编辑HTML源码。总之,一边关注内容,一边又关注展示,非常蛋疼。 同住的室友是做前端的,他给我推荐了个好东西,即markdown。
后来一接触,才恍然大悟,原来各种开源代码里的说明文档都是按markdown语法编写的, 怪不得之前一直感觉开源代码里的README.txt都长得一个模样呢,原来是有语法规范的。 接着自学了一下,发现跟Latex有点儿想,跟Wiki的语法也有点像,但Markdown语法要 简单得多。Markdown只是规定了一些控制字符,通过markdown转换工具,就可以转换成 HTML或者XHTML格式了,于是就可以马上用浏览器来展示了。特别适合用来写博客,因为 写博客的特点就是展现简单,没有各种复杂的图文混排,顶多就是一些超链接和代码, 图片也就一行一张那种简单形式。注意咯,markdown生成的HTML展示出来什么效果, 是由CSS的样式定义决定的,Markdown只负责转换成正确的HTML标签。 带来的最大好处是可以专注内容本身,摆脱纠结且丑陋的HTML标签。 当然markdown转换工具,可以自己写扩展,再配合CSS和Javascript,也可以弄出很炫的效果出来。
markdown语法可参见markdown语法英文版或者markdown语法中文版, 其中英文版语法说明是由markdown创始人John Gruber编写的,他本人还写了个perl版本的markdown解析工具, 其本人编写的比较正统,代码小巧,但缺乏扩展,使用起来不是特别方便,我也不大会perl脚本语言,所以不是特别喜欢。 有两个在线的markdown编写环境,一个是dillinger markdown在线编辑环境,另一个是mahua markdown在线编辑环境, 前者是老外弄的,后者是好像是一中国人弄的,两者都是所见即所得的编辑界面,左边写markdown内容, 右边就出展示结果,而且使用session记录了用户的输入,也就是说你完全可以拿这两个站点当成记事本用, 当你退出再打开,上次输入的内容还在。我刚开始特别喜欢后者,因为后者支持vim快捷键,而且网站访问比较快, 但后来发现,当输入内容较多,或者拷贝大段文本时,特别容易出现浏览器卡死,所以决定要自己弄一个独属于自己的markdown环境。
刚开始想弄一个在线的所见即所得环境,但发现有这么几个问题:
本想试试Django WMD Editor,但是,demo页一直打不开,作罢。 也尝试了一下PageDown Bootstrap,但是感觉不爽,不方便自定义扩展,界面一般。 后来想想,还是找个自己熟悉的语言编写的解析工具,方便写扩展,不爽的地方可以自己干掉。 vim本身支持markdown语法高亮,要求文件名的扩展名为.mkd或者.markdown,而且我也特别喜欢使用vim, 再加上,只要按照简单的markdown语法规范书写,最终就能得到合理的HTML,所以没有必要折腾一个所见即所得环境。 于是相中了python代码实现markdown解析工具,无需编译,修改方便。
markdown在vim中的语法高亮如图:
这里重点介绍python代码实现markdown解析工具的使用心得。
例子是:
First Header | Second Header
------------- | -------------
Content Cell | Content Cell
Content Cell | Content Cell
效果是:
First Header | Second Header |
---|---|
Content Cell | Content Cell |
Content Cell | Content Cell |
例子是:
```cpp
int main()
{
return 0;
}
```
效果是:
int main()
{
return 0;
}
例子是:
Apple
: Pomaceous fruit of plants of the genus Malus in
the family Rosaceae.
: An american computer company.
Orange
: The fruit of an evergreen tree of the genus Citrus.
效果是:
例子是:
Footnotes[^1] have a label[^label].
[^1]: This is a footnote
[^label]: A footnote on "label"
效果是:
下面的例子在标准markdown语法中会生成一个列表,而这里是生成两个列表:
1. ordered
1. list
* unordered
* list
效果是:
例子是:
[markup](http://example.com)
测试站点[example website][1]
[1]: http://example.com "example web"
效果是:
测试站点example website
具体markdown语法这里不讲,只是介绍一下该工具的独特之处:
这是python模块本身据有的特点,你可以
import markdown
md = markdown.Markdown()
html1 = md.reset().convert(text1)
html2 = md.reset().convert(text2)
也可以命令行直接敲入
python -m markdown -x extra < abc.mkd > abc.html
其中-x extra
表示使用基本扩展。
该模块代码中有比较丰富的扩展功能,其中支持属性设置就非常有用,这在标准markdown中是不支持的。例如:
欢迎访问![忆向博客][1]{: .myclass #myid width=600 height=100}站点。
[1]: http://www.hustyx.com/static/blog/images/yixianglogo.jpg "忆向博客logo图"
转换后变成:
<p>
欢迎访问<img alt="忆向博客" class="myclass" height="100" id="myid" src="http://www.hustyx.com/static/blog/images/yixianglogo.jpg" title="忆向博客logo图" width="600" />站点。
</p>
通过指定图片的长宽可以控制页面布局,还能加快浏览器展示页面。再举个可点击图片的例子:
欢迎访问[![忆向博客][1]{: width=600 height=100}](){: .click\_img}站点。
[1]: http://www.hustyx.com/static/blog/images/yixianglogo.jpg "忆向博客logo图"
转换后为:
<p>
欢迎访问<a class="click_img" href=""><img alt="忆向博客" height="100" src="http://www.hustyx.com/static/blog/images/yixianglogo.jpg" title="忆向博客logo图" width="600" /></a>站点。
</p>
当然也有一些问题:
URL如果包括&
会被转义,这个完全无法接受,还好是python代码,倒腾了一下,解决了这个问题,具体可见相关下载部分。
-x extra
实际是指使用一些基本扩展,这些基本扩展包括了extensions目录下的这么些个文件,一个文件对应了一种扩展:
smart_strong.py
fenced_code.py
footnotes.py
attr_list.py
def_list.py
tables.py
abbr.py
例如fenced_code.py就是指定代码块的转换格式,由:
```cpp
int main()
{
return 0;
}
```
转换为:
<pre><code class="cpp">int main()
{
return 0;
}
</code></pre>
但是每次敲入-x extra
太麻烦,于是我又修改了一下代码,默认就使用extra扩展,不需要加任何参数,参见相关下载。
敲命令的时候,转换后只是纯粹的html片段,没有html头尾,即没有<html><body></body></html>
包裹,更没有样式,于是我添加了个头尾, 转换后直接用浏览器打开,就有不错的展示效果。同样,参见相关下载。
markdown对于换行是不敏感的,如果你要换行,需要输入两个空格再加一个回车,这样转换后才会输入一个<br>
标签。所以, 你写文档的时候随时可换行,因为用浏览器展示出来时,只是多了一个空格,几乎看不出有断开的迹象。尽管不影响阅读, 但是可能会影响到搜索引擎的收录,因为爬虫看不到展示结果,爬虫看到的都是HTML源码。如果你正好在一个词中间进行了换行输入, 那搜索引擎在分词建索引时,就可能分不出正确的词。本来试图修改代码,试图在转换时,干掉无意义的换行和空格, 但是发现很麻烦,而且像英文,正好需要展示的时候,多一个空格来分隔两个单词。所以最好的建议还是,在写markdown的时候, 在词间回车换行。当然这不是什么大问题,内容丰富的网站不在乎这点小损失啦。
同一行如果出现多个_、*、-,那么需要进行斜杠转义,不然就会被识别为强调语义了。
如果代码段的开头或者结尾有`,那么在代码段的前后留一空格,并增加前后`的个数,避免`被识别为代码段的结束。例如:
运行`` `hostname` ``命令
转换后为:
<p>运行<code>`hostname`</code>命令</p>
同时道理,代码块用三个`包起来,如果代码开头有三个`了,那么,就换用四个`包起来。
实在搞不定,就直接写html,markdown也是能识别,并不作转换的。
此处附上我自己修改后的代码,可点击下载进行试用,我是基于Markdown-2.3.1.tar.gz做的修改。