

嗨,大家好!
今天,我想解释一下为什么Markdown是一个写得不好的工具,您应该避免在文档中使用它。
介绍
Markdown是Internet上最著名的轻量级标记语言。 它用于自述文件,介绍指南,Wiki页面,博客文章,评论。 它的流行是基于简单性和较低的编写阈值。 您可以在60秒钟内学习所有语法,几乎立即就可以使用自己喜欢的IDE开始编写第一个文档。 在撰写快速说明以描述产品功能和基本用法命令时,这特别好。 GitHub和GitLab甚至允许开发人员使用README.md文件自动启动新存储库,尽管两个项目都支持多种语言,包括Asciidoc和reStructuredText。
让我猜你的问题-这样一个受欢迎的工具怎么会这么糟糕? 它真的有很多缺点吗? 实际上,它们比您想象的要多。
为什么Markdown失败?
我想概述一下最烦人和令人沮丧的限制,这些限制可能会使您用Markdown编写技术文档时的经历变成一场噩梦。
- 缺乏规范 。 自2004年推出以来,Markdown一直没有技术规范,只有John Gruber在其博客文章中定义的规范为止。 缺乏强有力的指导方针,迫使不同的项目制定自己的规则来解析Markdown。 结果,基本的Markdown语法可以具有仅在特定规范中可用的额外功能集。 例如,缩写词或脚注。
- 香精 。 为了减轻由于缺乏规范而导致的现有限制,在Markdown之上构建的项目(尤其是静态站点生成器)引入了具有其自身语法的新样式。 当前,风味列表包含34(!)个条目。 显然,其中的某些风味彼此之间不兼容甚至不完整,因此您必须记住使用哪种风味版本,以避免语法和错误。
- 缺乏可扩展性 。 Markdown没有扩展系统,可以让您扩展语言而不影响其解析方式。
- 缺乏语义 。 使用Markdown,您只能写文本。 这意味着,如果您需要某种注释或技巧来吸引读者的注意,则必须嵌入HTML。 缺乏语义支持是一个问题,原因如下:a)Markdown现在依赖于特定的HTML类和页面设计。 b)文档内容不再可移植到其他输出格式。 c)转换为其他标记工具和页面设计变得更加困难
- 锁定和缺乏便携性。 大量的风味和缺乏语义支持会导致锁定。 您拥有的文档越多,您与现有配置的联系就越多。 之后,很难迁移到其他工具,因为自定义HTML类和flavor的功能将无法在当前工具和页面设计集之外运行。
还有其他选择吗?
Markdown有两个严重的竞争对手:reStructuredText(rST)和AsciiDoc。 两者的语法都非常相似,并且具有比Markdown更强大的功能。 最重要的是-两者都旨在创建文档。 我使用这些纯文本格式已有一段时间,而Asciidoc对我来说似乎更有趣。 因此,让我们对其进行一些概述。
为什么AsciiDoc成功?
AsciiDoc被剥夺了我上面提到的Markdown的缺点。 此外,AsciiDoc还具有Markdown所不具备的一些查杀功能,包括:
代码块
AsciiDoc允许您直接从源文件中添加“实时”代码段。 有了这种包含,您不必担心文档中的过时示例,因为一旦更改源代码,它们就会自动更新。 例如:
包括:: source_code.js []
也可以使用tag属性包括一部分源文件。 因此,您将应包括在这些标签之间的部分放置:
// tag :: code_example [] 函数乘法( num1 , num2 ){ var result = num1 * num2;返回结果;} // end :: code_example []
然后使用include指令包含此部分:
包括:: source_code.js [tag = code_example]
属性
属性用于启用内部功能或保存替换内容(如变量)。 例如:
[options =”页眉,页脚,自动宽度”] | === | 单元格A | 单元格B | ===
上面的示例显示了表的三个定义的属性。 我在“表”部分中描述的表的更多详细信息。
另一个例子:
:toc:正确:document_version:1.1.0
第一个属性在主要内容的右侧显示目录,而第二个属性在内容内包含文档版本的动态值:
当前文档版本为{document_version}。
在AsciiDoc中,每个元素都有其自己的属性集,可让您灵活地配置此元素。 例如,使用图像的属性,您可以添加备用标题,尺寸,外部链接,定义浮动和角色。 在Markdown中,唯一的方法就是使用内联HTML。
条件指令
属性是另一个很酷的AsciiDoc功能的关键:有条件的内容包含。 使用特殊指令ifdef , ifndef和ifeval您可以根据满足某些条件来控制应显示的内容。
如果设置了指定的属性,则使用ifdef指令显示内容:
ifdef :: github []此内容仅向GitHub用户显示。endif:: []
相反,如果未设置指定的属性,则使用ifndef指令隐藏内容:
ifdef :: github []此内容不会为GitHub用户显示。endif:: []
如果方括号内的表达式的值为true则ifeval指令将显示内容。 这可能有助于仅显示特定版本文档的说明:
ifeval :: [{api_version} <2.0.0]如果要使用版本{api_version}中可用的API方法,请使用以下端点:https://example.com/api/v1/endif :: []
建筑模块
构建块是包括非段落文本的特殊组件,例如代码清单,引号,表格等。这为您提供了更大的灵活性,可以在文档中添加通用内容。
例如,您可以添加一个清单块,如下所示:
----
这是_listing块_的示例。内部内容显示为文本。或通过在示例中直接添加标注以获取其他信息,例如:
[source,ruby] ----需要'asciidoctor'# Asciidoctor .convert_file'mysample.adoc'# ---- 导入库读取,解析并转换文件AsciiDoc标注 另一个强大的块是开放块 。 它可以充当其他任何块,并包含您想要的任何信息。 作为包含内容的非介入方式,这可能很有用。 例如:
[sidebar] .related information ----这是文字,用于显示与主要内容有关的信息。告诫
AsciiDoc支持5种现成的警告: Note , Tip , Important , Caution , Warning 。 这里最棒的是,警告还可以封装任何块内容。 如果您还记得的话,在Markdown中,告诫是某种块引用,写一个包含特殊格式示例的部分绝对让人失望。 在AsciiDoc中,您只需将所需内容与选定的警告类型一起添加即可。
ID,锚点和类
在Markdown中(我的意思是,基本语法),您唯一能做的就是用您自己的用户友好的子标签覆盖自动生成的标题锚。 使用AsciiDoc,您几乎可以在任何位置添加自定义锚:在节标题或离散标题,段落,块,链接或嵌入式图像,列表或文字块,短语等上。
例如:
段落的ID
[[notice]]此段引起了很多关注。或[#notice]此段引起了很多注意。此外,类和其他属性可用于链接。 基本语法如下:
link:url [可选的链接文本,可选的目标属性,可选的角色属性]因此,您可以编写如下内容:
Mister Gold Blog是由https://mister-gold.pro/[*Antonio*^,role =” green”]创建的。并收到带有绿色粗体文本的链接,该链接将在新标签页中打开。 同样,在没有内联HTML或硬编码CSS类提示的情况下,也可以进行这些操作。
AsciiDoc链接 桌子
表格在Markdown中也可用。 但是你能和他们做什么? 对齐内容…aaa和…就这样。 Asciidoc提供了多种方法来控制列中内容的大小,样式和布局。 跨列和行,添加嵌套表,跨列重复内容,甚至在横向模式下显示表-我敢打赌这是您使用表格式的最佳体验。
一些例子:
桌子宽度不同
[cols =” 50,20,30”] | === |第1列中的单元格|第2列中的单元格|第3列中的行1 |第3列中的单元格|第1列中的第1行|单元格中的|单元格第2列,第2行|第3列,第2行中的单元格| ===AsciiDoctor表格宽度 跨行
| === |第1列第1行的单元格|第2列第1行的单元格|第3列第1.2行的单元格||跨越第2行和第3行的单个单元格的内容|第2列第2行的单元格|第3列第2行的单元格|第2列第3行|第3列,第3行的单元格| ===AsciiDoctor表跨度 嵌套表格
[cols =” 1,2a”] | === | 第1栏| 第2列| 单元格1.1 | 单元格1.2 | 单元格2.1 | 单元格2.2 [cols =” 2,1”]!===!Col1!Col2!C11!C12!=== | ===嵌套的AsciiDoctor表 其他
除了出色的小丑功能外,AsciiDoc还具有许多语法“技巧”,使文档更加一致。 在这里,我将不涉及太多细节,仅列出其中一些:
- 硬性休息:您不再需要插入空白行来分隔两个段落或内容。 只需在行尾添加一个加号,就可以完成!
- 列表延续:直接在父列表项或子列表项中添加描述性段落或构件块。
- 标题:一种小的视觉增强效果,使内容更具可读性。
- 列表:借助内置属性,您可以进行有趣的修改,例如定义起始编号,创建带有反向编号的列表,甚至是带有命令列表且没有任何文本的列表。
- 数学公式和公式:要插入任何复杂度的数学公式,只需在文档标题中设置
stem属性。
这些技巧几乎是无限的-随着您更好地学习AsciiDoc,您会发现更多有趣的方面。
结论
实际上,令我惊讶的是,有这么多人认为Markdown是一个非常强大的文档记录工具。 尤其要考虑出现在“中型”上的具有类似主题的文章数。 所有这些故事的前提几乎都是相同的。 您从一个简单的文档或一组文档开始。 在这一点上,选择Markdown的本能很好。 快速学习曲线和原始语法似乎是一个成功的组合。 但是,随着文档的发展以及您需要更复杂的东西,Markdown的简单性成为最大的缺点。 最终,您最终会使用破坏便携性或寻找更好替代品的风味(以克服固有的局限性)。
它使我想起了一段时间前发现的两个有趣的博客文章。 在第一个中,Eric Holscher(“阅读文档”和“编写文档”的共同创始人)讲述了为什么不应该使用Markdown进行文档编制。 他的文章看起来很有说服力,因为我倾向于相信反对Markdown的人的观点,而他正在开发一种同时支持Markdown和reStructuredText的产品。 在第二篇文章中,汤姆·克里斯蒂(Tom Christie)试图驳斥埃里克(Eric)的论点。 但是他的论点颇具争议,因为汤姆只描述了使用Markdown的案例。 Tom坚持使用Markdown的答案很明确-他的项目很大(由MkDocs托管),但是除了底层的代码块外,什么也没有。 当然,Markdown在这里足够好。
正如我之前说的,Markdown具有许多现成的限制,这些限制基于现有的CommonMark规范无法解决。 例如,节重用,包含源代码或动态变量。 结果,Markdown仅适合创建自述文件或简单知识库之类的基本文档。
反过来,AsciiDoc提供更好的语义丰富性,标准化,并支持多种输出格式(HTML,DocBook,PDF和ePub)。 与Markdown相比,它还支持更广泛的语法,因此主要重点是确保内容的最大可重用性,而语法被设计为扩展为核心功能。 这确实使AsciiDoc成为正确的投资,因为它是用于创建任何大小的文档(包括自动生成的API文档)的完整,功能齐全的工具。
最后...
Markdown的发明者John Gruber认为:
Markdown的语法仅用于一个目的:用作Web编写的格式。
因此,我想以最简单的结论结束本文:
不要将Markdown用于并非旨在做的事情。 例如,编写文档。
最初由 Antonio 在 mister-gold.pro上发布 。









