diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/asciidoctor/interdoc_reftext.rb | 4 | ||||
-rw-r--r-- | lib/asciidoctor/interdoc_reftext/inline_node_mixin.rb | 46 | ||||
-rw-r--r-- | lib/asciidoctor/interdoc_reftext/processor.rb | 21 | ||||
-rw-r--r-- | lib/asciidoctor/interdoc_reftext/resolver.rb | 15 |
4 files changed, 58 insertions, 28 deletions
diff --git a/lib/asciidoctor/interdoc_reftext.rb b/lib/asciidoctor/interdoc_reftext.rb index e1f3389..dc884cb 100644 --- a/lib/asciidoctor/interdoc_reftext.rb +++ b/lib/asciidoctor/interdoc_reftext.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'asciidoctor' -require 'asciidoctor/extensions' +require 'asciidoctor' unless RUBY_PLATFORM == 'opal' +require 'asciidoctor/extensions' unless RUBY_PLATFORM == 'opal' require 'asciidoctor/interdoc_reftext/version' require 'asciidoctor/interdoc_reftext/processor' diff --git a/lib/asciidoctor/interdoc_reftext/inline_node_mixin.rb b/lib/asciidoctor/interdoc_reftext/inline_node_mixin.rb index f82b7a3..17370b0 100644 --- a/lib/asciidoctor/interdoc_reftext/inline_node_mixin.rb +++ b/lib/asciidoctor/interdoc_reftext/inline_node_mixin.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true +require 'asciidoctor' unless RUBY_PLATFORM == 'opal' require 'asciidoctor/interdoc_reftext/version' -require 'asciidoctor' module Asciidoctor::InterdocReftext # Mixin intended to be prepended into `Asciidoctor::Inline`. @@ -10,29 +10,39 @@ module Asciidoctor::InterdocReftext # represents an inter-document cross reference). module InlineNodeMixin - # Returns text of this inline element. - # - # @note This method will override the same name attribute reader in - # class `Asciidoctor::Inline`. - # - # @return [String, nil] - def text - if (value = super) - value - # If this node is an inter-document cross reference... - elsif @node_name == 'inline_anchor' && @attributes['path'] - resolver = interdoc_reftext_resolver - @text = resolver.call(@attributes['refid']) if resolver + if RUBY_PLATFORM == 'opal' + # Opal does not support `Module#prepend`, so we have to fallback to + # `include` with poor alias method chain approach. + def self.included(base_klass) + base_klass.send(:alias_method, :text_without_reftext, :text) + base_klass.send(:define_method, :text) do + text_without_reftext || interdoc_reftext + end + end + else + # Returns text of this inline element. + # + # @note This method will override the same name attribute reader in + # class `Asciidoctor::Inline`. + def text + super || interdoc_reftext end end private - # @return [#call, nil] an inter-document reftext resolver, or nil if not - # set for the document. - def interdoc_reftext_resolver + # Returns resolved reftext of this inline node if it is a valid + # inter-document cross-reference, otherwise returns nil. + # + # @return [String, nil] + def interdoc_reftext + # If this node is not an inter-document cross reference... + return if @node_name != 'inline_anchor' || @attributes['path'].nil? + # This variable is injected into the document by {Processor}. - @document.instance_variable_get(Processor::RESOLVER_VAR_NAME) + if (resolver = @document.instance_variable_get(Processor::RESOLVER_VAR_NAME)) + @text = resolver.call(@attributes['refid']) + end end end end diff --git a/lib/asciidoctor/interdoc_reftext/processor.rb b/lib/asciidoctor/interdoc_reftext/processor.rb index 0fa69fb..724a154 100644 --- a/lib/asciidoctor/interdoc_reftext/processor.rb +++ b/lib/asciidoctor/interdoc_reftext/processor.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'asciidoctor' -require 'asciidoctor/extensions' +require 'asciidoctor' unless RUBY_PLATFORM == 'opal' +require 'asciidoctor/extensions' unless RUBY_PLATFORM == 'opal' require 'asciidoctor/interdoc_reftext/inline_node_mixin' require 'asciidoctor/interdoc_reftext/resolver' require 'asciidoctor/interdoc_reftext/version' @@ -34,7 +34,7 @@ module Asciidoctor::InterdocReftext # # Eh, this is really nasty... The least evil way how to achieve the goal # seems to be monkey-patching of the `Asciidoctor::Inline` class. This is - # done via {InlineNodeMixin} which is prepended into the `Inline` class on + # done via {InlineNodeMixin} which is prepended* into the `Inline` class on # initialization of this processor. # # The actual logic that resolves reflabel for the given *refid* is @@ -43,11 +43,16 @@ module Asciidoctor::InterdocReftext # it into instance variable {RESOLVER_VAR_NAME} in the document, so # {InlineNodeMixin} can access it. # - # Prepending {InlineNodeMixin} into the `Asciidoctor::Inline` class has + # Prepending* {InlineNodeMixin} into the `Asciidoctor::Inline` class has # (obviously) a global effect. However, if {RESOLVER_VAR_NAME} is not # injected in the document object (e.g. extension is not active), `Inline` # behaves the same as without {InlineNodeMixin}. # + # _\* If running under Opal (JavaScript), {InlineNodeMixin} is not prepended + # into the `Asciidoctor::Inline`, because Opal does not support that. Thus + # it's included and the `#text` method is overriden using poor alias method + # chain approach. + # # NOTE: We use _reftext_ and _reflabel_ as interchangeable terms in this gem. class Processor < ::Asciidoctor::Extensions::TreeProcessor @@ -65,7 +70,13 @@ module Asciidoctor::InterdocReftext # Monkey-patch Asciidoctor::Inline unless already patched. unless ::Asciidoctor::Inline.include? InlineNodeMixin - ::Asciidoctor::Inline.send(:prepend, InlineNodeMixin) + if RUBY_PLATFORM == 'opal' + # Opal does not support `Module#prepend`, so we have to fallback to + # `include` with poor alias method chain approach. + ::Asciidoctor::Inline.send(:include, InlineNodeMixin) + else + ::Asciidoctor::Inline.send(:prepend, InlineNodeMixin) + end end end diff --git a/lib/asciidoctor/interdoc_reftext/resolver.rb b/lib/asciidoctor/interdoc_reftext/resolver.rb index e4a8eef..0f9a7c1 100644 --- a/lib/asciidoctor/interdoc_reftext/resolver.rb +++ b/lib/asciidoctor/interdoc_reftext/resolver.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true +require 'asciidoctor' unless RUBY_PLATFORM == 'opal' +require 'logger' unless RUBY_PLATFORM == 'opal' require 'asciidoctor/interdoc_reftext/version' -require 'asciidoctor' -require 'logger' module Asciidoctor::InterdocReftext # Resolver of inter-document cross reference texts. @@ -20,8 +20,17 @@ module Asciidoctor::InterdocReftext logger ||= if defined? ::Asciidoctor::LoggerManager ::Asciidoctor::LoggerManager.logger - else + elsif defined? ::Logger ::Logger.new(STDERR) + else + # Fake logger for Opal. + # TODO: Remove after update to Asciidoctor 1.5.7 or Opal with Logger. + Object.new.tap do |o| + # rubocop: disable MethodMissing + def o.method_missing(_, *args) + STDERR.puts(*args) + end + end end @document = document |