2018-02-23

猎数博客

数据挖掘,机器学习

markdown语法及pandoc扩展

作者:江航 / 2016-01-20 / (阅读 9,404 次) /



这里参考markdown官方说明分类介绍markdown的各种语法以及相关的pandoc扩展,其中pandoc的扩展部分,参考内容为pandoc的使用说明。如果是pandoc扩展的部分,会在其中明确指出。在使用pandoc进行转换的过程中,如果想要取消某个扩展,可以使用markdown-<扩展的名字>,比如想要把标题前空行的扩展去掉,可以使用pandoc -f makrdown-blank_before_header -t html -O about.html about.md。另外如果只是想使用某个扩展而其他的扩展都不要,可以使用markdown_strict+<扩展的名字>,比如markdown_strict+blank_before_hader。其中的markdown_strict表示标准的不带任何扩展的markdown语法。

标题

对于标题,只需要在其前面加上#就可以了。#的数量指定了标题的级别。最深为六级。

# 1号标题
## 2号标题
### 3号标题
#### 4号标题
##### 5号标题
###### 6号标题

另外,对于1号和2号标题,有另外一种语法,代码如下:


1号标题
=======

2号标题
-------

这个效果和上面的1,2号标题一样。这种风格来自另一个轻量级的标记语言—setext1,它的全称是Structure Enhanced Text。因此这种标题被称为setext风格的标题。

pandoc 扩展:标题前空行 blank_before_header

pandoc中,需要在标题的上一行留出一个空白行。因为普通行文中,被#号顶头的可能性很大,强制要求前面留出一个空行,行文时出现#号开头的行就没什么问题了。

pandoc 扩展:标题属性 header_attributes

标题行后面可以使用这样的语法来添加标题属性,这个属性通常为HTML和Latex使用。其语法为

# 标题{#id .class .class key=value key=value}

其中的id是最有用的,通常用于文内的交叉引用。使用id做文内引用的方法是 [标题名](#id),这样在生成的html和pdf文档中就会有到这个标题的超链了。其中的标题名不必要和该标题的名字一样,只要保证#id一样就可以了。

pandoc扩展:自动生成ID auto_identifiers

在没有指定标题id的情况下,pandoc会自动为每个标题生成一个id,生成id的方法是

  • 移除所有格式,链接等。
  • 移除所有标点符号(下划线,减号除外)
  • 用减号替代所有的空格
  • 將所有英文字母转为小写
  • 移除第一个字符前的所有内容(ID 不能以数字或标点符号开头)。
  • 如果剩下为空串,则使用section作为ID

由以上的规则知,如果标题为中文的情况下,基本上就什么都不剩啦。所以在使用pandoc的时候,通常要把这个扩展关掉。

如果指定了--section-divs选项,那么在生成的文档中,每个小节都会用div包住,并用该标题的id作为这个div的id。这样做的好处是,可以使用javascipt来对整个小节进行操作。

pandoc扩展:默认标题引用 implicit_header_references

todo

列表

无序列表

这是代码:

* item 1
* item 2
* item 3

效果如下:

  • item 1
  • item 2
  • item 3

这里的*可以替换成+-,效果一样。各个列表项之间可以加入空行。

有序列表

1. item 1
1. item 2
1. item 3

效果如下:

  1. item 1
  2. item 2
  3. item 3

注意这里和无序列表的区别,前面的*号换成数字,这里数字的具体值并不重要,全部写成1就可以了,编译器会自动给它们编号的。

嵌套列表

无需和有序列表、无序列表之间以及有序列表之间都可以嵌套,如下述代码

* item 1
    1. sub item 1
    1. sub item 2
    1. sub item 3
* item 2
* item 3

效果如下:

  • item 1
    1. sub item 1
    2. sub item 2
    3. sub item 3
  • item 2
  • item 3

注意这里的嵌套列表,需要缩进四个空格

多段列表

有时候,每个列表项都需要几段话来说明,这这种情况下,后面的段落需要有四个空格的缩进,段内需要换行时使用两个空格,如下所示

1. 这是item1 , 假设我们有很长的很长的很长的很长的  
    很长的很长的很长的很长的很长的很长的很长的说明

    这是说明的第二段,很长的很长的很长的很长的很长的  
    很长的很长的很长的很长的很长的很长的说明

    这是说明的第三段,很长的很长的很长的很长的很长的  
    很长的很长的很长的很长的很长的很长的说明

2. 这是项目2,它的说明不怎么长

效果如下:

  1. 这是item1 , 假设我们有很长的很长的很长的很长的
    很长的很长的很长的很长的很长的很长的很长的说明

    这是说明的第二段,很长的很长的很长的很长的很长的
    很长的很长的很长的很长的很长的很长的说明

    这是说明的第三段,很长的很长的很长的很长的很长的
    很长的很长的很长的很长的很长的很长的说明

  2. 这是项目2,它的说明不怎么长

段落和换行符

段落之间有一个空行。如果没有空行,那么它们会被认为是一个段落。同一个段落中不同的行之间的换行符会被一个空格代替。这个对于中文而言,造成的后果是,段落中会莫名其妙的多出几个空格,看着奇怪。pandoc中有一个扩展能自动处理这种换行符,这个扩展叫east_asian_line_breaks,这个扩展在pandoc中没有被缺省的打开,所以需要手动打开,即使用-from markdown+east_asian_line_breaks,这个扩展是在pandoc的1.16版本中实现,此前的版本中是没有这个扩展的。因此,如果你使用这个扩展是发现这个扩展不认识,那你需要升级你的pandoc的版本。

一行结束时,如果要强制换行,可以在行尾输入两个及以上空格。不然,pandoc会以上面的方式进行段内换行的处理。

引用

使用>来表示引用

> 这是引用
> 这还是引用

效果如下:

这是引用 这还是引用

在实际使用中,你可以只在第一行写上>,后面的行可以省略。直到碰到空行,这个引用会一直有效。引用可以嵌套,即引用中还可以有引用,使用方法,如下所示

> 你好,这是第一层引用

> > 这是第二层引用,很长的引用
这是第二层引用,很长的引用
这是第二层引用,很长的引用

以上代码产生的效果如下:

你好,这是第一层引用

这是第二层引用,很长的引用 这是第二层引用,很长的引用 这是第二层引用,很长的引用

注意这里的第二层引用和第一层引用之间的空行。pandoc中有一个扩展叫blank_before_blockquote,也就是在区块引言之前要有一个空行。否则不会被认为是区块引言。

加粗、斜体及删除线以及intraword_underscores扩展

代码:

**加粗**的语法
第二种__加粗__的方法
这个是*斜体*
第二种_斜体_
这里是~~删除线~~

效果如下:


加粗的语法
第二种__加粗__的方法
这个是斜体
第二种_斜体_
这里是删除线


有上面的生成效果看出,其中使用*作为加粗和斜体的生效了,但是使用_作为加粗的却没有效果,原因在于pandoc的另一个扩展intraword_underscores,这个扩展的意思是pandoc不会把文字中间的_解释为加粗的语法,因为pandoc认为在文字中使用_是一个普遍的现象。如果解释为加粗反而会带来不便,因此如果要在文字中间使用强调(加粗)语法,请使用*

链接

行内链接

代码:

[猎数博客](http://www.bagualu.net/wordpress)

效果如下:

猎数博客

链接的url后面可以跟title,格式为[文字](url title),url和title之间有一个空格,title需要用引号或者小括号包起来 如下所示:

代码:

[猎数博客](http://www.bagualu.net/wordpress "关注科技,数据挖掘")

效果:

猎数博客

参考链接

在参考链接中,链接和内容可以分开,这样有多个同样的链接时,只需要写一次,如下所示,其中链接的内容可以单独写在文章的下面。

- [文章1][1]
- [文章2][2]
- [文章1][1]

[1]: http://www.bagualu.net/wordpress/archives/5284
[2]: http://www.bagualu.net/wordpress/archives/5336

这段代码产生的效果如下:

其中第二个括号的数字可以为文字,这是用作区别各个参考链接的标识。比如[文章1][artical1] , 第二个括号中的标签不区分大小写。

如果第二个放括号为空或者没有第二个方括号,也可以做一个参考链接,此时,第一个中括号的内容就时标签内容,如[my web] , 在后面的参考链接部分只要写上[my web]: http://xxx.com就可以了。这是一个隐式的参考链接。

自动链接

在不指定链接文字的情况下,可以用这个语法直接生成一个链接

<http://www.bagualu.net/wordpress>

生成的链接效果为:

http://www.bagualu.net/wordpress

图片

代码:

![猎数博客](http://www.bagualu.net/wordpress/wp-content/themes/xuyang2/images/logo2.png)

效果如下:

和前面的链接一样,可以使用一个单独的中括号,然后在后面给出链接。也可以在链接后给出图片的alt。如

![猎数博客](url "alt")

或者![猎数博客] , 然后在最后面给出[猎数博客]: http://www.bagualu.net "科技博客"这样的图片链接。

水平线

代码:

---
***

效果如下:



注意,markdown中还有一种语法结构叫YAML元数据块,这种块以---开头,以---...结尾,因此,在使用多条水平线的时候,有可能与这个块混淆,因此,建议在使用水平线的地方,使用多余三个的-,这样可避免这种混淆。

定义

pandoc定义扩展definition_lists

可以用下面的方式来给出一个定义

词语1

 :    词语1的定义

    词语1的第二段定义
第二段定义是多行的

词语2

 :    词语2的定义

这段代码产生的效果如下:


词语1

词语1的定义

词语1的第二段定义 第二段定义是多行的

词语2

词语2的定义


其中词语所在行必须独占一行。词语后面的空行是可选的。

定义部分以:或者~开头,前面可以有一个或者两个空格。

一个词语可以有多个定义。每个定义可以有一个或多个块,其中可以包含代码,列表等。注意这里的每个块必须有四个空格的缩进(包括第一个块,四个空格从:或者开始计算,不包括这两个标点符号前面的空格,也就是这两个符号之后要有四个空格,然后才是定义的内容),不然不会被认为是一个有效的定义列表。

pandoc实例扩展example_lists

实例扩展使用@开始,如下所示

(@)  第一个实例,编号为1。
(@good)  第二个实例,编号为2。
关于上面这个实例的更多解释
(@)  第三个实例,编号为3。

可以像这样引用前面定义的实例,如请参考(@good)

生成的效果如下:


  1. 第一个实例,编号为1。
  2. 第二个实例,编号为2。 关于上面这个实例的更多解释
  3. 第三个实例,编号为3。

可以像这样引用前面定义的实例,如请参考(2)


代码

缩进代码块

一个以四个空格字符开头的段落被认为是代码,其中的字符不会被特殊处理,而是会被原样输出。注意其中的空行不需要使用四个空格。

行内代码

行内的代码使用`。 如`printf("hello world")`

pandoc扩展: 栅栏代码块 fenced_code_blocks

大段的代码可使用```或者~~~包起来, 如

```c
int main(){
    return 0;
}
```

如果在代码中使用到了``` ,可以在开头栅栏中使用更多的`, 比如四个,然后在结束的地方使用同样多的`就可以了。

pandoc 扩展: 行块 line_blocks

行块是以|开头的连续行,注意这里|后面的空格。行与行间的距离在输出时会原样保留,每行前的空白也会保留。如下所示

| 你好,第一行
|   你好,这是第二行
|       第三行

你好,第一行
  你好,这是第二行
      第三行

这种语法有效的保留了行前的空格,在有些情况下可以对格式有很好的控制。

上下标扩展superscribesubscript

上下标通过~^来指定,这两个符号中间的内容为下标和上标,如下所示

H~2~O

2^10^ = 1024

效果如下:

H2O

210 = 1024

多段列表和缩进代码块

前面看到,多段列表后面的段落和缩进代码块都是使用四个空格来说明。那么在多段列表中要使用代码块应该怎么做呢? 假定有下面的多段列表

1. 这是一个多段列表的第一段

    这是一个多段列表的第二段,第二段继续,第二段
第二段,第二段。

    这是一个多段列表中的代码段,使用栅栏代码块

    ```c
    printf("hello world")
    ```

    不使用栅栏代码块的情况

    printf("hello world");

1. 列表的第二项,使用栅栏代码块,但是不缩进的情况

```c
printf("hello world");
```

1.  多段列表的第三项,跟在一个没有缩进的栅栏代码块后面,它的标号会从1开始。

    多段列表第三项的第二段

这段代码的产生的效果如下:

  1. 这是一个多段列表的第一段

    这是一个多段列表的第二段,第二段继续,第二段 第二段,第二段。

    这是一个多段列表中的代码段,使用栅栏代码块

    printf("hello world")

    不使用栅栏代码块的情况

    printf(“hello world”);

  2. 列表的第二项,使用栅栏代码块,但是不缩进的情况

printf("hello world");
  1. 多段列表的第三项,跟在一个没有缩进的栅栏代码块后面,它的标号会从1开始。

    多段列表第三项的第二段

由上面的示例知,在多段列表中,要使用代码块,需要四个空格缩进,同时使用栅栏代码块,单独的缩进不会被认为是代码。另外,如果在使用栅栏代码块时不进行四个空格的缩进,会被认为是一个列表的结束,后面的列表项目不会继续编号,而是会从1开始重新编号。

表格

标准的markdown中没有表格的支持,关于表格的内容都属于是pandoc的扩展

pandoc表名扩展table_captions

这个扩展可以在表前或者表后使用一个独立的段来给出表格的名字,该段以Table:或者:开头。如后面所示

简单表格扩展simple_tables

简单表格的代码是这样的:

   右对齐   左对齐     中间对齐     缺省
--------    -------  ----------- --------
       1     2          2           3
   3         2         3           3

  Table: 简单的表格

这个代码产生的表格为:

简单的表格
右对齐 左对齐 中间对齐 缺省
1 2 2 3
3 2 3 3

表格的对齐方式为,表头与第二行虚线之间的对齐关系。表格下面必须有一个空白行。其中表头可以省略,此时必须在表格结束的地方添加一行虚线。如下所示


--------    -------  ----------- --------
       1     2          2           3
   3         2         3           3
--------    -------  ----------- --------

  Table: 简单的表格
简单的表格
1 2 2 3
3 2 3 3

多行表格扩展multiline_tabes

和上面的简单表格一样,多行表格只是让每个单元格或表头可以跨越多行。而表格的每行之间要有一个空行,另外,表头和表尾的虚线行不能省,如下所示


---------------------------------------------
   header    heander      多行的  
     1          2          内容
----------  ----------   --------------------
   单元格1    单元格2       多行的  
                            单元格

   单元格3    单元格4       单元格5
----------------------------------------------

: 多行的表格

其产生的表格如下:

多行的表格
header 1 heander 2 多行的 内容
单元格1 单元格2 多行的 单元格
单元格3 单元格4 单元格5

管道表格扩展pipe_tabes

管道表格可显示的指定各列的对齐方式,但是管道表格的单元格不可以是多行的,不能包含块级元素。下面是一个例子

| Right | Left | Default | Center |
|------:|:-----|---------|:------:|
|   12  |  12  |    12   |    12  |
|  123  |  123 |   123   |   123  |
|    1  |    1 |     1   |     1  |
: 管道表格,对齐方式通过上面虚线中的`:`指定

它产生的表格如下:

管道表格,对齐方式通过上面虚线中的:指定
Right Left Default Center
12 12 12 12
123 123 123 123
1 1 1 1

emacs风格的表格

在emacs中,可以通过M-x table-insert来插入一个文本的表格,其基本格式如下

+-----+-----+-----+
|c1   |  c2 |  c3 |
+-----+-----+-----+
|d1   | d2  | d3  |
+-----+-----+-----+
| e1  |e2   |  e3 |
+-----+-----+-----+

其显示出的效果如下:

c1

c2

c3

d1

d2

d3

e1

e2

e3

如果你喜欢使用emacs,那么插入这样的表格还是很方便的。

表格中的虚线行和Setext风格的标题

由上面的介绍知,在表格中会使用到虚线,而虚线如果放在一句文字下面也是二号标题的Setext风格表示,因此这里需要把这两种情况区分开。可行区分的方法是,表头的虚线行上方留出一个空行,这样就不会被识别为标题行。

对于简单的表格,表头下方的虚线是分为多段的,而标题行下的虚线是一条没有断开的虚线行,因此这种情况下,二者也可以被区分开。

元数据块

这一小部分内容可以在后面学习过pandoc模板以后在来看。

在markdown中可以嵌入元数据块,这些块用来给定文档的一些属性,这些块分为两种,一种是使用在文章最前面的标题块,还有一种是使用在文中任意地方的,叫YAML块,分别介绍如下:

pandoc标题块扩展 pandoc_title_block

这个块放在文件的最前面,格式如下:

% 标题
% 作者,多个作者使用分号分开
% 日期

这样的内容将会被解析,解析的结果可能会出现在最后的文档中(比如在pdf或者html的标题以及作者部分,之所以说“可能”,是因为自定义模板中可能没有这些输出)。这三个元素也可以只有其中一个或者两个,在这种情况下,在相应的地方要留出空行,比如

% 我的标题
%
% 2016年4月6日

标题以及作者可以是多行的,第二行以后的文字需要缩进。多个作者可使用分号分开,也可使用多行格式,例如:

% 我的标题
  多行的标题
% 作者1
  作者2
% 2016年4月6日

日期必须在一行,不能分行。

关于这些元素在最后输出文件中的位置,可以参考后面的pandoc模板部分。

pandoc YAML元数据扩展yaml_metadata_block

yaml块是用---开头,以---或者...结束的一个块,这中块可以出现在文中的任何地方,每个块开始的地方,必须在前面留出一个空行。yaml块也可以放在一个独立的文件中,在使用pandoc的时候,把这个yaml文件作为输入就可以了。pandoc在处理多个输入文件的时候,总是把这些文件合成一个文件,然后再进行处理,因此一个单独的yaml文件是不会有问题的。但是请注意一定要以---把yaml块包起来。

下面是一个处理独立yaml文件的命令行

pandoc aa.md metadata.yaml -s -o aa.html

yaml块中定义的变量会加入到文件的metadata中。如果一个变量被多个块定义,那么它的值为第一个被定义的地方,后面的定义无效。另外如果一个变量以下划线结束,它将不会被pandoc处理

下面是一个元数据块的例子,第一行中包含:,因此需要一个引号包起来,在abstract定义中,使用|来开始一个缩进的块。

---
title:  'This is the title: it contains a colon'
author:
- name: Author One
  affiliation: University of Somewhere
- name: Author Two
  affiliation: University of Nowhere
tags: [nothing, nothingness]
abstract: |
  This is the abstract.

  It consists of two paragraphs.
...

在上面的这个块中,作者部分有自定义的域,因此需要一个自定义的模板来显示它们,下面是一个模板的例子:

$for(author)$
$if(author.name)$
$author.name$$if(author.affiliation)$ ($author.affiliation$)$endif$
$else$
$author$
$endif$
$endfor$

数学公式

标准的markdown中没有数学公式的支持,不过可以通过MathJax的支持来在页面上显示数学公式,比如下面的例子:

$x^2 + y^2 = z^2$

效果如下:

\(x^2 + y^2 = z^2\)

要使用,可在页面中添加下面的代码:

<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
    extensions: ["tex2jax.js"],
    jax: ["input/TeX","output/HTML-CSS"],
    tex2jax: {inlineMath: [["$","$"],["\\(","\\)"]]}
  });
</script>
<script type="text/javascript" src="/MathJax/MathJax.js"></script>

你需要在你网站的根目录下有MathJax的包。

对于pdf而言,不需要使用javascript,直接使用pandoc生成就可以了,比html要方便。

嵌入html代码

在markdown文件中可以嵌入html代码,对于嵌入的html代码有两种情况

段级html代码嵌入及pandoc扩展markdown_in_html_blocks

嵌入的html代码段必须在头上和结尾出与markdown的其他部分用一个空行分开,并且起始tag和结束tag行前不要有空格或者tab。其次,在标准的markdown语法中,html代码段中间的markdown语法不会被处理。比如你用html代码段插入一个表格

<table>
<tr><td>[博客](http://www.bagualu.net)</td><td>**col2**</td></tr>
</table>

其中的链接和**不会被标准的markdown处理。而在pandoc中有一个扩展叫markdown_in_html_blocks , 打开这个扩展,可以使html代码块中markdown被解析。在pandoc中,上面的代码会生成链接和强调。

博客 col2

由此可见html代码段中间的markdown语法已经被处理。

行级的html代码嵌入

除了在段级的html代码,在行级嵌入html代码,可以直接使用标签就可以了。行级标签下的markdown语法会被处理。

pandoc扩展raw_html

严格说这不算是一个扩展,因为标准markdown中就有这个支持,这里做成一个扩展是为了可以方便的关掉它。对于嵌入的html格式,当输出为latex时,其中的html代码会被直接丢掉。由此可见,要在markdown中插入表格是一个比较麻烦的事情,因为不同格式下,其代码是不一样的。

pandoc扩展raw_tex

除了在markdown中嵌入html格式外,也可以在其中嵌入latex的代码。但是对于latex格式而言,其中的markdown格式是肯定不会被解释的。也就是说没有一个对应的markdown_in_tex_blocks的扩展来解释tex中的markdown语法。

pandoc引用扩展citation

这是关于如何添加参考文献的内容。

pandoc脚注扩展footnotes

pandoc可以使用下面的方式来产生脚注

这是一个脚注的例子[^1],第二个脚注的例子[^note2]

[^1]: 脚注的内容,这个内容不必要在文章最后,只要不包含在其他的块级元素中就可以了
[^note2]: 脚注的内容,更多内容更多内容更多内容
    第二行以后的脚注内容需要缩进
    更多内容更多内容更多内容

    更多内容更多内容

脚注结束的地方,不缩进就可以了

查看其实际产生的结果

这是一个脚注的例子2,第二个脚注的例子3

脚注结束的地方,不缩进就可以了

YAML语法简单介绍

前面提到了markdown中的元数据块可以通过YAML语法来指定。

YAML全称为(Yet Another Markup Language),也是一种标签语言。是以数据为表达目标的语言。通过空格和分行来分隔数据单元。下面是一个实例:

house:
  family:
    name: Doe
    parents:
      - John
      - Jane
    children:
      - Paul
      - Mark
      - Simone
  address:
    number: 34
    street: Main Street
    city: Nowheretown
    zipcode: 12345

其中连续的项目通过-来表示,map结构的key/value结构使用:来分隔。要求同一级别的数据前面缩进的空格数要相同。

在上面的例子中,Simone可使用hourse.family.children[3]来引用。

其他的相关内容:

  • 要添加注释,使用#符号。
  • 布尔值使用 truefalse
  • 空值使用 null 或者 ~
  • 数值支持
    1. 整数 ,如12
    2. 八进制数, 如012
    3. 16进制数, 如0xC
    4. 浮点数 , 如1.24
    5. 指数 , 如1.2e3
    6. 无穷: .inf

结束前,我们看这样一个例子:

title:
 - type: main
   text: My Book
 - type: subtitle
   text: An investigation of metadata

在这个例子中,要访问“My Book”,应该使用title[1].text。这里的两个-表示title下是一个数组结构。


  1. https://en.wikipedia.org/wiki/Setext

  2. 脚注的内容

  3. 脚注的内容,更多内容更多内容更多内容 第二行以后的脚注内容需要缩进 更多内容更多内容更多内容

    更多内容更多内容



本文地址: http://www.bagualu.net/wordpress/archives/5284 转载请注明






相关文章

  • markdown语法及pandoc扩展( 9,404 )
  • 用knitr动态生成markdown文件的内容( 7,909 )
  • 用pandoc把markdown转化为pdf文档( 6,112 )
  • 通过Rmarkdown包调用knitr和pandoc( 4,366 )
  • R + markdown简介( 3,626 )
  • bookdown( 3,568 )
  • 用pandoc把markdown转换为html( 2,563 )
  • 利用多篇markdown文件生成pdf书籍( 1,282 )
  • 标准版和pandoc版的markdown( 1,171 )
  • markdown 高级语法( 1,097 )
  • Leave a Reply

    您必须登录以发表评论,

    沪ICP备11036560号
    联系我: jianghang at bagualu.net