你可以通过实现和注册一个语法高亮适配器来将额外的语法高亮器集成到Asciidoctor中。你可以从头开始编写一个新的适配器,或者你可以扩展甚至替换一个内置的适配器。

创建一个新的适配器

要实现一个新的适配器,你必须创建一个扩展 {url-api-gems}/asciidoctor/{release-version}/Asciidoctor/SyntaxHighlighter/Base[Asciidoctor::SyntaxHighlighter::Base] 类的类,为 source-highlighter 属性注册适配器,并实现所需的方法。哪些方法是必须的取决于适配器是为客户端(在浏览器中运行)还是构建时(在文档转换时运行)的语法高亮器。

这是一个关于如何为Prism.js语法高亮库编写和注册一个语法高亮适配器的示例。Prism.js是一个客户端语法高亮器,这意味着它在浏览器中运行。这意味着适配器只需要实现与客户端语法高亮相关的方法,包括`format`、 docinfo?`和`docinfo

Prism.js的语法高亮适配器
Unresolved directive in custom.adoc - include::example$prism-syntax-highlighter.rb[]

将此代码保存到一个名为 .path_prism-syntax-highlighter.rb 的文件中。然后,在调用Asciidoctor时引用这个文件,并设置`source-highlighter=prism`以激活它:

$ asciidoctor -r ./prism-syntax-highlighter -a source-highlighter=prism document.adoc

你还可以定义一个在转换过程中运行的语法高亮器适配器。 我们将在扩展内置适配器的同时来看如何做到这一点。

扩展一个现有的适配器

您不必创建一个新的适配器,您可以通过继承一个内置适配器,覆盖其行为,并可以选择性地替换它来进行定制。

要扩展一个适配器,你需要使用 {url-api-gems}/asciidoctor/{release-version}/Asciidoctor/SyntaxHighlighter/Factory#for-instance_method[Asciidoctor::SyntaxHighlighter.for] 方法通过名称查找内置适配器的引用,创建一个扩展它的类,用一个独特的名称(或相同的名称,如果你想替换它)注册适配器,并重写任何你想修改的行为的方法。

这是自定义现有适配器的基本模板:

class CustomAdapter < (Asciidoctor::SyntaxHighlighter.for 'rouge')
  register_for 'rouge'

# override methods go here
end

让我们来看看一些如何定制内置适配器的例子。

文档信息

让我们重写 Pygments 的适配器以防止其向 HTML 中添加样式表(大概是因为样式将由不同的样式表提供)。

为Pygments扩展的语法高亮适配器
Unresolved directive in custom.adoc - include::example$extended-pygments-syntax-highlighter.rb[]

将此代码保存为名为 extended-pygments-syntax-highlighter.rb 的文件。然后,在调用Asciidoctor时需要这个文件,设置 source-highlighter=pygments 来激活它,就像你通常做的那样。

$ asciidoctor -r ./extended-pygments-syntax-highlighter.rb -a source-highlighter=pygments document.adoc

如果你想修改内置的适配器,使其遵循由`pygments-stylesheet`属性指定的自定义样式表的位置,你可以通过扩展适配器并重写`docinfo`方法来实现。

Unresolved directive in custom.adoc - include::example$pygments-syntax-highlighter-with-custom-stylesheet.rb[]

如果你想要装饰内置行为,你可以在方法内的任何地方调用`super`方法,以委托给内置适配器提供的行为。

突出显示

假设你想要代码的行号始终显示,不管文档中的设置如何。你可以通过覆盖`highlight`方法,设置`opts`参数的`:number_lines`键,然后使用`super`委托回内置适配器来实现这一点。

Unresolved directive in custom.adoc - include::example$always-number-lines.rb[]

创建格式化器(Rouge)

当使用Rouge作为语法高亮器时,你可以通过重写`create_formatter`方法来自定义格式化程序。这使你能够为处理源语言中某些特定的标记添加自定义逻辑。

假设你想要在代码注释中寻找裸露的URL并将它们转换成链接(即,自动链接),就像在AsciiDoc中一样。你可以通过在格式化器中编织额外的逻辑来实现,这个逻辑会寻找`Comment`分类中的标记,并对其值进行替换。

Unresolved directive in custom.adoc - include::example$autolink-urls-in-comments.rb[]

由于格式化器能够访问语法高亮器识别的代码中的所有标记,这种技术打开了很多可能性。例如,你可以在Java代码的`Keyword`类别中寻找`Type`标记,并创建一个指向API文档的链接。create_formatter`方法的`lang`参数让你知道标记属于的源语言(例如,`java)。

要研究您可能感兴趣的逻辑覆盖,浏览代码请前往 https://github.com/asciidoctor/asciidoctor/tree/{page-origin-refname}/lib/asciidoctor/syntax_highlighter [内置的语法高亮适配器]。