深入Markdown
openkk 12年前
前两天参加图灵社区的 <a href="/misc/goto?guid=4958522361449848490" target="_blank">iTran 乐译</a>活动,翻译这篇《 <a href="/misc/goto?guid=4958522361545323979" target="_blank">Dive Into Markdown</a>》,作者就是发明了 Markdown 的 John Gruber,从这篇文章中可以了解到他做 Markdown 的初衷。作者的引言、要点 1 和要点 2 都很有启发性。 <blockquote> <p>“有时候一件事情的真相,不是来自于对它的思考,而是来自于对它的感觉。” 。</p> <p style="text-align:left;">——STANLEY KUBRICK</p> </blockquote> <p> <strong>要点1</strong></p> <p> 这儿有个问题:你最近一次听到足以改变你内心想法的论述是什么时候?不仅仅是关于那些你没怎么想过的问题,也包括在听到这个论述之前你原本相当确信的观念。</p> <p> 也就是说,你最近一次认识到自己在某个观念上彻底错了是什么时候?</p> <p> 如果你的回答是“从来没有”,或者是“很久以前”,那么这是否就意味着你总是正确的?</p> <p> 这里有我的一个故事。</p> <p> 一月份的时候,关于 Postel 法则在解析 XML 聚合信息流(比如 <a href="/misc/goto?guid=4958522361640044869" target="_blank">RSS</a> 和 <a href="/misc/goto?guid=4958522361731316972" target="_blank">Atom</a> 这样的格式)的软件中的应用,曾经有过一次争论。这次争论简而言之,就是 <a href="/misc/goto?guid=4958522361819324439" target="_blank">Postel 法则认为</a>:“自己做的时候要谨慎,对别人的东西要宽容”,而 XML 规范则明确说明:“一旦发现致命错误,解析器就不能再继续正常的解析流程了(比如,绝不能继续将字符数据和文档结构描述信息还用标准方式传递给应用程序)。”</p> <p> 那么,解析 XML 聚合信息流的软件该如何抉择呢?是依照 Postel 法则,包容遇到的错误?还是依照 XML 标准,一遇到严重错误就中端处理?</p> <p> <a href="http://inessential.com/?comments=1&postid=2770" target="_blank">Brent Simmons</a>(Mac 系统上的主流新闻聚合阅读器 NetNewsWire 的开发者)和 <a href="/misc/goto?guid=4958522362009011168" target="_blank">NIck Bradbury</a>(Windows 系统上主流新闻聚合阅读器 FeedDemon 的开发者)都认为在处理 Atom 和 XML 信息流时,他们的软件应该采取严格的标准。很多牛人都同意他们的看法。</p> <p> “客户端的标准应该严格”的论点,我觉得可以归结为一下几点:</p> <ol> <li> <p>正确、规整的 XML 要好于有语法错误的 XML;</p> </li> <li> <p>要写出能生成正确、规整的 XML 的软件并不是那么难(就像 <a href="/misc/goto?guid=4958522362102128528" target="_blank">Tim Bray 说的</a>,“任何不能用规整的 XML 写聚合信息流的人都是无能的蠢货”)。</p> </li> <li> <p>如果主流的 XML 信息流阅读软件都要求正确、规整的 XML 数据,那么就会促使生成信息流的应用不再输出糟糕的 XML。</p> </li> </ol> <p> 这三点我都同意,因此,我坚定地站在“客户端解析时应该有严格标准”的阵营中。</p> <p> 但之后我读了 Mark Pilgrim 的“<a href="/misc/goto?guid=4958522362181709656" target="_blank">思想实验</a>”。Pilgrim 不仅是信息流解析应该宽松的倡议者,而且他公开了自己的所有代码,还写出了著名的开源信息流解析器 <a href="/misc/goto?guid=4958522362274799418" target="_blank">Universal Feed Parser</a></p> <p> Pilgrim 的观点,至少在我看来是这样的:如果你在做处理 XML 信息流的软件,而你的解析器非常严格,那么你的用户在遇到异常数据的时候就会遭殃。事实上,你的用户终究是会遇到异常数据的;这种情况发生的话,也许错在造成数据异常的人,但最终受害的却是你的用户,就因为客户端被强加的严格检查。</p> <p> 读过之后,我认真思考了他的思想实验,最终意识到我之前彻底错了,他是对的。(Simmons 也改变了他自己的想法,看以到<a href="http://inessential.com/?comments=1&postid=2785" target="_blank">这里</a>和<a href="http://inessential.com/?comments=1&postid=2786" target="_blank">这里</a>看后续的故事。)</p> <p> Pilgrim 仅凭借他在“<a href="/misc/goto?guid=4958522362181709656" target="_blank">思想实验</a>”中的论述,就让我认识到自己错了。但有意思的是,他说服我的时候,<strong>并没有反驳任何一个让我一开始站在“严格解析”阵营的事实</strong>。</p> <p> 这就是我要说的第一点:当我最终改变某个观点的时候,通常并不是因为我掌握的事实有误,而是因为我没有选对事实。</p> <p> <strong>要点2</strong></p> <p> 回头来看,所有博客软件背后的基本理念,其核心似乎都很简单。你是在管理一系列的文章,而不是有一系列网页的网站,博客软件会帮你将文章转换成网页。</p> <p> 博客软件对一般人的吸引力很容易理解。没有博客软件,他们就没法发布站点。</p> <p> 但博客软件对行家们——就是完全有能力用 HTML 手写出一个博客网站的专家们——的吸引力在哪儿呢?当然了,确实有<a href="/misc/goto?guid=4958522362557196781" target="_blank">一些人坚持手写</a>。但是对大多数人,甚至包括世界上<a href="/misc/goto?guid=4958522362652757610" target="_blank">最博学</a>和<a href="/misc/goto?guid=4958522362756126279" target="_blank">最著名</a>的 web 工程师,都在用博客软件包(或者是<a href="/misc/goto?guid=4958522362843047909" target="_blank">开发自己的</a>博客发布程序)。</p> <p> 答案是方便,灵活。博客软件免去了更新站点的过程中绝大多数的单调劳动。我必须承认——直到我 2002 年发布 Daring Fireball 的几个月前才明白这点。我能手写一整个网站出来而且还觉得写代码很容易,这样的事实让我忽视了在这个过程中有很多很多机械重复性的工作。</p> <p> 下面是我每次往 Daring Fireball 上发布一篇新文章实际上会发生的事:</p> <ol> <li> <p>新文章出现在首页的顶部(同时从首页移去最旧的文章);</p> </li> <li> <p>新文章有一个单独的永久页面;</p> </li> <li> <p>在我的 RSS 信息流中更新这篇文章;</p> </li> <li> <p>标题和新页面的链接被添加到我的<a href="/misc/goto?guid=4958522362941512980" target="_blank">存档</a>页面;</p> </li> <li> <p>新页面的标题和链接作为“下一篇”被添加到上一篇文章中。</p> </li> </ol> <p> 我只需要一个操作——发布一篇文章——然后 Movable Type 就会创建一个新文件,并且更新其他四项。这些任务都不<em>难</em>手动完成,其实很大程度上就是拷贝-粘贴的事儿。这些工作确实很无聊——而且即使确实不<em>难</em>,我仍然很可能出错。我会犯错,因为我可能烦了,或是忘了操作其中哪步。单调的重复性工作正是计算机所擅长,而不适合人类的。</p> <p> 另外,博客软件的这种封装也显得很自然。写一篇文章——或是对现有文章做出修改——感觉上就应该是一项任务。我要编辑的是文章,而不是文章所出现的页面。</p> <p> 因此,我要说的第二点是:不能仅仅因为一件事情不难,就认为它应该这样做。</p> <p> <strong>下面我要试着将要点 1 和要点 2 结合起来,说说 Markdown 的事儿。</strong></p> <p> 让我们先回退一步。之前我说了,博客软件让你将站点当作文章的集合来管理,而不是页面的集合。</p> <p> 那么什么是一篇<em>文章</em>?</p> <p> 常见的说法是,一篇文章就是一个 HTML 代码段。不是完整的 HTML 文档,仅仅是一段 HTML 格式的文本——博客软件负责生成完整的 HTML(或者 XML)文档。你的博客模板里有关于文档结构的所有标签——<html>, <head>, <body>, 等等——以及给你文章预留的位置。一旦你发布,你的博客软件就把你的文章当作 HTML 代码短插入你的 HTML 模板中。</p> <p> 在我写 Daring Fireball 的第一年里,即从 2002 年 8 月到 2003 年 8 月的整整一年,我非常认可“文章就是 HTML 代码段”的说法。我甚至从来没有考虑过别的可能性。我在 Daring Fireball 中写的每一篇文章,都是标准的 HTML 格式。(其实是 XHTML,但这种区别现在不重要。)</p> <p> 当然,除了一点之外,那就是 HTML<em>代码段</em>不能被作正确性验证,因为 HTML 是一种文件类型。你可以写出<em>规整的</em>HTML 代码——确保关闭每一个标签,转换每一个&和<>符号——但你却不能将 HTML 代码段放到 <a href="/misc/goto?guid=4958316970700539474" target="_blank">W3C HTML Validator</a> 上做检查,也不能用 BBEdit 的 HTML 语法检查工具。</p> <p> 我期望的工作流程是:</p> <ol> <li> <p>在 BBEdit 中写文章,编辑,修订;</p> </li> <li> <p>搞定后,登录 MT 的 web 界面,将文章粘贴进去,然后发布。</p> </li> </ol> <p> 但我的实际工作流程看起来却是这样的:</p> <ol> <li> <p>在 BBEdit 中写文章;</p> </li> <li> <p>在浏览器中预览:</p> </li> <li> <p>切换到 BBEdit 中修订;</p> </li> <li> <p>重复上面的步骤,直到搞定;</p> </li> <li> <p>登录 MT,粘贴文章,然后发布。</p> </li> </ol> <p> 最终,我领悟到:这太愚蠢了。用电脑写文章的最大优势就是编辑起来比较直接。写、读、修订,都在同一个窗口中、同一种模式下完成。</p> <p> 用 HTML 格式直接写文章的理由——我用了很多年的理由——是 HTML 并不难。这点<em>我仍然认同</em>。HTML 很容易学会,而且一旦学会,就能马上用起来。专业的 web 开发?那确实很难。但 HTML 的基本 tag 和规则——足够能让你用 HTML 代码直接撰写博客的 HTML 知识——是很简单的。</p> <p> 但像 <a href="/misc/goto?guid=4958522363059794484" target="_blank">Lynx</a> 这样的纯文本浏览器也不直接给你显示 HTML 源代码,是有原因的。因为 HTML 本身就不是要作为一种可读格式存在的。用一种没有可读性的格式来写作,你不觉得很奇怪吗?突然间,我感到自己很荒唐。</p> <p> 要点 1 的应用:我没说写 HTML 源代码很难,而且仍然同意它很容易。我在论述完全不相关的另一个观点——我们所说的容易,是指讲文章标记上各种标签很容易,而不是阅读和排版容易。</p> <p> 要点 2 的应用:即使你仍然坚持认为,用 HTML 源代码写文章很容易,但难道这样不是很繁琐吗?要写"AT&T"而不是直接写"AT&T",这难道不无聊吗?(更别提要把 URL 的&符号进行编码。)</p> <p> 现在是 2004 年了!你的电脑难道不应该有能力判断你的文章哪里是分段,哪里是副标题吗?</p> <p> 别跟我说 Movable Type 的“转换分段符”功能可以实现这个效果。2.661版 MT 的“转换分段符”功能将会把输入的如下两行:</p> <div class="cnblogs_code"> <pre><span style="color:#0000ff;"><</span><span style="color:#800000;">h2</span><span style="color:#0000ff;">></span>This is a header.<span style="color:#0000ff;"></</span><span style="color:#800000;">h2</span><span style="color:#0000ff;">></span> This is a paragraph</pre> </div> <p> 转换成:</p> <div class="cnblogs_code"> <pre> <span style="color:#0000ff;"><</span><span style="color:#800000;">p</span><span style="color:#0000ff;">><</span><span style="color:#800000;">h2</span><span style="color:#0000ff;">></span>This is a header.<span style="color:#0000ff;"></</span><span style="color:#800000;">h2</span><span style="color:#0000ff;">></span> <span style="color:#0000ff;"></</span><span style="color:#800000;">p</span><span style="color:#0000ff;">><</span><span style="color:#800000;">p</span><span style="color:#0000ff;">></span>This is a paragraph.<span style="color:#0000ff;"></</span><span style="color:#800000;">p</span><span style="color:#0000ff;">></span></pre> </div> <p> 这效果真是够矬的。TypePad 显然能做到不在块级别的 HTML 标签外再嵌套一层没用的<p>标签——因此 MT3.0 大概也能做到——但这仍然无法改变其所生成 HTML 代码的冗余和难看。</p> <p> 为什么桌面版的博客编辑器需要提供“预览”模式呢?你在发送一封电子邮件之前,不需要“预览”——您写完邮件,回过头读一下,然后编辑修改,就行了。</p> <p> 实际上,我很喜欢写电子邮件。电子邮件是我最喜欢的写作媒介。在过去的 5 年里,我发送的邮件超过 16,000封。电子邮件的纯文本传统让我能清楚、准确地表达我自己, 中途不会有别的东西来干扰我。</p> <p> 就这样,Markdown 诞生了。电子邮件风格的 web 写作方式。</p> <p> 其他多数的“文本-HTML”转换器都基于这样的假设,即 HTML 的标签很难用,所以他们用自己的标签来替代 HTML 的标签,结果是相较于 HTML 既不“更容易”也不“更可读“。而且,最终的结果是当用户遇到问题时,很难自如翻阅手册,不得不再次捡起 HTML 来。</p> <p> 其他的转换器都意在替换 HTML,而 Markdown 则考虑的是别的东西。它希望能最有效解决问题,既能让人在必要的时候很容易地使用原生的 HTML,也能让你在只需要写字的时候可以专心地写纯文本。</p> <p> 多数博客应用提供的一些标签快捷按钮——斜体、加粗、链接、图片、引用——并不是你一开始就需要考虑的。把插入这些标签做的这么容易,并不会让写作更容易,相反,会让你的文章结构更难被辨识。</p> <p> 但当你真的需要使用内嵌的 HTML 源码时——比如说,要用自定义的类属性来创建一个特殊样式的有序列表——你应该能直接就写 HTML。不用做字符转义,不用特殊的模式转换标记,就直接用标签好了。Markdown 让你能这样做,因为它是专门被设计为只作为 HTML 预处理器的。</p> <p> (如果你确实需要将 Markdown 格式的文档转换为非 HTML 格式,只需要先将它转换为 HTML,然后使用现有的 HTML 转换器就行了。)</p> <p> 尽管我确实认为 HTML 很简单,但在一个特定领域它真的很棘手(如果不能说难的话):用 HTML 标记语言来写关于 HTML 标记的东西实在很让人头痛。当你写<em>有关</em>代码的东西的时候,你应该只用关注示例代码本身——而不是每一个涉及<, &, < 以及&符号的转义问题。</p> <p> 除了让在文档中添加内嵌 HTML 变得容易之外,Markdown 也让在代码段中添加<em>示例</em> HTML 标签变得容易了。</p> <p> <strong>感觉 vs 思考</strong></p> <p> 纯文本在印刷上的局限性——单一的字体,单一的字号,没有斜体和加粗——跟打字机的局限性非常类似。设想有个不错的人给你买了个礼物:一个用原始打字机打印出来的一本经典小说的手稿,就比如说是 Fitzgerald 的“了不起的盖茨比”吧。你可以坐下来静静读这本手稿,从头到尾,这样获得的阅读体验,与你阅读一本精心排版和包装后的书的体验几乎是一样的。没错,那种感觉贯穿在打字机充满油污的、等宽 Courier 式的字体中,以及用下划线代替斜体的习惯,等等。——但文字依旧流畅,从纸面飞跃到你的心中,就像 Fitzgerald 所期望的那样。</p> <p> 我在文章开头引用的 Stanley Kubrick 的名言是我最喜欢的话之一。当你读或者写用 HTML 标签标记的文字时,这些标记在强迫你集中注意力去思考他们。而我希望 Markdown 格式的文本所传达的是一种感觉。<br /> <img title="20120817_112809_1.jpeg" border="0" alt="20120817_112809_1.jpeg" src="https://simg.open-open.com/show/1556f5fcf15e759243373006db3758fa.jpg" width="286" height="176" /><br /> 来自: <a id="link_source2" href="/misc/goto?guid=4958522363150069695" target="_blank">blog.makto.me</a></p>