用pandoc把markdown转换为html

markdown 到 html 的简单转换

第一个转换

markdown到html的转换是我们目前最感兴趣的,这里列出一些常用的方法。假设有以下的markdown文档abc.md, 内容如下:

    # 标题1
    
    ## 子标题1
    
    你好,这是一个测试

使用命令pandoc -f markdown -t html -o abc1.html abc.md, 生成的html文档abc1.html为:

<h1 id="标题1">标题1</h1>
<h2 id="子标题1">子标题1</h2>
<p>你好,这是一个测试</p>

如果想要一个完整的文档,可以添加-s参数。即pandoc -f markdown -t html -o abc2.html -s abc.md, 生成的文档为:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta http-equiv="Content-Style-Type" content="text/css" />
  <meta name="generator" content="pandoc" />
  <title></title>
  <style type="text/css">code{white-space: pre;}</style>
</head>
<body>
<h1 id="标题1">标题1</h1>
<h2 id="子标题1">子标题1</h2>
<p>你好,这是一个测试</p>
</body>
</html>

在生成的HTML中包含其他文件

如果要在markdown文件中包含其他的文件,可以使用pandoc的参数下面三个参数:

  -H FILENAME           --include-in-header=FILENAME                    
  -B FILENAME           --include-before-body=FILENAME                  
  -A FILENAME           --include-after-body=FILENAME  

这三个参数的意义显而易见,就是在头上,或者在文档最前面、最后面包含一部分内容。假设有一个头文件header.html为这个

<title>这是标题</title>

那么,pandoc -f markdown -t html -B ./header.html -o abc3.html -s abc.md生成的文件为:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta http-equiv="Content-Style-Type" content="text/css" />
  <meta name="generator" content="pandoc" />
  <title></title>
  <style type="text/css">code{white-space: pre;}</style>
</head>
<body>
<title>这是标题</title>
<h1 id="标题1">标题1</h1>
<h2 id="子标题1">子标题1</h2>
<p>你好,这是一个测试</p>
</body>
</html>

这里可以看见header.html中的内容被加入了。如果这里插入markdown格式的内容为是不会被处理的,它会原样放进去。

生成目录

pandoc可以自动文文章生成目录,方法是将各个级别的标题抽取出来,作成一个列表。

pandoc中,这个叫toc,全称为table of contents, 要生成toc,可以在pandoc的命令行指定参数 --toc或者--table-of-contents, 缺省情况下,目录的深度是3级,即--toc-depth 3, 你可以利用这个参数指定生成目录的深度。对于html而言,生成的目录链接会指向各个标题的id。如果各个标题的id都被正确生成了,那么目录应该是没有问题的。如果你发现有些标题没有生成正确的id或者是生成的链接有问题,请检查一下关于id生成的问题。

html中的标题属性

前面在markdown语法的pandoc扩展中有提到一个标题属性扩展,标题中的id属性会用来生成html标题的id,有时候你会碰到这种情况,即不是每个标题都生成了id,以至于生成目录(toc)中的有些链接是无效的。原因是pandoc的另一个扩展ascii_identifiers。如果这个扩展被开启,那么id会通过对标题进行处理以后得到的,处理的方法是留下ASCII字符,空格之类的符号用_代替。如果某个标题的内容是中文,那么就有可能没有id了,因为pandoc各种去掉之后,就什么都不剩了。这样导致生成的目录链接有问题,就是纯中文的标题会没有链接。

解决这个问题的方法是要么使ascii_identifiers扩展无效,要么就是在标题后面指定一个id,方法如下:

## 这是一个标题 {#title1}

### 这是下一级标题 {#subtitle1}

在标题后面的花括号中,指定一个id,生成的html中,该标题就会使用给定的id。而不会再去作处理。上面的markdown生成的html为:

<h2 id="title1">这是一个标题</h2>
<h3 id="subtitle1">这是下一级标题</h3>

如果不想手动来设置每个标题的id,你可以选择将ascii_identifiers这个扩展去掉。

交叉引用

前面提到了生成目录的方法,其中目录就是根据id来指向某个标题。在目录中是自动生成的。同样的,在文中,我们也可以手动的来建立这些链接,这样就生成了文中的内链。使用的方式是[标题名](#id),这样在生成的html中,就会生成相关的链接。 以上面的两个标题为例,假设我想要引用上面的二级标题,可以在文中写请参考[下一级标题](#subtitle)

pandoc 模板

在了解了pandoc把markdown转换为html的基本过程之后,可以更加详细地来看看一个完整的html文档是如何生成的。

pandoc使用一个html模板来生成一个html页面,我们可以使用命令pandoc -D html来查看缺省的模板, 它看起来像这样:

pandoc -D html
#> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
#> <html xmlns="http://www.w3.org/1999/xhtml"$if(lang)$ lang="$lang$" xml:lang="$lang$"$endif$>
#> <head>
#>   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
#>   <meta http-equiv="Content-Style-Type" content="text/css" />
#>   <meta name="generator" content="pandoc" />
#> $for(author-meta)$
#>   <meta name="author" content="$author-meta$" />
#> $endfor$
#> $if(date-meta)$
#>   <meta name="date" content="$date-meta$" />
#> $endif$
#>   <title>$if(title-prefix)$$title-prefix$ - $endif$$pagetitle$</title>
#>   <style type="text/css">code{white-space: pre;}</style>
#> $if(quotes)$
#>   <style type="text/css">q { quotes: "“" "”" "‘" "’"; }</style>
#> $endif$
#> $if(highlighting-css)$
#>   <style type="text/css">
#> $highlighting-css$
#>   </style>
#> $endif$
#> $for(css)$
#>   <link rel="stylesheet" href="$css$" $if(html5)$$else$type="text/css" $endif$/>
#> $endfor$
#> $if(math)$
#>   $math$
#> $endif$
#> $for(header-includes)$
#>   $header-includes$
#> $endfor$
#> </head>
#> <body>
#> $for(include-before)$
#> $include-before$
#> $endfor$
#> $if(title)$
#> <div id="$idprefix$header">
#> <h1 class="title">$title$</h1>
#> $if(subtitle)$
#> <h1 class="subtitle">$subtitle$</h1>
#> $endif$
#> $for(author)$
#> <h2 class="author">$author$</h2>
#> $endfor$
#> $if(date)$
#> <h3 class="date">$date$</h3>
#> $endif$
#> </div>
#> $endif$
#> $if(toc)$
#> <div id="$idprefix$TOC">
#> $toc$
#> </div>
#> $endif$
#> $body$
#> $for(include-after)$
#> $include-after$
#> $endfor$
#> </body>
#> </html>

在看了这个文档之后,你会发现其中有些html标签,还有一些特殊的标签和代码。下面来看看pandoc是如何解释这些特殊标签和代码的。

在进行模板处理的时候,pandoc中会自动生成一些变量,还有一些变量是用户用各种方式指定的。在模板中要引用一个变量使用$变量名$,模板中可以使用条件判断,形式如下:

$if(title)$
  <title>$title$</title>
$else$
  <title>缺省的标题</title>
$endif$

上面的意思是,如果定义了title变量,那么就输出title的内容,否则就输出缺省的标题。

另外有些变量中含有多个内容,比如需要包含的内容,此时可以使用for循环来打印其中的内容,如下所示

$for(header-includes)$
$header-includes$
$endfor$

另外,如果要在模板中打印$,使用$$就可以了。

有了这些知识,基本上就可以看明白模板中的内容了。基于此,我们也可以定义自己的模板。自定义模板写好之后,可以使用--template=FILENAME来指定模板文件。

pandoc模板中可以使用的变量

前面知道了如何在模板中使用变量,那么在pandoc中到底有哪些变量可以使用和如何设置呢?对于不同的输出文档而言,使用pandoc -D <format> 可以输出该格式的模板。其中可以看到模板中使用了哪些变量。对于其中使用的变量一般可以使用YAML元数据块来设定。也可以在命令行中使用-M参数来指定。

其中有一个重要的变量body,它是整个markdown的内容。这个是无法通过YAML或者命令行来设置的。



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




发表评论

电子邮件地址不会被公开。 必填项已用*标注