diff options
Diffstat (limited to 'lib/banzai/filter')
-rw-r--r-- | lib/banzai/filter/ascii_doc_sanitization_filter.rb | 37 | ||||
-rw-r--r-- | lib/banzai/filter/base_sanitization_filter.rb | 2 | ||||
-rw-r--r-- | lib/banzai/filter/kroki_filter.rb | 42 | ||||
-rw-r--r-- | lib/banzai/filter/merge_request_reference_filter.rb | 2 | ||||
-rw-r--r-- | lib/banzai/filter/syntax_highlight_filter.rb | 5 |
5 files changed, 61 insertions, 27 deletions
diff --git a/lib/banzai/filter/ascii_doc_sanitization_filter.rb b/lib/banzai/filter/ascii_doc_sanitization_filter.rb index a1a204ec652..11762c3bfb4 100644 --- a/lib/banzai/filter/ascii_doc_sanitization_filter.rb +++ b/lib/banzai/filter/ascii_doc_sanitization_filter.rb @@ -6,8 +6,8 @@ module Banzai # # Extends Banzai::Filter::BaseSanitizationFilter with specific rules. class AsciiDocSanitizationFilter < Banzai::Filter::BaseSanitizationFilter - # Section anchor link pattern - SECTION_LINK_REF_PATTERN = /\A#{Gitlab::Asciidoc::DEFAULT_ADOC_ATTRS['idprefix']}(:?[[:alnum:]]|-|_)+\z/.freeze + # Anchor link prefixed by "user-content-" pattern + PREFIXED_ID_PATTERN = /\A#{Gitlab::Asciidoc::DEFAULT_ADOC_ATTRS['idprefix']}(:?[[:alnum:]]|-|_)+\z/.freeze SECTION_HEADINGS = %w(h2 h3 h4 h5 h6).freeze # Footnote link patterns @@ -54,43 +54,34 @@ module Banzai whitelist[:attributes]['table'] = %w(class) whitelist[:transformers].push(self.class.remove_element_classes) + # Allow `id` in anchor and footnote elements + whitelist[:attributes]['a'].push('id') + whitelist[:attributes]['div'].push('id') + # Allow `id` in heading elements for section anchors SECTION_HEADINGS.each do |header| whitelist[:attributes][header] = %w(id) end - whitelist[:transformers].push(self.class.remove_non_heading_ids) - # Allow `id` in footnote elements - FOOTNOTE_LINK_ID_PATTERNS.keys.each do |element| - whitelist[:attributes][element.to_s].push('id') - end - whitelist[:transformers].push(self.class.remove_non_footnote_ids) + # Remove ids that are not explicitly allowed + whitelist[:transformers].push(self.class.remove_disallowed_ids) whitelist end class << self - def remove_non_footnote_ids + def remove_disallowed_ids lambda do |env| node = env[:node] - return unless (pattern = FOOTNOTE_LINK_ID_PATTERNS[node.name.to_sym]) + return unless node.name == 'a' || node.name == 'div' || SECTION_HEADINGS.any?(node.name) return unless node.has_attribute?('id') - return if node['id'] =~ pattern - - node.remove_attribute('id') - end - end - - def remove_non_heading_ids - lambda do |env| - node = env[:node] - - return unless SECTION_HEADINGS.any?(node.name) - return unless node.has_attribute?('id') + return if node['id'] =~ PREFIXED_ID_PATTERN - return if node['id'] =~ SECTION_LINK_REF_PATTERN + if (pattern = FOOTNOTE_LINK_ID_PATTERNS[node.name.to_sym]) + return if node['id'] =~ pattern + end node.remove_attribute('id') end diff --git a/lib/banzai/filter/base_sanitization_filter.rb b/lib/banzai/filter/base_sanitization_filter.rb index fc3791e0cbf..4f9e8cffd11 100644 --- a/lib/banzai/filter/base_sanitization_filter.rb +++ b/lib/banzai/filter/base_sanitization_filter.rb @@ -25,7 +25,7 @@ module Banzai # Allow data-math-style attribute in order to support LaTeX formatting whitelist[:attributes]['code'] = %w(data-math-style) - whitelist[:attributes]['pre'] = %w(data-math-style data-mermaid-style) + whitelist[:attributes]['pre'] = %w(data-math-style data-mermaid-style data-kroki-style) # Allow html5 details/summary elements whitelist[:elements].push('details') diff --git a/lib/banzai/filter/kroki_filter.rb b/lib/banzai/filter/kroki_filter.rb new file mode 100644 index 00000000000..dbd4de32a47 --- /dev/null +++ b/lib/banzai/filter/kroki_filter.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +require "nokogiri" +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 + def call + return doc unless settings.kroki_enabled + + diagram_selectors = ::Gitlab::Kroki.formats(settings) + .map { |diagram_type| %(pre[lang="#{diagram_type}"] > code) } + .join(', ') + + return doc unless doc.at(diagram_selectors) + + diagram_format = "svg" + doc.css(diagram_selectors).each do |node| + diagram_type = node.parent['lang'] + img_tag = Nokogiri::HTML::DocumentFragment.parse(%(<img src="#{create_image_src(diagram_type, diagram_format, node.content)}"/>)) + node.parent.replace(img_tag) + end + + doc + end + + private + + def create_image_src(type, format, text) + ::AsciidoctorExtensions::KrokiDiagram.new(type, format, text) + .get_diagram_uri(settings.kroki_url) + end + + def settings + Gitlab::CurrentSettings.current_application_settings + end + end + end +end diff --git a/lib/banzai/filter/merge_request_reference_filter.rb b/lib/banzai/filter/merge_request_reference_filter.rb index f05902078dc..0b8bd17a71b 100644 --- a/lib/banzai/filter/merge_request_reference_filter.rb +++ b/lib/banzai/filter/merge_request_reference_filter.rb @@ -59,7 +59,7 @@ module Banzai super(object_sym, tooltip: false) end - def data_attributes_for(text, parent, object, data = {}) + def data_attributes_for(text, parent, object, **data) super.merge(project_path: parent.full_path, iid: object.iid, mr_title: object.title) end diff --git a/lib/banzai/filter/syntax_highlight_filter.rb b/lib/banzai/filter/syntax_highlight_filter.rb index 6dc0cce6050..1d3bbe43344 100644 --- a/lib/banzai/filter/syntax_highlight_filter.rb +++ b/lib/banzai/filter/syntax_highlight_filter.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require 'rouge/plugins/common_mark' +require "asciidoctor/extensions/asciidoctor_kroki/extension" # Generated HTML is transformed back to GFM by app/assets/javascripts/behaviors/markdown/nodes/code_block.js module Banzai @@ -14,7 +15,7 @@ module Banzai LANG_PARAMS_ATTR = 'data-lang-params' def call - doc.search('pre:not([data-math-style]):not([data-mermaid-style]) > code').each do |node| + doc.search('pre:not([data-math-style]):not([data-mermaid-style]):not([data-kroki-style]) > code').each do |node| highlight_node(node) end @@ -86,7 +87,7 @@ module Banzai end def use_rouge?(language) - %w(math mermaid plantuml suggestion).exclude?(language) + (%w(math suggestion) + ::AsciidoctorExtensions::Kroki::SUPPORTED_DIAGRAM_NAMES).exclude?(language) end end end |