class Asciidoctor::Converter::TemplateConverter
A {Converter} implementation that uses templates composed in template languages supported by {github.com/rtomayko/tilt Tilt} to convert {AbstractNode} objects from a parsed AsciiDoc document tree to the backend format.
The converter scans the specified directories for template files that are supported by Tilt. If an engine name (e.g., “slim”) is specified in the options Hash
passed to the constructor, the scan is restricted to template files that have a matching extension (e.g., “.slim”). The scanner trims any extensions from the basename of the file and uses the resulting name as the key under which to store the template. When the {Converter#convert} method is invoked, the transform argument is used to select the template from this table and use it to convert the node.
For example, the template file “path/to/templates/paragraph.html.slim” will be registered as the “paragraph” transform. The template is then used to convert a paragraph {Block} object from the parsed AsciiDoc tree to an HTML backend format (e.g., “html5”).
As an optimization, scan results and templates are cached for the lifetime of the Ruby process. If the {rubygems.org/gems/concurrent-ruby concurrent-ruby} gem is installed, these caches are guaranteed to be thread safe. If this gem is not present, there is no such guarantee and a warning will be issued.
Constants
- DEFAULT_ENGINE_OPTIONS
Attributes
Public Class Methods
# File lib/asciidoctor/converter/template.rb, line 46 def clear_caches @caches[:scans].clear @caches[:templates].clear end
# File lib/asciidoctor/converter/template.rb, line 52 def initialize backend, template_dirs, opts = {} Helpers.require_library 'tilt' unless defined? ::Tilt.new @backend = backend @templates = {} @template_dirs = template_dirs @eruby = opts[:eruby] @safe = opts[:safe] @active_engines = {} @engine = opts[:template_engine] @engine_options = {}.tap {|accum| DEFAULT_ENGINE_OPTIONS.each {|engine, engine_opts| accum[engine] = engine_opts.merge } } if opts[:htmlsyntax] == 'html' # if not set, assume xml since this converter is also used for DocBook (which doesn't specify htmlsyntax) @engine_options[:haml][:format] = :html5 @engine_options[:slim][:format] = :html end @engine_options[:slim][:include_dirs] = template_dirs.reverse.map {|dir| ::File.expand_path dir } if (overrides = opts[:template_engine_options]) overrides.each do |engine, override_opts| (@engine_options[engine] ||= {}).update override_opts end end case opts[:template_cache] when true logger.warn 'optional gem \'concurrent-ruby\' is not available. This gem is recommended when using the default template cache.' unless defined? ::Concurrent::Map @caches = self.class.caches when ::Hash @caches = opts[:template_cache] else @caches = {} # the empty Hash effectively disables caching end scan end
Public Instance Methods
Public: Convert an {AbstractNode} to the backend format using the named template.
Looks for a template that matches the value of the template name or, if the template name is not specified, the value of the {AbstractNode#node_name} property.
node - the AbstractNode
to convert template_name - the String
name of the template to use, or the value of
the node_name property on the node if a template name is not specified. (optional, default: nil)
opts - an optional Hash
that is passed as local variables to the
template. (optional, default: nil)
Returns the [String] result from rendering the template
# File lib/asciidoctor/converter/template.rb, line 97 def convert node, template_name = nil, opts = nil unless (template = @templates[template_name ||= node.node_name]) raise %(Could not find a custom template to handle transform: #{template_name}) end # Slim doesn't include helpers in the template's execution scope (like HAML), so do it ourselves node.extend ::Slim::Helpers if (defined? ::Slim::Helpers) && (::Slim::Template === template) # NOTE opts become locals in the template if template_name == 'document' (template.render node, opts).strip else (template.render node, opts).rstrip end end
Public: Checks whether there is a Tilt template registered with the specified name.
name - the String
template name
Returns a [Boolean] that indicates whether a Tilt template is registered for the specified template name.
# File lib/asciidoctor/converter/template.rb, line 119 def handles? name @templates.key? name end
Public: Registers a Tilt template with this converter.
name - the String
template name template - the Tilt template object to register
Returns the Tilt template object
# File lib/asciidoctor/converter/template.rb, line 136 def register name, template if (template_cache = @caches[:templates]) template_cache[template.file] = template end @templates[name] = template end
Public: Retrieves the templates that this converter manages.
Returns a [Hash] of Tilt template objects keyed by template name.
# File lib/asciidoctor/converter/template.rb, line 126 def templates @templates.merge end