一个 {url-api-gems}/asciidoctor/{release-version}/Asciidoctor/Extensions/TreeProcessor[TreeProcessor^] 扩展在源代码的块被解析成文档结构之后,在Document实例上运行,如由Document对象及其子AbstractNode对象(例如,Section、Block、List、ListItem)所表示的。
Asciidoctor 会在每个注册的 TreeProcessor 扩展的实例上调用 Processor#process
方法。
Important
|
TreeProcessor扩展是在解释任何内联标记之前运行的。当调用TreeProcessor扩展的process方法时,文档中的块节点包含未处理、未转换的文本。内联标记的转换是在文档转换时进行的。因此,TreeProcessor扩展可以替换节点上的源文本,但它必须考虑到这些文本仍将被解析(根据块的内容模型)。 |
树处理器扩展示例
- 目的
-
检测包含shell命令的文字块,去除提示符,并使用CSS对命令进行样式设置,以使提示符无法被选择(如help.github.com所示)。
sample-with-shell-session.adoc
$ echo "Hello, World!" > Hello, World! $ gem install asciidoctor
ShellSessionTreeProcessor
class ShellSessionTreeProcessor < Asciidoctor::Extensions::TreeProcessor LF = ?\n def process document (document.find_by(context: :literal) {|candidate| candidate.lines[0].start_with? '$ ', '> ' }).each do |block| (children = block.parent.blocks)[children.index block] = convert_to_terminal_listing block end nil end def convert_to_terminal_listing block attrs = block.attributes attrs['role'] = 'terminal' prompt_attr = (attrs.key? 'prompt') ? %( data-prompt="#{block.sub_specialchars attrs['prompt']}") : nil lines = (block.content.split LF).map do |line| if line.start_with? '$ ' %(<span class="command"#{prompt_attr}>#{line[2..-1]}</span>) elsif line.start_with? '> ' %(<span class="output">#{line[5..-1]}</span>) #%(<span class="output"><span class="comment-prefix"># </span>#{line[5..-1]}</span>) else line end end create_listing_block block.parent, lines * LF, attrs, subs: nil end end
使用方法
Asciidoctor::Extensions.register do tree_processor ShellSessionTreeProcessor end Asciidoctor.convert_file 'sample-with-shell-session.adoc', safe: :safe