summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.adoc1
-rw-r--r--lib/asciidoctor/converter.rb18
-rw-r--r--lib/asciidoctor/document.rb11
-rw-r--r--test/converter_test.rb10
4 files changed, 28 insertions, 12 deletions
diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc
index 98561088..40f8557c 100644
--- a/CHANGELOG.adoc
+++ b/CHANGELOG.adoc
@@ -63,6 +63,7 @@ Enhancements / Compliance::
* drop verse table cell style (treat as normal table cell) (#3111)
* log warning if footnoteref macro is found and compat mode is not enabled (#3114)
* log debug message instead of warning if block style is unknown (#3092)
+ * allow backend to delegate to a registered backend using the syntax synthetic:delegate when using custom templates (e.g., slides:html) (#891)
Improvements::
diff --git a/lib/asciidoctor/converter.rb b/lib/asciidoctor/converter.rb
index 91703a29..fbb452c3 100644
--- a/lib/asciidoctor/converter.rb
+++ b/lib/asciidoctor/converter.rb
@@ -213,22 +213,26 @@ module Converter
# found, the built-in converter is returned or nil if no converter is found.
#
# backend - the String backend name.
- # opts - an optional Hash of options that get passed on to the converter's constructor. If the :template_dirs
- # key is found in the options Hash, this method returns a {CompositeConverter} that delegates to a
- # {TemplateConverter}. (optional, default: {})
+ # opts - a Hash of options to customize creation; also passed to the converter's constructor:
+ # :template_dirs - a String Array of directories used to instantiate a {TemplateConverter} (optional).
+ # :delegate_backend - a backend String of the last converter in the {CompositeConverter} chain (optional).
#
# Returns the [Converter] instance.
def create backend, opts = {}
- template_dirs = opts[:template_dirs]
if (converter = self.for backend)
converter = converter.new backend, opts if ::Class === converter
- if template_dirs && BackendTraits === converter && converter.supports_templates?
+ if (template_dirs = opts[:template_dirs]) && BackendTraits === converter && converter.supports_templates?
CompositeConverter.new backend, (TemplateConverter.new backend, template_dirs, opts), converter, backend_traits_source: converter
else
converter
end
- elsif template_dirs
- TemplateConverter.new backend, template_dirs, opts
+ elsif (template_dirs = opts[:template_dirs])
+ if (delegate_backend = opts[:delegate_backend]) && (converter = self.for delegate_backend)
+ converter = converter.new delegate_backend, opts if ::Class === converter
+ CompositeConverter.new backend, (TemplateConverter.new backend, template_dirs, opts), converter, backend_traits_source: converter
+ else
+ TemplateConverter.new backend, template_dirs, opts
+ end
end
end
diff --git a/lib/asciidoctor/document.rb b/lib/asciidoctor/document.rb
index 14afd9ad..5b48cf77 100644
--- a/lib/asciidoctor/document.rb
+++ b/lib/asciidoctor/document.rb
@@ -1116,7 +1116,7 @@ class Document < AbstractBlock
# Internal: Create and initialize an instance of the converter for this document
#--
# QUESTION is there any additional information we should be passing to the converter?
- def create_converter backend
+ def create_converter backend, delegate_backend
converter_opts = { document: self, htmlsyntax: @attributes['htmlsyntax'] }
if (template_dirs = (opts = @options)[:template_dirs] || opts[:template_dir])
converter_opts[:template_dirs] = [*template_dirs]
@@ -1125,6 +1125,7 @@ class Document < AbstractBlock
converter_opts[:template_engine_options] = opts[:template_engine_options]
converter_opts[:eruby] = opts[:eruby]
converter_opts[:safe] = @safe
+ converter_opts[:delegate_backend] = delegate_backend if delegate_backend
end
if (converter = opts[:converter])
(Converter::CustomFactory.new backend => converter).create backend, converter_opts
@@ -1268,15 +1269,15 @@ class Document < AbstractBlock
current_backend = @backend
current_basebackend = (attrs = @attributes)['basebackend']
current_doctype = @doctype
+ actual_backend, _, new_backend = new_backend.partition ':' if new_backend.include? ':'
if new_backend.start_with? 'xhtml'
attrs['htmlsyntax'] = 'xml'
new_backend = new_backend.slice 1, new_backend.length
elsif new_backend.start_with? 'html'
attrs['htmlsyntax'] ||= 'html'
end
- if (resolved_backend = BACKEND_ALIASES[new_backend])
- new_backend = resolved_backend
- end
+ new_backend = BACKEND_ALIASES[new_backend] || new_backend
+ new_backend, delegate_backend = actual_backend, new_backend if actual_backend
if current_doctype
if current_backend
attrs.delete %(backend-#{current_backend})
@@ -1291,7 +1292,7 @@ class Document < AbstractBlock
# QUESTION should we defer the @backend assignment until after the converter is created?
@backend = attrs['backend'] = new_backend
# (re)initialize converter
- if Converter::BackendTraits === (converter = create_converter new_backend)
+ if Converter::BackendTraits === (converter = create_converter new_backend, delegate_backend)
new_basebackend = converter.basebackend
new_filetype = converter.filetype
if (htmlsyntax = converter.htmlsyntax)
diff --git a/test/converter_test.rb b/test/converter_test.rb
index 93db687d..57a7ddc7 100644
--- a/test/converter_test.rb
+++ b/test/converter_test.rb
@@ -154,6 +154,16 @@ context 'Converter' do
assert_xpath '//aside/header/following-sibling::p[text()="Sidebar content"]', output, 1
end
+ test 'should allow custom backend to emulate a known backend' do
+ doc = Asciidoctor.load 'content', backend: 'html5-tweaks:html', template_dir: (fixture_path 'custom-backends/haml'), template_cache: false
+ assert doc.basebackend? 'html'
+ assert_equal 'html5-tweaks', doc.backend
+ converter = doc.converter
+ assert_kind_of Asciidoctor::Converter::TemplateConverter, (converter.find_converter 'embedded')
+ refute_kind_of Asciidoctor::Converter::TemplateConverter, (converter.find_converter 'admonition')
+ assert_equal '<p>content</p>', doc.convert
+ end
+
test 'should create template converter even when a converter is not registered for the specified backend' do
input = 'paragraph content'
output = convert_string_to_embedded input, backend: :unknown, template_dir: (fixture_path 'custom-backends/haml/html5-tweaks'), template_cache: false