目录:网上冲浪指南

AsciiDoc 简介

2020/03/29

If the Markdown content does not result in the "right" output (defined as output that the author wants, not output that adheres to some dictated system of rules), the expectation is that the author should continue experimenting by changing the content or the processor to achieve the desired output.

IETF RFC7763
The text/markdown Media Type

Mardown 是一种很简单的标记语言,人人都可以很容易的入门,但是当你想要更进一步优化排版的时候,你会发现 Markdown 并不支持你想要的排版,于是你只好内嵌各种 HTML 然后为这些 HTML 标签添加样式来达到你想要的效果。这个时候再回过头看你的文章,你发现自己好像变成了一个前端开发者。

这不优雅,你也不想这样,于是你选择去找支持这些功能的编辑器、插件,这些编辑器的 Markdown 实现各有“风味”,在经过一番尝试过后,你最终懂得了尺有所长,寸有所短的道理,没有那种“风味”的 Markdown 能够完全满足你的口味。现在你该从 Markdown 的世界里面走出来了,来看看 AsciiDoc 。

与 Markdown 不同,AsciiDoc 最开始是被设计作为 DocBook XML 格式的纯文本替代,而 DocBook 是设计用来编写有关计算机硬件和软件的技术文件,一次编写完成后可以转换成 PDF、EPUB、CHM、HTML 等格式,所以 AsciiDoc 在内容排版、格式样式的控制上要比 Markdown 强很多。

不过特性多并没有让 AsciiDoc 的语法变得过于复杂,这主要得益于 AsciiDoc 的语法具备一定的拓展性,再多的特性也可以通过同一套语法规则来实现。

AsciiDoc VS Markdown 常用语法对比

特性 Markdown AsciiDoc

加粗

**bold**

*bold*

**b**old

**b**old

斜体

*斜体*

_斜体_

做不到

__斜__体

monospace

`monospace`

`monospace`

monospace

`mono`space

``mono``space

链接

[Example](https://example.com)

https://example.com[Example]

参照引用

参考[使用说明](#usage)

<h2 id="usage">使用说明</h2>
参考<<_使用说明>>

== 使用说明

锚点

 <h2 id="usage">使用说明</h2>
[#usage]
== 使用说明

行内锚点

<span id="step-1">第一步</span>关机
[[step-1]]第一步关机

行内图片

![Logo](/logo.png)

image:logo.png[Logo]

块级图片

<img style="display: block;" src="Logo.png" alt="Logo" />

image::logo.png[Logo]

标题

## Heading 2
## Heading 2
== Heading 2

块级引用

> Hello
>
> World
____
Hello

World
____

字面块

    echo hello world
行首添加一个或者多个空格进行缩进
 echo hello world
使用专门的块分隔符
....
echo hello world
....

代码块

```js
console.log('hello')
```
  1. 兼容 Markdown 语法

  2. AsciiDoc 语法

    [source, js]
    -----
    console.log('hello')
    -----

无序列表

* item1
* item2
  * item2.1
* item3
* item1
* item2
** item2.1
* item3

有序列表

1. first
2. second
3. third
. first
. second
. third

分割线

***
---
'''

警告提示

这个没有

NOTE: 温馨提示

块标题

这个也没有

.系统要求
* 1G RAM
* Win7 以上

自定义 CSS 类

这个也没有

[.heimu]_你知道的太多了_

从这份表格中不难发现 AsciiDoc 语法在大多数情况下是要比 Markdown 更简洁的,而且功能上要比 Markdown 要丰富,尽管有些 Markdown 编辑器可以渲染一些拓展语法,但是要记住,这些拓展出来的语法并非是 Markdown 本身的一部分,而是这个特定的 Markdown 编辑器的私货,同样一份文件,你看到的渲染结果可能跟其他人看到的并不一样。

上面的表格将 AsciiDoc 拉到跟 Markdown 一个水平进行对比,这对 AsciiDoc 来说是不公平的,它有很多实用的功能在 Markdown 中根本不存在,例如表格的单元格合并、块级内容设置标题等。

代码块的相关功能

在展示代码块的时候,你可能需要将一段代码中的某一部分更加突出的展示出来,Markdown 用户的做法就是给代码加上一段令人影响深刻的注释,AsciiDoc 用户则选择使用自带的高亮功能。

[source, js, subs=+quotes] (1)
----
const a = require('foo');
##const { b } = require('bar');##
a.func(b);
----
1 这里的 subs 是代码块的一个属性,用来设置 AsciiDoc 语法替换的功能;+quotes 表示启用行内语法标记的替换。

除了高亮之外其他的行内标记语法都可以通过这种方式在代码块中使用。

const a = require('foo');
const { b } = require('bar');
a.func(b);

有时候仅仅高亮出来还不够,我们还想附上一段解释性的说明,Markdown 用户继续选择使用一段注释掺杂在代码块中,而 AsciiDoc 用户可以使用 Callout 功能。

[source, js]
----
const a = require('foo');
const { b } = require('bar'); // <1>
a.func(b);
----
<1> 这里加载了 `bar` 包,并将其**解构**(此处省略很多字)……

AsciiDoc 可以自动的将代码中的特定格式注释(// <x># <x>)解析为标注符号,随后只要在代码块的下方为每个标注编写说明,AsciiDoc 就可以生成一份标注列表。

const a = require('foo');
const { b } = require('bar'); (1)
a.func(b);
1 这里加载了 bar 包,并将其解构(此处省略很多字)……

有时候你还可能会同时列出好几个代码块,为了区分每个代码块,AsciiDoc 还提供了代码块命名的能力:

.index.js
[source, js]
----
const a = require('foo');
const { b } = require('bar');
a.func(b);
----

不仅仅是代码块,每个块级的元素都可以在块前使用 .Title 的方式来为块添加一个标题。

index.js
const a = require('foo');
const { b } = require('bar');
a.func(b);

更加语义化的提示信息

在 Markdown 中想要突出一段提示信息的话,能做的无非就是加粗、斜体,AsciiDoc 则提供了更加恰当的展示元素——Admonition

AsciiDoc 提供了 5 中类型的提示:

  • NOTE

  • TIP

  • IMPORTANT

  • CAUTION

  • WARNING

在一段文字的开头加上 `提示类型: ` 就可以将其标记为提示性段落:

TIP: 在非洲,每 60 秒就会过去一分钟
在非洲,每 60 秒就会过去一分钟

如果你的提示内容比较长,需要多个段落来说明,那么就需要先使用 ==== 包围你的内容,这样会创建一个样例块,然后在样例块的前面加上 [提示类型] 就可以将整个样例块标记为提示性块:

[WARNING]
====
永远不要用下面的命令来清理电脑!

```shell
sudo rm -rf /
```
====

永远不要用下面的命令来清理电脑!

sudo rm -rf /

更方便的列表

AsciiDoc 使用 * 来创建无序列表,这跟一些富文本编辑软件的快捷输入习惯一样,如果需要创建多级列表,只需要重复 * 就可以了。

* item1
** item1.1
* item2
** item2.1
*** item2.1.1
* item3
  • item1

    • item1.1

  • item2

    • item2.1

      • item2.1.1

  • item3

有序列表的创建方式也是一样的,只需要把 * 换成 . 就行了,AsciiDoc 会自动的进行编号。在我看来,这种要比 Markdown 的列表语法要更好:

  1. 不需要维护缩进

  2. 调整列表项位置时不用调整编号

AsciiDoc 的列表项默认只能容纳一段内容(文字间不能存在空行),如果想在一个列表项中容纳多个块级元素,需要使用 + 来延续列表项。

列表项中嵌套表格、代码块
* who is your daddy
+
[%header]
|===
|Foo

|bar
|foo bar
|===
+
[source, shell]
-----
echo 23333
-----

* there is no spoon
Example 1. 显示效果
  • who is your daddy

    Foo

    bar

    foo bar

    echo 23333
  • there is no spoon

所以,在 AsciiDoc 中处理列表嵌套时不用担心缩进的问题,只需要简单的从上往下写就好了。

更实用的列表

除了上面两种常见的列表之外,AsciiDoc 还提供了几种特殊样式的列表,例如 Q&A 以及定义列表。

.Q&A
[qanda]
电脑检测不到键盘怎么办?::
  按 kbd:[F3] 继续。
电脑检测不到鼠标怎么办?::
  点击重试按钮重新检测。

// (1)

HTML:: 超文本标记语言
JavaScrip:: Java 脚本语言

//

[horizontal]
HTML:: 超文本标记语言
JavaScrip:: Java 脚本语言
1 使用 AsciiDoc 注释标记强行分割列表
Q&A
  1. 电脑检测不到键盘怎么办?

    F3 继续。

  2. 电脑检测不到鼠标怎么办?

    点击重试按钮重新检测。

HTML

超文本标记语言

JavaScrip

Java 脚本语言

横着排版的定义列表
HTML

超文本标记语言

JavaScrip

Java 脚本语言

排版更灵活的图片

.山上的日落 (1)
[link=https://www.flickr.com/photos/javh/5448336655] (2)
[.right.text-right] (3)
image::https://d33wubrfki0l68.cloudfront.net/dbfc383d23401ccbed7262a1822dba9babecb949/69a10/images/sunset.jpg[Sunset,300,200]  <5>(4)
1 设置图片块的标题
2 把图片变成可点击的链接
3 right 设置图片浮动到右侧;text-right 设置图片右对齐
4 image::图片地址[属性] 定义一个图片块
5 [属性] 中的内容分别为替换文字、宽度、高度
Sunset
Figure 1. 山上的日落

嵌入行内图片只需要把 :: 换成 : 就可以了,如果需要定义行内图片的链接等属性,只需要写在属性栏位就可以了:

在如今的世界中 image:https://upload.wikimedia.org/wikipedia/commons/3/35/Tux.svg[Linux,25,35,link=https://www.linux.org/] 无处不在。

在如今的世界中 Linux 无处不在。

功能完善的表格

AsciiDoc 的表格跟上面介绍的几个功能比起来要稍微复杂一些,因为表格可以控制的选项实在是太多了,不过我们可以先从最基本的形式入手,看看 AsciiDoc 的表格语法长啥样。

|=== (1)
(2)
| col 1, row 1 | Cell in col 2, row 1 (3)
(4)
| col 1, row 2
| Cell in col 2, row 2 (3)

| col 1, row 3 | Cell in col 2, row 3
|=== (1)
1 表格是一个块级元素,使用 |=== 分隔
2 在第一行之前插入一个空行,表示第一行不是表头
3 | 表示创建一个新的单元格,同一行的单元格可以一行写完,也可以分多行编写
4 插入空行表示在表格中插入一个新行

col 1, row 1

Cell in col 2, row 1

col 1, row 2

Cell in col 2, row 2

col 1, row 3

Cell in col 2, row 3

这种简明的语法让 AsciiDoc 可以自动的推断出表格的列数,当然,你也可以手动的声明表格的列数:

[cols="3*"] (1)
|===

| col 1, row 1 | Cell in col 2, row 1

| col 1, row 2
| Cell in col 2, row 2

| col 1, row 3 | Cell in col 2, row 3
|===
1 3*1,1,1 的简写形式,表示表格有 3 列,3 列的宽度比例为 1:1:1。

AsciiDoc 列数的简单表达形式也可以跟完整形式混用,例如 2*,5,表示表格有 3 列,宽度比例为 2:2:5。

col 1, row 1

col 2, row 1

col 3, row 1

col 1, row 2

col 2, row 2

col 3, row 2

col 1, row 3

col 2, row 3

col 3, row 3

控制单元格内容的对齐方式也很简单,只需要在表示单元格的 | 前加上 水平对齐标记.垂直对齐标记 就可以了。

标记 作用

<

左对齐、顶部对齐

^

居中

>

右对齐、底部对齐

[cols="2*,5"]
|===

| col 1, row 1 | col 2, row 1
>| col 3, row 1 (1)

| col 1, row 2 | col 2, row 2
.>| col 3, row 2 (2)

^.>| col 1, row 3 | col 2, row 3 | col 3, row 3 (3)
|===
1 右对齐
2 底部对齐
3 水平居中并底部对齐

col 1, row 1

col 2, row 1

col 3, row 1

col 1, row 2

col 2, row 2

col 3, row 2

col 1, row 3

col 2, row 3

col 3, row 3

接下来,再进一步,让我们来尝试合并单元格!跟控制文本对齐的语法一样,我们也只需要在单元格 | 之前加上 列合并数.行合并数+ 的标记就可以了。

|===

| col 1, row 1
2+| col 2, row 1 (1)

| col 1, row 2
.2+| col 2, row 2  (2)
| col 3, row 2

| col 1, row 3
| col 3, row 3

| col 1, row 4
2.2+| col 2, row 4 (3)

|col 1, row 5
|===
1 合并第一行的二、三两列
2 合并第二行与第三行的第二列
3 合并第四、五行的二、三两列

col 1, row 1

col 2, row 1

col 1, row 2

col 2, row 2

col 3, row 2

col 1, row 3

col 3, row 3

col 1, row 4

col 2, row 4

col 1, row 5

表格小技巧
  • 如果表格块的第一行单元格前面没有空行且后面有至少一个空行,那么这一行将被当作表头处理。

  • 在表格块前面加上 [%header],就可以强制将第一行单元格设置为表头。

  • 在表格块前加上 [format=csv],就可以直接将 csv 格式的数据表扔到表格块。

最后

上面列举出来的只是 AsciiDoc 功能的冰山一角,但足以应对绝大多数的使用场景,不过如果想要将 AsciiDoc 运用自如,阅读官网的用户手册的过程必不可少。