Class: Banzai::Filter::References::ReferenceFilter

Inherits:
HTML::Pipeline::Filter
  • Object
show all
Includes:
OutputSafety, RequestStoreReferenceCache
Defined in:
lib/banzai/filter/references/reference_filter.rb

Overview

Base class for GitLab Flavored Markdown reference filters.

References within <pre>, <code>, <a>, and <style> elements are ignored.

Context options:

:project (required) - Current project, ignored if reference is cross-project.
:only_path          - Generate path-only links.

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from OutputSafety

#escape_once

Methods included from RequestStoreReferenceCache

#cached_call, #get_or_set_cache

Constructor Details

#initialize(doc, context = nil, result = nil) ⇒ ReferenceFilter

Returns a new instance of ReferenceFilter.


32
33
34
35
36
37
# File 'lib/banzai/filter/references/reference_filter.rb', line 32

def initialize(doc, context = nil, result = nil)
  super

  @new_nodes = {}
  @nodes = self.result[:reference_filter_nodes]
end

Class Attribute Details

.object_classObject

Implement in child class Example: self.object_class = MergeRequest


25
26
27
# File 'lib/banzai/filter/references/reference_filter.rb', line 25

def object_class
  @object_class
end

.reference_typeObject

Implement in child class Example: self.reference_type = :merge_request


21
22
23
# File 'lib/banzai/filter/references/reference_filter.rb', line 21

def reference_type
  @reference_type
end

Class Method Details

.call(doc, context = nil, result = nil) ⇒ Object


27
28
29
# File 'lib/banzai/filter/references/reference_filter.rb', line 27

def call(doc, context = nil, result = nil)
  new(doc, context, result).call_and_update_nodes
end

Instance Method Details

#callObject


43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/banzai/filter/references/reference_filter.rb', line 43

def call
  ref_pattern_start = /\A#{object_reference_pattern}\z/

  nodes.each_with_index do |node, index|
    if text_node?(node)
      replace_text_when_pattern_matches(node, index, object_reference_pattern) do |content|
        object_link_filter(content, object_reference_pattern)
      end
    elsif element_node?(node)
      yield_valid_link(node) do |link, inner_html|
        if link =~ ref_pattern_start
          replace_link_node_with_href(node, index, link) do
            object_link_filter(link, object_reference_pattern, link_content: inner_html)
          end
        end
      end
    end
  end

  doc
end

#call_and_update_nodesObject


39
40
41
# File 'lib/banzai/filter/references/reference_filter.rb', line 39

def call_and_update_nodes
  with_update_nodes { call }
end

#each_nodeObject

Iterates over all <a> and text() nodes in a document.

Nodes are skipped whenever their ancestor is one of the nodes returned by `ignore_ancestor_query`. Link tags are not processed if they have a “gfm” class or the “href” attribute is empty.


87
88
89
90
91
92
93
# File 'lib/banzai/filter/references/reference_filter.rb', line 87

def each_node
  return to_enum(__method__) unless block_given?

  doc.xpath(query).each do |node|
    yield node
  end
end

#groupObject


108
109
110
# File 'lib/banzai/filter/references/reference_filter.rb', line 108

def group
  context[:group]
end

#nodesObject

Returns an Array containing all HTML nodes.


96
97
98
# File 'lib/banzai/filter/references/reference_filter.rb', line 96

def nodes
  @nodes ||= each_node.to_a
end

#object_classObject


100
101
102
# File 'lib/banzai/filter/references/reference_filter.rb', line 100

def object_class
  self.class.object_class
end

#projectObject


104
105
106
# File 'lib/banzai/filter/references/reference_filter.rb', line 104

def project
  context[:project]
end

#references_in(text, pattern = object_reference_pattern) ⇒ Object

Public: Find references in text (like `!123` for merge requests)

references_in(text) do |match, id, project_ref, matches|
  object = find_object(project_ref, id)
  "<a href=...>#{object.to_reference}</a>"
end

text - String text to search.

Yields the String match, the Integer referenced object ID, an optional String of the external project reference, and all of the matchdata.

Returns a String replaced with the return of the block.

Raises:

  • (NotImplementedError)

78
79
80
# File 'lib/banzai/filter/references/reference_filter.rb', line 78

def references_in(text, pattern = object_reference_pattern)
  raise NotImplementedError, "#{self.class} must implement method: #{__callee__}"
end

#requires_unescaping?Boolean

Returns:

  • (Boolean)

112
113
114
# File 'lib/banzai/filter/references/reference_filter.rb', line 112

def requires_unescaping?
  false
end