markdown的学习使用经历

为什么选择markdown

本博客后台使用的文本编辑器为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语法中文版, 其中英文版语法说明是由markdown创始人John Gruber编写的,他本人还写了个perl版本的markdown解析工具, 其本人编写的比较正统,代码小巧,但缺乏扩展,使用起来不是特别方便,我也不大会perl脚本语言,所以不是特别喜欢。 有两个在线的markdown编写环境,一个是dillinger markdown在线编辑环境,另一个是mahua markdown在线编辑环境, 前者是老外弄的,后者是好像是一中国人弄的,两者都是所见即所得的编辑界面,左边写markdown内容, 右边就出展示结果,而且使用session记录了用户的输入,也就是说你完全可以拿这两个站点当成记事本用, 当你退出再打开,上次输入的内容还在。我刚开始特别喜欢后者,因为后者支持vim快捷键,而且网站访问比较快, 但后来发现,当输入内容较多,或者拷贝大段文本时,特别容易出现浏览器卡死,所以决定要自己弄一个独属于自己的markdown环境。

刚开始想弄一个在线的所见即所得环境,但发现有这么几个问题:

  1. 必须同时保存markdown原文和转换后的HTML,否则无法平衡修改的便利和访问的高效
  2. 要将markdown编辑环境和TinyMCE柔和在一起,因为markdown尽管方便,但是没有TinyMCE那么灵活

本想试试Django WMD Editor,但是,demo页一直打不开,作罢。 也尝试了一下PageDown Bootstrap,但是感觉不爽,不方便自定义扩展,界面一般。 后来想想,还是找个自己熟悉的语言编写的解析工具,方便写扩展,不爽的地方可以自己干掉。 vim本身支持markdown语法高亮,要求文件名的扩展名为.mkd或者.markdown,而且我也特别喜欢使用vim, 再加上,只要按照简单的markdown语法规范书写,最终就能得到合理的HTML,所以没有必要折腾一个所见即所得环境。 于是相中了python代码实现markdown解析工具,无需编译,修改方便。

markdown在vim中的语法高亮如图:

markdown hilight in vim

markdown的使用

这里重点介绍python代码实现markdown解析工具的使用心得。

表格

例子是:

First Header  | Second Header
------------- | -------------
Content Cell  | Content Cell
Content Cell  | Content Cell

效果是:

First HeaderSecond 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.

效果是:

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"

效果是:

Footnotes1 have a label2.


  1. This is a footnote 

  2. A footnote on "label" 

列表

下面的例子在标准markdown语法中会生成一个列表,而这里是生成两个列表:

1. ordered
1. list

* unordered
* list

效果是:

  1. ordered
  2. list
  • unordered
  • list

链接

例子是:

[markup](http://example.com)

测试站点[example website][1]

[1]: http://example.com "example web"

效果是:

markup

测试站点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会被转义

URL如果包括&会被转义,这个完全无法接受,还好是python代码,倒腾了一下,解决了这个问题,具体可见相关下载部分。

  • 输入-x extra太麻烦了

-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头尾,即没有<html><body></body></html>包裹,更没有样式,于是我添加了个头尾, 转换后直接用浏览器打开,就有不错的展示效果。同样,参见相关下载

  • markdown换行问题

markdown对于换行是不敏感的,如果你要换行,需要输入两个空格再加一个回车,这样转换后才会输入一个<br>标签。所以, 你写文档的时候随时可换行,因为用浏览器展示出来时,只是多了一个空格,几乎看不出有断开的迹象。尽管不影响阅读, 但是可能会影响到搜索引擎的收录,因为爬虫看不到展示结果,爬虫看到的都是HTML源码。如果你正好在一个词中间进行了换行输入, 那搜索引擎在分词建索引时,就可能分不出正确的词。本来试图修改代码,试图在转换时,干掉无意义的换行和空格, 但是发现很麻烦,而且像英文,正好需要展示的时候,多一个空格来分隔两个单词。所以最好的建议还是,在写markdown的时候, 在词间回车换行。当然这不是什么大问题,内容丰富的网站不在乎这点小损失啦。

值得注意

同一行如果出现多个_、*、-,那么需要进行斜杠转义,不然就会被识别为强调语义了。

如果代码段的开头或者结尾有`,那么在代码段的前后留一空格,并增加前后`的个数,避免`被识别为代码段的结束。例如:

运行`` `hostname` ``命令

转换后为:

<p>运行<code>`hostname`</code>命令</p>

同时道理,代码块用三个`包起来,如果代码开头有三个`了,那么,就换用四个`包起来。

实在搞不定,就直接写html,markdown也是能识别,并不作转换的。

相关下载

此处附上我自己修改后的代码,可点击下载进行试用,我是基于Markdown-2.3.1.tar.gz做的修改。

发表于 2014年01月06日 17:13   评论:0   阅读:3407  



回到顶部

首页 | 关于我 | 关于本站 | 站内留言 | rss
python logo   django logo   tornado logo