AsciidoctorJ 1.6.0 发布,终于来了!

作者 Robert Panzer, Dan AllenSarah White -

经过数年的酝酿(或者说是桶陈?),我们终于发布了 AsciidoctorJ 1.6.0!相关构件可从 BintrayMaven Central 获取。

AsciidoctorJ 是什么?

AsciidoctorJ 是在 JVM 上运行 Asciidoctor 的官方库。使用 AsciidoctorJ,您可以转换 AsciiDoc 内容,分析已解析的 AsciiDoc 文档的结构,并用 Java 和其他 JVM 语言编写 Asciidoctor 扩展。

在升级之前,您需要了解一些重要的事情,本文将对此进行介绍。虽然 AsciidoctorJ 仍然建立在强大的 Asciidoctor RubyGem 的基础上,但它已经发展成为一个独立的を有份的项目。此次发布为新老用户带来了稳定性和关键增强。请举杯,我们将为您带来所有细节。

迈向 SemVer 的重要里程碑

尽管版本号如此,这次发布应被视为一次重大发布。因此,它与 1.5.x 系列的发布不兼容。

AsciidoctorJ 1.6.0 是为了准备切换到语义化版本控制 (SemVer) 而进行的最后一次过渡性发布。我们将最后一次打破规则,但有充分的理由。考虑到 1.6.0 分支已经桶陈了很长时间,我们希望允许其被启用以收集反馈,并挖掘出意外的惊喜,然后再跳到 2.0.0 和 SemVer。如果一切顺利,我们预计 2.0.0 版本将在该版本之后不久发布。届时,我们将开始按照 SemVer 规则对 AsciidoctorJ 进行版本控制。

要了解更多关于 SemVer 以及它如何影响 Asciidoctor 项目的总体情况,请参阅 切换到语义化版本控制

切换到 SemVer 也意味着 AsciidoctorJ 将独立于 Asciidoctor 进行版本控制。AsciidoctorJ 已经发展成为不仅仅是为 JVM 打包的 Asciidoctor RubyGem。它拥有完整的 API,包括基于 Java 的扩展以及与 Java 生态系统的紧密集成(例如,JUL、Ruby 对象桥接等)。其独立的版本线将允许它更快地发展,并帮助大家更好地理解每个版本将带来什么。最重要的是,它将解决导致 1.6.0 版本积压多年的情况。

新功能

主要的 API 和打包更改

自 AsciidoctorJ 诞生以来,我们对 JRuby 以及它如何桥接 Ruby 和 Java 对象有了很多了解。利用这些知识,我们彻底重新设计了底层集成,以解决原始设计中的不足。

这种重新设计需要我们对 API 进行破坏性更改,这对于 AsciidoctorJ 的持续发展是绝对必要的。但这同时也为我们提供了修复众多 Bug 的机会,而这些 Bug 在 1.5.x 系列中无法在不破坏兼容性的情况下修复。您会很高兴地得知,重新设计消除了在编写扩展或使用 1.5.x 版本导航文档模型时可能遇到的故障。

作为此更改的一部分,我们将 API 和实现类拆分为单独的包和 JAR,以对其进行适当的隔离。我们还通过映射 Asciidoctor 中的所有节点类型并移除 ContentPart 和 StructuredDocument API 来协调相互冲突的文档模型。请参阅 API 文档(apiimpl)以了解可用的类型及其组织方式。

重构的扩展 API

得益于重新设计,基于 JRuby 的实现被更好地隐藏在 API 之后。特别是,API 中不再有 JRuby 的 RubyObject 类的引用。

抽象语法树 (AST) 的接口已完全重命名,以更好地表示其目的。例如,AbstractNode 接口已重命名为 ContentNode,AbstractBlock 已重命名为 StructuralNode,Inline 已重命名为 PhraseNode。Java 中映射了更多的 AST,包括列表和定义列表,以及用于在扩展处理器中创建表结构的辅助工具。

总的来说,扩展和 AST 的 API 应该感觉像是一个纯粹的 Java 库(例如,getAttr() 现在是 getAttribute())。您甚至可以使用基于注释的配置(例如,@Name)来定义扩展处理器。

请查阅 集成器指南,了解所有相关信息并找到许多示例。

添加了转换器 API

引入了一个新的转换器 API,使得完全用 Java 实现自定义输出格式的转换器成为可能。此 API 允许您从 Java 扩展 Asciidoctor,类似于您已经通过扩展 API 所能做到的。您可以按照 转换器文档 来了解如何使用这个新 API。

事实上,已经有一个转换器使用此 API 从 Groovy 将 AsciiDoc 转换为 Leanpub 风格的 Markdown

访问 Asciidoctor 的日志

当 Asciidoctor 在文档中遇到问题时,它会将错误和警告消息记录到 Ruby 日志记录器。将 Asciidoctor 集成到您自己的软件中时,捕获这些日志消息以便妥善处理非常重要。以前,这些消息是 AsciidoctorJ 无法触及的。现在情况已不再如此。新的 日志处理 API 会捕获 Asciidoctor 中记录的消息,并将它们路由到您自己的日志处理程序。

更好的文档

AsciidoctorJ 1.6.0 提供了扩展和经过测试的 文档,用于编写扩展和转换器。这些文档保证是正确的,因为它们会与每次提交一起测试 ;) 并且正在将文档整合到 Asciidoctor 的新 Antora 文档站点中。

有关此版本中发生的更改的更详细说明,请参阅 发布说明。请记住,由于 1.6.0 的开发与 1.5.x 并行了很长时间,因此 1.6.0 中的许多更改可能对您来说已经很熟悉了,因为它们已被反向移植到 1.5.x 发布系列中。

迁移说明

如果您只使用 Asciidoctor、Asciidoctor.Factory 和 *Builder 类(例如,Asciidoctor#convertFile),您可能无需更改代码。事实上,Asciidoctor Maven PluginAsciidoctor Gradle Plugin 已经支持此版本,主要是因为它们只依赖于公共的加载/转换 API。

AST 和扩展 API 的必要更改确实引入了破坏性更改,需要修改您现有的扩展。迁移扩展主要是为了符合新的 API。这主要包括切换 AST 接口的新名称,并与更新的方法签名保持一致。除了名称和签名更改之外,API 仍然应该是可识别的,因此与您现有的逻辑兼容。

以下是为 AsciidoctorJ 1.5.8 和 1.6.0 编写的几个扩展示例,以让您了解需要注意的更改类型:

如果您在迁移扩展或文档内省代码时遇到困难,请在 问题跟踪器 中提交问题,以便我们找到前进的道路。

Java 兼容性

Asciidoctor 1.6.0 最低需要 Java 8。它也能在 Java 11 上运行,并且已针对 Java 11 进行测试。

从 AsciidoctorJ 1.6.0 开始,该项目将遵循 Oracle 官方 Java SE 支持路线图 来确定其 Java 兼容性。虽然 AsciidoctorJ 不需要 Oracle Java SE,但该路线图可以作为判断哪些 Java 版本被认为是当前的有用参考。

Asciidoctor 1.6.0 尚不支持在模块路径上运行,这是 Java 9 中引入的 Java 平台模块系统 的一个关键特性。我们希望在即将发布的版本中实现这一点。然而,这将取决于 AsciidoctorJ 的依赖项(最重要的是 JRuby)在这方面的进展。尽管有此限制,您仍然可以在 Java 11 上运行 Asciidoctor 1.6.0。

致谢

我们想借此机会表彰几位关键人物,他们共同促成了这次发布的成功。

  • Jérémie Bresson,他发起将 API 和实现类分离,并现代化了 API 签名。

  • Abel Romero,他协助设计了 JUL 日志集成,并首先在 Maven 插件中进行了测试。

  • Frank Becker,他彻底改进和简化了 Gradle 构建。

  • Guillaume Grossetie,他对 API 和实现进行了大量清理和改进,并通过启动 AsciidoctorG 对重新设计进行了压力测试。

  • Charles NutterThomas Enebo 以及 JRuby 团队,他们创建和维护了 AsciidoctorJ 所基于的 JRuby。

  • 最后,我们的“前辈” Alex Soto,他启动了 AsciidoctorJ 项目,并向我们展示了其潜在的可能性。

当然,还有许多其他人值得感谢。正如我们多次说过的,没有 众多志愿者 的辛勤工作和协作,这个项目是不可能实现的。所以,谢谢您!

2.0.0 的展望

破坏性更改尚未结束。在走向 2.0.0 的过程中,我们希望进一步拆分 AsciidoctorJ 的 API 和其实现。我们的主要目标是支持底层的替代实现,例如 Asciidoctor.js,使用相同的公共 API。

为了帮助我们达到 2.0.0,我们恳请您测试 1.6.0 版本,并告知我们您是否遇到任何问题或更改,这些更改妨碍您迁移到它。现在是时候在 2.0.0 版本发布之前将其做好。请在 问题跟踪器 中报告您发现的所有问题。

感谢您陪伴我们一起将 AsciiDoc 的精华带到 JVM。


Asciidoclet 1.5.0 已发布!

作者 John EricksenBen Evans -

Asciidoctor 1.5.0AsciidoctorJ 1.5.0 发布之后,Asciidoclet 的 1.5.0 版本也已发布,其中包含多项重要新功能,包括全新的外观与感觉!

什么是 Asciidoclet?

Asciidoclet 允许 Java 开发人员使用便携且丰富的 AsciiDoc 语法编写 Javadoc 注释,而非 HTML。

简而言之,为什么还要写像这样的混乱的 Javadoc?

/**
 * This class has the following features:
 * <ul>
 *   <li>Support for <strong>foo</strong></li>
 *   <li>Support for bar</li>
 * </ul>
 */
public class Thing implements Something { ... }

……而不是像这样写整洁的 Javadoc!

/**
 * This class has the following features:
 *
 * - Support for *foo*
 * - Support for bar
 */
public class Thing implements Something { ... }

好多了!现在源代码中的注释更容易阅读和编写,并且可以在 Javadoc 之外重用。最重要的是,从 Javadoc 生成的 HTML 仍然看起来很棒(甚至可能更好)。

当然,这个例子只是展示了其可能性的冰山一角。表格、列表、带有语法高亮的代码示例、链接、包含文件以及 Asciidoctor 的所有功能都可以通过轻量级的 AsciiDoc 语法获得。

现在,开发人员可以专注于内容而不是格式,同时仍然能获得美丽的效果。

构件信息

构件信息(jCenter @ Bintray)
组 ID 工件 ID 版本 下载

org.asciidoctor

asciidoclet

1.5.0

pom jar javadoc (jar) sources (jar)

构件信息(Maven Central)
组 ID 工件 ID 版本 下载

org.asciidoctor

asciidoclet

1.5.0

pom jar javadoc (jar) sources (jar)

安装

在 Maven 中,只需将 Asciidoclet doclet 名称和构件添加到 maven-javadoc-plugin 声明中即可

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-javadoc-plugin</artifactId>
  <version>2.9</version>
  <executions>
    <execution>
      <goals>
        <goal>jar</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <doclet>org.asciidoctor.Asciidoclet</doclet>
    <docletArtifact>
      <groupId>org.asciidoctor</groupId>
      <artifactId>asciidoclet</artifactId>
      <version>1.5.0</version>
    </docletArtifact>
  </configuration>
</plugin>

请参阅 Asciidoclet 指南,其中包含适用于其他构建系统和所有可用 doclet 选项的示例。

发布亮点

基于 Asciidoctor 1.5.0 构建

Asciidoclet 继承了 Asciidoctor 1.5.0AsciidoctorJ 1.5.0 的所有改进。

Asciidoctor 1.5.0 引入了一些语法更改。有关如何迁移内容的详细信息,请参阅 迁移指南

改进的样式表

Asciidoclet 包含一个默认样式表,其中包含来自 Asciidoctor 1.5.0 的样式。这意味着 Javadoc 中的 AsciiDoc 内容将以与 Asciidoctor 在其他环境中的外观和感觉相似的方式进行渲染。

Javadoc output
图 1. 使用 Java 8 派生样式表的示例 Javadoc

Javadoc 的 HTML 输出在 Java 平台的不同版本之间有所不同,因此 Asciidoclet 会根据其运行的 Java 版本选择合适的样式表。

  • 对于 Java 7 和 8,使用基于默认 Java 8 Javadoc 样式表的样式表。

  • 对于 Java 5 和 6,样式表基于 Java 6 Javadoc 样式表。

如果您想使用自己的样式表,仍然可以通过 Javadoc 的 -stylesheetfile 选项来实现。

AsciiDoc 概述文件

Javadoc 的 -overview 选项允许您指定一个 HTML 文件,该文件将在生成的文档中用作概述或索引页面。这对于较大的项目尤其有用,其中概述可以为用户提供有用的介绍并帮助他们导航 API。

Asciidoclet 现在也支持使用 AsciiDoc 编写的概述文件,并全面支持 AsciiDoc 的功能,如包含文件和文档属性。名为 *.adoc*.ad*.asciidoc*.txt 的概述文件将由 Asciidoclet 处理。其他文件假定为 HTML,并将由 Javadoc 的标准 doclet 处理。

文档属性

Asciidoclet 现在完全支持 Asciidoctor 的 文档属性。这是 Asciidoctor 最强大的功能之一。文档属性是可以传递给 Asciidoctor 以影响最终输出生成方式的参数。

属性在运行 Asciidoclet 时使用一个或多个 -a(或 --attribute)选项指定。--attributes-file 选项从 AsciiDoc 文件中读取属性。在渲染 Javadoc 注释时,这些属性将被传递给 Asciidoctor。

以下是一些关于文档属性在 Javadoc 中可能很有用的示例。

变量替换

Javadoc 注释或概述文件中的属性引用将被替换为属性值。

/**
 * {product-name} will change your life!
 * @version {version}
 */

当 doclet 使用 -a product-name=Foo -a version=1.0 运行时,Asciidoctor 会在生成的 HTML 输出中将所有 {product-name}{version} 属性引用替换为给定的值。这使得在不更改源代码的情况下将值注入 Javadoc 变得非常简单。

条件包含

AsciiDoc 的 条件指令 可以根据属性的存在或缺失来选择性地包含内容。当相同的 AsciiDoc 源在不同环境中重复使用时,这很有用。

例如,如果您想在 Javadoc 概述页面和网站中使用相同的 AsciiDoc 内容,但有一些差异,您可以使用属性来告诉 Asciidoctor 何时包含某些内容。

= Documentation for the Foo project

ifdef::javadoc[]
// content that should only appear in Javadoc
endif::javadoc[]

ifdef::my-website[]
// content that should only appear on the web site
endif::my-website[]

Asciidoclet 在运行时会自动设置 javadoc 属性,因此可以轻松选择仅用于 Javadoc 的内容。当然,您也可以定义自己的属性。

Java 和 Ruby 扩展支持

Asciidoctor 可以使用 Java 或 Ruby 库进行扩展,Asciidoclet 也继承了此功能。

  • Java 扩展在类路径可用时会自动加载,使用 AsciidoctorJ 的 Extension SPI

  • Ruby 库(Gems)使用 -r(或 --require)选项加载。

在使用 --require 选项时,我们建议同时指定 --gem-path 选项以显式设置已安装 gem 的位置。这样做可以确保您的构建保持可移植和可重现。您可以使用 gem-maven-plugin 将 gem 直接安装到您的构建目录中。

许多扩展可用,但对于 Javadoc 作者来说,最有用的一种可能是 Asciidoctor Diagram。让我们看看如何将其与 Asciidoclet 结合使用。

在 Javadoc 中嵌入图表

Asciidoctor Diagram 是一个流行的 Asciidoctor 扩展,它允许您在 AsciiDoc 源中嵌入纯文本图表描述,这些描述在 Asciidoctor 运行时会被渲染成图像。这对于在 Javadoc 中描述软件实现的架构或行为非常有价值。

这是一个包含 PlantUML 顺序图的 Javadoc 注释示例。

/**
 * This class implements the following protocol:
 *
 * [plantuml]
 * ....
 * Alice -> Bob: Authentication Request
 * Bob --> Alice: Authentication Response
 *
 * Alice -> Bob: Another authentication Request
 * Alice <-- Bob: another authentication Response
 * ....
 */
public class AuthServer { ... }

上面的图表在 Javadoc 输出中的显示方式如下:

Example output using Asciidoctor Diagram
图 2. 使用 Asciidoctor Diagram 的示例输出

不错!开发人员可以轻松地以纯文本形式查看和更新图表,而阅读 Javadoc 的用户将看到精美的渲染图像。

还支持许多其他类型的图表,包括 Graphvizblockdiagditaa。有关更多示例,请参阅 Asciidoctor Diagram 的文档

要在 Asciidoclet 中启用 Asciidoctor Diagram 支持:

  1. 安装 Asciidoctor Diagram gem,asciidoctor-diagram

    $ gem install asciidoctor-diagram
  2. 使用以下 doclet 选项运行 Asciidoclet:

    --require asciidoctor-diagram
    --gem-path ${env.GEM_PATH} (1)
    --attribute data-uri (2)
    1 --gem-path ${env.GEM_PATH} 选项告知 Asciidoctor 的 JRuby 运行时在哪里查找 gem(在使用 --require 时),实际上是在内部设置 $GEM_PATH 环境变量。
    2 data-uri 属性是必需的,以便图像数据嵌入到生成的 HTML 文件中。[1]
  3. 欣赏装饰您 Javadoc 的精美图表!

致谢!

我们希望这个新版本能让您的 Javadoc 更加出色。我们感谢所有为 Asciidoclet 做出贡献的人。如果您对如何改进它有什么想法,欢迎通过GitHub 上的仓库提交想法和拉取请求。


1. 如果没有 data-uri 属性,Asciidoctor Diagram 会将图像文件写入一个与生成的 HTML 不匹配的位置。在撰写本文时,此问题正在 Asciidoctor Diagram 中得到解决。有关详细信息,请参阅问题 #39

Asciidoctor.js 1.5.0 发布到 Bower 和 npm!

作者 Guillaume GrossetieAnthonny Quérouil -

发布列车正在运行!Asciidoctor.js 的 1.5.0 版本已发布,现已在 Bowernpm 上可用。此版本是使 Asciidoctor.js 在 JavaScript 生态系统中得到广泛应用的重要一步。

Bower and npm
Asciidoctor in JavaScript.
It was a dream.
Then it was a prototype.
Now, it’s the real deal.
什么是 Asciidoctor.js?

Asciidoctor.js 是在 JavaScript 中使用 Asciidoctor 的官方库。它与 Asciidoctor 共享相同的源代码,并通过 Opal 转译为 JavaScript。使用 Asciidoctor.js,您可以从 JavaScript 转换 AsciiDoc 内容或分析已解析的 AsciiDoc 文档的结构。

升级到 Asciidoctor 1.5.0 时,请参阅迁移指南,了解如何迁移内容。

发布亮点

Asciidoctor.js 就是 Asciidoctor

正如在 Asciidoctor 1.5.0 的发布说明 中提到的,我们努力使 Asciidoctor.js (JavaScript) 和 Asciidoctor core (Ruby) 保持一致。这意味着您可以期望 Asciidoctor.js 能够像原始版本一样解析和转换文档。甚至包含文件也能正常工作!

要使某些功能(如包含文件)正常工作,需要特别注意,因为 JavaScript 是一个与 Ruby 不同的环境,并且 JavaScript 环境之间甚至存在关键差异!

例如,在 Ruby 中读取包含文件只是使用常规的 Ruby IO API 的问题。在浏览器环境中,我们必须使用 XMLHttpRequest(即 Ajax)作为 IO API。如果 Asciidoctor.js 在 Node.js 上运行,我们必须使用 Node IO API fs.readSync() 来使其工作。

请放心,我们正在继续努力消除任何差异,将 Asciidoctor core 的所有出色功能带到 JavaScript。

请继续阅读,了解如何获取 Asciidoctor.js!

使用 Asciidoctor.js 比以往任何时候都更简单

如果您是前端或后端 JavaScript 开发人员,您只需一个命令即可获取最新版本的 Asciidoctor.js。

Bower 包

使用 Bower 安装 Asciidoctor.js
$ bower install asciidoctor.js --save
可选的 --save 标志会自动将包添加到您项目的依赖项中。

安装包后,您可以将以下 script 标签添加到您的 HTML 页面中:

<script src="bower_components/asciidoctor.js/dist/asciidoctor-all.min.js"></script>

asciidoctor-all.min.js 是一个 minified 版本,包含 Asciidoctor core、扩展 API 和 Opal。

这是一个简单的示例,使用 doctype: 'inline' 选项和 showtitle 属性将 AsciiDoc 转换为 HTML5:

var asciidoc = "https://asciidoctor.org.cn[*Asciidoctor*] " +
    "running on https://opalrb.com[_Opal_] " +
    "brings AsciiDoc to the browser!";
var options = Opal.hash2(['doctype', 'attributes'], {doctype: 'inline', attributes: ['showtitle']});
var html = Opal.Asciidoctor.$convert(asciidoc, options);
console.log(html);

请参阅 前端开发指南,了解更多关于 Bower 包的信息。

npm 包

使用 npm 安装 Asciidoctor.js
$ npm install asciidoctor.js --save
可选的 --save 标志会自动将包添加到您项目的依赖项中。

安装包后,首先要做的就是使用 require 加载 asciidoctor.js 模块,然后您就可以开始使用 API 了:

sample.js
var asciidoctor = require('asciidoctor.js')(); (1)
var opal = asciidoctor.Opal; (2)

var processor = null;
var useExtensions = true;

if (useExtensions) {
  processor = asciidoctor.Asciidoctor(true); (3)
}
else {
  processor = asciidoctor.Asciidoctor(); (4)
}

var content = "https://asciidoctor.org.cn[*Asciidoctor*] " +
    "running on https://opalrb.com[_Opal_] " +
    "brings AsciiDoc to Node.js!";
var options = opal.hash2(
    ['doctype', 'attributes'],
    {doctype: 'inline', attributes: ['showtitle']});
var html = processor.$convert(content, options); (5)
console.log(html); (6)
1 加载 Asciidoctor.js 库
2 检索并别名顶级 Opal 命名空间
3 实例化启用扩展的 Asciidoctor
4 实例化不带扩展的 Asciidoctor
5 使用 Asciidoctor.js 将 AsciiDoc 内容转换为 HTML5
6 将 HTML5 输出打印到控制台

将文件另存为 sample.js 并使用 node 命令运行它:

$ node sample.js

您应该会在终端中看到以下输出:

<a href="https://asciidoctor.org.cn"><strong>Asciidoctor</strong></a> running on <a href="https://opalrb.com"><em>Opal</em></a> brings AsciiDoc to Node.js!</p>
要成功使用 Asciidoctor.js,理解如何在 JavaScript 环境中处理 Ruby 对象非常重要。我们建议您浏览 Opal 文档,了解方法名称的映射方式以及它期望的数据类型。

请参阅 后端开发指南,了解更多关于 npm 包的信息。

Asciidoctor.js 在 Node 上如火如荼

Node.js 是 JavaScript 最热门的领域,npm 是管理和分发这种热度的包管理器。我们希望 Asciidoctor.js 成为这个生态系统的一部分。我们也需要它在那里开始构建工具。这就是为什么我们迈出了将 Asciidoctor.js 打包成 npm 包的第一步……实际上是多个!Asciidoctor 现在拥有了一个新的游乐场!

以下是已发布的 npm 包:

asciidoctor.js

Asciidoctor.js 的主要 npm 包

grunt-asciidoctor

一个用于在您的 Grunt 项目中处理 AsciiDoc 源文件的 npm 包

社区已经开始如何使用这些包了:

asciidoc-preview (Atom 编辑器)

Atom 的一个插件,可在您输入时显示文档的预览!

asciidoc-preview (Brackets 编辑器)

Brackets 的一个扩展,可在您输入时显示文档的预览!

grunt-asciidoctor-assemble

@tedbergeron 编写的 Grunt 的静态网站生成器。

当然,仍然存在挑战,但我们会解决它们。前往 Asciidoctor.js 项目参与其中。

让我们玩这个新游戏吧!

JVM 上的 Asciidoctor.js

您没看错。浏览器不是唯一能运行 JavaScript 的地方。(我们不是指像 Node.js 这样从浏览器逃出来的 JavaScript 引擎。)我们说的是最支持多语言的运行时,JVM

Alex Soto 正在努力将 Asciidoctor.js 集成到 AsciidoctorJ 中,这样您就可以在 JVM 上使用它,利用 Nashorndynjs 和其他运行在其上的 JavaScript 引擎。 AsciidocFX 项目已经在 Nashorn 上使用 Asciidoctor.js,所以这不仅仅是一个想法!

为了确保 Asciidoctor.js 在 JVM 上顺利运行,仍然需要解决几个挑战,例如让包含文件工作。前往 AsciidoctorJ 项目参与其中,帮助实现这一目标!

致谢

Asciidoctor.js 与 Asciidoctor core 的对齐是一项重大工作。它需要许多人的投入,他们齐心协力应对这一挑战。

我们尤其要感谢 Opal 开发者,特别是 Adam Beynon、meh 和 Elia Schito,他们使得 Asciidoctor.js 得以实现。他们对我们的工作非常积极响应,对 Opal 进行了更改和修复,并提供了宝贵的输入,使我们能够不断前进。

我们还要感谢 Anthonny Quérouil,他构建了一个 Grunt 构建来编译、聚合和压缩 Asciidoctor.js,并帮助将构件发布到 Bower 和 npm。

感谢所有测试 Asciidoctor.js 的人,无论是直接测试还是通过使用工具。您的参与使 Asciidoctor.js 成为真正强大的工具!

如果您有任何问题或反馈,我们鼓励您参与 讨论列表。我们在那里见!


Asciidoctor Maven 插件 1.5.0 已发布!

作者 Dan Allen -

Storm in Desert

西部地区可能仍在经历旱季,但我们很高兴能为 Maven 用户带来 Asciidoctor Maven 插件 1.5.0 版本,并将其发布到 Maven Central 和 jCenter!

此版本带来了 Asciidoctor 1.5.0AsciidoctorJ 1.5.0 的所有改进,以及对站点插件的增强。与之前的版本一样,该插件基于相同版本的 AsciidoctorAsciidoctorJ 项目(现已使用语义化版本)—— 1.5.0。

构件信息

构件信息(jCenter @ Bintray)
组 ID 工件 ID 版本 下载

org.asciidoctor

asciidoctor-maven-plugin

1.5.0

pom jar javadoc (jar) sources (jar)

构件信息(Maven Central)
组 ID 工件 ID 版本 下载

org.asciidoctor

asciidoctor-maven-plugin

1.5.0

pom jar javadoc (jar) sources (jar)

安装或升级

安装或升级到 1.5.0 版本非常简单。只需更新 pom.xml 中的版本即可。所有必要的依赖项都将通过 Maven 的依赖管理自动拉取。

<plugins>
  <plugin>
    <groupId>org.asciidoctor</groupId>
    <artifactId>asciidoctor-maven-plugin</artifactId>
    <version>1.5.0</version>
  </plugin>
</plugins>

请参阅 示例项目,复制粘贴即可轻松上手!

升级到 Asciidoctor 1.5.0 时,请参阅迁移指南,了解如何迁移内容。

请参阅 Asciidoctor Maven 插件的手册,了解有关配置选项和插件其他功能的更多信息。

发布亮点

发布到 jCenter

Asciidoctor Maven 插件现已发布到 Bintray 的 jCenter!这意味着您可以更轻松地找到该插件,并且它已发布到 Web 上二进制文件的未来目的地。您可以选择在有新版本时接收 Bintray 的通知。

将非 AsciiDoc 文件复制到输出目录(#67

Asciidoctor Maven 插件现在会将非 AsciiDoc 文件复制到输出目录,因此您可以在 AsciiDoc 源文件夹中放置资源,例如图像或样式表。此更改使 Asciidoctor Maven 插件的行为与 Gradle 插件的行为保持一致。

添加配置以设置 gem 路径并加载附加 gem(#109

您现在可以使用 gemPath 配置选项指定一个或多个 gem 安装目录(即 GEM_PATH)的位置。此设置的主要目的是加载 AsciidoctorJ 中未打包的其他 Ruby 库,例如 asciidoctor-diagram。您可以使用 require 配置选项加载其他库(绝对路径、相对路径或 gem 名称)。

以下是有关如何在 pom.xml 中的插件声明中使用该配置的示例:

<configuration>
  <gemPath>${project.build.directory}/gems-provided</gemPath>
  <requires>
    <require>asciidoctor-diagram</require>
  </requires>
</configuration>
如果您想在构建过程中自动下载和安装 gem,则需要使用 gem-maven-plugin。请参阅 示例项目,复制粘贴即可轻松上手!
独立配置 AsciidoctorJ(#111

在 1.5.0 之前,如果您定义了 GEM_HOMEGEM_PATH 环境变量(通常在使用 RVM 时),Maven 插件会让 JRuby 看到安装在项目外部的 gem。这可能导致构建不可重现。

我们通过清除 GEM_PATH 环境变量(除非它在插件配置中指定)在一定程度上解决了这个问题。但是,GEM_HOME 环境变量直到 AsciidoctorJ 1.5.1 才能正确清除。在此期间,如果 GEM_HOME 设置为构建外部的路径,我们会发出警告,以便您知道手动重置该值(例如,通过运行 rvm use system)。

正确处理 false 和空属性值(#93

0.1.4 版本中存在一个回归,该版本将 false 和空属性值都视为 true。Maven 需要额外的处理才能正确转换这些值。现在可以使用空字符串值,它表示启用属性;或者使用 false 值,它表示禁用属性。例如:

<configuration>
  <attributes>
    <toc/>
    <linkcss>false</linkcss>
  </attributes>
</configuration>

此配置等同于以下 Asciidoctor 的命令行参数:

-a toc -a linkcss!
在 Maven 站点插件中生成 XHTML(#61

Asciidoctor 1.5.0 中最重要的改进之一是添加了 XHTML 后端。简单地说,这个后端输出 XHTML5(符合 XML 标准的 HTML5),而不是通常的简写 HTML5。添加这个后端的主要原因是修复 Asciidoctor Maven 插件中站点模块的行为。Maven 站点插件使用的 XML 解析器将为此而感谢您!

EPUB3 输出

AsciidoctorJ 开箱即用地提供了与 Asciidoctor EPUB3 转换器的集成。这意味着您可以在 Maven 插件中使用它,而无需声明任何额外的依赖项。只需将后端设置为 epub3 即可!

EPUB3 转换器目前处于 Alpha 阶段。当一切稳定下来时,可能会有一些小问题!

有关此版本中已修复问题的更多信息,请参阅问题跟踪器中的1.5.0 里程碑

致谢

感谢所有贡献者为这个版本做出的贡献,以及所有参与使 Asciidoctor 成为出色的文档工具链和社区的人们!我们特别要感谢 Asciidoctor Gradle 插件的开发者,他们为我们提供了许多关于如何使 Maven 插件优秀的想法!

享受构建出色的文档吧!


Asciidoctor Gradle 插件 1.5.0 已发布!

作者 Andres Almiray -

花费的时间比我们预期的要长,但 Asciidoctor Gradle 插件 1.5.0 版本终于来了!Asciidoctor Gradle 插件基于 AsciidoctorJ,并且首次与其版本号方案保持一致。

这是入门的基本设置:

从这个版本开始,该插件跟踪 AsciidoctorJ 版本,因此从 0.7.3 跳到了 1.5.0。Asciidoctor 1.5.0 中包含许多精彩内容,如 发布说明中所述,但对 Gradle 用户来说,最有趣的可能是能够使用 Groovy 编写自定义扩展(或称为标签处理器)。您可以通过将包含扩展的 JAR 放在类路径上来包含扩展,或者直接在 Gradle 构建中编写它们,将代码放在 buildSrc 中。最新的选项有一个简单的示例,位于 github.com/aalmiray/asciidoctor-piglatin-example

此版本中的其他功能包括:

  • 使用 AsciidoctorTask 上的 requires 属性加载基于 Ruby 的扩展的能力。

  • 使用 AsciidoctorTask 上的 gemPath 属性设置 gem 安装路径的能力。

建议开发人员尽快升级。请注意插件 README 中提出的兼容性问题。不要忘记回顾 Asciidoctor 1.5.0 带来的更改,请参阅迁移指南

Hackergarten
图 1. Basel Hackergarten @ Canoo 7 月 24 日

继续创作出色的(以及 Groovy 的)文档吧!

升级到 1.5.0(推荐)很简单。只需在 Gradle 构建文件中更新版本即可。所有必要的依赖项都应通过 Gradle 拉取。

升级到 Asciidoctor 1.5.0 时,请参阅迁移指南,了解如何迁移内容。

有关此版本中已修复问题的更多信息,请参阅问题跟踪器中的1.5.0 里程碑


AsciidoctorJ 1.5.0 发布!

作者 Alex Soto -

我们很高兴地将 Asciidoctor 的最新里程碑 Asciidoctor 1.5.0,以 AsciidoctorJ 1.5.0 的形式带到 JVM!

AsciidoctorJ 是什么?

AsciidoctorJ 是在 JVM 上使用 Asciidoctor 的官方库。借助 AsciidoctorJ,您可以使用 Java 和其他 JVM 语言转换 AsciiDoc 内容或分析已解析的 AsciiDoc 文档的结构。

已解决的问题

以下问题已在 1.5.0 版本中解决:

  • 添加了向 AsciidoctorJ 注册扩展的方法,这些扩展可以用 RubyJava 编写。解决了 #90#157

  • 创建了一个 SPI,以便通过将 jar 添加到 classpath 中来自动注册 Java 扩展。解决了 #97

  • Extension API 已更新,以反映 Asciidoctor 1.5.0 中所做的修改。解决了 #113#114#148#162#166

  • 提供了一个方法来注销之前注册的任何扩展。解决了 #122

  • 向 CLI 类添加了 -r-I 标志,分别用于要求额外的 Ruby 脚本和追加到加载路径。解决了 #171

  • 向 CLI 类添加了 -V--version 标志。解决了 #87#117

  • 添加了与 Asciidoctor EPUB3 项目的集成。您可以将 epub3 设置为后端。解决了 #168#179

  • 使用 findBy 方法更新了 AbstractBlock 类。解决了 #164

  • 更新了 Document 类以与 Asciidoctor::Document 对齐,因此获取标题可以返回一个 Title 类(包含标题、副标题),而不是一个包含完整标题的字符串。解决了 #167

  • 推广了属性 sectnumlevelshardbreaksappendix-captionstemhide-uri-schemanofootersource-languagecompat-mode。解决了 #91#92#94#105#121#129#144#163

  • 您可以从 JRubyRuntimeContext 类中获取 AsciidoctorJ 中使用的 Ruby 实例。解决了 #93

  • 修复了 Ruby 实例和 Attributes 类的一个 bug,该 bug 阻止了 Gradle 插件正常工作。解决了 #96

  • AsciiDocDirectoryWalker 中跳过以“_”(下划线)开头的​​文件和目录。解决了 #124

  • slf4j 添加为日志系统。解决了 #126

  • 修复了 base_dirRuby 环境的一个 bug。解决了 #135

  • Document 对象(如 SectionBlockNodeDocument 等)已移至 org.asciidoctor.dom 包。

  • 将 Java 版本更新为 Java 7。解决了 #176

有关此版本中修复的问题的更多信息,请参阅问题跟踪器中的 1.5.0 里程碑

迁移

从 1.5.0 版本开始,artifactId 已从 asciidoctor-java-integration 更改为 asciidoctorj。您现在应该在项目的 pom.xml 文件中使用以下依赖项声明:

<dependency>
    <groupId>org.asciidoctor</groupId>
    <artifactId>asciidoctorj</artifactId>
    <version>1.5.0</version>
</dependency>

升级到 Asciidoctor 1.5.0 时,请参考 迁移指南了解迁移内容的详细信息。我们也鼓励您浏览 Asciidoctor 1.5.0 的 发行说明

Asciidoctor 1.5.0 在内部和公共 API 方面都引入了许多更改。例如,扩展 API 已以非微小的方式进行了修改,因此在升级到此版本的 AsciidoctorJ 时,您可能需要将扩展更新到新 API。

访问更新的 AsciidoctorJ 手册,了解如何安装和使用 AsciidoctorJ。

此版本为 Gradle 插件、Maven 插件和 Asciidoclet 的新版本让路,这些插件都基于 AsciidoctorJ。请期待后续的公告!


Asciidoctor 1.5.0 “Bleeding Heart” 已发布!

作者 Dan AllenSarah White -

备受期待的 Asciidoctor 1.5.0 “Bleeding Heart” 版本终于到了!此版本包含大量的 150 项修复、改进和增强,以及对 AsciiDoc 语法的几项细化。我们有信心您将比以往任何时候都更喜欢用 Asciidoctor 写作。

Asciidoctor 1.5.0 是 0.1.4 的续作。我们更改了数字以采用语义化版本方案,并表明此版本已远远超出稳定状态。

请注意!

在升级到 Asciidoctor 1.5.0 之前,重要的是要知道我们对 AsciiDoc 语法进行了一些更改,这些更改不向后兼容。不过,不要惊慌!我们还引入了兼容模式。

有关受影响语法以及如何迁移(或准备迁移)您的内容的信息,请参阅迁移指南。通过进行这些语法更改,我们正致力于使 AsciiDoc 更一致且更易于学习。

里程碑与动力

在 Asciidoctor 1.5.0 的开发周期中,我们关闭了 150 个问题。在上次发布时,我们宣布 Asciidoctor 已从 RubyGems.org 下载 50,000 次。这次,我们不仅使下载量翻倍,更是翻了四倍!在发布时,Asciidoctor 的总下载量已超过 225,000 次!

我们最自豪的不是下载量。而是杰出人士的社区 。Asciidoctor 生态系统现在已有 50 多名贡献者,并且此版本仅就收到了该群体中几乎每个人的参与!如果您还没有机会参与 Asciidoctor,那么现在是加入的最佳时机。

以下是我们跨越的里程碑的摘要:

  • 1.5.0 版本关闭了 150 个问题

  • 总共 50 名贡献者

  • 总共 225,000 次下载

  • 总共 1,800 次提交

  • 1,500 个测试

  • 总共 1000 个问题(包括拉取请求)

  • 总共关闭 800 个问题(包括拉取请求)

  • 400 个邮件列表主题

  • 2 年开发(首次提交于 2012 年 6 月 1 日)

如果不讨论处理器的速度,这就不算是一次 Asciidoctor 发布公告。1.5.0 版本比前一个版本又提高了10%的速度。为了让您了解其速度有多快,Spring Framework 参考指南,共有 50,000 多行,在 Asus ZenBook UX301LA 上使用 Ruby 2.1 可在1.15 秒内渲染为 HTML。

Asciidoctor 现在被更多的开源项目使用,包括 Groovy、Griffon、GroovyFX、Infinispan、Weld、Hibernate OGM、Spring Data 和 git-scm.com。它还用于制作 NFJS,杂志。最重要的是,Sarah 一直在努力填写 Asciidoctor 自己的用户手册,并帮助团队了解如何编写更好的文档。

如果您没有注意到,Asciidoctor 项目正在。因此,让我们来看看这个新版本有什么内容!

发布亮点

使用 MathJax 进行技术写作

如果您需要在写作中进行技术表达,Asciidoctor 与 MathJax 集成,允许您直接在文档中编写 TeX / LaTeXAsciiMath 表达式。

排版好的 LaTeX 数学方程式
\[x = {-b \pm \sqrt{b^2-4ac} \over 2a}\]

只需简单声明 stem 属性,您现在就可以在纯文本中编写行内公式!

图表,图表,图表

您可以通过由纯文本生成的图表为文档添加更多视觉元素。Asciidoctor Diagram 源于将 PlantUML 扩展移植到 Asciidoctor 的请求。Pepijn Van Eeckhoudt(@pepijnve)接管并创建了一个全面的图表扩展,该扩展不仅增加了与 PlantUML 的集成,还增加了三个额外的绘图工具,以及一个用于未来添加更多工具的框架。

Asciidoctor Diagram 1.5.0 现在支持以下绘图工具:

Asciidoctor Diagram process diagram

请参阅 Asciidoctor Diagram 指南,了解如何从 AsciiDoc 文档中的 ASCII 艺术创建图表。

想知道如何从命令行界面加载扩展,例如 Asciidoctor Diagram?请继续阅读。

从 CLI 加载扩展

Asciidoctor 在 0.1.4 版本中引入了一个扩展 API,允许您扩展 AsciiDoc 语法并访问处理器的生命周期。但是,只能在通过 API 调用 Asciidoctor 或创建自定义启动脚本时才能加载这些扩展。

asciidoctor 命令现在支持 -r-I 标志(从 ruby 命令移植而来),分别用于要求附加路径或修改加载路径。

以下是一个示例,演示如何使用 -r 标志启用 Asciidoctor Diagram 扩展:

$ asciidoctor -r asciidoctor-diagram sample.adoc

-r 标志还接受绝对或相对路径,并且可以多次使用。

$ asciidoctor -r ./my-extension-a.rb -r ./my-extension-b.rb sample.adoc

在执行任何其他处理之前,-r 标志引用的脚本将按照它们列出的顺序加载。

现在您可以获得 asciidoctor 命令的全部功能以及扩展!

拥抱 DocBook 5

DocBook 5 规范于 2008 年定稿。我们是时候拥抱它了。

DocBook 5 现在是使用 docbook 后端 时的默认输出。如果您仍需要生成 DocBook 4.5,请使用 docbook45 后端。

迎合 XML 解析器

HTML5 重新引入了灵活的 HTML 语法,该语法仅松散地基于 SGML…​而且绝对不是 XML。此决定使 HTML5 更易于上手。然而,这会让 XML 解析器

为了兼容使用 XML 解析器读取生成 HTML 的工具,Asciidoctor 现在可以输出 HTML5 的 XHTML 变体,即 XHTML5

要输出 XHTML5 而不是 HTML5,请将后端设置为 xhtml,或更明确地说,设置为 xhtml5。“x”位于名称开头,巧妙地告诉 Asciidoctor 关闭自闭标签、为布尔属性赋值以及向根元素添加 xmlns 属性。

相信我们,您的 XML 解析器会感谢您。

PDF 和 EPUB3

Asciidoctor 现在可以直接使用 Asciidoctor PDFAsciidoctor EPUB3 从 AsciiDoc 转换为 PDF 和 EPUB3。这些转换器托管在它们自己的存储库中,并作为单独的 gem 分发。

EPUB3 generated by Asciidoctor EPUB3

这些转换器目前处于 alpha 阶段,但仍然非常实用。

Asciidoctor.js 就是 Asciidoctor

Guillaume Grossetie (@mogztter) 在 1.5.0 开发周期中领导了将 Asciidoctor.js 代码库与 Asciidoctor 核心对齐的努力。经过大量的调整和 Opal 补丁,Asciidoctor.js 现在可以直接构建在 master 和 Asciidoctor 1.5.0 版本之上。这意味着 Asciidoctor.js 就是 Asciidoctor,这是第一次。

Anthonny Quérouil (@anthonny) 随后开发了一个 Grunt 构建脚本来打包 Asciidoctor.js 并将其发布到 npm(Node.js 包管理器)和 Bower(Web 包管理器)。

Guillaume 是 Chrome 版 AsciiDoc 预览的创建者,Anthonny 是 Atom 版 AsciiDoc 预览的创建者。Atom 版 AsciiDoc 预览是对 Anton Moiseev (@antonmoiseev) 发起的 AsciiDoc 语言定义的补充。Thomas Kern (@nerk) 迅速跟进,基于上述工作推出了 Brackets 版 AsciiDoc 插件。我们还将 Asciidoctor.js 的老牌项目 DocGist 纳入了 Asciidoctor 组织。DocGist 由 Anders Nawroth (@nawroth) 创建。Guillaume、Anthonny、Anders、Thomas、Anton 和其他人一直在协作开发基于 Asciidoctor.js 的工具。他们正在帮助 Asciidoctor 大胆地迈向 AsciiDoc 实现前所未有的领域。

Asciidoctor.js 与 Asciidoctor 核心的对齐是一项重大努力。我非常感谢 Guillaume、Anthonny 和 Opal 团队(Adam Beynon、meh 和 Elia Schito)促成了这一切。

AsciiDoc 语法调整

单引号(')和反引号(`)是 AsciiDoc 语法中两个经常让人头疼的标记字符。它们经常互相干扰。我们决定调整一些 AsciiDoc 语法来解决这个问题,并总体上使其更一致、更容易学习。这些更改不仅减少了解析器的错误,还加强了加号字符的含义,并通过将反引号作为粗体格式的主要字符,使其与 Markdown 更为一致。

使用 compat-mode 进行迁移

在介绍变化之前,我们想强调的是,您可以通过设置 compat-mode 属性来忽略斜体、粗体和直通语法更改,该属性在此处显示定义在文档头中

:compat-mode:

或通过使用两行文档标题

Document Title
==============

Compat mode 用于在新语法偏离旧语法时启用旧语法。有关迁移您的 AsciiDoc 文档和可用的过渡语法的更多信息,请参阅迁移指南

“+”表示直通

原始 AsciiDoc 语法中的 + 字符使用不一致。单个加号(+)和双加号(++)用于将文本格式化为粗体,而三个加号(+++)和四个加号(++++)用于转义文本以供处理。

我们将 AsciiDoc 变得更直观、更容易教授,始终将 + 用作直通格式标记。我们没有使用单个加号和双加号进行粗体格式化,而是将它们分别作为受限和不受限的字面量(即,“按原样显示”)。例如

+_bar_+ becomes _bar_
foo++_bar_++ becomes foo_bar_

我们还没有提到如何将文本格式化为粗体。为此,我们将把反引号重新投入使用。

Markdown 风格的粗体

熟悉 Markdown 的作者习惯于使用反引号(`)将文本格式化为粗体。我们在 Asciidoctor 中采用了这一约定。

将反引号字符括在文本周围现在表示文本应仅以粗体格式显示。反引号字符添加直通语义,就像以前一样。在大多数情况下,不需要直通语义,因此使用反引号进行粗体格式化就足够了。

`literal` becomes literal (in monospace)
`{backend}` becomes html5 (in monospace)
a``||``b becomes a||b (where || is monospace)

如果您想防止在粗体文本中进行替换,只需记住,“加号用于直通”

`+{backend}+` becomes {backend} (in monospace)

通过不将粗体格式与直通(字面)语义混合,我们稍微偏离了 Markdown 中反引号的行为。但是,这是因为 AsciiDoc 具有其他功能,例如属性引用,我们希望在将文本格式化为粗体时能够利用这些功能。

将有一段时间您需要同时使用 Asciidoctor 0.1.4 和 1.5.0 来处理您的文档(主要是等待 GitHub 升级)。我们在处理器中添加了特殊的逻辑来处理混合语法,供您在此期间使用。有关迁移您的 AsciiDoc 文档和可用的过渡语法的详细信息,请参阅迁移指南

更智能的“智能”引号

旧版 AsciiDoc 也使用反引号来制作弯曲引号。由于其语法与粗体字面文本的语法非常相似,因此经常会以意想不到的方式匹配。我们使智能引号语法…​更智能

在 Asciidoctor 1.5.0 中,反引号作为引号上的修饰符,表示它应该是弯曲的。现在,您将反引号放在引号字符内,紧邻被引用的短语,以使其“智能”。

Dig through a copy of '`The Times`' and you're bound to see a lot of "`smart`" quotes.

此更改使反引号更靠近引号,从而使解析更加确定。有关更多弯曲引号和撇号示例,请参阅用户手册的弯曲引号

引号表示引号

除非您在兼容模式下运行 Asciidoctor,否则引号将不再处理短语周围的单引号。

AsciiDoc 传统上支持单引号作为将短语标记为斜体的备用语法。然而,短语周围的单引号在西方语言中已经有非常明确的含义。让它们成为它们不是的东西绝不是一个好主意。我们从未建议这样做。此外,它们与新的弯曲引号语法冲突,因此必须删除它们。

有关帮助顺利过渡到新语法的更多信息,请参阅迁移指南

调整级别偏移

leveloffset 属性用于在合并文档时调整节的级别。它对于单个包含级别来说效果很好,但正如 Groovy 开发者 CédricGuillaume 所发现的,当涉及到多级嵌套时,它会迅速失效。

问题在于级别偏移值被假定为绝对值。Asciidoctor 现在支持使用前导 + 或 - 运算符的相对级别偏移值。

:leveloffset: +1
include::chapter-01.adoc[]
:leveloffset: -1

或者,您可以在 include 指令上直接指定 leveloffset 属性,这样您就不必担心恢复旧值了。

include::chapter-01.adoc[leveloffset=+1]

过滤标签指令

Groovy 开发者经常使用 include 和 tag 指令。他们发现,在更广泛的标记范围内,标签指令会被带入文档。Asciidoctor 现在会删除这些行,以便您可以将细粒度的范围嵌套在更广泛的范围内

标签指令也使用更严格的匹配进行搜索,以避免假匹配。

替换修饰符

当您需要自定义块上的替换时,过去必须列出所有您想启用的替换。现在可以使用+-修饰符添加或删除默认替换集中的替换(例如,[subs=+quotes])。这应该能节省很多不必要的输入!

安全资产

通过 SSL 提供资源是避免中间人攻击和一般性窥视的最佳实践。

Asciidoctor 开箱即用的所有远程资源,例如 Font Awesome,现在都通过 SSL 从 https://cdnjs.cloudflare.com 和 https://fonts.googleapis.ac.cn 提供。

隐藏 URI 方案

Asciidoctor 会自动检测并自动链接 URL。作者通常不会利用此功能,因为链接会显示 URI 方案前缀(例如 http://)。因此,他们最终会冗长地编写它,只是为了隐藏前缀。

https://asciidoctor.org.cn[asciidoctor.org]

现在,如果您在文档上设置了 hide-uri-scheme 属性,Asciidoctor 就可以生成完全相同的结果。

:hide-uri-scheme:

https://asciidoctor.org.cn
设置 hide-url-scheme 时的渲染 URL

人性化的交叉引用

如果您链接到文档中的其他锚点,则可以通过标题而不是 ID 来引用它。

Refer to <<Section A>>.

== Section A

随着文档的成熟,您可能希望切换到使用 ID,但这肯定有助于早期草稿的流程!

打印您的文档

Leif Gruenwoldt (@leif81) 指出打印样式过于激进,导致打印文档失去其完整性。我们一起调整了样式表,直到输出看起来几乎和 DocBook 工具链生成的 PDF 一样好。当使用 book doctype 时,样式甚至会将章节分成不同的页面。除了这些样式之外,我们还为 Web 和打印的所有网格和框架排列方式添加了丢失的表格边框样式。

拥有 HTML5 和 CSS3,谁还需要 DocBook?

Print preview of HTML generated by Asciidoctor

开源字体

Asciidoctor 的文化深深植根于开源,所以我们希望完全是开源的。

过去,默认样式表依赖于安装在用户系统上的 Microsoft 核心字体(Arial 和 Georgia)。我们已将这些专有字体替换为开源字体,这些字体我们从 Google Fonts 加载。

以下是我们选择的字体

  • Noto Serif - 正文和块标题

  • Open Sans Light - 章节标题

  • Droid Sans Mono - 粗体文本和预格式化块

我们特别喜欢Noto Serif,因为它是一种极易阅读的字体并且支持世界上所有语言。

我们对默认样式表进行了其他改进,使其外观专业、现代。以下是新默认主题的预览

Screenshot of default Asciidoctor theme

Font Awesome 4.1

说到字体,Asciidoctor 集成了 Font Awesome 4.1,这要归功于 Guillaume Grossetie (@mogztter) 的工作!您现在拥有超过 400 个图标可用于装饰您的文档!

Font Awesome 4 中许多图标的名称都已更改。如果您现有的文档使用图标宏,您可能需要添加 Guillaume 创建的 Font Awesome 3 兼容 CSS 来简化迁移。

“一切都很棒!!!”

致谢

Asciidoctor 最棒的部分是,并且将永远是,它充满活力的社区。我们要感谢以下为本次发布做出贡献的人。

我们要特别鸣谢以下人员

  • Guillaume GrossetieKen DreyerLeif Gruenwoldt@megathaumKen FinniganBrian CarlsonAslak KnutsenDavid GambaWim ChampagneCharles MoulliardJean-Louis JouannicRoman PriesolJames FitzGibbon,他们首次为 Asciidoctor 核心做出了贡献。

  • Guillaume Grossetie 牵头完成了 Asciidoctor 核心和 Asciidoctor.js 的对齐工作。

  • Anthonny Quérouil 为 Asciidoctor.js 设置了 Grunt 构建,并将其发布到了 npm 和 Bower。

  • Opal 团队成员(Adam BeynonmehElia Schito)帮助我们实现了与 Opal 的兼容性,并进行了必要的上游更改。

  • Ken Dreyer 对 Fedora 的 RPM 包进行了全面改造,并将 Asciidoctor 测试套件升级到了 Minitest 5。

  • Peter Neubauer 制作了第一个Asciidoctor T 恤,我在发布时穿了!

我(Dan)还要感谢Sarah White,感谢她为软件设计提供意见、编辑用户手册、更新网站、进行测试(或说:破坏)以及为项目建立文档工作流程所做的巨大努力。没有她的奉献精神,Asciidoctor 就不会有今天的成就。

还要感谢所有使用该项目、倡导更好文档以及参与日益壮大的子项目生态系统的人。Asciidoctor 的使命是帮助您成功地编写、发布和交流您的内容,并乐在其中!通过您的反馈和参与,我们可以共同实现这一目标!我们鼓励您在邮件列表、Twitter 或 IRC 上提问并讨论项目的任何方面。

如果您在源代码、文档或网站内容中发现错误或遗漏,请随时提交问题或开一个 pull request 来修复。我们总是渴望了解您的体验以及如何改进它们。总之,我们正在让文档变得有趣、简单且有益!

下一步是什么?

本次发布只是发布列车的开端。请关注 AsciidoctorJ、Asciidoctor.js、构建插件(Gradle 和 Maven)、Linux 包等版本的发布!

Asciidoctor 的下一个版本将是 1.5.1 版本。从现在开始,我们计划更快地迭代,并且只为主要和次要版本发布公告。

有关更改的完整列表,请参阅CHANGELOG


Asciidoctor 0.1.4 发布!

作者 Dan AllenSarah White -

我们非常激动(也松了一口气)地宣布发布Asciidoctor 0.1.4

什么是 Asciidoctor?

Asciidoctor 是一个快速、开源的文本处理器和发布工具链,用于将 AsciiDoc 标记转换为 HTML 5、DocBook 5.0、DocBook 4.5 和自定义输出格式。Asciidoctor 用 Ruby 编写,打包为 RubyGem 并发布到RubyGems.org。Asciidoctor 处理器也可以通过Java 集成库供任何 JVM 语言或构建系统访问。

请遵循“安装或更新 Asciidoctor”页面上的说明开始。

一个里程碑式的发布

Asciidoctor 0.1.4 最初计划是一个小版本。结果却成了一个跨越阵亡将士纪念日到劳动节的整个夏天的项目,最终成为了迄今为止最大的版本。90 — 没错,90 — 个问题在此过程中被关闭,生成了325 个提交

开发周期的延长部分原因在于用户反馈量的显著增加。我们也不想再错过一个版本而没有包含一个扩展机制,我们很高兴地说,这个机制在这个版本中以技术预览的形式提供。

这个开发周期也充满了里程碑。在上一个版本发布时,我们宣布 Asciidoctor 总下载量已达到 20,000 次。Asciidoctor 0.1.3 本身就超过了这一数字,达到了 27,000 次,总下载量更是突破了 50,000 次大关!但这仅仅是开始。

以下是我们超越的一些额外里程碑

  • > 1,000 次提交(总计 1,158 次)

  • > 1,000 个测试(总计 1245 个)

  • > 500 个已关闭问题(总计 523 个)

  • > 100 个邮件列表主题(总计 117 个)

  • > 1 年的开发(首次提交于 2012 年 6 月 1 日)

再次感谢 Asciidoctor 的出色社区提供的宝贵反馈,帮助 Asciidoctor 在与 AsciiDoc 语法的兼容性上超越了 Python 实现。Asciidoctor 的速度比上一个版本又提高了15%。仅举个例子,该处理器有多快,由 O’Reilly 出版的 16,000 行《企业 Web 开发:从桌面到移动》一书在 Ultrabook 上渲染为 HTML 只需0.85 秒

Asciidoctor 现在已被主要的开源项目使用,最著名的是 Groovy、Spring XD、Spring Security、OpenShift Origin、Neo4j、CRaSH、RichFaces 和 Granite DS 等。在所有开发工作的同时,我们还开始了我们自己的文档工作。Sarah 为项目制定了文档策略(即信息架构),并起草了Asciidoctor 用户手册的初稿。这也是我们首次在GitHub 的每个标签以及存储库根目录的CHANGELOG.adoc文件中拥有一个合适的变更日志。

正如您所见,这里的形势一片大好

基于此,让我们来看看这个新版本有什么内容!(跳转到TL;DR 获取缩略版。)

头条新闻

随处可见的酷炫图标!

Asciidoctor 0.1.4 引入了一个内联宏,用于在段落内容的任意位置插入图标。

这是一个在标签名称列表前插入标签图标的示例

icon:tags[] ruby, asciidoctor

这是示例的渲染效果

ruby, asciidoctor

您甚至可以通过为其分配角色来给图标着色

icon:tags[role=blue] ruby, asciidoctor

显示为

ruby, asciidoctor

图标宏识别几个属性,可用于修改图标的大小、方向和功能。这是一个大型、蓝色的 Twitter Logo,它喝得太多了,但仍然设法链接到 Twitter 主页

创建自

icon:twitter[4x, flip=vertical, link=http://twitter.com]

目前,图标的名称是从Font Awesome图标集中解析的。您可以在图标页面上查看可能的图标名称选项。对其他图标集的支持正在 issue #539 中讨论。

如果您不使用基于字体的图标,Asciidoctor 会在 iconsdir 目录中查找磁盘上的图像。

解决 issue #529

其他改进
  • Asciidoctor 现在使用 Font Awesome 3.2.1(从 cdnjs.com 加载)(#451

文档间引用

在 AsciiDoc 中,xref 内联宏用于创建从一个节到另一个节的交叉引用(即链接)。Asciidoctor 0.1.4 扩展了此功能,允许链接到另一个 AsciiDoc 文档中的节。这消除了使用文档之间的直接链接(例如 HTML 链接)的需要,这些链接将文档耦合到单个后端。交叉引用还捕获了在相关文档之间建立引用的意图。

以下是在 AsciiDoc 中定义 xref 的常规方法

Refer to <<section-b>> for more information.

此 xref 创建一个指向 ID 为section-b的节的链接。

假设 xref 定义在文档document-a.adoc中。如果目标节位于单独的文档document-b.adoc中,作者可能会倾向于编写

Refer to link:document-b.html#section-b[Section B] for more information.

然而,此链接耦合到 HTML 输出。更糟糕的是,如果document-b.adoc包含在与document-a.adoc相同的 master 中,则链接将指向一个实际上不存在的文档!

使用文档间 xref 可以缓解这些问题

Refer to <<document-b.adoc#section-b,Section B>> for more information.

See you when you get back from <<document-b#section-b,Section B>>!

目标 ID 现在放在哈希符号(#)后面。在哈希符号前面是引用文档的名称(文件扩展名是可选的)。我们还为引用分配了一个标签,因为 Asciidoctor (还)无法解析单独文档中的节标题。

当 Asciidoctor 生成此 xref 的链接时,它会首先检查document-b.adoc是否包含在与document-a.doc相同的 master 中。如果没有,它将生成一个指向document-b.html的链接,智能地将原始文件扩展名替换为输出文件的扩展名。

<a href="document-b.html#section-b">Section B</a>

如果document-b.adoc包含在与document-a.doc相同的 master 中,则文档将被放入链接目标中,看起来就像普通 xref 的输出

<a href="#section-b">Section B</a>

现在您可以创建文档间引用而无需麻烦了。

解决 issue #417

不再丢失行!

默认情况下,原始 AsciiDoc 处理器会在包含对缺失属性的引用(例如 {bogus})的行上删除整行。此“功能”已添加到 Python 实现中,用于创建使用 AsciiDoc 语法的自定义后端。

Asciidoctor 不需要这种行为,因为它的模板是由专门的模板语言(例如 ERB、Haml、Slim 等)组成的。但是,此行为的主要问题是它会让作者、编辑或读者感到沮丧。对他们来说,并不总是能立即发现某一行丢失了。发现其缺失通常需要完整(且乏味)地通读文档或节。

Asciidoctor 0.1.4 引入了两个属性来缓解此不便:attribute-missingattribute-undefined

attribute-missing

attribute-missing 属性控制如何处理缺失的引用。默认情况下,缺失的引用会保留原样,这样作者就能清楚地知道它们何时未被满足,因为其意图很可能是被替换。

此属性有三个可能的值

skip

保留引用(默认设置)

drop

删除引用,但不删除行

drop-line

删除发生引用的行(兼容行为)

考虑以下 AsciiDoc 行

Hello, {name}!

假设 name 属性未定义,则行在每种情况下处理方式如下

skip

Hello, {name}!

drop

Hello, !

drop-line

attribute-undefined

attribute-undefined 属性控制如何处理取消定义属性的表达式(例如 {set:name!})。默认情况下,该行将被删除,因为该表达式是一个语句,而不是内容。在这种情况下,坚持兼容行为是合理的,因为这种表达式不用于生成内容。

我们建议将任何取消定义属性的语句放在单独一行。

解决 issue #523

YouTube 和 Vimeo 视频

video::[] 宏现在支持来自 YouTube 和 Vimeo 等外部视频托管服务。要使用此功能,请将视频 ID 放在宏目标中,并将托管服务的名称放在第一个位置属性中。Asciidoctor 会将两者组合起来,生成正确的嵌入代码以在 HTML 输出中插入视频。

这是一个嵌入 YouTube 视频的示例

video::rPQoq7ThGAU[youtube, 640, 360]

这是一个嵌入 Vimeo 视频的示例

video::67480300[vimeo, 400, 300]

您可以通过宏上的附加属性和选项来控制视频设置。例如,您可以使用 start 属性偏移播放开始时间,并使用 autoplay 选项启用自动播放。

video::rPQoq7ThGAU[youtube, 640, 360, start=60, options=autoplay]

解决了问题 #587

DocBook 5.0 后端

除了 DocBook 4.5,Asciidoctor 0.1.4 还可以生成 DocBook 5.0 输出,由 docbook5 后端处理。

docbook5 后端的输出与 docbook45 的输出仅有细微差别,足以使其符合 DocBook 5.0 规范。差异总结如下

  • 文档根目录使用 XSD 声明而不是 DTD

  • 用于文档信息的 <info> 元素,而不是 <articleinfo><bookinfo>

  • 包含作者姓名的元素被包装在 <personname> 元素中

  • 元素的 ID 使用 xml:id 属性定义

  • 链接使用 <link> 而不是 <ulink>

  • 链接的 URL 使用 xlink:href 属性定义

有关 DocBook 5.0 与 DocBook 4.5 差异的更多详细信息,请参阅 DocBook v5.0 有哪些新功能?

要使用 DocBook 5.0 后端,请将后端设置为 docbook5,如下例所示

$ asciidoctor -b docbook5 sample.adoc

这是此后端生成的 DocBook 5.0 文档示例

<?xml version="1.0" encoding="UTF-8"?>
<article xmlns="http://docbook.org/ns/docbook"
    xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:lang="en">
  <info>
    <title>Hello, AsciiDoc!</title>
    <date>2013-09-03</date>
    <author>
      <personname>
        <firstname>Doc</firstname>
        <surname>Writer</surname>
      </personname>
      <email>doc@example.com</email>
    </author>
    <authorinitials>DW</authorinitials>
  </info>
  <simpara>
    An introduction to <link xlink:href="http://asciidoc.org">AsciiDoc</link>.
  </simpara>
  <section xml:id="_first_section">
    <title>First Section</title>
    <itemizedlist>
      <listitem>
        <simpara>item 1</simpara>
      </listitem>
      <listitem>
        <simpara>item 2</simpara>
      </listitem>
    </itemizedlist>
  </section>
</article>

解决了问题 #411

其他改进
  • 默认情况下,xmlns 属性已添加到根 DocBook 元素。设置 noxmlns 属性可禁用此功能。

Debian 和 Ubuntu 包

继 Fedora 包之后,Asciidoctor 现在也为 Debian 和 Ubuntu 打包了,这要归功于 Per Andersson!无需多言!

您可以使用以下命令在 Debian 或 Ubuntu 上安装 Asciidoctor

$ sudo apt-get install asciidoctor
目前,只有 Asciidoctor 0.1.3 的软件包可用。Asciidoctor 0.1.4 的更新软件包应在此版本发布后几周内可用。

解决了问题 #216

漂亮的源代码列表

我们知道代码对您很重要。它对我们也很重要。因此,我们在本次发布中对源代码列表进行了一些很棒的改进。

代码注释不会被复制

以前,当读者从 Asciidoctor 生成的 HTML 页面中选择并复制包含注释的代码时,注释编号会一起被复制。这些多余的字符可能会在读者粘贴代码的位置导致编译或运行时错误。读者不应该以这种方式感到惊讶,或者需要理解为什么额外的字符会出现在剪贴板中。复制和粘贴应该像预期的那样工作。

在此版本中,我们使用了一些 CSS 技巧来防止注释被复制。无论读者如何努力,这些注释都无法被选中。(行号也是如此)。

另一方面,您也不希望注释注解弄乱您的代码。我们无法在原始源代码中使用花哨的 CSS 游戏,但我们可以利用行注释!您现在可以将注释整齐地隐藏在行注释后面。Asciidoctor 会识别注释数字前面的行注释字符——以及可选的空格——并在渲染文档时将其删除。

以下是支持的行注释

----
line of code  // <1>
line of code   # <2>
line of code  ;; <3>
----
<1> A callout behind a line comment for JavaScript, Java, and C-style languages.
<2> A callout behind a line comment for Ruby, Python, Perl, etc.
<3> A callout behind a line comment for Clojure and Lisp-style languages.

以下是渲染后的注释代码示例

line of code  (1)
line of code  (2)
line of code  (3)
1 JavaScript、Java 和 C 风格语言的行注释后面的注释。
2 Ruby、Python、Perl 等的行注释后面的注释。
3 Clojure 和 Lisp 风格语言的行注释后面的注释。

请注意,行注释字符已消失!现在选择这些行。正如您所见,注释被留在了后面。

我们希望注释能够提供帮助,而不是带来麻烦。

Asciidoctor 要求注释必须放在行的末尾。

解决了问题 #478

说到麻烦,XML 中的注释又如何呢?继续阅读以找出答案。

XML 兼容的注释

XML 没有行注释,所以我们的“将注释隐藏在行注释后面”的技巧在这里不起作用。我们尝试了语法,并想出了一个我们认为有效且看起来相当干净的方案。我们只是拉伸了注释数字周围的尖括号,并将其变成了一个 XML 注释

<1><!--1-->

以下是 XML 兼容注释在列表中显示的效果

[source,xml]
----
<section>
  <title>Section Title</title>  <!--1-->
</section>
----
<1> The section title is required.

以下是注释渲染后的效果

<section>
  <title>Section Title</title>  (1)
</section>
1 需要章节标题。

再次,请注意注释已消失,并且注释编号无法被选中。

此语法也适用于 HTML 列表中的注释。

解决了问题 #582

Asciidoc 兼容文件中包含了一个用于 XML 兼容注释的宏定义,以便 asciidoc 命令也能识别它们。

由于这些增强功能,读者和开发人员都可以复制和粘贴包含注释的源代码,而无需担心导致错误的“搭便车”现象。但是,我们对注释的技巧还没有结束。

无高亮注释

我们收到报告称,在使用 CodeRay 源代码高亮器时(例如 source-highlighter=coderay),在某些情况下注释没有被替换。

事实证明,问题在于代码中注释的存在(无论是行注释还是其他注释)会导致它们被高亮显示并被破坏。这里的技巧是在高亮显示之前将注释从源代码中提取出来,然后再恢复它们。这样,源代码高亮器就看不到它们了,我们可以确保它们被正确地放置在应有的位置,而不会被破坏。

您无需更改任何内容即可利用此改进。此功能在使用 CodeRay 或 Pygments(即“服务器端”源代码高亮器)时有效。

解决了问题 #534

等等,您说过 Pygments 了吗?

没错。Asciidoctor 可以使用 Pygments 来高亮源代码!

使用 Pygments 进行语法高亮

Asciidoc 社区中最受欢迎的源代码高亮器——也许是整个世界——是 Pygments。直到现在,Asciidoctor 只与 CodeRay 集成进行“服务器端”源代码高亮,主要是因为它也用 Ruby 编写。

感谢 GitHub 的那些了不起的人,Pygments 有一个名为 pygments.rb 的不错的 Ruby 包装库,这使得集成变得轻而易举。

要使用 Pygments 和 Asciidoctor,您需要安装 Pygments(如果还没有,还需要安装 Python)。运行类似以下命令:

$ "`\which apt-get || \which yum || \which brew`" install python-pygments

然后您需要安装 pygments.rb RubyGem。

$ gem install pygments.rb

要激活 Asciidoctor 中的 Pygments,请在文档的标题中将 pygments 值赋给 source-highlighter 属性。

:source-highlighter: pygments

瞧!您的代码现在拥有“pygments”了。

解决了问题 #538

其他改进
  • 默认的 CodeRay 主题已更新,使其与默认的 Asciidoctor 样式更好地匹配。

  • 如果对源代码列表使用了 subs 属性(只要 specialcharacters 在 subs 列表中),语法高亮将不再被禁用。

换行还是滚动,这是个问题

以前,Asciidoctor 样式表被配置为阻止列表和字面量块中的换行(例如 white-space: pre-wrap; word-wrap: normal)。这种行为并不总是可取的,因为它会导致浏览器窗口在内容超出页面宽度时滚动。对许多人来说,这种水平滚动被认为是比换行更严重的阅读问题。

由于对如何处理溢出文本有两种观点,所以任何一种选择都不会让所有受众都满意。因此,我们在 Asciidoctor 0.1.4 中使这种行为可配置。

默认的 Asciidoctor 样式表现在通过应用 CSS white-space: pre-wrapword-wrap: break-word 来换行列表和字面量块中的长行。行在单词边界处换行,类似于大多数文本编辑器换行的方式。

有两种方法可以阻止行换行,从而使用水平滚动代替

  • 在块上设置 nowrap 选项

  • 取消设置文档属性 prewrap

您可以使用字面量块或列表块上的 nowrap 选项来阻止在 HTML 中换行

public class ApplicationConfigurationProvider extends HttpConfigurationProvider
{
   @Override
   public Configuration getConfiguration(ServletContext context)
   {
      return ConfigurationBuilder.begin()
               .addRule()
               .when(Direction.isInbound().and(Path.matches("/{path}")))
               .perform(Log.message(Level.INFO, "Client requested path: {path}"))
               .where("path").matches(".*");
   }
}

使用 nowrap 选项时,nowrap 类会被添加到 <pre> 元素中。此样式类将 CSS 更改为 white-space: preword-wrap: normal

要全局应用 nowrap 选项,请取消设置文档上的 prewrap 属性。

:prewrap!:

prewrap 属性被取消设置时,nowrap 类会被添加到任何 <pre> 元素中,即使块上不存在 nowrap 选项。

现在,您可以使用最适合您和您的读者的方法进行换行。

解决了问题 #303

标记您的列表

列表无处不在。让我们让它们发挥作用。

使用清单完成任务

列表项现在可以使用清单标记为已完成。如果您使用 Asciidoctor 来跟踪任务的完成情况,请准备好开始勾选您的任务!

清单(即任务列表)是未排序列表,其中包含标记为已选中([*][x])或未选中([ ])的项。这是一个例子

清单
- [*] checked
- [x] also checked
- [ ] not checked
-     normal list item

当清单渲染为 HTML 时,复选框标记将转换为 HTML 复选框,并具有适当的选中状态。有关更多详细信息,请查看用户手册中的清单部分。用户手册

如果您启用基于字体的图标(即 -a icons=font),复选框标记将使用基于字体的图标渲染!看起来是这样的

  • 已选中

  • 也已选中

  • 未选中

  • 普通列表项

漂亮!

解决了问题 #200

列表的更多项目符号和编号样式

Asciidoctor 0.1.4 为列表提供了额外的项目符号和编号样式。列表标记(项目符号或编号样式)使用列表的块样式设置。

Asciidoctor 现在识别 HTML 和 DocBook 中所有可用的无序列表项目符号。

无序列表标记可以使用以下任一块样式设置

  • 方形

  • 圆形

  • 圆盘

  • noneno-bullet(缩进,但无项目符号)

  • unstyled(无缩进或项目符号)(仅限 HTML)

  • inline(像段落一样,无项目符号)(仅限 HTML)

这些样式受默认 Asciidoctor 样式表支持。

存在时,样式名称将分配给无序列表元素,如下所示

对于 HTML

样式名称将分配给 <ul> 元素上的 class 属性。

对于 DocBook

样式名称将分配给 <itemizedlist> 元素上的 mark 属性。

以下是如何创建带有方形项目符号的无序列表

[square]
* one
* two
* three

对于有序列表,除了现有选项外,Asciidoctor 现在还支持小写希腊字母和零前导十进制编号样式。

这两种新样式仅在 HTML 后端受支持(DocBook 不识别这些选项)。

以下是一些示例,显示了如标题行所示的块样式的各种编号样式

[arabic]* [decimal] [loweralpha] [lowergreek]

* 如果未指定块样式,则为默认编号

可以使用自定义角色来实现自定义编号样式。在您的样式表中定义一个新的类选择器(例如 .custom),该选择器将 list-style-type 属性设置为您选择的值。然后,将该类的名称(例如 [.custom])作为角色分配给您希望应用该编号的任何列表。

有关项目符号和编号的更多信息,请参阅 用户手册

解决了问题 #364#472#620

其他改进
  • 当角色简写(例如 [.custom])用于有序列表时,默认的编号样式不再被丢弃。

更多省时功能

表格的隐式表头行

在 Asciidoctor 0.1.3 中添加了用于指定表格格式的简写语法(例如 ,===;===)之后,仍然需要使用块属性行来启用表头行(例如 [options="header"])似乎很繁琐。

现在可以通过遵循一些约定来隐式启用表头行。以下是在 Asciidoctor 0.1.4 中引入的用于确定第一行是否应为表头行的约定

  1. 表格分隔符内的第一行内容不为空。

  2. 表格分隔符内的第二行内容为空。

  3. 未在块属性中指定 options 属性。

如果所有这些规则都成立,则表格的第一行将被视为表头行。基于现有约定,如果未指定 cols 属性,则表格的列数将设置为第一行(即表头行)的列数。

这是一个具有隐式表头行的表格示例

|===
|A |B |C (1)

|A-1
|B-2
|C-3

|A-2| B-2| C-2

|A-3
|B-3
|C-3
|===
1 符合表头行的约定。

渲染效果如下

A B C

A-1

B-1

C-1

A-2

B-2

C-2

A-3

B-3

C-3

您可以随意安排剩余行的单元格。但请注意,我们正在考虑未来使用类似的约定来启用页脚。因此,如果您依赖此约定来启用表头行,则建议不要将最后一行的所有单元格放在同一行上,除非您打算将其作为页脚行。

解决了问题 #387

块选项的简写语法

在传统的 AsciiDoc 语法中,块选项在块的属性列表中使用 options 属性指定。Asciidoctor 0.1.4 允许使用块简写语法指定选项,其中选项名称前面带有百分号(%)。

考虑以下具有三个选项的表格块

使用传统 AsciiDoc 语法的块选项
[options="header,footer,autowidth"]
|===
|Cell A |Cell B
|===

这是使用简写语法(%)编写选项的方式

使用 Asciidoctor 简写语法的块选项
[%header%footer%autowidth]
|===
|Cell A |Cell B
|===

让我们考虑将选项与其他简写语法结合使用。

传统 AsciiDoc 语法
[horizontal, role="properties", options="step"]
property 1:: does stuff
property 2:: does different stuff
Asciidoctor 简写语法
[horizontal.properties%step]
property 1:: does stuff
property 2:: does different stuff

解决了问题 #481

格式化(即引用的)文本上的简写语法

在 Asciidoctor 0.1.3 中引入的块简写语法现在也可以用于内联格式化(即引用的)文本。

这是一个具有两个角色的内联锚点和格式化文本的示例

传统 AsciiDoc 语法
[[free_the_world]][big goal]_free the world_
Asciidoctor 简写语法
[#free_the_world.big.goal]_free the world_
由于引用的文本没有 ID,id 属性将被转换为位于文本前面的锚点。

在 HTML 后端,此语法变为

<a id="free_the_world"><em class="big goal">free the world</em>

在 DocBook 后端,它变为

<anchor id="free_the_world" xreflabel="free the world"/><emphasis><phrase
role="big goal">free the world</phrase></emphasis>

解决了问题 #517

其他改进
  • 可以使用反斜杠转义格式化文本前面的属性列表(例如 \[role]*bold*)。在这种情况下,文本仍会被格式化,但属性列表将被转义并按原样输出。(#421

反引号包围文本的角色扮演

为了与 AsciiDoc 中的其他格式化(即引用的)文本保持一致,现在可以为反引号包围的文本分配角色。

给定

[rolename]`escaped monospace text`

生成的 HTML 如下

<code class="rolename">escaped monospace text</code>

使用 Asciidoctor 0.1.4 中的新简写语法,还可以指定 ID(即锚点)

[#idname.rolename]`escaped monospace text`

这会生成

<a id="idname"></a><code class="rolename">escaped monospace text</code>

请记住,反引号包围的文本不受其他内联替换的影响,而是按原样传递。

解决了问题 #419

从 CLI 处理多个源文件

Asciidoctor CLI(即 asciidoctor 命令)不再是单一用途的!您可以将多个源文件(或文件名模式)传递给 Asciidoctor CLI,它将依次处理所有文件。

假设您的目录中有两个 AsciiDoc 文件,a.adocb.adoc。当您在终端中输入以下命令时

$ asciidoctor a.adoc b.adoc

Asciidoctor 将处理这两个文件,将 a.adoc 转换为 a.html,将 b.adoc 转换为 b.html

为了节省您的输入,您可以使用 glob 操作符(*)通过单个参数匹配两个文件

$ asciidoctor *.adoc

Shell 将会把前面的命令展开成您之前输入的那个

$ asciidoctor a.adoc b.adoc

您还可以使用双 glob 操作符(**)替换目录名来渲染子目录中的所有 AsciiDoc 文件

$ asciidoctor **/*.adoc

要匹配当前目录和子目录中的所有文件,请同时使用这两个 glob 模式

$ asciidoctor *.adoc **/*.adoc

如果文件名参数被引用,Shell 将不会展开它

$ asciidoctor '*.adoc'

这次,文本 *.adoc 将直接传递给 Asciidoctor,而不是展开成 a.adocb.adoc。在这种情况下,Asciidoctor 会在内部处理 glob 匹配,方式与 Shell 相同(当文件名未被引用时)——有一个例外。Asciidoctor 可以使用单个 glob 模式匹配当前目录和子目录中的文件,无论深度如何

$ asciidoctor '**/*.adoc'

这才是真正节省输入!

解决了问题 #227

其他改进
  • 当输入是 stdin 时,asciidoctor 命令会写入指定的输出文件。(#500

例如,以下命令将写入 output.html 而不是控制台

$ echo "content" | asciidoctor -o output.html -

格式化无处不在

让图片各就各位

图片是增强文本的绝佳方式,无论是为了说明一个想法、展示而非讲述,还是仅仅为了帮助读者与文本产生共鸣。

开箱即用,图片和文本就像油和水一样。图片不喜欢与文本共享空间。它们对此有点“固执”。这就是为什么我们调整了图片宏中的控件,以便您可以让图片和文本流畅地协同工作。

您可以通过两种方式定位图片

  1. 命名属性

  2. 角色

定位属性

Asciidoctor 已经支持块图片上的 align 属性来在块内对齐图片(例如,左、右或居中)。在此版本中,我们在块和内联图片宏中都添加了 float 命名属性。此属性将图片拉到页面的一侧或另一侧,并分别将块或内联内容环绕在它周围。

这是一个浮动块图片的示例。图片后面的段落或其他块将浮动到图片旁边的可用空间中。图片还将水平居中在图片块中。

右对齐并居中在块内的块图片
image::tiger.png[Tiger,200,200,float="right",align="center"]

这是一个浮动内联图片的示例。图片将浮动到段落文本的右上角。

位于段落文本右侧的内联图片
image:linux.png[Linux,150,150,float="right"]
You can find Linux everywhere these days!

当您使用命名属性时,CSS 会被内联添加(例如 style="float: left")。这是不良做法,因为它会使页面在您想要自定义主题时更难设置样式。使用 CSS 类来处理这些事情要好得多,这些类在 AsciiDoc 术语中映射到角色。

定位角色

以下是上面的示例,现在已配置为使用映射到默认 Asciidoctor 样式表中 CSS 类的角色

使用定位角色的图片宏
[.right.text-center]
image::tiger.png[Tiger,200,200]

image:linux.png[Linux,150,150,role="right"]
You can find Linux everywhere these days!

下表列出了默认提供的用于定位图片的所有角色。

图片定位角色
浮动 对齐

角色

text-left

text-right

text-center

块图片

内联图片

仅仅设置图片的浮动方向不足以实现正确的定位。这是因为,默认情况下,图片和文本之间没有留白。为了解决这个问题,我们为使用定位命名属性或角色的图片添加了合理的边距。

如果您想自定义图片样式,可能需要自定义边距,您可以提供自己的样式表补充(通过使用自己的样式表,该样式表建立在默认样式表之上,或将样式添加到 docinfo 文件中)。

图片框

通常会为图片添加边框,以便进一步将其与文本区分开。您可以使用 thumb 角色(或简写 th),也可以在默认样式表中将任何块或内联图片设置为缩略图样式。

thumb 角色不会改变图片尺寸。要做到这一点,您需要为图片分配高度和宽度。

这是一个非常常见的例子,用于向博客文章添加图片。图片浮动到右侧并添加边框,使其比文本更突出。

image:logo.png[role="related thumb right"] Here's text that will wrap around the image to the left.

请注意,我们为图片添加了 related 角色。此角色在技术上并非必需,但它为图片提供了语义含义。

控制浮动

当您开始浮动图片时,您可能会发现太多的内容围绕着图片。您需要一种方法来清除浮动。这可以通过另一个角色 float-group 来提供。

假设我们已经将两张图片浮动在一起,并且希望下一段出现在它们下方。

[.left]
.Image A
image::a.png[A,240,180]

[.left]
.Image B
image::b.png[B,240,180,title="Image B"]

Text below images.

当这个例子在浏览器中渲染并查看时,段落文本会出现在图片右侧。要解决此行为,您只需将图片“分组”到一个具有自包含浮动的块中。方法如下

[.float-group]
--
[.left]
.Image A
image::a.png[A,240,180]

[.left]
.Image B
image::b.png[B,240,180]
--

Text below images.

这次,文本将出现在我们想要的图片下方。

解决了问题 #460

图片 URL 被渲染,而不是被篡改

AsciiDoc 无法决定是支持远程图片(即带有 URL 目标的图片)还是不支持。虽然您一直可以使用 URL 作为块图片,但 AsciiDoc 和 Asciidoctor 都会忽略带有 URL 目标的内联图片。

即使是块图片,如果您定义了 imagesdir 属性来设置本地图片的位置,AsciiDoc 也会崩溃。在这种情况下,AsciiDoc 会通过盲目地在此 URL 前加上此路径来篡改图片 URL。糟糕!

事情变得一团糟。现在不是了。您现在可以引用来自任何 URL 的图片(例如,您的博客、图片托管服务、您的文档服务器等),而无需担心下载图片并将它们放在本地的某个位置。Asciidoctor 能正确处理。我们还更新了 AsciiDoc 兼容文件,以便 AsciiDoc 也能正确处理。

以下是一些带有 URL 目标的图片示例

带有 URL 目标的块图片
imagesdir: ./images

image::https://upload.wikimedia.org/wikipedia/commons/3/35/Tux.svg[Tux,250,350]
带有 URL 目标的内联图片
imagesdir: ./images

You can find image:https://upload.wikimedia.org/wikipedia/commons/3/35/Tux.svg[Linux,25,35] everywhere these days.
当图片目标是 URI 时,imagesdir 的值将被忽略。

如果您想避免为每张图片输入 URL 前缀,并且所有图片都位于同一服务器上,您可以使用 imagesdir 属性来设置基本 URL

使用 URL 作为图片的基 URL
:imagesdir: https://upload.wikimedia.org/wikipedia/commons

image::3/35/Tux.svg[Tux,250,350]

这次,imagesdir 被使用,因为图片目标不是 URL(imagesdir 恰好是一个)。

解决了问题 #470

其他改进
  • 包含 URL 的脚注现在可以正确解析并在输出到 HTML 时格式化。(#506

行为良好的目录(TOC)

html5 后端的 TOC 现在渲染为无序列表而不是有序列表。之所以进行此更改,是因为有序列表的自动编号与 AsciiDoc 中的编号策略不一致,因此在语义上是不正确的。这也消除了在缺少默认样式表时出现的“章节重复编号”问题。此外,可以删除 type="none" 列表属性的解决方法。

解决了问题 #461

Asciidoctor 现在能够正确地对文档中禁用编号的部分进行章节编号。以前,Asciidoctor 会在禁用章节编号的文档区域递增章节编号计数器,导致章节编号跳过。Asciidoctor 现在会在禁止编号的区域冻结计数器,以防止编号出现间隙。

如果文档一开始开启了章节编号,Asciidoctor 之前还会阻止关闭章节编号。现在,如果向 Asciidoctor 传递了 -a numbered 选项,它仍然会遵守文档流中的 :numbered!: 指令。

简而言之,章节编号现在能正常工作了。

解决了问题 #341

其他改进
  • tocnumbered 属性在 DocBook 后端默认启用。(#540

  • 通过为 toc-positiontoctoc2 属性赋值 right,可以将目录定位到右侧。(#467, #618

  • 在默认的 Asciidoctor 样式表中,序言(preamble)的 toc 得到了更新,采用了类似面板的样式(正如在 asciidoctor.org 上看到的)。(#507

Markdown 风格的水平线

Asciidoctor 通过识别 Markdown 的水平线,继续扩展对(合理)Markdown 语法的支持。这样做的目的是为了简化迁移(内容和思维的迁移)。

为了避免与 AsciiDoc 块分隔符的语法冲突,只识别 3 个重复字符(-*)。与 Markdown 一样,字符之间的空格是可选的。

识别的 Markdown 水平线语法
---

- - -

***

* * *

Markdown 水平线的宏定义包含在 AsciiDoc 兼容性文件中,以便 asciidoc 命令也能识别它们。

解决了问题 #455

内容,或多或少

从 URI 包含内容

include 指令现在可以直接从 URI 包含内容。

以下是一个演示如何包含 AsciiDoc 内容的示例

:asciidoctor-source: https://raw.githubusercontent.com/asciidoctor/asciidoctor/master

include::{asciidoctor-source}/README.adoc[]

以下是另一个示例,展示了如何包含源文件的特定行

:asciidoctor-source: https://raw.githubusercontent.com/asciidoctor/asciidoctor/master

[source,ruby]
----
include::{asciidoctor-source}/lib/asciidoctor/helpers.rb[lines=10..30]
----

由于这是一个潜在危险的功能,如果安全模式为 SECURE 或更高,它将被禁用。假设安全模式低于 SECURE,您还必须设置 allow-uri-read 属性,以允许 Asciidoctor 从 URI 读取内容。

从 URI 读取内容显然比从本地文件读取慢得多。Asciidoctor 提供了一种缓存从 URI 读取的内容的方式,强烈建议使用。

要启用内置缓存,您必须

  • 安装 open-uri-cached gem

  • 设置 cache-uri 属性

当这两个条件满足时,Asciidoctor 将根据 HTTP 缓存建议缓存从 URI 读取的内容。

解决了问题 #445

其他改进
  • include 指令现在相对于当前文档解析文件,而不是相对于根文档。这适用于在自身已被包含的文件内部使用的 include 指令。(#572

AsciiDoc 允许您通过提供 docinfo 文件将自定义内容包含在输出文档(HTML 或 DocBook)的页眉中。在 Asciidoctor 0.1.4 中,docinfo 文件也可以用来向页脚添加自定义内容。

页脚 docinfo 文件通过在文件名中添加 -footer 来与页眉 docinfo 文件区分。在 HTML 输出中,页脚内容插入在 footer div 中(即 <div id="footer">)。在 DocBook 输出中,页脚内容插入在结束的 </article></book> 元素之前。

docinfo

如果您想在特定文档的页脚添加内容,请将内容放在文件 <docname>-footer.html(对于 HTML 输出)或 <docname>-footer.xml(对于 DocBook 输出)中,其中 <docname> 是文档名称,不包含 AsciiDoc 扩展名。然后,在 AsciiDoc 源文档中设置 docinfo 属性以启用该功能。

docinfo1

如果您想在同一目录的所有文档的页脚添加内容,请将内容放在文件 docinfo-footer.html(对于 HTML 输出)或 docinfo-footer.xml(对于 DocBook 输出)中。然后,在 AsciiDoc 源文档中设置 docinfo1 属性以启用该功能。

docinfo2

如果您希望文档查找任一 docinfo 文件,请在 AsciiDoc 源文档中设置 docinfo2 属性。

解决了问题 #486

附加增强功能
  • 属性会在 docinfo 文件(页眉和页脚)的内容中进行替换。(#403

  • 可以通过取消分配 last-update-label 属性来禁用页脚中的“最后更新”行(#407

忽略为静态站点生成器添加的前置信息

许多静态站点生成器(例如 Jekyll、Middleman、Awestruct)依赖于添加到文档顶部的“前置信息”来确定如何渲染内容。前置信息通常从文件的第一行开始,并由块分隔符(例如 ---)界定。

以下是一个包含前置信息的文档示例

-(1)
layout: default (2)
-(1)
= Document Title

content
1 前置信息分隔符
2 前置信息数据

静态站点生成器会在将文档传递给 Asciidoctor 处理器进行渲染之前删除这些行。然而,在生成器之外,这些额外的行会混淆 AsciiDoc 处理器。

如果设置了 skip-front-matter 属性,Asciidoctor 0.1.4 将识别前置信息并在解析文档之前将其消耗掉。Asciidoctor 将移除的内容存储在 front-matter 属性中,以便进行集成。Asciidoctor 在读取包含文件时也会移除前置信息。

Awestruct 可以直接从文档标题中定义的 AsciiDoc 属性获取所需信息,从而无需担心前置信息。

解决了问题 #502

后端增强

样式表默认嵌入

在早期版本的 Asciidoctor 中,我们默认将 HTML 输出中的样式表链接,而不是嵌入它——这与 AsciiDoc 的工作方式相反。我们这样做的原因是想让 HTML 输出文档保持轻量。我们发现新用户通常不会发现默认样式表,当依赖 CSS 的某些功能不起作用时,他们会感到困惑。

我们宁愿让 Asciidoctor 开箱即用。这对新用户来说是更好的体验,并且我们可以减少回答相同论坛帖子的时间。

因此,在 Asciidoctor 0.1.4(及之后)版本中,样式表默认嵌入到 HTML 输出中(即不设置 linkcss)。如果没有指定样式表,则嵌入默认样式表。新用户不再需要调整 linkcsscopycss 属性。

事实证明,改变这个默认设置还有另一个好处。我们不再需要依赖 copycss 属性了。现在,如果设置了 linkcss 属性,样式表将被复制到 stylesdir(输出目录内),以便 HTML 文档可以找到它们。如果您使用的是默认样式表,您会看到 asciidoctor.css 出现在这个目录中。要禁用此行为,只需取消设置 copycss 属性(即 copycss!)。

当设置了 linkcss 样式表属性时,Asciidoctor 尚未复制用户指定的样式表。

解决了问题 #428

辅助样式表

Asciidoctor 还会默认嵌入提供 CodeRay 或 Pygments 语法高亮主题的样式表。

对于 CodeRay

如果 source-highlighter 属性是 coderay,并且 coderay-css 属性是 class,CodeRay 样式表将

  • 嵌入(如果未设置 linkcss,为默认行为)

  • 复制到输出目录中 stylesdir 文件夹内的 asciidoctor-coderay.css 文件(如果设置了 linkcss

对于 Pygments

如果 source-highlighter 属性是 pygments,并且 pygments-css 属性是 class,Pygments 样式表将

  • 嵌入(如果未设置 linkcss,为默认行为)

  • 复制到输出目录中 stylesdir 文件夹内的 asciidoctor-pygments.css 文件(如果设置了 linkcss

解决了问题 #381

多个自定义模板目录

自定义模板现在可以存储在多个目录中。这意味着您可以复制您想修改的模板来扩展现有的后端。然后,在调用 Asciidoctor 时,只需同时指定包含原始模板的目录和包含自定义模板的目录。

在 CLI 中,通过多次使用 -T 选项来指定多个模板目录。

$ asciidoctor -T /path/to/original/templates -T /path/to/modified/templates sample.adoc

在 API 中,通过将数组传递给 template_dirs 选项来指定多个模板目录

Asciidoctor.render_file 'sample.adoc', :safe => :safe, :in_place => true,
    :template_dirs => ['/path/to/original/templates', '/path/to/modified/templates']

尽情发挥吧!

解决了问题 #437

其他改进
  • API 中的模板引擎选项(即 :template_engine)现在映射到 CLI 中的 --template-engine(长选项)或 -E(短选项)。此选项用于解析后端模板的位置,相对于使用 --template-dir(长选项)或 -T(短选项)指定的路径。(#406

  • 后端模板现在会被缓存,这样在同一个 Ruby 进程中调用 Asciidoctor 时就不会重新加载它们。默认情况下,Asciidoctor 使用内部缓存,尽管可以使用 :template_cache 选项将自定义缓存传递给 API。(#438

AsciiDoc 中的 man 页

AsciiDoc 最有趣的用途之一是为 Unix 和类 Unix 操作系统创建 man 页(manual pages 的缩写)。man 页遵循特殊的文档结构。当 doctype 属性设置为 manpage 时,AsciiDoc,现在是 Asciidoctor,就能识别这种结构。

在读取使用 manpage doctype 的 AsciiDoc 文档时,Asciidoctor 会解析以下 man 页元数据

  • mantitle

  • manvolnum

  • manname

  • manpurpose

mantitlemanvolum 从文档标题中捕获。mannamemanpurpose 取自文档的第一个节,该节必须是级别 1 的节,并且内容格式为 <manname> - <manpurpose>

以下是一个用 AsciiDoc 编写的 man 页示例

= asciidoctor(1)
:doctype: manpage

== NAME
asciidoctor - converts AsciiDoc source files...

== SYNOPSIS
*asciidoctor* ['OPTION']... 'FILE'...

从这份文档中,Asciidoctor 提取了以下与 man 页相关的属性

mantitle

asciidoctor

manvolnum

1

manname

asciidoctor

manpurpose

将 AsciiDoc 源文件转换为……

请参考 Asciidoctor man 页的 AsciiDoc 源文件 来查看完整示例。git 的 man 页也是从 AsciiDoc 文档生成的,所以您也可以将它们作为另一个示例来参考。

解决了问题 #488

其他改进
  • 使用 html5 后端将 man 页渲染为 HTML 时,Asciidoctor 会产生与 AsciiDoc 相同的输出。(#489

  • Asciidoctor Backends 仓库 托管了一个 manpage 后端 的早期草稿,该后端现在用于生成 Asciidoctor 的 man 页。

扩展!

自从我开始从事 Asciidoctor 的工作以来,我一直热切地期待有机会开发扩展 API。那个时候已经到了。 我很高兴地说,在 Asciidoctor 0.1.4 中,扩展作为技术预览提供。

技术预览

扩展 API 应被视为实验性并可能发生更改。此技术预览旨在让有兴趣的开发者进行尝试,并帮助完善设计。

如果您现在需要扩展提供的功能,请不要犹豫。只需记住,在升级 Asciidoctor 时,您可能需要重构部分扩展。

简介

我一直期待将扩展引入 Asciidoctor 的原因是因为它们已经证明对 AsciiDoc 和 Python 实现的成功至关重要。尽管它们取得了成功,但仍然有充足的改进空间。

AsciiDoc 中的扩展(技术上称为过滤器)存在一些问题

  • 编写它们很有挑战性,因为它们工作在非常低的级别(读作:棘手的正则表达式)

  • 它们很脆弱,因为它们依赖系统命令来执行任何重要操作

  • 由于缺乏与正式分发系统的集成,它们难以分发

Asciidoctor 的目标一直是允许使用完整的编程语言(无论是 Ruby、Java、Groovy 还是 JavaScript)编写扩展,这与我们对后端(渲染)机制所做的一样。这样,您就不必费尽心思去获取所需的功能,并且可以使用事实上的标准打包机制(如 RubyGems 或 JAR)来分发扩展。

扩展点

以下是 Asciidoctor 0.1.4 中可用的扩展点。

预处理器 (Preprocessor)

在原始源代码行传递给解析器之前进行处理。

树处理器 (Treeprocessor)

解析完成后,处理 Asciidoctor::Document(AST)。

后处理器 (Postprocessor)

在文档渲染完成后、写入磁盘之前处理输出。

块处理器 (Block processor)

处理标记有自定义块样式的块内容(即 [custom])。(类似于 AsciiDoc 过滤器)

块宏处理器 (Block macro processor)

注册自定义块宏并处理它(例如 gist::12345[])。

内联宏处理器 (Inline macro processor)

注册自定义内联宏并处理它(例如 btn:[Save])。

包含处理器 (Include processor)

处理 include::<filename>[] 指令。

这些扩展是使用一种类似于 DSL 的回调机制按文档注册的

Asciidoctor::Extensions.register do |document|
  preprocessor FrontMatterPreprocessor
  treeprocessor TerminalCommandTreeprocessor
  postprocessor CustomFooterPostprocessor
  block :yell, YellBlock
  block_macro :gist, GistMacro if document.basebackend? 'html'
  inline_macro :man, ManpageMacro
end

您可以为每种类型注册多个处理器,但每个自定义块或宏只能有一个处理器。注册的每个类在创建 Asciidoctor::Document 时都会被实例化。

目前还没有处理内置块(如普通段落)的扩展点。请关注未来 Asciidoctor 版本的功能。

目前,您需要使用 Asciidoctor API(而不是 CLI)来注册扩展并调用 Asciidoctor。最终,我们将能够通过扫描 LOAD_PATH(Ruby)或类路径(Java)来加载打包在 RubyGem(Ruby)或 JAR(Java)中的扩展。我们还可能提供一些内置扩展,可以使用名为 extensions 的属性来启用它们,这与 Markdown 处理器的工作方式类似。

对于 JVM 用户,是的,您可以使用 Java 编写扩展。我们已经进行了原型开发并且有效。我们仍在处理一些技术挑战和文档,以使其完全顺利,但我们会做到的。有关详细信息,请关注 #97 的讨论。

解决了问题 #97#100

我想特别感谢那些为 Asciidoctor 的扩展 API 提供灵感的库的作者,尤其是 Middleman、Python Markdown 和 Kramdown。

示例扩展

以下是几个扩展示例及其注册方式。

预处理器示例

目的

从文档顶部提取供 Jekyll 和 Awestruct 等站点生成器使用的前置信息。

sample-with-front-matter.ad
---
tags: [announcement, website]
---
= Document Title

content

[subs="attributes,specialcharacters"]
.Captured front matter
....
---
{front-matter}
---
....
FrontMatterPreprocessor
require 'asciidoctor'
require 'asciidoctor/extensions'

class FrontMatterPreprocessor < Asciidoctor::Extensions::Preprocessor
  def process reader, lines
    return reader if lines.empty?
    front_matter = []
    if lines.first.chomp == '---'
      original_lines = lines.dup
      lines.shift
      while !lines.empty? && lines.first.chomp != '---'
        front_matter << lines.shift
      end

      if (first = lines.first).nil? || first.chomp != '---'
        lines = original_lines
      else
        lines.shift
        @document.attributes['front-matter'] = front_matter.join.chomp
        # advance the reader by the number of lines taken
        (front_matter.length + 2).times { reader.advance }
      end
    end
    reader
  end
end
用法
Asciidoctor::Extensions.register do |document|
  preprocessor FrontMatterPreprocessor
end

Asciidoctor.render_file 'sample-with-front-matter.ad', :safe => :safe, :in_place => true

树处理器示例

目的

检测包含终端命令的字面块,去除提示符字符,并使用 CSS 对命令进行样式设置,使其提示符字符无法被选中(如 help.github.com 上所示)。

sample-with-terminal-command.ad
 $ echo "Hello, World!"

 $ gem install asciidoctor
TerminalCommandTreeprocessor
class TerminalCommandTreeprocessor < Asciidoctor::Extensions::Treeprocessor
  def process
    process_blocks @document if @document.blocks?
  end

  def process_blocks node
    node.blocks.each_with_index do |block, i|
      if block.context == :literal && block.lines.first.start_with?('$ ')
        node.blocks[i] = convert_to_terminal_listing block
      else
        process_blocks block if block.blocks?
      end
    end
  end

  def convert_to_terminal_listing block
    attributes = block.attributes
    attributes['role'] = 'terminal'
    lines = block.lines.map do |line|
      line = block.sub_specialcharacters line.chomp
      if line.start_with? '$ '
        %(<span class="command">#{line[2..-1]}</span>)
      else
        line
      end
    end
    Asciidoctor::Block.new @document, :listing, :content_model => :verbatim, :subs => [],
        :source => lines * "\n", :attributes => attributes
  end
end
用法
Asciidoctor::Extensions.register do |document|
  treeprocessor TerminalCommandTreeprocessor
end

Asciidoctor.render_file 'sample-with-terminal-command.ad', :safe => :safe, :in_place => true

后处理器示例

目的

插入自定义页脚文本。

CustomFooterPostprocessor
class CustomFooterPostprocessor < Asciidoctor::Extensions::Postprocessor
  def process output
    content = 'Copyright Acme, Inc.'
    if @document.basebackend? 'html'
      replacement = %(<div id="footer-text">\\1<br>\n#{content}\n</div>)
      output = output.sub(/<div id="footer-text">(.*?)<\/div>/m, replacement)
    elsif @document.basebackend? 'docbook'
      replacement = %(<simpara>#{content}</simpara>\n\\1)
      output = output.sub(/(<\/(?:article|book)>)/, replacement)
    end
    output
  end
end
用法
Asciidoctor::Extensions.register do |document|
  postprocessor CustomFooterPostprocessor
end

Asciidoctor.render_file 'sample.ad', :safe => :safe, :in_place => true

块处理器示例

目的

注册一个名为 yell 的自定义块样式,该样式将所有单词大写并将句点转换为感叹号。

sample-with-yell-block.ad
[yell]
The time is now. Get a move on.
YellBlock
require 'asciidoctor'
require 'asciidoctor/extensions'

class YellBlock < Asciidoctor::Extensions::BlockProcessor
  option :contexts, [:paragraph]
  option :content_model, :simple

  def process parent, reader, attributes
    lines = reader.lines.map {|line| line.upcase.gsub(/\.( |$)/, '!\\1') }
    Asciidoctor::Block.new parent, :paragraph, :source => lines, :attributes => attributes
  end
end
用法
Asciidoctor::Extensions.register do |document|
  block :yell, YellBlock
end

Asciidoctor.render_file 'sample-with-yell-block.ad', :safe => :safe, :in_place => true

块宏处理器示例

目的

创建一个名为 gist 的块宏,用于嵌入 gist。

sample-with-gist-macro.ad
.My Gist
gist::123456[]
GistMacro
require 'asciidoctor'
require 'asciidoctor/extensions'

class GistMacro < Asciidoctor::Extensions::BlockMacroProcessor
  def process parent, target, attributes
    title = (attributes.has_key? 'title') ?
        %(\n<div class="title">#{attributes['title']}</div>) : nil
    source = %(<div class="gistblock">#{title}
<div class="content">
<script src="https://gist.github.com/#{target}.js"></script>
</div>
</div>)
    Asciidoctor::Block.new parent, :pass, :content_model => :raw, :source => source
  end
end
用法
Asciidoctor::Extensions.register do |document|
  if document.basebackend? 'html'
    block_macro :gist, GistMacro
  end
end

Asciidoctor.render_file('sample-with-gist.ad', :safe => :safe, :in_place => true)

内联宏处理器示例

目的

创建一个名为 man 的内联宏,用于链接到 manpage。

sample-with-man-link.ad
See man:gittutorial[7] to get started.
ManpageMacro
require 'asciidoctor'
require 'asciidoctor/extensions'

class ManpageMacro < Asciidoctor::Extensions::InlineMacroProcessor
  option :pos_attrs, ['volnum']

  def process parent, target, attributes
    text = manname = target
    suffix = ''
    target = "#{manname}.html"
    if (volnum = attributes.fetch('volnum', nil))
      suffix = "(#{volnum})"
    end
    @document.register(:links, target)
    %(#{Asciidoctor::Inline.new(parent, :anchor, text, :type => :link, :target => target).render}#{suffix})
  end
end
用法
Asciidoctor::Extensions.register do |document|
  inline_macro :man, ManpageMacro
end

Asciidoctor.render_file('sample-with-man-link.ad', :safe => :safe, :in_place => true)

包含处理器示例

目的

从 URI 包含文件。

sample-with-uri-include.ad
:source-highlighter: coderay

.Gemfile
[source,ruby]
----
include::https://raw.githubusercontent.com/asciidoctor/asciidoctor/master/Gemfile[]
----
UriIncludeProcessor
require 'asciidoctor'
require 'asciidoctor/extensions'
require 'uri-open'

class UriIncludeProcessor < Asciidoctor::Extensions::IncludeProcessor
  def handles? target
    target.start_with?('http://') or target.start_with?('https://')
  end

  def process reader, target, attributes
    content = open(target).readlines
    reader.push_include content, target, target, 1, attributes
  end
end
用法
Asciidoctor::Extensions.register do |document|
  include_processor UriIncludeProcessor
end

Asciidoctor.render_file('sample-with-uri-include.ad', :safe => :safe, :in_place => true)

AsciiDoc 兼容性文件更新

AsciiDoc 兼容性文件 compat/asciidoc.conf 进行了以下改进:

  • 添加了 5 级(<h6>)章节标题

  • 当设置 linkattrs 时,识别链接宏中的属性

  • 移除了 linkcss 属性

  • 修复了对带围栏代码块的检测

  • 识别 XML 风格的呼叫点

  • 如果图像目标是 URI 或绝对路径,则不将其 imagesdir 前缀添加到图像目标

  • 为图像内联宏添加 float 属性

  • 以与 Asciidoctor 一致的方式从图像文件名计算 alt 文本

  • 识别 Markdown 风格的水平线

解决了问题 #441 及其他相关问题。

致谢

Asciidoctor 最棒的部分是它的社区。我们要感谢以下人员为本次发布做出的贡献和参与

我们要特别感谢 Alex SotoXavier Coulon 为主 Asciidoctor 存储库做出的首次代码贡献,以及 Per Anderssen 将 Asciidoctor 集成到 Debian 和 Ubuntu 中!

我(Dan)还要感谢 Sarah White 在整理文档和为项目准备文档工作流程方面付出的巨大努力。

额外感谢所有使用该项目的人以及那些参与到不断增长的子项目生态系统中的人。Asciidoctor 的使命是帮助您成功地编写、发布和沟通您的内容!通过您的反馈和参与,我们可以共同实现这一目标!我们鼓励您在邮件列表或 IRC 上提问并讨论项目的任何方面。

如果您在源代码、文档或网站内容中发现错误或遗漏,请随时提交 issue 或打开 pull request 进行修复。我们始终渴望了解您的体验以及我们如何能帮助改善它们。我们一起让文档变得有趣、轻松且有价值!

下一步是什么?

本次发布只是发布火车(release train)的开始。请留意 Java 集成、Maven 插件、Gradle 插件以及更近期的更新,如编辑器等的发布。

Asciidoctor 的下一个版本将是 1.5.0。本次发布将重点关注扩展 API 的改进、额外的语法便利性和工具链的增强。

我们在下一个版本中更改了版本号方案,为次要版本(point releases)留出了空间,并摆脱 1.0.0 的限制。

我们希望让 Asciidoctor 1.5.0 的发布更易于管理,并在大约 2 个月内完成发布。有了您的参与和反馈,我们可以做到!

附录 A:TL;DR

  • 样式表默认嵌入

  • 文档间的交叉引用(例如 <<doc-b#section-a,文档 B 中的 Section A>>

  • 表格的隐式标题行

  • DocBook 5.0 后端(即 docbook5

  • 图标内联宏(例如 icon:heart[2x]),主要用于基于字体的图标

  • 清单

  • 代码列表中的开发人员和用户友好型呼叫点

  • Pygments 语法高亮器(例如 source-highlighter=pygments

  • 块选项的简写表示法(例如 [%header%footer]

  • 格式化文本的 id 和 role 的简写表示法(例如 [#id.role]_text_

  • 反引号包围的文本的角色(例如 [role]`text`

  • 文档页脚的 Docinfo 文件(例如 docinfo-footer.(html|xml)

  • 使用 include::[] 指令从 URL 包含文件

  • 包含文件相对于当前包含文件解析

  • 视频宏对 YouTube 和 Vimeo ID 的支持(例如 video::12345[youtube,480,360]

  • 缺失的属性引用(例如 {bogus})不会导致行被丢弃(默认情况下)

  • 解析 man 页元数据

  • TOC 定位(例如 toc-position=right, toc=righttoc2=right

  • 改进了文档和 TOC 中的章节编号

  • 《Asciidoctor 用户手册》的初稿

  • Debian 和 Ubuntu 软件包(加入 Fedora 软件包)

请参阅 0.1.4 发行说明 查看完整的变更列表。


Asciidoctor Maven 插件 0.1.3.1 发布!

作者 Jason Porter -

我很自豪地宣布 Asciidoctor Maven 插件 0.1.3.1 版本发布!这只是一个 bug 修复版本,用于纠正我在 0.1.3 版本中犯的一些错误(抱歉)。与之前的 0.1.3 版本一样,它基于相同版本的 Asciidoctor Java 集成项目和 Asciidoctor 项目——0.1.3。

感谢所有 贡献者 的帮助。

继续前进,再次制作出色的文档!

插件构件信息
Group ID Artifact ID 最新版本 下载

org.asciidoctor

asciidoctor-maven-plugin

0.1.3.1

pom jar

升级到 0.1.3.1(推荐)很简单。只需更新 Maven POM 中的版本即可。所有必需的依赖项都应通过 Maven 拉取。

有关此版本中修复的问题的更多信息,请参阅问题跟踪器中的 0.1.3.1 milestone


Asciidoctor Maven 插件 0.1.3 发布!

作者 Jason Porter -

这个版本比我希望的要花更长的时间才发布,但它终于来了!我很自豪地发布 Asciidoctor Maven 插件 0.1.3 版本!与之前的版本一样,它基于相同版本的 Asciidoctor Java 集成项目和 Asciidoctor 项目——0.1.3。

此版本对最终用户来说新功能很少,因为更改主要是为了使用 Java 集成项目中的一些新的易用性功能。

我想特别感谢 Brian Leathem 在这个版本中的帮助,他帮助我完成了一些事情,并推动我发布它。另外,感谢所有 贡献者 的帮助。

继续前进,再次制作出色的文档!

插件构件信息
Group ID Artifact ID 最新版本 下载

org.asciidoctor

asciidoctor-maven-plugin

0.1.3

pom jar

升级到 0.1.3(推荐)很简单。只需更新 Maven POM 中的版本即可。所有必需的依赖项都应通过 Maven 拉取。

有关此版本中修复的问题的更多信息,请参阅问题跟踪器中的 0.1.3 milestone


  • 1 of 2