resources/asciidoctor/lib/open_in_widget/extension.rb (87 lines of code) (raw):

# frozen_string_literal: true require 'fileutils' require_relative '../delegating_converter' require_relative '../migration_log' require_relative '../log_util' ## # Extensions for enriching certain source blocks with "OPEN IN CONSOLE", # "OPEN IN SENSE", "OPEN IN KIBANA", AND/OR "COPY_AS_CURL". # # Usage # # [source,console] # --------- # GET / # --------- # # or # # [source,sense] # --------- # GET / # --------- # # or # # [source,kibana] # --------- # GET / # --------- # # or # # [source,sense,snippet=path/to/snippet.console] # --------- # GET / # --------- # module OpenInWidget def self.activate(registry) DelegatingConverter.setup(registry.document) do |doc| Converter.new doc end end ## # Converter implementation that adds the "open in" links class Converter < DelegatingConverter include LogUtil include MigrationLog CALLOUT_SCAN_RX = / ?#{Asciidoctor::CalloutScanRx}/ def convert_listing(node) return yield unless node.style == 'source' lang = node.attr 'language' return yield unless %w[console sense kibana ess ece].include? lang snippet_path = snippet_path node, lang, node.attr('snippet') convert_listing_with_widget node, lang, snippet_path, yield end def convert_listing_with_widget(node, lang, snippet_path, original) roles = node.roles roles.delete 'default' extra_classes = roles.empty? ? '' : " #{roles.join ' '}" <<~HTML.strip #{original} <div class="#{lang}_widget#{extra_classes}" data-snippet="#{snippet_path}"></div> HTML end def snippet_path(block, lang, snippet) return handle_override_snippet block, snippet if snippet handle_implicit_snippet block, lang end ## # Copy explicitly configured snippets to the right path so kibana can pick # them up when you click "open in console" and then warn the user that they # are lame. def handle_override_snippet(block, snippet) snippet_path = "snippets/#{snippet}" normalized = block.normalize_system_path snippet_path if File.readable? normalized copy_override_snippet block, normalized, snippet_path warn_override_snippet block else error block: block, message: "can't read snippet from #{normalized}" end snippet_path end ## # Handles non-override snippets by assigning them a number and copying them # some place that kibana can read them. def handle_implicit_snippet(block, lang) snippet_number = block.document.attr 'snippet_number', 1 snippet = "#{snippet_number}.#{lang}" block.document.set_attr 'snippet_number', snippet_number + 1 snippet_path = "snippets/#{snippet}" source = block.source.gsub(CALLOUT_SCAN_RX, '') + "\n" write_snippet block, source, snippet_path snippet_path end ## # Copies an override snippet from the filesystem into the # snippets directory. def copy_override_snippet(block, source, uri) info block: block, message: "copying snippet #{source}" copy_proc = block.document.attr 'copy_snippet' if copy_proc # Delegate to a proc for copying if one is defined. Used for testing. copy_proc.call(uri, source) else destination = ::File.join block.document.options[:to_dir], uri destination_dir = ::File.dirname destination FileUtils.mkdir_p destination_dir FileUtils.cp source, destination end end ## # Writes a snippet extracted from the asciidoc file into the # snippets directory. def write_snippet(block, snippet, uri) info block: block, message: "writing snippet #{uri}" write_proc = block.document.attr 'write_snippet' if write_proc # Delegate to a proc for copying if one is defined. Used for testing. write_proc.call(uri, snippet) else destination = ::File.join block.document.options[:to_dir], uri destination_dir = ::File.dirname destination FileUtils.mkdir_p destination_dir File.open(destination, 'w') { |file| file.write(snippet) } end end def warn_override_snippet(block) migration_warn( block, block.source_location, 'override-snippet', 'reading snippets from a path makes the book harder to read' ) end end end