Class: DocTemplate::Tags::BaseTag

Inherits:
Object
  • Object
show all
Defined in:
lib/doc_template/tags/base_tag.rb

Constant Summary collapse

SOFT_RETURN_RE =
/([[:graph:]]+\[|\][[:graph:]]+)/.freeze
UNICODE_SPACES_RE =
/(\u0020|\u00A0|\u1680|\u180E|[\u2000-\u200B]|\u202F|\u205F|\u3000|\uFEFF)/.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#anchorObject (readonly)

Returns the value of attribute anchor.



9
10
11
# File 'lib/doc_template/tags/base_tag.rb', line 9

def anchor
  @anchor
end

#contentObject (readonly)

Returns the value of attribute content.



9
10
11
# File 'lib/doc_template/tags/base_tag.rb', line 9

def content
  @content
end

Class Method Details

.parse(node, opts = {}) ⇒ Object



12
13
14
# File 'lib/doc_template/tags/base_tag.rb', line 12

def parse(node, opts = {})
  new.parse(node, opts)
end

.tag_with_html_regexpObject

Raises:

  • (NotImplementedError)


16
17
18
19
20
# File 'lib/doc_template/tags/base_tag.rb', line 16

def tag_with_html_regexp
  raise NotImplementedError unless const_defined?(:TAG_NAME)

  @tag_with_html_regexp ||= /\[[^\]]*#{self::TAG_NAME}[[^:,;.]]*:?\s?[^\]]*\]/i
end

.template_path_for(name) ⇒ Object



22
23
24
# File 'lib/doc_template/tags/base_tag.rb', line 22

def template_path_for(name)
  File.join ::Lcms::Engine::Engine.root.join('lib', 'doc_template', 'templates'), name
end

Instance Method Details

#before_tag(node) ⇒ Object

Precede the specified element with tag’s placeholder



30
31
32
# File 'lib/doc_template/tags/base_tag.rb', line 30

def before_tag(node)
  node.before Nokogiri::HTML.fragment(placeholder)
end

#check_tag_soft_return(node) ⇒ Object



34
35
36
37
38
39
40
# File 'lib/doc_template/tags/base_tag.rb', line 34

def check_tag_soft_return(node)
  # need to remove unicode spaces bc they're not handled by [[:graph:]]
  return unless node.content.gsub(UNICODE_SPACES_RE, '') =~ SOFT_RETURN_RE

  raise ::Lcms::Engine::DocumentError,
        "Soft return for #{self.class::TAG_NAME} detected: #{node.content}, use hard return instead"
end

#content_until_break(node) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
# File 'lib/doc_template/tags/base_tag.rb', line 42

def content_until_break(node)
  [].tap do |result|
    check_tag_soft_return(node)
    while (sibling = node.next_sibling)
      break if include_break?(sibling)

      result << sibling.to_html
      sibling.remove
    end
  end.join
end

#content_until_materials(node) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
# File 'lib/doc_template/tags/base_tag.rb', line 54

def content_until_materials(node)
  [].tap do |result|
    check_tag_soft_return(node)
    while (sibling = node.next_sibling)
      break if include_break_for?(sibling, 'stop_materials_tags')

      result << sibling.to_html
      sibling.remove
    end
  end.join
end

#ela2?(metadata) ⇒ Boolean

Returns:

  • (Boolean)


66
67
68
# File 'lib/doc_template/tags/base_tag.rb', line 66

def ela2?()
  .resource_subject == 'ela' && .grade == '2'
end

#ela6?(metadata) ⇒ Boolean

Returns:

  • (Boolean)


70
71
72
# File 'lib/doc_template/tags/base_tag.rb', line 70

def ela6?()
  .resource_subject == 'ela' && .grade == '6'
end

#gdoc?(opts) ⇒ Boolean

Returns:

  • (Boolean)


74
75
76
# File 'lib/doc_template/tags/base_tag.rb', line 74

def gdoc?(opts)
  opts[:context_type].to_s.casecmp('gdoc').zero?
end

#include_break?(node) ⇒ Boolean

Returns:

  • (Boolean)


78
79
80
# File 'lib/doc_template/tags/base_tag.rb', line 78

def include_break?(node)
  include_break_for? node, 'stop_tags'
end

#include_break_for?(node, key) ⇒ Boolean

Returns:

  • (Boolean)


82
83
84
85
86
87
88
89
90
91
# File 'lib/doc_template/tags/base_tag.rb', line 82

def include_break_for?(node, key)
  stop_tags = Array.wrap ::DocTemplate::Tags.config[self.class::TAG_NAME.downcase][key]
  return false if stop_tags.empty?

  tags = stop_tags.map { |t| ::DocTemplate::Tags.const_get(t)::TAG_NAME }.join('|')

  result = node.content =~ /\[\s*(#{tags})/i
  check_tag_soft_return(node) if result
  result
end

#materialsObject



93
94
95
# File 'lib/doc_template/tags/base_tag.rb', line 93

def materials
  @materials || []
end

#parse(node, _options = {}) ⇒ Object



97
98
99
100
101
# File 'lib/doc_template/tags/base_tag.rb', line 97

def parse(node, _options = {})
  @result = node
  remove_tag
  self
end

#parse_nested(node, opts = {}) ⇒ Object



103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/doc_template/tags/base_tag.rb', line 103

def parse_nested(node, opts = {})
  if node == opts[:parent_node]
    opts[:iteration] = opts[:iteration].to_i + 1
    if opts[:iteration] > DocTemplate::Document::MAX_PARSE_ITERATIONS
      raise ::Lcms::Engine::DocumentError, "Loop detected for node:<br>#{node}"
    end
  end
  parsed = ::DocTemplate::Document.parse(Nokogiri::HTML.fragment(node), opts.merge(level: 1))
  # add the parts to the parent document
  opts[:parent_document].parts += parsed.parts if opts[:parent_document]
  parsed.render
end

#parse_template(context, template_name) ⇒ Object



116
117
118
119
120
# File 'lib/doc_template/tags/base_tag.rb', line 116

def parse_template(context, template_name)
  @tmpl = context
  template = File.read template_path(template_name)
  ERB.new(template).result(binding)
end

#placeholderObject



122
123
124
# File 'lib/doc_template/tags/base_tag.rb', line 122

def placeholder
  @placeholder ||= "{{#{placeholder_id}}}"
end

#placeholder_idObject



126
127
128
# File 'lib/doc_template/tags/base_tag.rb', line 126

def placeholder_id
  @placeholder_id ||= "#{self.class.name.demodulize.underscore}_#{SecureRandom.hex(10)}"
end

#renderObject



130
131
132
# File 'lib/doc_template/tags/base_tag.rb', line 130

def render
  @result.to_s.presence || placeholder
end

#replace_tag(node) ⇒ Object

Replace the tag element with its placeholder. Or inline the tag if requested



138
139
140
141
# File 'lib/doc_template/tags/base_tag.rb', line 138

def replace_tag(node)
  replacement = @opts&.[](:explicit_render) ? content : Nokogiri::HTML.fragment(placeholder)
  node.replace replacement
end

#tag_dataObject



143
144
145
# File 'lib/doc_template/tags/base_tag.rb', line 143

def tag_data
  {}
end

#template_name(opts) ⇒ Object

First look for the template override inside possible gems And use standard one if not found



151
152
153
154
155
156
# File 'lib/doc_template/tags/base_tag.rb', line 151

def template_name(opts)
  context = opts.fetch(:context_type, :default).to_s
  override =
    ::DocTemplate::Tags.config.dig(self.class::TAG_NAME.to_s.downcase, 'templates', context)
  override.presence || self.class::TEMPLATES[context.to_sym]
end

#template_path(name) ⇒ Object



158
159
160
161
162
163
164
# File 'lib/doc_template/tags/base_tag.rb', line 158

def template_path(name)
  custom_path =
    Array.wrap(::DocTemplate::Tags.config['templates_paths']).detect do |path|
      File.exist?(File.join path.to_s, name)
    end
  custom_path.present? ? File.join(custom_path, name) : self.class.template_path_for(name)
end