Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/banzai/filter')
-rw-r--r--lib/banzai/filter/references/reference_cache.rb57
-rw-r--r--lib/banzai/filter/table_of_contents_tag_filter.rb44
2 files changed, 74 insertions, 27 deletions
diff --git a/lib/banzai/filter/references/reference_cache.rb b/lib/banzai/filter/references/reference_cache.rb
index 24b8b4984cd..816ce973cad 100644
--- a/lib/banzai/filter/references/reference_cache.rb
+++ b/lib/banzai/filter/references/reference_cache.rb
@@ -28,20 +28,11 @@ module Banzai
@references_per_parent[parent_type] ||= begin
refs = Hash.new { |hash, key| hash[key] = Set.new }
- nodes.each do |node|
- prepare_node_for_scan(node).scan(regex) do
- parent_path = if parent_type == :project
- full_project_path($~[:namespace], $~[:project])
- else
- full_group_path($~[:group])
- end
-
- ident = filter.identifier($~)
- refs[parent_path] << ident if ident
- end
+ if Feature.enabled?(:milestone_reference_pattern, default_enabled: :yaml)
+ doc_search(refs)
+ else
+ node_search(nodes, refs)
end
-
- refs
end
end
@@ -172,6 +163,39 @@ module Banzai
delegate :project, :group, :parent, :parent_type, to: :filter
+ # Deprecated: https://gitlab.com/gitlab-org/gitlab/-/issues/336268
+ def node_search(nodes, refs)
+ nodes.each do |node|
+ prepare_node_for_scan(node).scan(regex) do
+ parent_path = if parent_type == :project
+ full_project_path($~[:namespace], $~[:project])
+ else
+ full_group_path($~[:group])
+ end
+
+ ident = filter.identifier($~)
+ refs[parent_path] << ident if ident
+ end
+ end
+
+ refs
+ end
+
+ def doc_search(refs)
+ prepare_doc_for_scan(filter.doc).to_enum(:scan, regex).each do
+ parent_path = if parent_type == :project
+ full_project_path($~[:namespace], $~[:project])
+ else
+ full_group_path($~[:group])
+ end
+
+ ident = filter.identifier($~)
+ refs[parent_path] << ident if ident
+ end
+
+ refs
+ end
+
def regex
strong_memoize(:regex) do
[
@@ -185,6 +209,13 @@ module Banzai
Gitlab::SafeRequestStore["banzai_#{parent_type}_refs".to_sym] ||= {}
end
+ def prepare_doc_for_scan(doc)
+ html = doc.to_html
+
+ filter.requires_unescaping? ? unescape_html_entities(html) : html
+ end
+
+ # Deprecated: https://gitlab.com/gitlab-org/gitlab/-/issues/336268
def prepare_node_for_scan(node)
html = node.to_html
diff --git a/lib/banzai/filter/table_of_contents_tag_filter.rb b/lib/banzai/filter/table_of_contents_tag_filter.rb
index 13d0a6a4cc7..4e80b543e2d 100644
--- a/lib/banzai/filter/table_of_contents_tag_filter.rb
+++ b/lib/banzai/filter/table_of_contents_tag_filter.rb
@@ -2,26 +2,31 @@
module Banzai
module Filter
- # Using `[[_TOC_]]`, inserts a Table of Contents list.
- # This syntax is based on the Gollum syntax. This way we have
- # some consistency between with wiki and normal markdown.
- # If there ever emerges a markdown standard, we can implement
- # that here.
+ # Using `[[_TOC_]]` or `[TOC]` (both case insensitive), inserts a Table of Contents list.
#
+ # `[[_TOC_]]` is based on the Gollum syntax. This way we have
+ # some consistency between with wiki and normal markdown.
# The support for this has been removed from GollumTagsFilter
#
+ # `[toc]` is a generally accepted form, used by Typora for example.
+ #
# Based on Banzai::Filter::GollumTagsFilter
class TableOfContentsTagFilter < HTML::Pipeline::Filter
- TEXT_QUERY = %q(descendant-or-self::text()[ancestor::p and contains(., 'TOC')])
+ TEXT_QUERY = %q(descendant-or-self::text()[ancestor::p and contains(translate(., 'TOC', 'toc'), 'toc')])
def call
return doc if context[:no_header_anchors]
doc.xpath(TEXT_QUERY).each do |node|
- # A Gollum ToC tag is `[[_TOC_]]`, but due to MarkdownFilter running
- # before this one, it will be converted into `[[<em>TOC</em>]]`, so it
- # needs special-case handling
- process_toc_tag(node) if toc_tag?(node)
+ if toc_tag?(node)
+ # Support [TOC] / [toc] tags, which don't have a wrapping <em>-tag
+ process_toc_tag(node)
+ elsif toc_tag_em?(node)
+ # Support Gollum like ToC tag (`[[_TOC_]]` / `[[_toc_]]`), which will be converted
+ # into `[[<em>TOC</em>]]` by the markdown filter, so it
+ # needs special-case handling
+ process_toc_tag_em(node)
+ end
end
doc
@@ -31,14 +36,25 @@ module Banzai
# Replace an entire `[[<em>TOC</em>]]` node with the result generated by
# TableOfContentsFilter
+ def process_toc_tag_em(node)
+ process_toc_tag(node.parent)
+ end
+
+ # Replace an entire `[TOC]` node with the result generated by
+ # TableOfContentsFilter
def process_toc_tag(node)
- node.parent.parent.replace(result[:toc].presence || '')
+ # we still need to go one step up to also replace the surrounding <p></p>
+ node.parent.replace(result[:toc].presence || '')
end
- def toc_tag?(node)
- node.content == 'TOC' &&
+ def toc_tag_em?(node)
+ node.content.casecmp?('toc') &&
node.parent.name == 'em' &&
- node.parent.parent.text == '[[TOC]]'
+ node.parent.parent.text.casecmp?('[[toc]]')
+ end
+
+ def toc_tag?(node)
+ node.parent.text.casecmp?('[toc]')
end
end
end