diff --git a/lib/ES/Util.pm b/lib/ES/Util.pm index 86869410b24e6..a8e75a93cb580 100644 --- a/lib/ES/Util.pm +++ b/lib/ES/Util.pm @@ -85,9 +85,8 @@ sub build_chunked { '-d' => 'book', '-a' => 'showcomments=1', '-a' => "lang=$lang", - '-a' => 'base_edit_url=' . $edit_url, '-a' => 'root_dir=' . $root_dir, - $private ? ( '-a' => 'edit_url!' ) : (), + $private ? () : ( '-a' => "edit_url=$edit_url" ), # Disable warning on missing attributes because we have # missing attributes! # '-a' => 'attribute-missing=warn', @@ -206,10 +205,9 @@ sub build_single { '-d' => $type, '-a' => 'showcomments=1', '-a' => "lang=$lang", - '-a' => 'base_edit_url=' . $edit_url, '-a' => 'root_dir=' . $root_dir, + $private ? () : ( '-a' => "edit_url=$edit_url" ), '-a' => 'asciidoc-dir=' . $asciidoc_dir, - $private ? ( '-a' => 'edit_url!' ) : (), # Disable warning on missing attributes because we have # missing attributes! # '-a' => 'attribute-missing=warn', diff --git a/resources/asciidoctor/lib/edit_me/extension.rb b/resources/asciidoctor/lib/edit_me/extension.rb new file mode 100644 index 0000000000000..205d373d3367c --- /dev/null +++ b/resources/asciidoctor/lib/edit_me/extension.rb @@ -0,0 +1,37 @@ +require_relative '../scaffold.rb' + +include Asciidoctor + +## +# TreeProcessor extension to automatically add "Edit Me" links to appropriate +# spots in the documentation. +class EditMe < TreeProcessorScaffold + include Logging + + def process document + logger.error("sourcemap is required") unless document.sourcemap + if document.attributes['edit_url'] + super + end + end + + def process_block block + if [:preamble, :section, :floating_title].include? block.context + def block.title + url = @document.attributes['edit_url'] + url += '/' unless url.end_with?('/') + url += source_path + "#{super}Edit me" + end + if :preamble == block.context + def block.source_path + document.source_location.path + end + else + def block.source_path + source_location.path + end + end + end + end +end diff --git a/resources/asciidoctor/lib/elastic_compat_tree_processor/extension.rb b/resources/asciidoctor/lib/elastic_compat_tree_processor/extension.rb index 9f9731b451565..561c4327bf28d 100644 --- a/resources/asciidoctor/lib/elastic_compat_tree_processor/extension.rb +++ b/resources/asciidoctor/lib/elastic_compat_tree_processor/extension.rb @@ -1,4 +1,4 @@ -require 'asciidoctor/extensions' +require_relative '../scaffold.rb' include Asciidoctor @@ -23,13 +23,8 @@ # <1> The count of categories that were matched # <2> The categories retrieved # -class ElasticCompatTreeProcessor < Extensions::TreeProcessor - def process document - process_blocks document - nil - end - - def process_blocks block +class ElasticCompatTreeProcessor < TreeProcessorScaffold + def process_block block if block.context == :listing && block.style == "source" && false == block.subs.include?(:specialcharacters) # callouts have to come *after* special characters @@ -37,9 +32,6 @@ def process_blocks block block.subs << :specialcharacters block.subs << :callouts if had_callouts end - for subblock in block.context == :dlist ? block.blocks.flatten : block.blocks - process_blocks subblock - end end end \ No newline at end of file diff --git a/resources/asciidoctor/lib/extensions.rb b/resources/asciidoctor/lib/extensions.rb index 351dacfbdcebf..6d536169f43df 100644 --- a/resources/asciidoctor/lib/extensions.rb +++ b/resources/asciidoctor/lib/extensions.rb @@ -1,10 +1,15 @@ require_relative 'added/extension' +require_relative 'edit_me/extension' require_relative 'elastic_compat_tree_processor/extension' require_relative 'elastic_compat_preprocessor/extension' require_relative 'elastic_include_tagged/extension' Extensions.register do + # Enable storing the source locations so we can look at them. This is required + # for EditMe to get a nice location. + document.sourcemap = true preprocessor ElasticCompatPreprocessor + treeprocessor EditMe treeprocessor ElasticCompatTreeProcessor include_processor ElasticIncludeTagged block_macro AddedBlock diff --git a/resources/asciidoctor/lib/scaffold.rb b/resources/asciidoctor/lib/scaffold.rb new file mode 100644 index 0000000000000..1dae7d11d0268 --- /dev/null +++ b/resources/asciidoctor/lib/scaffold.rb @@ -0,0 +1,23 @@ +require 'asciidoctor/extensions' + +include Asciidoctor + +## +# Scaffolding for TreeProcessor extensions to automatically iterate. +class TreeProcessorScaffold < Extensions::TreeProcessor + def process_block document + raise ::NotImplementedError, %(TreeProcessorScaffold subclass must implement ##{__method__} method) + end + + def process document + process_blocks document + nil + end + + def process_blocks block + process_block block + for subblock in block.context == :dlist ? block.blocks.flatten : block.blocks + process_blocks subblock + end + end +end diff --git a/resources/asciidoctor/spec/edit_me_spec.rb b/resources/asciidoctor/spec/edit_me_spec.rb new file mode 100644 index 0000000000000..35b3378596ff0 --- /dev/null +++ b/resources/asciidoctor/spec/edit_me_spec.rb @@ -0,0 +1,374 @@ +require 'edit_me/extension' + +RSpec.describe EditMe do + before(:each) do + Extensions.register do + tree_processor EditMe + end + end + + after(:each) do + Extensions.unregister_all + end + + it "adds a link to the preface" do + attributes = { + 'edit_url' => 'www.example.com/docs/' + } + input = <<~ASCIIDOC + :preface-title: Preface + Words. + ASCIIDOC + expected = <<~DOCBOOK + + Preface<ulink role="edit_me" url="www.example.com/docs/<stdin>">Edit me</ulink> + Words. + + DOCBOOK + expect(convert input, attributes).to eq(expected.strip) + end + + it "does not add a link to the preface if edit_url isn't set" do + input = <<~ASCIIDOC + :preface-title: Preface + Words. + ASCIIDOC + expected = <<~DOCBOOK + + Preface + Words. + + DOCBOOK + expect(convert input).to eq(expected.strip) + end + + it "adds a link to each chapter title" do + attributes = { + 'edit_url' => 'www.example.com/docs/' + } + input = <<~ASCIIDOC + include::resources/edit_me/chapter1.adoc[] + + include::resources/edit_me/chapter2.adoc[] + ASCIIDOC + expected = <<~DOCBOOK + + Chapter 1<ulink role="edit_me" url="www.example.com/docs/resources/edit_me/chapter1.adoc">Edit me</ulink> + Words. + + + Chapter 2<ulink role="edit_me" url="www.example.com/docs/resources/edit_me/chapter2.adoc">Edit me</ulink> + Words. + + DOCBOOK + expect(convert input, attributes).to eq(expected.strip) + end + + it "does not add a link to each chapter title if edit_link is not set" do + input = <<~ASCIIDOC + include::resources/edit_me/chapter1.adoc[] + + include::resources/edit_me/chapter2.adoc[] + ASCIIDOC + expected = <<~DOCBOOK + + Chapter 1 + Words. + + + Chapter 2 + Words. + + DOCBOOK + expect(convert input).to eq(expected.strip) + end + + it "adds a link to each section title" do + attributes = { + 'edit_url' => 'www.example.com/docs/' + } + input = <<~ASCIIDOC + include::resources/edit_me/section1.adoc[] + + include::resources/edit_me/section2.adoc[] + ASCIIDOC + expected = <<~DOCBOOK +
+ Section 1<ulink role="edit_me" url="www.example.com/docs/resources/edit_me/section1.adoc">Edit me</ulink> + Words. +
+
+ Section 2<ulink role="edit_me" url="www.example.com/docs/resources/edit_me/section2.adoc">Edit me</ulink> + Words. +
+ DOCBOOK + expect(convert input, attributes).to eq(expected.strip) + end + + it "does not add a link to each section title if edit_link is not set" do + input = <<~ASCIIDOC + include::resources/edit_me/section1.adoc[] + + include::resources/edit_me/section2.adoc[] + ASCIIDOC + expected = <<~DOCBOOK +
+ Section 1 + Words. +
+
+ Section 2 + Words. +
+ DOCBOOK + expect(convert input).to eq(expected.strip) + end + + it "adds a link to each appendix title" do + attributes = { + 'edit_url' => 'www.example.com/docs/' + } + input = <<~ASCIIDOC + include::resources/edit_me/appendix1.adoc[] + + include::resources/edit_me/appendix2.adoc[] + ASCIIDOC + expected = <<~DOCBOOK + + Appendix 1<ulink role="edit_me" url="www.example.com/docs/resources/edit_me/appendix1.adoc">Edit me</ulink> + Words. + + + Appendix 2<ulink role="edit_me" url="www.example.com/docs/resources/edit_me/appendix2.adoc">Edit me</ulink> + Words. + + DOCBOOK + expect(convert input, attributes).to eq(expected.strip) + end + + it "does not add add a link to each appendix tile if edit_url is not set" do + input = <<~ASCIIDOC + include::resources/edit_me/appendix1.adoc[] + + include::resources/edit_me/appendix2.adoc[] + ASCIIDOC + expected = <<~DOCBOOK + + Appendix 1 + Words. + + + Appendix 2 + Words. + + DOCBOOK + expect(convert input).to eq(expected.strip) + end + + it "adds a link to each glossary title" do + attributes = { + 'edit_url' => 'www.example.com/docs/' + } + input = <<~ASCIIDOC + include::resources/edit_me/glossary1.adoc[] + + include::resources/edit_me/glossary2.adoc[] + ASCIIDOC + expected = <<~DOCBOOK + + Glossary 1<ulink role="edit_me" url="www.example.com/docs/resources/edit_me/glossary1.adoc">Edit me</ulink> + Words. + + + Glossary 2<ulink role="edit_me" url="www.example.com/docs/resources/edit_me/glossary2.adoc">Edit me</ulink> + Words. + + DOCBOOK + expect(convert input, attributes).to eq(expected.strip) + end + + it "does not add a link to each glossary title if edit_link is not set" do + input = <<~ASCIIDOC + include::resources/edit_me/glossary1.adoc[] + + include::resources/edit_me/glossary2.adoc[] + ASCIIDOC + expected = <<~DOCBOOK + + Glossary 1 + Words. + + + Glossary 2 + Words. + + DOCBOOK + expect(convert input).to eq(expected.strip) + end + + it "adds a link to each bibliography title" do + attributes = { + 'edit_url' => 'www.example.com/docs/' + } + input = <<~ASCIIDOC + include::resources/edit_me/bibliography1.adoc[] + + include::resources/edit_me/bibliography2.adoc[] + ASCIIDOC + expected = <<~DOCBOOK + + Bibliography 1<ulink role="edit_me" url="www.example.com/docs/resources/edit_me/bibliography1.adoc">Edit me</ulink> + Words. + + + Bibliography 2<ulink role="edit_me" url="www.example.com/docs/resources/edit_me/bibliography2.adoc">Edit me</ulink> + Words. + + DOCBOOK + expect(convert input, attributes).to eq(expected.strip) + end + + it "does not add a link to each bibliography title if edit_link is not set" do + input = <<~ASCIIDOC + include::resources/edit_me/bibliography1.adoc[] + + include::resources/edit_me/bibliography2.adoc[] + ASCIIDOC + expected = <<~DOCBOOK + + Bibliography 1 + Words. + + + Bibliography 2 + Words. + + DOCBOOK + expect(convert input).to eq(expected.strip) + end + + it "adds a link to each dedication title" do + attributes = { + 'edit_url' => 'www.example.com/docs/' + } + input = <<~ASCIIDOC + include::resources/edit_me/dedication1.adoc[] + + include::resources/edit_me/dedication2.adoc[] + ASCIIDOC + expected = <<~DOCBOOK + + Dedication 1<ulink role="edit_me" url="www.example.com/docs/resources/edit_me/dedication1.adoc">Edit me</ulink> + Words. + + + Dedication 2<ulink role="edit_me" url="www.example.com/docs/resources/edit_me/dedication2.adoc">Edit me</ulink> + Words. + + DOCBOOK + expect(convert input, attributes).to eq(expected.strip) + end + + it "does not add a link to each dedication title if edit_link is not set" do + input = <<~ASCIIDOC + include::resources/edit_me/dedication1.adoc[] + + include::resources/edit_me/dedication2.adoc[] + ASCIIDOC + expected = <<~DOCBOOK + + Dedication 1 + Words. + + + Dedication 2 + Words. + + DOCBOOK + expect(convert input).to eq(expected.strip) + end + + it "adds a link to each colophon title" do + attributes = { + 'edit_url' => 'www.example.com/docs/' + } + input = <<~ASCIIDOC + include::resources/edit_me/colophon1.adoc[] + + include::resources/edit_me/colophon2.adoc[] + ASCIIDOC + expected = <<~DOCBOOK + + Colophon 1<ulink role="edit_me" url="www.example.com/docs/resources/edit_me/colophon1.adoc">Edit me</ulink> + Words. + + + Colophon 2<ulink role="edit_me" url="www.example.com/docs/resources/edit_me/colophon2.adoc">Edit me</ulink> + Words. + + DOCBOOK + expect(convert input, attributes).to eq(expected.strip) + end + + it "does not add a link to each colophon title if edit_link is not set" do + input = <<~ASCIIDOC + include::resources/edit_me/colophon1.adoc[] + + include::resources/edit_me/colophon2.adoc[] + ASCIIDOC + expected = <<~DOCBOOK + + Colophon 1 + Words. + + + Colophon 2 + Words. + + DOCBOOK + expect(convert input).to eq(expected.strip) + end + + it "adds a link to each floating title" do + attributes = { + 'edit_url' => 'www.example.com/docs/' + } + input = <<~ASCIIDOC + == Chapter + + include::resources/edit_me/float1.adoc[] + + include::resources/edit_me/float2.adoc[] + ASCIIDOC + expected = <<~DOCBOOK + + Chapter<ulink role="edit_me" url="www.example.com/docs/<stdin>">Edit me</ulink> + Float 1Edit me + Words. + Float 2Edit me + Words. + + DOCBOOK + expect(convert input, attributes).to eq(expected.strip) + end + + it "does not add a link to each floating title if edit_link is not set" do + input = <<~ASCIIDOC + == Chapter + + include::resources/edit_me/float1.adoc[] + + include::resources/edit_me/float2.adoc[] + ASCIIDOC + expected = <<~DOCBOOK + + Chapter + Float 1 + Words. + Float 2 + Words. + + DOCBOOK + expect(convert input).to eq(expected.strip) + end +end \ No newline at end of file diff --git a/resources/asciidoctor/spec/resources/edit_me/appendix1.adoc b/resources/asciidoctor/spec/resources/edit_me/appendix1.adoc new file mode 100644 index 0000000000000..ce5e21f91164a --- /dev/null +++ b/resources/asciidoctor/spec/resources/edit_me/appendix1.adoc @@ -0,0 +1,4 @@ +[appendix] +== Appendix 1 + +Words. diff --git a/resources/asciidoctor/spec/resources/edit_me/appendix2.adoc b/resources/asciidoctor/spec/resources/edit_me/appendix2.adoc new file mode 100644 index 0000000000000..1f13553ff156a --- /dev/null +++ b/resources/asciidoctor/spec/resources/edit_me/appendix2.adoc @@ -0,0 +1,4 @@ +[appendix] +== Appendix 2 + +Words. diff --git a/resources/asciidoctor/spec/resources/edit_me/bibliography1.adoc b/resources/asciidoctor/spec/resources/edit_me/bibliography1.adoc new file mode 100644 index 0000000000000..c9ad13209efe1 --- /dev/null +++ b/resources/asciidoctor/spec/resources/edit_me/bibliography1.adoc @@ -0,0 +1,4 @@ +[bibliography] +== Bibliography 1 + +Words. diff --git a/resources/asciidoctor/spec/resources/edit_me/bibliography2.adoc b/resources/asciidoctor/spec/resources/edit_me/bibliography2.adoc new file mode 100644 index 0000000000000..fa83aeea8e692 --- /dev/null +++ b/resources/asciidoctor/spec/resources/edit_me/bibliography2.adoc @@ -0,0 +1,4 @@ +[bibliography] +== Bibliography 2 + +Words. diff --git a/resources/asciidoctor/spec/resources/edit_me/chapter1.adoc b/resources/asciidoctor/spec/resources/edit_me/chapter1.adoc new file mode 100644 index 0000000000000..3398df89d8a35 --- /dev/null +++ b/resources/asciidoctor/spec/resources/edit_me/chapter1.adoc @@ -0,0 +1,3 @@ +== Chapter 1 + +Words. diff --git a/resources/asciidoctor/spec/resources/edit_me/chapter2.adoc b/resources/asciidoctor/spec/resources/edit_me/chapter2.adoc new file mode 100644 index 0000000000000..270f73c367faa --- /dev/null +++ b/resources/asciidoctor/spec/resources/edit_me/chapter2.adoc @@ -0,0 +1,3 @@ +== Chapter 2 + +Words. \ No newline at end of file diff --git a/resources/asciidoctor/spec/resources/edit_me/colophon1.adoc b/resources/asciidoctor/spec/resources/edit_me/colophon1.adoc new file mode 100644 index 0000000000000..47dcee5e7b037 --- /dev/null +++ b/resources/asciidoctor/spec/resources/edit_me/colophon1.adoc @@ -0,0 +1,4 @@ +[colophon] +== Colophon 1 + +Words. diff --git a/resources/asciidoctor/spec/resources/edit_me/colophon2.adoc b/resources/asciidoctor/spec/resources/edit_me/colophon2.adoc new file mode 100644 index 0000000000000..3f4550d736e8f --- /dev/null +++ b/resources/asciidoctor/spec/resources/edit_me/colophon2.adoc @@ -0,0 +1,4 @@ +[colophon] +== Colophon 2 + +Words. diff --git a/resources/asciidoctor/spec/resources/edit_me/dedication1.adoc b/resources/asciidoctor/spec/resources/edit_me/dedication1.adoc new file mode 100644 index 0000000000000..c3fce60bd9428 --- /dev/null +++ b/resources/asciidoctor/spec/resources/edit_me/dedication1.adoc @@ -0,0 +1,4 @@ +[dedication] +== Dedication 1 + +Words. diff --git a/resources/asciidoctor/spec/resources/edit_me/dedication2.adoc b/resources/asciidoctor/spec/resources/edit_me/dedication2.adoc new file mode 100644 index 0000000000000..2c4e2f1af5c11 --- /dev/null +++ b/resources/asciidoctor/spec/resources/edit_me/dedication2.adoc @@ -0,0 +1,4 @@ +[dedication] +== Dedication 2 + +Words. diff --git a/resources/asciidoctor/spec/resources/edit_me/float1.adoc b/resources/asciidoctor/spec/resources/edit_me/float1.adoc new file mode 100644 index 0000000000000..5b373d0221681 --- /dev/null +++ b/resources/asciidoctor/spec/resources/edit_me/float1.adoc @@ -0,0 +1,4 @@ +[float] +=== Float 1 + +Words. diff --git a/resources/asciidoctor/spec/resources/edit_me/float2.adoc b/resources/asciidoctor/spec/resources/edit_me/float2.adoc new file mode 100644 index 0000000000000..1937b011094ef --- /dev/null +++ b/resources/asciidoctor/spec/resources/edit_me/float2.adoc @@ -0,0 +1,4 @@ +[float] +=== Float 2 + +Words. diff --git a/resources/asciidoctor/spec/resources/edit_me/glossary1.adoc b/resources/asciidoctor/spec/resources/edit_me/glossary1.adoc new file mode 100644 index 0000000000000..4ca7670eadfe0 --- /dev/null +++ b/resources/asciidoctor/spec/resources/edit_me/glossary1.adoc @@ -0,0 +1,4 @@ +[glossary] +== Glossary 1 + +Words. diff --git a/resources/asciidoctor/spec/resources/edit_me/glossary2.adoc b/resources/asciidoctor/spec/resources/edit_me/glossary2.adoc new file mode 100644 index 0000000000000..9ed4b1bd97e93 --- /dev/null +++ b/resources/asciidoctor/spec/resources/edit_me/glossary2.adoc @@ -0,0 +1,4 @@ +[glossary] +== Glossary 2 + +Words. diff --git a/resources/asciidoctor/spec/resources/edit_me/section1.adoc b/resources/asciidoctor/spec/resources/edit_me/section1.adoc new file mode 100644 index 0000000000000..20cd00459b7c1 --- /dev/null +++ b/resources/asciidoctor/spec/resources/edit_me/section1.adoc @@ -0,0 +1,3 @@ +=== Section 1 + +Words. diff --git a/resources/asciidoctor/spec/resources/edit_me/section2.adoc b/resources/asciidoctor/spec/resources/edit_me/section2.adoc new file mode 100644 index 0000000000000..5f7209a831e1b --- /dev/null +++ b/resources/asciidoctor/spec/resources/edit_me/section2.adoc @@ -0,0 +1,3 @@ +=== Section 2 + +Words. diff --git a/resources/asciidoctor/spec/spec_helper.rb b/resources/asciidoctor/spec/spec_helper.rb index dfa209d6d5e33..e226c41d774e8 100644 --- a/resources/asciidoctor/spec/spec_helper.rb +++ b/resources/asciidoctor/spec/spec_helper.rb @@ -34,16 +34,19 @@ def initialize warnings, result ## # Convert an asciidoc string into docbook. If the conversion results in any # errors or warnings then raises a ConvertError. -def convert input +def convert input, extra_attributes = {} logger = Asciidoctor::MemoryLogger.new + attributes = { + 'docdir' => File.dirname(__FILE__), + } + attributes.merge! extra_attributes result = Asciidoctor.convert input, { :safe => :unsafe, # Used to include "funny" files. :backend => :docbook45, :logger => logger, :doctype => :book, - :attributes => { - 'docdir' => File.dirname(__FILE__), - }, + :attributes => attributes, + :sourcemap => true, } if logger.messages != [] then raise ConvertError.new(logger.messages, result)