欢迎访问优讯网!
您当前的位置:首页 > 爱编程

Asciidoctor 与 gradle 整合生成 PDF备忘

时间:2019-07-25 09:00:44  来源:优讯网  作者:小卡司  浏览次数:
缘起
简单文档一般使用 markdown 就足够了,尤其单页文档,不过稍微复杂点的文档用这玩意显然就很不方便了,就单单一个不支持 include 就很痛苦,虽然可以用 pandoc 做一些 hack 处理,不过麻烦啊,尤其还需要生成 html5、pdf 的时候。

所以这时候个人倾向于使用 asciidoc 格式来写文档。

配置
编译 asciidoc 成 html5、pdf 的话,Asciidoctor 提供了命令行工具,不过这玩意需要通过 gem 安装,如果额外还想生成 PDF,还需要安装 asciidoctor-pdf,看看官方文档就知道麻烦事不少。

所以还是配合 gradle 省事,一个配置文件搞定,尤其对于 java 程序员来说,gradle 应该算是标配了吧——呃,maven 用户可能有话说。

目录结构
gradle 项目的一个最基本的目录结构应该如下:

.
├── build.gradle
├── data
│   ├── fonts
│   │   ├── KaiGenGothicCN-Bold-Italic.ttf
│   │   ├── KaiGenGothicCN-Bold.ttf
│   │   ├── KaiGenGothicCN-Regular-Italic.ttf
│   │   ├── KaiGenGothicCN-Regular.ttf
│   │   ├── RobotoMono-Bold.ttf
│   │   ├── RobotoMono-BoldItalic.ttf
│   │   ├── RobotoMono-Italic.ttf
│   │   └── RobotoMono-Regular.ttf
│   └── themes
│       └── basic-theme.yml
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
    └── docs
        └── asciidoc
            ├── chapter
            │   └── 0010_overview.adoc
            ├── images
            │   └── keep
            └── spec.adoc

简单说明一下:

src/docs/asciidoc: asciidoc 所在目录
data/fonts: 用于生成 PDF 的字体文件目录
data/themes: 用于定义 PDF 的主题文件目录
build.gradle 配置
buildscript {
    repositories {
        maven {
            url "http://maven.aliyun.com/nexus/content/groups/public/"
        }

        jcenter()
        mavenCentral()
    }
}

plugins {
    id "org.asciidoctor.jvm.convert" version "2.3.0"
    id "org.asciidoctor.jvm.pdf" version "2.3.0"
}

wrapper {
    distributionType = Wrapper.DistributionType.ALL
}

version = '1.0.0'

asciidoctor {
    logDocuments true

    // sourceDir  file('docs')
    sources {
        include 'spec.adoc'
    }
    baseDirFollowsSourceDir()
    // outputDir  file('build/docs')

    // 强制每次都重新生成
    outputs.upToDateWhen { false }
    outputOptions {
        backends = ['html5', 'pdf']
    }

    // pdfThemes {
    //     local 'basic', {
    //         styleDir = file('data/themes/basic')
    //         styleName = 'basic'
    //     }
    // }
    attributes 'pdf-fontsdir': file('data/fonts')
    attributes 'pdf-stylesdir': file('data/themes')
    attributes 'pdf-style': 'basic'

     // 版本号
    attributes 'revnumber': project.version

    // 一些通用属性
    attributes 'toc': 'left'
    attributes 'toclevels': 4
    attributes 'toc-title': '目录'
    attributes 'docinfo1': ''
    attributes 'imagesdir': 'images'
    // 语法高亮,可选项有 coderay, highlightjs, prettify, pygments
    // 为保证生成的 html5 和 pdf 均有语法高亮,所以启用 coderay
    // 使用其它几个选项还需要做不少额外的工作,没有必要
    attributes 'source-highlighter': 'coderay'
    attributes 'sectnums': true
    attributes 'sectanchors': true
    attributes 'sectlinks': true
    attributes 'experimental': true


    // TIP、NOTE 之类的用自体图标显示
    // 之所以将此属性放置在这儿是为了避免 idea asciidoc 插件无法正常显示
    attributes 'icons': 'font'
}
重点需要注意:

plugins 下的两个 plugin 使用版本为 2.3.0,而官网是 2.4.0,但是后者在各个 maven 库中都没发现,估计截止当前位置尚未更新
asciidoctor 配置中可以不用官网文档写的 pdfThemes,也就是上面源码中注释的部分,直接采用 attributes 'pdf-fontsdir' 这种配置即可,看源码就知道,前者也不过就是为了达到后者的效果
source-highlighter 使用 coderay,这个相比其它源码高亮工具稍显简单,不过好处是不需额外配置就可以提供 PDF 高亮。
PDF 示例:

PDF 示例

入口 adoc 文件示例
= 开发规范

:toc: left
:toc-title: 目录
:toclevels: 3
:source-highlighter: coderay
:imagesdir: images
:icons: font
:sectnums:
:sectanchors:
:sectlinks:
:experimental:
:revnumber: v1.0

[#overview]
== 概述
include::chapter/0010_overview.adoc[]
上述文件其实把 build.gradle 中的 attributes 又定义了一遍,之所以如此是为了在 vscode、WebStorm 之类的工具中可以直接预览,当然这是可选项,如果不需要这种比较一致的预览需求,完全可以把入口 adoc 中的这些配置项删除。

PDF 中文字体的额外配置
上述配置完成之后执行 ./gradlew asciidoctor 已经可以生成 html5、pdf 了,不过打开 pdf 的话会发现中文乱码,中文都变成了¬,此问题可参见官方说明 Built-In (AFM) Fonts

提示如下:

The following text could not be fully converted to the Windows-1252 character set:
| <string with unknown glyph>
PDF 乱码示例:

pdf 乱码示例

之所以乱码主要是 asciidoctor-pdf 默认使用的 default-theme.yml 中配置的字体文件不支持中文,点开看看这个文件就知道怎么回事了。

可以去 asciidoctor-pdf-cjk-kai_gen_gothic 下载「怀源黑体」(思源黑体的 ttf 版)和「Roboto Mono」等宽字体,放置到 data/fonts 下面。

之后编写 data/themes/basic-theme.yml:

#
# 重载 https://github.com/asciidoctor/asciidoctor-pdf/blob/master/data/themes/default-theme.yml
# 使用中文字体解决 pdf 乱码问题
#

extends: default

# 重载字体定义
font:
    catalog:
        KaiGen Gothic CN:
            normal: KaiGenGothicCN-Regular.ttf
            bold: KaiGenGothicCN-Bold.ttf
            italic: KaiGenGothicCN-Regular-Italic.ttf
            bold_italic: KaiGenGothicCN-Bold-Italic.ttf
        Roboto Mono:
            normal: RobotoMono-Regular.ttf
            bold: RobotoMono-Bold.ttf
            italic: RobotoMono-Italic.ttf
            bold_italic: RobotoMono-BoldItalic.ttf
    fallbacks:
        - KaiGen Gothic CN

# 覆盖基础字体
base:
    font_family: KaiGen Gothic CN

# 覆盖等宽字体
literal:
    font_family: Roboto Mono
最后在 build.gradle 中配置:

    attributes 'pdf-fontsdir': file('data/fonts')
    attributes 'pdf-stylesdir': file('data/themes')
    attributes 'pdf-style': 'basic'
中文问题解决!

Spring REST Docs 版本要求
asciidoc 的另一个使用场景是配合 Spring REST Docs 生成 api 文档,不过需要注意的是这时候只能使用 1.5.x 版本的 org.asciidoctor.convert,因为 Spring REST Docs 暂时还不支持新版 asciidoctor。

这时候需要注意 build.gradle 中一些配置需要调整,例如:

    outputOptions {
        backends = ['html5', 'pdf']
    }
需要调整为:

backends 'html5', 'pdf'
来顶一下
返回首页
返回首页
推荐资讯
计算机的正确使用姿势 电脑痴如何正确的使用电脑
计算机的正确使用姿势
好用的后台管理的前端框架模版H-ui H-ui框架模版分享
好用的后台管理的前端
微信电脑多开方法 无需辅助电脑版微信双开方法分享
微信电脑多开方法 无
Python实现网站百度主动推送 python实现主动推送网站地图
Python实现网站百度主
相关文章
栏目更新
栏目热门