Preprocessor扩展在AsciiDoc源码被解析之前运行。具体来说,它是在Document实例被创建并且它的PreprocessorReader已经初始化完毕,开始读取源文档的行之后运行的。
Warning
|
如果预处理器扩展从阅读器中读取行,它将会引起副作用。其中一个副作用是头部中的文档属性可能无法被正确解释。另一个是它可能会干扰行号跟踪。如果扩展增加或删除了行,解析器可能会产生误导性的行号信息。因此,如果可能的话,应该避免在预处理器扩展中与阅读器交互。 预处理器扩展仍然可以用来修改文档对象上的选项,在这种情况下不会有副作用。它也可以安全地用作事件监听器,或许用来运行其他代码。通过读取实际AsciiDoc文档之上的行,可能也能避免副作用,正如本页上的示例所示。这么做是安全的,因为这些行不会被解释为AsciiDoc。 |
在调用预处理器扩展之前,Asciidoctor 将主文档的源文本分割成行并对它们进行规范化处理。之后,它从这些行创建一个 PreprocessorReader 的实例。
Asciidoctor 首先将 Document 和 PreprocessorReader 实例传递给扩展的 Asciidoctor::Extensions::Processor#process
方法。如果扩展从读取器中读取了行,那些行将首先被 Asciidoctor 的内部预处理器预处理。扩展可以修改 Reader,并且可以返回相同的 Reader(或等效的假值)或一个新的 Reader 实例来替换它。然而,如上所述,当从原始的 PreprocessorReader 实例读取行时要小心,因为它可能会产生副作用。
预处理器扩展示例
- 目的
-
从文档顶部去除前置内容,这部分内容通常会被像Jekyll这样的站点生成器使用。
带有前言的样本.adoc
tags: [announcement, website]
---
= 文档标题
内容
[subs=+attributes]
.Captured front matter
----
---
{front-matter}
---
----
前置事项预处理器
class FrontMatterPreprocessor < Asciidoctor::Extensions::Preprocessor def process document, reader lines = reader.lines # get raw 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 preprocessor FrontMatterPreprocessor end Asciidoctor.convert_file 'sample-with-front-matter.adoc', safe: :safe