Class: DocTemplate::Tables::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/doc_template/tables/base.rb

Constant Summary collapse

SPLIT_REGEX =
/[,;\r\n]/.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeBase

Returns a new instance of Base.



14
15
16
17
18
# File 'lib/doc_template/tables/base.rb', line 14

def initialize
  @data = {}
  @errors = []
  @table_exists = false
end

Instance Attribute Details

#dataObject (readonly)

Returns the value of attribute data.



8
9
10
# File 'lib/doc_template/tables/base.rb', line 8

def data
  @data
end

#errorsObject (readonly)

Returns the value of attribute errors.



8
9
10
# File 'lib/doc_template/tables/base.rb', line 8

def errors
  @errors
end

Class Method Details

.parse(fragment, *args) ⇒ Object



10
11
12
# File 'lib/doc_template/tables/base.rb', line 10

def self.parse(fragment, *args)
  new.parse(fragment, *args)
end

Instance Method Details

#collect_and_render_tags(data, fields, opts = {}) ⇒ Object

Inside each field in ‘fields` Array splits the string by `separator` String or RegExp. Clean the each chunk and keep only clear fragment: `<p><span></span></p>`

options:

:skip_sanitize - to skip sanitization
:separator - separator to split the input
:keep_elements - +Array+ of HTML elements to keep during sanitizing

Used when field contain only tags separated with separator. If there is any other text content - use #parse_in_context

Parameters:

  • data (Hash)

    resulting hash of #parse method

  • fields (Array)

    array of fields to clean tags in

  • opts (Hash) (defaults to: {})

    Additional options

Returns:

  • modified ‘data` parameter



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/doc_template/tables/base.rb', line 38

def collect_and_render_tags(data, fields, opts = {})
  fields.each do |field|
    (data[field] = []) && next if (row = data[field]).blank?

    tags = row
             .split(opts[:separator].presence || SPLIT_REGEX)
             .map(&:squish)
             .reject(&:blank?)

    data[field] =
      tags.map do |tag|
        html = Nokogiri::HTML.fragment "<p><span>#{tag}</span></p>"
        parsed_html = DocTemplate::Document.parse(html).render.squish
        next parsed_html if opts.key?(:skip_sanitize)

        # NOTE: Allow HTML tags which present in the tag only
        keep = opts[:keep_elements] || []
        Sanitize.fragment(parsed_html, elements: keep)
      end
  end
  data
end

#fetch_materials(data, key) ⇒ Object



102
103
104
105
106
107
108
109
110
# File 'lib/doc_template/tables/base.rb', line 102

def fetch_materials(data, key)
  return data if (materials = data[key.to_s]).blank?

  data['material_ids'] =
    materials.split(SPLIT_REGEX).compact.map do |identifier|
      Lcms::Engine::Material.find_by(identifier: identifier.strip.downcase)&.id
    end.compact
  data
end

#parse(fragment, *args) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/doc_template/tables/base.rb', line 61

def parse(fragment, *args)
  @options = args.extract_options!

  # get the table
  table_key_cell = fragment.at_xpath("table//tr[1]/td[1][contains(., '#{self.class::HEADER_LABEL}')]")
  table = table_key_cell&.ancestors('table')&.first
  @table_exists = table.present?
  return self unless @table_exists

  table.search('br').each { |br| br.replace("\n") }
  @data = fetch table

  table.remove
  self
end

#parse_in_context(content, opts = {}) ⇒ Hash

Update content of the field with parsed data Generates nested Hash for each of supported context types.

Use case: In case when nested Tags should be parsed differently for different context types we need explicitly specify each supported context type.

Parameters:

  • content (String)

    HTML content to parse and render tags from

  • opts (Hash) (defaults to: {})

    Additional options

Returns:

  • (Hash)

    nested Hash for each of supported context types



88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/doc_template/tables/base.rb', line 88

def parse_in_context(content, opts = {})
  # do not generate parts placeholder - inline all the tags
  opts[:explicit_render] = true
  html = Nokogiri::HTML.fragment content

  {}.tap do |result|
    ::DocTemplate.context_types.each do |context_type|
      opts[:context_type] = context_type
      rendered_content = DocTemplate::Document.parse(html.dup, opts).render
      result[context_type] = DocTemplate.sanitizer.post_processing(rendered_content, opts)
    end
  end
end

#table_exist?Boolean

Returns:

  • (Boolean)


112
113
114
# File 'lib/doc_template/tables/base.rb', line 112

def table_exist?
  table_exists
end