From acf7043035db950c79fdaa6393da6a1daf165d91 Mon Sep 17 00:00:00 2001 From: Nik Everett Date: Wed, 30 Jan 2019 15:55:30 -0500 Subject: [PATCH 1/4] Asciidoctor: Add support for inline callouts Adds support for inline callout in a fairly hacky way. These look like: ``` ---- POST <1> /_search/scroll <2> ---- <1> words <2> other words ``` They are supported by asciidoc and the elasticsearch reference uses a few of them and they look *great*. Asciidoctor doesn't support them and doesn't have a nice extension point to add them so we hack asciidoctor fairly shamelessly to get them in. This cuts the number of failures when building the Elasticsearch reference down from "then entire screen" to 3. --- lib/ES/Util.pm | 2 + resources/asciidoctor/lib/extensions.rb | 3 + .../lib/inline_callout/extension.rb | 70 +++++++++++++++++++ .../asciidoctor/spec/inline_callout_spec.rb | 57 +++++++++++++++ 4 files changed, 132 insertions(+) create mode 100644 resources/asciidoctor/lib/inline_callout/extension.rb create mode 100644 resources/asciidoctor/spec/inline_callout_spec.rb diff --git a/lib/ES/Util.pm b/lib/ES/Util.pm index 906d1a83d93f7..3f3a3abaacf12 100644 --- a/lib/ES/Util.pm +++ b/lib/ES/Util.pm @@ -93,6 +93,7 @@ sub build_chunked { # '-a' => 'attribute-missing=warn', '-a' => 'asciidoc-dir=' . $asciidoc_dir, $resources ? ( '-a' => 'resources=' . join(',', @$resources)) : (), + '-a' => 'inline-callouts', '--destination-dir=' . $dest, docinfo($index), $index @@ -211,6 +212,7 @@ sub build_single { $private ? () : ( '-a' => "edit_url=$edit_url" ), '-a' => 'asciidoc-dir=' . $asciidoc_dir, $resources ? ( '-a' => 'resources=' . join(',', @$resources)) : (), + '-a' => 'inline-callouts', # Disable warning on missing attributes because we have # missing attributes! # '-a' => 'attribute-missing=warn', diff --git a/resources/asciidoctor/lib/extensions.rb b/resources/asciidoctor/lib/extensions.rb index b7eaa25ee5445..b579a22712ac6 100644 --- a/resources/asciidoctor/lib/extensions.rb +++ b/resources/asciidoctor/lib/extensions.rb @@ -6,6 +6,9 @@ require_relative 'elastic_compat_preprocessor/extension' require_relative 'elastic_include_tagged/extension' +# This extensions is special because it is evil - just loading it is enough +require_relative 'inline_callout/extension' + Extensions.register Added Extensions.register do # Enable storing the source locations so we can look at them. This is required diff --git a/resources/asciidoctor/lib/inline_callout/extension.rb b/resources/asciidoctor/lib/inline_callout/extension.rb new file mode 100644 index 0000000000000..3303cd824125a --- /dev/null +++ b/resources/asciidoctor/lib/inline_callout/extension.rb @@ -0,0 +1,70 @@ +require 'asciidoctor' + +include Asciidoctor + +## +# Enables inline callouts which asciidoc supports but asciidoctor doesn't. +# Filed as enhancement request at +# https://github.com/asciidoctor/asciidoctor/issues/3037 +# +# Usage +# +# POST <1> /_search/scroll <2> +# +# NOTE: This isn't an asciidoctor extension so much as a hack. Just including +# the file causes us to hack asciidoctor to enable the behavior. By default we +# don't do anything if you don't set the the `inline-callouts` attribute so +# you need to *ask* for the change in behavior. +# +module InlineCallout + InlineCalloutScanRx = /\\?/ + InlineCalloutSourceRx = %r(((?://|#|--|;;) ?)?(\\)?<!?(|--)(\d+|\.)\3>) + InlineCalloutSourceRxt = "(\\\\)?<()(\\d+|\\.)>" + InlineCalloutSourceRxMap = ::Hash.new {|h, k| h[k] = /(#{::Regexp.escape k} ?)?#{InlineCalloutSourceRxt}/ } + + # Disable VERBOSE so we don't log any warnings. It really isn't great to + # have to patch these in like this but it gets the job done and we're looking + # to get this into Asciidoctor proper. These methods are basically the same + # as the methods in asciidoctor but with new regexes. + old_verbose = $VERBOSE + $VERBOSE = false + Parser.class_eval do + def self.catalog_callouts(text, document) + found = false + autonum = 0 + callout_rx = (document.attr? 'inline-callouts') ? InlineCalloutScanRx : CalloutScanRx + text.scan(callout_rx) { + # lead with assignments for Ruby 1.8.7 compat + captured, num = $&, $2 + document.callouts.register num == '.' ? (autonum += 1).to_s : num unless captured.start_with? '\\' + # we have to mark as found even if it's escaped so it can be unescaped + found = true + } if text.include? '<' + found + end + end + + Substitutors.module_eval do + def sub_callouts(text) + autonum = 0 + text.gsub(callout_rx) { + # honor the escape + if $2 + # use sub since it might be behind a line comment + $&.sub(RS, '') + else + Inline.new(self, :callout, $4 == '.' ? (autonum += 1).to_s : $4, :id => @document.callouts.read_next_id, :attributes => { 'guard' => $1 }).convert + end + } + end + + def callout_rx + if attr? 'line-comment' + ((attr? 'inline-callouts') ? InlineCalloutSourceRxMap : CalloutSourceRxMap)[attr 'line-comment'] + else + (attr? 'inline-callouts') ? InlineCalloutSourceRx : CalloutSourceRx + end + end + end + $VERBOSE = old_verbose +end diff --git a/resources/asciidoctor/spec/inline_callout_spec.rb b/resources/asciidoctor/spec/inline_callout_spec.rb new file mode 100644 index 0000000000000..071cae1c8202d --- /dev/null +++ b/resources/asciidoctor/spec/inline_callout_spec.rb @@ -0,0 +1,57 @@ +require 'inline_callout/extension' + +RSpec.describe InlineCallout do + it "enables support for inline callouts if requested" do + attributes = { + 'inline-callouts' => '', + } + input = <<~ASCIIDOC + ---- + POST <1> /_search/scroll <2> + ---- + <1> words + <2> other words + ASCIIDOC + expected = <<~DOCBOOK + + + POST /_search/scroll + + + words + + + other words + + + + DOCBOOK + expect(convert(input, attributes)).to eq(expected.strip) + end + + it "does not enable support for inline callouts by default" do + input = <<~ASCIIDOC + ---- + POST <1> /_search/scroll <2> + ---- + <1> words + <2> other words + ASCIIDOC + expected = <<~DOCBOOK + + + POST <1> /_search/scroll + + + words + + + other words + + + + DOCBOOK + actual = convert input, {}, eq('WARN: : line 4: no callout found for <1>') + expect(actual).to eq(expected.strip) + end +end \ No newline at end of file From 5b062abf2e6bf009bd7a2741b40bf75f3e9ca80b Mon Sep 17 00:00:00 2001 From: Nik Everett Date: Thu, 31 Jan 2019 14:32:59 -0500 Subject: [PATCH 2/4] Explain a little better --- .vscode/settings.json | 4 ++++ resources/asciidoctor/lib/inline_callout/extension.rb | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000000000..dadd2421e7081 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "python.linting.enabled": true, + "python.pythonPath": "/usr/bin/python2" +} \ No newline at end of file diff --git a/resources/asciidoctor/lib/inline_callout/extension.rb b/resources/asciidoctor/lib/inline_callout/extension.rb index 3303cd824125a..6f66230550221 100644 --- a/resources/asciidoctor/lib/inline_callout/extension.rb +++ b/resources/asciidoctor/lib/inline_callout/extension.rb @@ -12,8 +12,8 @@ # POST <1> /_search/scroll <2> # # NOTE: This isn't an asciidoctor extension so much as a hack. Just including -# the file causes us to hack asciidoctor to enable the behavior. By default we -# don't do anything if you don't set the the `inline-callouts` attribute so +# the file causes us to monkey patch its code into asciidoctor. By default we +# don't change asciidoctor, but if you set the `inline-callouts` attribute so # you need to *ask* for the change in behavior. # module InlineCallout From 408053b25dced388d0629447f2fdb905f73b17d0 Mon Sep 17 00:00:00 2001 From: Nik Everett Date: Thu, 31 Jan 2019 14:35:06 -0500 Subject: [PATCH 3/4] Drop note about 1.8.7 --- resources/asciidoctor/lib/inline_callout/extension.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/resources/asciidoctor/lib/inline_callout/extension.rb b/resources/asciidoctor/lib/inline_callout/extension.rb index 6f66230550221..208d27f9d2ac7 100644 --- a/resources/asciidoctor/lib/inline_callout/extension.rb +++ b/resources/asciidoctor/lib/inline_callout/extension.rb @@ -34,7 +34,6 @@ def self.catalog_callouts(text, document) autonum = 0 callout_rx = (document.attr? 'inline-callouts') ? InlineCalloutScanRx : CalloutScanRx text.scan(callout_rx) { - # lead with assignments for Ruby 1.8.7 compat captured, num = $&, $2 document.callouts.register num == '.' ? (autonum += 1).to_s : num unless captured.start_with? '\\' # we have to mark as found even if it's escaped so it can be unescaped From 611a6e100030b64d9e7ce052cd96ddbed8d06fec Mon Sep 17 00:00:00 2001 From: Nik Everett Date: Thu, 31 Jan 2019 14:35:56 -0500 Subject: [PATCH 4/4] Drop extra --- .vscode/settings.json | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index dadd2421e7081..0000000000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "python.linting.enabled": true, - "python.pythonPath": "/usr/bin/python2" -} \ No newline at end of file