Pandoc 多Markdown转单PDF

Pandoc 简介

Pandoc, 免费的文档转换器, 支持常见的各种文件格式的相互转换, 如Markdown, HTML, EPUB, LaTeX, docx, RTF, PDF 等.

本篇以Windows下的多Markdown转单PDF为例, 最后也会介绍Ubuntu下的使用方法.

Pandoc 安装

Windows下的安装:

  • Pandoc: 直接到 Installing pandoc 下载安装.
  • MiKTeX: 直接到 Getting MiKTeX 下载安装, Pandoc默认使用 LaTeX 创建PDF, Windows上安装MiKTeX就包含了LaTeX. 安装完后, 打开 MiKTeX Console 检查MiKTeX及宏包的更新(第一次运行Pandoc转出PDF时, 可能会提示安装缺失的宏包)

安装完后, 检查和添加Pandoc和MiKTeX的环境变量

在这里插入图片描述

环境变量添加完, 首次需要在Powershell中刷新下环境, 让Powershell能找到MiKTeX一堆宏包exe文件的路径

$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User") 

pandoc-latex-template

如果用默认参数, pandoc xxx.md --pdf-engine=xelatex -o yyy.pdf 生成PDF, 会发现各种小问题, 如代码块未和正文明显区分, 代码块中的单行过长会超出文档边界等.

类似PPT套模版, Pandoc生成好看的PDF也需要一套好用的模版, 如这个star数超多的 pandoc-latex-template, 即大名鼎鼎的eisvogel.

下载最新的pandoc-latex-template的 Releases 压缩包, 解压后, 把 eisvogel.latex 文件放入 C:\Users\<Your-Username>\AppData\Roaming\pandoc\templates\ 目录下即可(没有就自己新建目录).

Readme和examples中也介绍了很多eisvogel可以调的参数, 如命令行中让代码块不显示行号 -V listings-disable-line-numbers=true 等.

字体安装

Pandoc默认参数不支持中文, 需要指定中文字体才可以, Powershell 中查看支持的中文字体:

fc-list :lang=zh

最好是安装一些商用免费的. 如 得意黑?, 华为的鸿蒙字体HarmonyOS Sans?, 小米的MiSans?

下面的脚本以 阿里巴巴普惠体微软cascadia-code 字体为例, 下载压缩包解压后, 双击ttf文件即可在Windows上安装. 这两种字体的数字’1, 小写l和大写I是可以分清楚的, 数字0 和大写O也能分清.

Powershell 脚本

现在有以下一些文件

> wsl tree -L 2                                  
.
├── 2022
│   ├── docker.assets	# .assets文件夹里面是md文件对应的图片
│   ├── docker.md
│   ├── wsl2.assets
│   └── wsl2.md
├── 2023
│   ├── rusterr.md
│   ├── test0.assets
│   ├── test0.md
│   ├── zellij.assets
│   └── zellij.md
├── cover.md
├── logo.png
└── md2pdf.ps1

文件 cover.md 是手写的封面文件, 主要是设置主标题, 副标题, 作者, 日期, logo, 颜色等

---
title: "Markdown Notes"
subtitle: "Write in TyporalI"
author: [Karoto]
date: "2023-01-12"
keywords: [Markdown, PDF]
---

把所有的.md文件转出成一个PDF文件, 下面是一个尚可能用的脚本, 仅供参考, md2pdf.ps1

# Recursive search for all .md files in the current directory and subdirectories
$mdfiles = Get-ChildItem -Path . -Recurse -Filter *.md
# Recursive search for all .assets folders in the current directory and subdirectories
$assets = Get-ChildItem -Path . -Recurse -Filter *.assets
# copy all .md files and .assets folders to new directory
New-Item -ItemType Directory -Path ./temp
$mdfiles | Copy-Item -Destination ./temp -Recurse
$assets | Copy-Item -Destination ./temp -Recurse
# change directory to new directory
Set-Location ./temp
# Recursive search for all .md files in the current directory and subdirectories
$mdfiles = Get-ChildItem -Path . -Recurse -Filter *.md
# print $mdfiles
$mdfiles | ForEach-Object {Write-Host $_.FullName}

# PDF Name
$pdffile = "../notes.pdf"

# Convert .md files to .pdf
pandoc $mdfiles -o $pdffile --from markdown --template eisvogel  --listings `
    --pdf-engine=xelatex `
    -V mainfont='Alibaba PuHuiTi' `
    -V sansfont='Alibaba PuHuiTi' `
    -V monofont='Cascadia Mono' `
    -V CJKmainfont='Alibaba PuHuiTi' `
    -V CJKsansfont='Alibaba PuHuiTi' `
    -V CJKmonofont='Cascadia Mono' `
    --toc `
    -V toc-own-page=true `
    -V toc-title="Content" `
    -V toc-color=NavyBlue `
    --number-sections `
    -V colorlinks=true `
    -V linkcolor=blue `
    -V urlcolor=blue `
    -V code-block-font-size=\scriptsize `
    -V titlepage=true `
    -V titlepage-color="FFFFFF" `
    -V titlepage-rule-color="FFFFFF" `
    -V titlepage-text-color="000000" `
    -V titlepage-logo="../logo.png" `
    -V logo-width=20mm `

# change directory back to original directory
Set-Location ..
# remove temp directory
Remove-Item -Path ./temp -Recurse

说明:

  • 脚本中把所有的md文件和assets文件夹复制到临时文件夹temp, 这里没有对重名文件处理, 如果有, 可能的结果是覆盖
  • 进入temp文件夹, 运行pandoc命令生成了pdf文件
  • 最后是退出temp文件夹并删除temp
  • --template eisvogel 使用了 模版 eisvogel
  • -V, --variable 变量
  • 正文, 封面和目录字体使用 阿里巴巴普惠体 Alibaba PuHuiTi, 代码英文字体是 Cascadia Mono
  • CJK的意思是Chinese, Japanese和Korean, 代表中日韩文字
  • --toc 自动添加目录, toc-title="Content" 这个写成 toc-title="目录" 会报错, 还不知道怎么解决
  • --number-sections 自动添加章节编号 1, 1.1, 2.1 这种, 不用自己在Markdown中手写编号, 章节的顺序是 $mdfiles 这个string list里面按照拼音升序的顺序, 如果想改变章节顺序, 可以手动编号或直接手写 $mdfiles 变量列表
  • 颜色方面, toc-color=NavyBlue设置了目录是深蓝色字体, titlepage-text-color="000000"设置封面黑色字体, linkcolor=blue 和 urlcolor=blue 设置链接是蓝色字体
  • 代码块的字体比正文小了些: code-block-font-size=\scriptsize, 可以设置为 \tiny, \scriptsize, \footnotesize, \small, \normalsize, \large, \Large, \LARGE, \huge and \Huge
  • 有行号的代码块复制的时候会连行号一块复制, 可以设置不显示行号 -V listings-disable-line-numbers=true
  • titlepage-logo="../logo.png"logo-width=20mm 指定了封面logo的目录和大小, 其实也可以直接写到封面的md文件里面

下面就看一下powershell脚本运行后, 生成的 notes.pdf 文件的效果

封面的标题, 副标题, 作者, logo 和日期:

在这里插入图片描述

自动编号的目录和页眉

在这里插入图片描述

页脚

在这里插入图片描述

正文图片, 链接颜色:

在这里插入图片描述

代码高亮, 行号, 单行的自动换行:

在这里插入图片描述

整体效果还算不错, 更好的封面效果可以参阅 title-page-custom

Ubuntu Pandoc

在 Ubuntu20 测试, 一直报 ! LaTeX Error: File scrartcl.cls’ not found.` 还不知道怎么解决, Ubuntu18没有这个问题, 所以暂时推荐在Ubuntu18上来测试.

Pandoc和texlive安装

#!/bin/bash
# https://pandoc.org/installing.html#linux
# https://github.com/jgm/pandoc/releases
wget https://github.com/jgm/pandoc/releases/download/2.19.2/pandoc-2.19.2-1-amd64.deb
sudo dpkg -i pandoc-2.19.2-1-amd64.deb
pandoc --version
sudo apt install -y texlive texlive-xetex texlive-latex-recommended

阿里巴巴普惠体和Cascadia Code字体安装

# fonts, Alibaba-PuHuiTi
# https://www.zitijia.com/i/250417369808129081.html
# 下载解压
sudo mkdir -p /usr/share/fonts/Alibaba-PuHuiTi
sudo cp -r Alibaba-PuHuiTi/* /usr/share/fonts/Alibaba-PuHuiTi
sudo fc-cache -fv
fc-list :lang=zh | grep Alibaba

# fonts, Cascadia Code
# https://github.com/microsoft/cascadia-code/releases
wget https://github.com/microsoft/cascadia-code/releases/download/v2111.01/CascadiaCode-2111.01.zip
unzip CascadiaCode-2111.01.zip
sudo mkdir -p /usr/share/fonts/Cascadia-Code
sudo cp -r ttf/* /usr/share/fonts/Cascadia-Code
sudo fc-cache -fv
fc-list | grep Cascadia

Eisvogel模版安装

# Eisvogel
# https://github.com/Wandmalfarbe/pandoc-latex-template/releases
mkdir -p eisvogel && cd eisvogel
wget https://github.com/Wandmalfarbe/pandoc-latex-template/releases/download/v2.1.0/Eisvogel-2.1.0.tar.gz
tar -xvf Eisvogel-2.1.0.tar.gz
mkdir -p ~/.pandoc/templates
cp eisvogel.latex ~/.pandoc/templates
cd ..

下面是Ubuntu的脚本 md2pdf.sh

#!/bin/bash

# if tmp exists, delete it
if [ -d "tmp" ]; then
    rm -rf tmp
fi
mkdir -p tmp

# Recursive search for all .md files in the current directory and subdirectories
md_files=$(find . -type f -name "*.md")
# Recursive search for all .assets folders in the current directory and subdirectories
assets_folders=$(find . -type d -name "*.assets")
# copy all .assets folders and .md files to the temp directory
cp -r $md_files $assets_folders tmp
cd tmp
# Recursive search for all .md files in the current directory and subdirectories
md_files=$(find . -type f -name "*.md")
echo $md_files
# PDF Name
pdf_name="../notes.pdf"

# Convert all .md files to .pdf
pandoc -o $pdf_name $md_files \
    --from markdown \
    --template eisvogel \
    --pdf-engine=xelatex --listings \
    --toc --number-sections \
    -V mainfont="Alibaba PuHuiTi" \
    -V sansfont="Alibaba PuHuiTi" \
    -V monofont="Cascadia Code" \
    -V CJKmainfont="Alibaba PuHuiTi" \
    -V CJKsansfont="Alibaba PuHuiTi" \
    -V CJKmonofont="Cascadia Code" \
    -V colorlinks=true \
    -V urlcolor=blue \
    -V linkcolor=blue \
    -V toc-color=NavyBlue \
    -V titlepage=true \
    -V titlepage-color="FFFFFF" \
    -V titlepage-rule-color="FFFFFF" \
    -V titlepage-text-color="000000" \
    -V titlepage-logo="../logo.png" \
    -V logo-width=20mm 
    

说明:

  • 仍然是把所有的md文件和assets文件夹拷贝到tmp文件夹
  • 去掉了 code-block-font-size=\scriptsize, 这么写有问题, 代码块前会有scriptsize字符, 改成code-block-font-size=\\scriptsize 有一个图片的位置变了, 索性删去了
  • 导出的PDF文档效果和Windows上基本一致

Markdown 合并

其实可以直接把多个Markdown合并成一个md文件, 图片都是相对路径, 把图片的assets文件夹和合并后的md文件放一个目录, 然后用Typora打开md文件, 导出PDF即可, 下面给出一个合并的脚本

#!/bin/bash

# if tmp exists, delete it
if [ -d "tmp" ]; then
    rm -rf tmp
fi
mkdir -p tmp

# Recursive search for all .md files in the current directory and subdirectories
md_files=$(find . -type f -name "*.md")
# Recursive search for all .assets folders in the current directory and subdirectories
assets_folders=$(find . -type d -name "*.assets")
# copy all .assets folders and .md files to the temp directory
cp -r $md_files $assets_folders tmp
cd tmp
# Recursive search for all .md files in the current directory and subdirectories
md_files=$(find . -type f -name "*.md")
echo $md_files
# all .md files into one file
echo "# Contents
@[toc]
" > all.md
cat $md_files >> all.md

欢迎关注微信公众号
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值