= Tree Processor Extension Example
:navtitle: Tree Processor
Purpose::
Detect literal blocks that contain shell commands, strip the prompt character and style the command using CSS in such a way that the prompt character cannot be selected (as seen on help.github.com).
== sample-with-shell-session.adoc
[source,asciidoc]
----
$ echo "Hello, World!"
> Hello, World!
$ gem install asciidoctor
----
== ShellSessionTreeProcessor
[source,ruby]
----
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? '$ '
%(#{line[2..-1]})
elsif line.start_with? '> '
%(#{line[5..-1]})
#%(#{line[5..-1]})
else
line
end
end
create_listing_block block.parent, lines * LF, attrs, subs: nil
end
end
----
== Usage
[source,ruby]
----
Asciidoctor::Extensions.register do
tree_processor ShellSessionTreeProcessor
end
Asciidoctor.convert_file 'sample-with-shell-session.adoc', safe: :safe
----