用Markdown写日志

这篇文章原本发表在另外一个我和别人合写的博客,现在新博开张,姑且移过来作为第一篇文章。


既然开了群博,就要鼓励各位参与者多写日志、写高质量的日志。而其中一点,就是教会大家一些技巧,降低写出高质量日志的难度。这就是本文的目的。
不过日志只是其中一个方面,Markdown的本意是用易读易写的纯文本对文档进行简单的排版,推而广之,其实还可以用来写别的东西,譬如邮件,譬如简历或者论文(不过对后两者Markdown显得太弱了,可能用wiki标签甚至是强大的Latex会更好,这就是后话了)。
如果你有足够的好奇心和耐性,建议你全部看完;否则,为了不因为你的不耐烦浪费了初衷,请直接跳到HOW TO 部分。

首先,这篇日志就是用Markdown(配合MEditor,你可以选择其它Markdown转HTML工具,例如MarkdownPad)写的。

updated: 现在我会推荐以pandoc为后端的两个编辑器 Typora 和 Smark。它们跨平台,支持格式全面,而且免费。MarkdownPad 支持的格式少得可怜,而且高级功能都要收费。Typora 是首选,目前还是beta版本就已经非常惊艳,如果未来 Typora 正式版收费,那么我会推荐开源的Smark。

WHAT’S Markdown

WHAT不是这篇文章的重点,建议你直接去维基百科看Markdown的词条(其实里面也有简单示例):
维基百科上的词条
稍微得瑟一下的是,这条词条是我创建的。我在写这篇日志查找资料过程中,发现维基没有Markdown的词条,所以把这篇日志写到一半,暂停,把词条写完再回来写日志。
词条的内容主要来自英文翻译,部分有所更新和修改。
如果你发现问题,欢迎告诉我,或者更直接地,参与词条的编辑。

WHY Markdown

Markdown的哲学

以下内容引自官方文档的翻译:

Markdown 的目標是實現「易讀易寫」。

不過最需要強調的便是它的可讀性。一份使用 Markdown 格式撰寫的文件應該可以直接以純文字發佈,並且看起來不會像是由許多標籤或是格式指令所構成。Markdown 語法受到一些既有 text-to-HTML 格式的影響,包括 Setext、atx、Textile、reStructuredText、Grutatext 和 EtText,然而最大靈感來源其實是純文字的電子郵件格式。

因此 Markdown 的語法全由標點符號所組成,並經過嚴謹慎選,是為了讓它們看起來就像所要表達的意思。像是在文字兩旁加上星號,看起來就像強調。Markdown 的清單看起來,嗯,就是清單。假如你有使用過電子郵件,區塊引言看起來就真的像是引用一段文字。

我的需要

  • 考虑一下日志(或者类似的轻量级超文本)的特点我们会发现,主要是纯文本编辑,但需要少量的排版功能。一般而言,我们希望足够简单轻量,最好可以离线编辑,排版具有 一致性稳定性 (也就是不会因为一个小小的误操作把排好的全弄乱)。
  • 大部分人写日志会使用的,就是博客提供的后台,也有部分会使用类似Word的编辑软件写好再粘贴,但他们本质上都是WYGIWYS(what you get is what you see,所见即所得)编辑器。
  • 博客后台做的工作,其实是把你编辑(或者粘贴)的内容,转换成HTML代码。譬如说你想对某个字加粗,实际上后台做的事情是往目标前后加上<b>加粗</b>,然后浏览器解析HTML标签,效果就变成了加粗
  • 但这样有几个缺点。首先你必须得在线(较真的话,编辑纯文本内容时可以不用,但排版必须要)。
  • 其次这样的编辑方式稳定性也很不好,很有可能你一个误操作,排版全乱,而你还不知道发生什么事。这是因为编辑器自动转换代码时,自动判断未必是那么智能,尤其当文章很长,格式很多,而且互相干扰时。
  • 最后如果你要把文章在别处再发表,又不想重新排版,你就要复制黏贴HTML源码(几乎所有后台都提供编辑HTML代码的功能)。问题是,自动生成的代码垃圾代码极多,可读性极差,这带来了潜在的显示一致性(两边效果不一致)和稳定性(复制漏了某个符号导致排版崩溃)的问题,而且你想做小修改也很难。
  • 类Word的软件做的工作比较类似,但是转换的过程更为复杂,转换成的文档编码一般只有兼容该标准的软件才能解析和编辑(你试试用记事本打开doc文档),不太可能人工阅读(更别谈修改)。所以博客后台会出现的问题这里都会有,或者说会更严重。而且一个功能丰富的软件,也就意味着heavy,意味着启动速度慢等等。
  • 一致性和稳定性差几乎是所有WYGIWYS的通病。

综合以上各点,最稳妥的方法似乎就是,拿个编辑器直接敲HTML代码。

作为标记语言,HTML还是很好懂的。就是几个标签对(也有少量单个标签,像换行<br/>),每一对标签对中间夹着的部分实现特定排版功能。(参考上面加粗的示例)但是好懂还是不等于方便。作为结构化的语言,HTML太严谨了,为了一个很简单的功能得敲很多标签,嵌套和配对还不能出错。加入大量标签之后,文章也变得不好识别。而事实上,大部分功能我们还用不到。所以在遇到Markdown前,我还是宁愿用所见即所得编辑器。

Markdown的好处就刚好弥补了这些问题。它易读易写。它的排版符号经过谨慎筛选,即使不解析,也基本保留了文章原样,你能很容易看明白它的作用。它极其简单轻量,只实现最essential的功能,而不是enough。当然大部分情况下,已经足够了。偶尔遇到一些没有的功能,它还允许直接写HTML补充。配合一个支持实时预览的Markdown编辑器,基本接近所见即所得。
你想一下,前后加*或者_就是斜体,加两个就是加粗,3个就粗斜体,加个#就是标题,三个“-”单独一行就是分割线,有序列表自动排序号,加[]就是超链接…..刷新一下就可以看到效果(其实连刷新也可以省,带实时预览功能的编辑器可以编辑同时看到效果),而且一致性和稳定性良好。有什么理由不选用?

所见即所得 V.S. 所想即所得

其实更重要的是,相对于“所见即所得”,标记语言的排版被认为是 WYGIWYT(所想即所得) 。它的特点是 内容与格式分离

在所见即所得模式下编辑,编辑对象本身既包含了内容,也包含了格式。这要求你要么一边写一边设置格式(于是乎你的思维要不断在“写什么内容”和“怎样的显示效果”之间切换);要么一口气写完内容,然后一点一点回头识别出不同的区块,然后分别设置格式。如果你设置完之后不满意,或者改变用途所以要重设格式,你又要重头来设置一遍。(好吧,我知道Word爱好者会告诉我,其实可以设置和应用样式,然后要改时统一修改样式。这的确稍微轻松了,但是稳定性仍然有待提高。而且有这样一个问题,你能直接看出某段文字应用了哪个样式吗?)我完全没有否定Word的意思,Word有大量功能是轻量级标记语言做不到的。不过话说回来,那部分的功能我很可能会选用LaTeX。

所想即所得是让编辑者把注意力放在内容上,写到标题,你只需简单标记一下,这是一级标题(# 或者 <h1></h1>)。是的,你还是需要分神标记一下,但是你只需想起这个是标题,你并没有从内容的思路跳出,思考标题该是什么样子的。类似的,这是强调,这是链接,这是列表……你都不要考虑显示效果。写完之后(当然实时编辑器写的时候就能看见),经过解析,你就会看到在当前解析器设置下,标题、强调、链接、列表…..等等这些元素是什么样子的。如果你满意,事情就这么结了。如果还想调整,只需对着某一类元素调整,那么整个文档都会一致的调整过来,而这一点可以通过设置解析器,或者增加一个css文件达到目的。整个编辑内容的过程,你只需简单的标记一下,这“是什么”,但是“是什么”对显示成“什么样子”是中立的,你可以等到完全编辑完了内容,再来统一地考虑“什么”是“什么样子”。

HOW TO Markdown

好了,前面费了这么大篇幅告诉大家Markdown的好处,也是时候开始教学了。
其实如果你是对代码有一定的敏感度,或者学过一下HTML,你就会发现Markdown太简单,比那些见过的代码都要简单。因为它本来就不算什么代码。你可以直接去看一下语法,然后就可以开始了。
Markdown语法官方完整版
Markdown语法中文完整版
Markdown语法中文精简版

不过为了更直观一些,我还是想给出常用功能的对照示例。看懂了,就可以实现基本的写日志的排版格式。

1.段落

Markdown的段落由一个或多个连续的行构成,段落间靠一个或以上视觉上的空行(也就是不管实际是什么字符只要看上去是空白)划分。一般的段落不应该用空格或制表符缩进(缩进有特殊意义,下面讲到)。这个就不用给示例了,因为见到的,就是写的时候的样子。但是强调段落还是有意义的,因为段落是很多效果的生效单位。

2.换行和强迫断行

首先,Markdown对段落内的“换行符”是直接无视的,也就是说虽然你写的时候敲了回车,但是最终的显示结果却是整段连成一行,由浏览器自动换行。
这点跟HTML很像。HTML也是无视换行,想强迫断行,就得加入<br/>标签。类似地,Markdown也可以强迫断行,但简单的多,只需要在行末以两个或以上空格结束即可。这个很容易明白,也不演示了。

3.强调

这个倒不用解释,直接上演示:
代码
*强调* 或者 _强调_
**加重强调** 或者 __加重强调__
***特别强调*** 或者 ___特别强调___
对应的效果
强调 (斜体效果)
加重强调 (粗体效果)
特别强调 (粗斜体效果)

4.标题

这个也很好理解。HTML有六级标题H1~H6,数字越小越高级,字体越大。
跟这个相对应,在标题前面加多少个井号#就是几级标题。需要注意的是,#需要加在行首才起效。
# 一级标题

一级标题

#### 四级标题

四级标题

特别地,一级和二级还有一种写法,就是在标题紧接下来的一行,加上任意数量的等号=(一级)或者减号-(二级)。效果上面演示过,就不再演示了。

一级标题  
=======  
二级标题  
----

5.列表

无序列表用一个星号、加号或者减号做标记,每个项一行,标记在行首,标记和内容之间至少有一个空格,列表本身要作为单独的段落:

* 无序列表项目1  
+ 项目2  
- 项目3  
  • 无序列表项目1
  • 项目2
  • 项目3

有序列表跟无序列表很接近,要求基本一样,只是标记变成了一个数字+一个英文句点+至少一个空格+内容:

9. 有序列表项目1  
2. 项目2  
7. 项目3  
  1. 有序列表项目1
  2. 项目2
  3. 项目3

需要注意的是,只要是数字就可以,显示的数字会在列表里自动排序,跟你输入的数字无关。

6.引用

有时我们引用了别人的一些原话,需要特别强调这是引用,除了双引号,还有一个选择就是用引用框把内容包起来。
只需要在段落开头加一个右尖括号’>’就可以把这段话变成引用。
引用可以嵌套。如果要在一个引用里插入一个引用,可以用两个’>’开头。依此类推,根据嵌套层次加相应数量的符号。

1
2
3
4
5
6
7
> 一段引用。第一行。(提醒,这里插入了两个空格强迫断行,下同)
> 这是第二行。
> > 这是一个嵌套的引用。这是第一行。
> > 这是第二行
>
> 外层引用第三行。前面需要一个视觉上的空行表示内层嵌套结束,空行前面的'>'可有可无。
>

一段引用。第一行。
这是第二行。

这是一个嵌套的引用。这是第一行。
这是第二行

外层引用第三行。前面需要一个视觉上的空行表示内层嵌套结束,空行前面的’>’可有可无。

需要注意引用框在某些页面的风格设置下并不明显(貌似网易和Qzone都是),结果只能看到内容缩进了,这时还是用引号表明引用比较明显。

7.链接和图片

因为大家都知道链接和图片长啥样(什么!没见过?请看文末的版权声明,那里既有链接也有图片),所以不演示效果,只给代码。
链接有4种写法(支持相对地址):

  1. <链接地址> 这种形式只是简单的标出链接地址。
  2. [文字](链接地址 “标题”) 给文字添加链接,其中标题是可选的。
  3. 先在需要链接的地方插入[文字][标记] ,然后在后面一个以[标记]:开头的新行给出地址(一般是段落后面或文章末尾,冒号后面至少有一个空格,标记不可以重复)。
  4. 或者直接以[文字][]这种形式编写,在下面的新行中使用
    [文字]:链接 的形式声明链接。(相当于省略标记,文字同时充当标记)

示例:[Markdown语法完整版][md]然后在后面的某一行添加(后面这行不会显示):
[md]: https://github.com/othree/markdown-syntax-zhtw/blob/master/syntax.md

图片可以算是一种特殊的链接,可以使用链接的后三种写法,只是要在前面加上!表示这是图片。
例如![图片](http://i.creativecommons.org/l/by-nc-nd/2.5/cn/88x31.png "这是创用协议的图片")

8.水平分割线

使用三个以上的星号“*”、减号“-”或者下划线“_”来表示。星号跟减号之间可以插入任意空格,如果减号没有插入空格,那它必须在单独的一个段落里,否则会将上一行识别为标题。
* * *
***
*****
- - -
-----------------
效果如下:


9.代码等特殊内容

介绍了这么多,已经认识了相当多的符号用来产生格式。但是,如果要显示这些符号本身呢?我上面的示例又是如何将代码显示出来而不是产生格式呢?

  1. 对于单个特殊符号,在前面加反斜杠\就可以按字面含义显示;而如果\和特殊字符凑在一起只是巧合,你其实要显示\而不是取消特殊字符的功能,那就输入\\两个反斜杠,相当于前面的\取消掉后面的\的取消功能。
  2. 在大部分情况下,Markdown会很智能地判断是否将<和&转换成HTML实体引用。一般情况下都会换成实体引用,以保留字面意义;当Markdown认为这是HTML标签和实体引用的一部分时,就会保留其代码含义;而如果是在代码块里的代码,Markdown又会替换,以让代码原样输出而不是产生功能。如果你不能确定而想保留字面含义,可以手动转换成对应的实体引用&lt;&amp;
  3. 如果是一行代码,可以把内容包在一对反引号(Esc下面那个)``中,Markdown会照原样输出。
  4. 如果是一段代码,只要段落的每一行都缩进4个空格或者1个Tab,就可以整段原样输出。这种用法会让保留所有的空白字符——而一般情况下,Markdown会删除所有换行和空格,打乱原有的缩进和排版。

10.缩进

4个空格或者1个Tab的缩进除了形成原样输出的代码块之外,还有别的一些功能,所以拿出来单独总结。

  1. 形成代码块,这个上面说了。
  2. 形成嵌套。
  3. 嵌套里的代码块。

11.其它

对于Markdown没有的功能,其实可以直接写HTML代码实现。注意的是,在区块级的HTML标签对里,Markdown语法不再起效。

编辑器

updated:2017-01-09

目前我用过的Markdown编辑器

  • Typora :Windows、Mac、Linux 跨平台
  • Smark: 同样的跨平台,但是界面细节不如Typora。作者原本只是写给自己用,所以只编译了Windows版,其他平台要自己安装Qt然后编译。
  • MarkdownPad: 因为有实时刷新,早期是Windows上比较不错的选择。但功能少且免费功能更少,在遇到 Smark 和 Typora 之后就不用了。
  • MEditor: 台湾网友托管在Github的工具,开发得特别早,在Markdown还没流行时,给Markdown编辑提供了很多方便(再怎么样也比记事本强)。不过预览需要手动刷新,这今时今日显得稍微有点陈旧。
  • http://notepag.es

其他工具

除了编辑器以外,还有很多Markdown相关的工具,提供更多的想象空间。

  • pandoc: 文档转换的瑞士军刀,通过命令行在多种标记语言和文档格式间转换。直接使用稍有不变,实际上Typora的部分 和 Smark的大部分功能,都是调用pandoc作为后端实现的。
  • nodePPT:国人基于node.js实现,托管在Github的命令行工具,可以由Markdown生成Html5 演示文稿。
  • Marp: 日本程序员使用coffeescript 实现,托管在Github的编辑器,可以编辑经过拓展的Markdown语法,并生成PDF演示文稿。
  • Hexo: 台湾网友基于node.js实现,托管在Github的命令行工具,可以通过Markdown生成静态博客。支持多种插件和模板。
  • Gitbook: 基于node.js + Markdown + Git,将一个Repository 转换为一个静态网站或者一本书。同时有一个网站Gitbook.com可以发布。比起 pandoc 将单个文件转换,一个库更方便管理章节。

本文就是使用 Markdown标记语言 编辑的。 想了解更多,可以查看 Markdown完整语法 以及下载上述的Markdown编辑器试用。

Aaron Swartz

R.I.P


“知识共享 署名-非商业性使用-禁止演绎 2.5 中国大陆(CC BY-NC-ND 2.5)”许可协议
本作品为本人原创,采用“知识共享 署名-非商业性使用-禁止演绎 2.5 中国大陆(CC BY-NC-ND 2.5)”许可协议进行许可。
本作品允许复制和传播。如需转载,请留言告知,原文转载并在文章开头明显位置加上署名和原链接,不得用于商业用途,不得修改、转换或者以本作品为基础进行创作,谢谢合作。详情请点击查看协议具体内容。