diff options
| author | Dan Allen <dan.j.allen@gmail.com> | 2019-03-01 17:46:00 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-03-01 17:46:00 -0700 |
| commit | 4e64a87a12e074d12ceafd5c3a2164a4a6aac7b4 (patch) | |
| tree | 4118ee332e780299a00e67608186dc4cc8526aa2 | |
| parent | 719077330a51b023d41237bfc9b058d0486ae613 (diff) | |
resolves #891 allow backend to delegate to a registered backend using the syntax synthetic:delegate (PR #3100)
| -rw-r--r-- | CHANGELOG.adoc | 1 | ||||
| -rw-r--r-- | lib/asciidoctor/converter.rb | 18 | ||||
| -rw-r--r-- | lib/asciidoctor/document.rb | 11 | ||||
| -rw-r--r-- | test/converter_test.rb | 10 |
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 |
