From 7f409d5466a95f5e054d2db4ce41ec0a81b67ac3 Mon Sep 17 00:00:00 2001 From: Guillaume Grossetie <ggrossetie@gmail.com> Date: Fri, 6 Nov 2020 13:22:36 +0100 Subject: [PATCH] Integrate Asciidoctor Kroki gem --- Gemfile | 1 + Gemfile.lock | 44 ++++++++++++++++++++ lib/banzai/filter/kroki_filter.rb | 12 +++--- lib/banzai/pipeline/ascii_doc_pipeline.rb | 1 - lib/gitlab/asciidoc.rb | 22 ++++++++-- lib/gitlab/asciidoc/kroki_block_processor.rb | 37 ---------------- lib/gitlab/kroki.rb | 8 ---- 7 files changed, 68 insertions(+), 57 deletions(-) delete mode 100644 lib/gitlab/asciidoc/kroki_block_processor.rb delete mode 100644 lib/gitlab/kroki.rb diff --git a/Gemfile b/Gemfile index 80d617286d1a6..e0ec983ad7678 100644 --- a/Gemfile +++ b/Gemfile @@ -159,6 +159,7 @@ gem 'wikicloth', '0.8.1' gem 'asciidoctor', '~> 2.0.10' gem 'asciidoctor-include-ext', '~> 0.3.1', require: false gem 'asciidoctor-plantuml', '~> 0.0.12' +gem 'asciidoctor-kroki', '~> 0.2.0' gem 'rouge', '~> 3.25.0' gem 'truncato', '~> 0.7.11' gem 'bootstrap_form', '~> 4.2.0' diff --git a/Gemfile.lock b/Gemfile.lock index b9fb5d1085ee0..45bdca0bb4d91 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,7 @@ GEM remote: https://rubygems.org/ specs: + Ascii85 (1.0.3) RedCloth (4.3.2) abstract_type (0.0.7) acme-client (2.0.6) @@ -71,6 +72,7 @@ GEM addressable (2.7.0) public_suffix (>= 2.0.2, < 5.0) aes_key_wrap (1.1.0) + afm (0.2.2) akismet (3.0.0) android_key_attestation (0.3.0) apollo_upload_server (2.0.2) @@ -84,6 +86,21 @@ GEM asciidoctor (2.0.10) asciidoctor-include-ext (0.3.1) asciidoctor (>= 1.5.6, < 3.0.0) + asciidoctor-kroki (0.2.0) + asciidoctor (~> 2.0) + asciidoctor-pdf (= 1.5.3) + asciidoctor-pdf (1.5.3) + asciidoctor (>= 1.5.3, < 3.0.0) + concurrent-ruby (~> 1.1.0) + prawn (~> 2.2.0) + prawn-icon (~> 2.5.0) + prawn-svg (~> 0.30.0) + prawn-table (~> 0.2.0) + prawn-templates (~> 0.1.0) + safe_yaml (~> 1.0.0) + thread_safe (~> 0.3.0) + treetop (~> 1.6.0) + ttfunk (~> 1.5.0, >= 1.5.1) asciidoctor-plantuml (0.0.12) asciidoctor (>= 1.5.6, < 3.0.0) ast (2.4.1) @@ -563,6 +580,7 @@ GEM hana (1.3.6) hangouts-chat (0.0.5) hashdiff (1.0.1) + hashery (2.1.2) hashie (3.6.0) hashie-forbidden_attributes (0.1.1) hashie (>= 3.0) @@ -839,12 +857,33 @@ GEM parser (2.7.2.0) ast (~> 2.4.1) parslet (1.8.2) + pdf-core (0.7.0) + pdf-reader (2.4.1) + Ascii85 (~> 1.0.0) + afm (~> 0.2.1) + hashery (~> 2.0) + ruby-rc4 + ttfunk peek (1.1.0) railties (>= 4.0.0) pg (1.2.3) png_quantizator (0.2.1) po_to_json (1.0.1) json (>= 1.6.0) + polyglot (0.3.5) + prawn (2.2.2) + pdf-core (~> 0.7.0) + ttfunk (~> 1.5) + prawn-icon (2.5.0) + prawn (>= 1.1.0, < 3.0.0) + prawn-svg (0.30.0) + css_parser (~> 1.6) + prawn (>= 0.11.1, < 3) + prawn-table (0.2.2) + prawn (>= 1.3.0, < 3.0.0) + prawn-templates (0.1.2) + pdf-reader (~> 2.0) + prawn (~> 2.2) premailer (1.11.1) addressable css_parser (>= 1.6.0) @@ -1049,6 +1088,7 @@ GEM crack (~> 0.4) ruby-prof (1.3.1) ruby-progressbar (1.10.1) + ruby-rc4 (0.1.5) ruby-saml (1.7.2) nokogiri (>= 1.5.10) ruby-statistics (2.1.2) @@ -1176,9 +1216,12 @@ GEM tpm-key_attestation (0.9.0) bindata (~> 2.4) openssl-signature_algorithm (~> 0.4.0) + treetop (1.6.11) + polyglot (~> 0.3) truncato (0.7.11) htmlentities (~> 4.3.1) nokogiri (>= 1.7.0, <= 2.0) + ttfunk (1.5.1) tzinfo (1.2.8) thread_safe (~> 0.1) u2f (0.2.1) @@ -1269,6 +1312,7 @@ DEPENDENCIES asana (= 0.10.2) asciidoctor (~> 2.0.10) asciidoctor-include-ext (~> 0.3.1) + asciidoctor-kroki (~> 0.2.0) asciidoctor-plantuml (~> 0.0.12) atlassian-jwt (~> 0.2.0) attr_encrypted (~> 3.1.0) diff --git a/lib/banzai/filter/kroki_filter.rb b/lib/banzai/filter/kroki_filter.rb index 95d1bcf7f27cc..881b390bd3688 100644 --- a/lib/banzai/filter/kroki_filter.rb +++ b/lib/banzai/filter/kroki_filter.rb @@ -1,18 +1,17 @@ # frozen_string_literal: true require "nokogiri" -require "zlib" -require "base64" +require "asciidoctor/extensions/asciidoctor_kroki/extension" module Banzai module Filter # HTML that replaces all diagrams supported by Kroki with the corresponding img tags. # class KrokiFilter < HTML::Pipeline::Filter - DIAGRAM_SELECTORS = ::Gitlab::Kroki::DIAGRAM_TYPES + DIAGRAM_SELECTORS = ::AsciidoctorExtensions::Kroki::SUPPORTED_DIAGRAM_NAMES .map { |diagram_type| %(pre[lang="#{diagram_type}"] > code) } .join(', ') - DIAGRAM_SELECTORS_WO_PLANTUML = ::Gitlab::Kroki::DIAGRAM_TYPES + DIAGRAM_SELECTORS_WO_PLANTUML = ::AsciidoctorExtensions::Kroki::SUPPORTED_DIAGRAM_NAMES .select { |diagram_type| diagram_type != 'plantuml' } .map { |diagram_type| %(pre[lang="#{diagram_type}"] > code) } .join(', ') @@ -39,10 +38,9 @@ def call private - # QUESTION: should should we use the asciidoctor-kroki gem to delegate this logic? def create_image_src(type, format, text) - data = Base64.urlsafe_encode64(Zlib::Deflate.deflate(text, 9)) - "#{settings.kroki_url}/#{type}/#{format}/#{data}" + ::AsciidoctorExtensions::KrokiDiagram.new(type, format, text) + .get_diagram_uri(settings.kroki_url) end def settings diff --git a/lib/banzai/pipeline/ascii_doc_pipeline.rb b/lib/banzai/pipeline/ascii_doc_pipeline.rb index 1f6a47bf939b0..90edc7010f45b 100644 --- a/lib/banzai/pipeline/ascii_doc_pipeline.rb +++ b/lib/banzai/pipeline/ascii_doc_pipeline.rb @@ -9,7 +9,6 @@ def self.filters Filter::AssetProxyFilter, Filter::SyntaxHighlightFilter, Filter::ExternalLinkFilter, - Filter::KrokiFilter, Filter::PlantumlFilter, Filter::ColorFilter, Filter::ImageLazyLoadFilter, diff --git a/lib/gitlab/asciidoc.rb b/lib/gitlab/asciidoc.rb index 3ea698550ec11..a7ab8e00126fd 100644 --- a/lib/gitlab/asciidoc.rb +++ b/lib/gitlab/asciidoc.rb @@ -2,6 +2,7 @@ require 'asciidoctor' require 'asciidoctor-plantuml' +require 'asciidoctor/extensions/asciidoctor_kroki/extension' require 'asciidoctor/extensions' require 'gitlab/asciidoc/html5_converter' require 'gitlab/asciidoc/mermaid_block_processor' @@ -23,7 +24,14 @@ module Asciidoc 'source-highlighter' => 'gitlab-html-pipeline', 'icons' => 'font', 'outfilesuffix' => '.adoc', - 'max-include-depth' => MAX_INCLUDE_DEPTH + 'max-include-depth' => MAX_INCLUDE_DEPTH, + # This feature is disabled because it relies on File#read to read the file. + # If we want to enable this feature we will need to provide a "GitLab compatible" implementation. + # This attribute is typically used to share common config (skinparam...) across all PlantUML diagrams. + # The value can be a path or a URL. + 'kroki-plantuml-include!' => '', + # This feature is disabled because it relies on the local file system to save diagrams retrieved from the Kroki server. + 'kroki-fetch-diagram!' => '' }.freeze def self.path_attrs(path) @@ -50,8 +58,8 @@ def self.render(input, context) block ::Gitlab::Asciidoc::MermaidBlockProcessor if Gitlab::CurrentSettings.kroki_enabled - ::Gitlab::Kroki::DIAGRAM_TYPES.each do |name| - block ::Gitlab::Asciidoc::KrokiBlockProcessor, name + ::AsciidoctorExtensions::Kroki::SUPPORTED_DIAGRAM_NAMES.each do |name| + block ::AsciidoctorExtensions::KrokiBlockProcessor, name end end end @@ -59,7 +67,13 @@ def self.render(input, context) extra_attrs = path_attrs(context[:requested_path]) asciidoc_opts = { safe: :secure, backend: :gitlab_html5, - attributes: DEFAULT_ADOC_ATTRS.merge(extra_attrs), + attributes: DEFAULT_ADOC_ATTRS + .merge(extra_attrs) + .merge({ + # Define the Kroki server URL from the settings. + # This attribute cannot be overridden from the AsciiDoc document. + 'kroki-server-url' => Gitlab::CurrentSettings.kroki_url + }), extensions: extensions } context[:pipeline] = :ascii_doc diff --git a/lib/gitlab/asciidoc/kroki_block_processor.rb b/lib/gitlab/asciidoc/kroki_block_processor.rb deleted file mode 100644 index 078c72f835bdd..0000000000000 --- a/lib/gitlab/asciidoc/kroki_block_processor.rb +++ /dev/null @@ -1,37 +0,0 @@ -# frozen_string_literal: true - -require 'asciidoctor' - -module Gitlab - module Asciidoc - # Kroki BlockProcessor - # - class KrokiBlockProcessor < ::Asciidoctor::Extensions::BlockProcessor - use_dsl - - on_context :literal, :listing - parse_content_as :simple - - def process(parent, reader, attrs) - diagram_type = @name - diagram_text = reader.string - create_kroki_source_block(parent, diagram_type, diagram_text, attrs) - end - - private - - def create_kroki_source_block(parent, diagram_type, diagram_text, attrs) - # If "subs" attribute is specified, substitute accordingly. - # Be careful not to specify "specialcharacters" or your diagram code won't be valid anymore! - subs = attrs['subs'] - diagram_text = parent.apply_subs(diagram_text, parent.resolve_subs(subs)) if subs - html = %(<div><pre data-kroki-style="display" lang="#{diagram_type}"><code>#{CGI.escape_html(diagram_text)}</code></pre></div>) - ::Asciidoctor::Block.new(parent, :pass, { - content_model: :raw, - source: html, - subs: :default - }.merge(attrs)) - end - end - end -end diff --git a/lib/gitlab/kroki.rb b/lib/gitlab/kroki.rb deleted file mode 100644 index fff1aa14a7ad5..0000000000000 --- a/lib/gitlab/kroki.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module Kroki - # QUESTION: should we use the asciidoctor-kroki gem? - DIAGRAM_TYPES = %w(plantuml ditaa graphviz blockdiag seqdiag actdiag nwdiag packetdiag rackdiag c4plantuml erd mermaid nomnoml svgbob umlet vega vegalite wavedrom).freeze - end -end -- GitLab