Class: Docx::Elements::Containers::TextRun

Inherits:
Object
  • Object
show all
Includes:
Container, Element
Defined in:
lib/docx/containers/text_run.rb

Constant Summary collapse

DEFAULT_FORMATTING =
{
  italic:    false,
  bold:      false,
  underline: false,
  strike: false
}

Constants included from Element

Element::DEFAULT_TAG

Instance Attribute Summary collapse

Attributes included from Element

#node

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Element

#append_to, #at_xpath, #copy, #html_tag, included, #insert_after, #insert_before, #parent, #parent_paragraph, #prepend_to, #xpath

Methods included from Container

#blank!, #properties, #remove!

Constructor Details

#initialize(node, document_properties = {}) ⇒ TextRun

Returns a new instance of TextRun.



24
25
26
27
28
29
30
31
32
33
34
# File 'lib/docx/containers/text_run.rb', line 24

def initialize(node, document_properties = {})
  @node = node
  @text_nodes = @node.xpath('w:t').map {|t_node| Elements::Text.new(t_node) }
  @text_nodes = @node.xpath('w:t|w:r/w:t').map {|t_node| Elements::Text.new(t_node) }

  @properties_tag = 'rPr'
  @text       = parse_text || ''
  @formatting = parse_formatting || DEFAULT_FORMATTING
  @document_properties = document_properties
  @font_size = @document_properties[:font_size]
end

Instance Attribute Details

#formattingObject (readonly)

Returns the value of attribute formatting.



22
23
24
# File 'lib/docx/containers/text_run.rb', line 22

def formatting
  @formatting
end

#textObject

Returns the value of attribute text.



21
22
23
# File 'lib/docx/containers/text_run.rb', line 21

def text
  @text
end

Class Method Details

.tagObject



17
18
19
# File 'lib/docx/containers/text_run.rb', line 17

def self.tag
  'r'
end

Instance Method Details

#bolded?Boolean

Returns:

  • (Boolean)


105
106
107
# File 'lib/docx/containers/text_run.rb', line 105

def bolded?
  @formatting[:bold]
end

#external_link?Boolean

Returns:

  • (Boolean)


121
122
123
# File 'lib/docx/containers/text_run.rb', line 121

def external_link?
  !@node.attributes['id'].nil?
end

#font_sizeObject



133
134
135
136
137
138
139
# File 'lib/docx/containers/text_run.rb', line 133

def font_size
  size_attribute = @node.at_xpath('w:rPr//w:sz//@w:val')

  return @font_size unless size_attribute

  size_attribute.value.to_i / 2
end

#hrefObject



125
126
127
# File 'lib/docx/containers/text_run.rb', line 125

def href
  @document_properties[:hyperlinks][hyperlink_id]
end

#hyperlink?Boolean

Returns:

  • (Boolean)


117
118
119
# File 'lib/docx/containers/text_run.rb', line 117

def hyperlink?
  @node.name == 'hyperlink' && external_link?
end


129
130
131
# File 'lib/docx/containers/text_run.rb', line 129

def hyperlink_id
  @node.attributes['id'].value
end

#italicized?Boolean

Returns:

  • (Boolean)


101
102
103
# File 'lib/docx/containers/text_run.rb', line 101

def italicized?
  @formatting[:italic]
end

#parse_formattingObject



73
74
75
76
77
78
79
80
# File 'lib/docx/containers/text_run.rb', line 73

def parse_formatting
  {
    italic:    !@node.xpath('.//w:i').empty?,
    bold:      !@node.xpath('.//w:b').empty?,
    underline: !@node.xpath('.//w:u').empty?,
    strike: !@node.xpath('.//w:strike').empty?
  }
end

#parse_textObject

Returns text contained within text run



48
49
50
# File 'lib/docx/containers/text_run.rb', line 48

def parse_text
  @text_nodes.map(&:content).join('')
end

#striked?Boolean

Returns:

  • (Boolean)


109
110
111
# File 'lib/docx/containers/text_run.rb', line 109

def striked?
  @formatting[:strike]
end

#substitute(match, replacement) ⇒ Object

Substitute text in text @text_nodes



53
54
55
56
57
58
# File 'lib/docx/containers/text_run.rb', line 53

def substitute(match, replacement)
  @text_nodes.each do |text_node|
    text_node.content = text_node.content.gsub(match, replacement)
  end
  reset_text
end

#substitute_with_block(match, &block) ⇒ Object

Weird things with how $1/$2 in regex blocks are handled means we can’t just delegate block to gsub to get block, we have to do it this way, with a block that gets a MatchData, from which captures and other match data can be retrieved. ruby-doc.org/3.3.7/MatchData.html



64
65
66
67
68
69
70
71
# File 'lib/docx/containers/text_run.rb', line 64

def substitute_with_block(match, &block)
  @text_nodes.each do |text_node|
    text_node.content = text_node.content.gsub(match) { |_unused_matched_string|
      block.call(Regexp.last_match)
    }
  end
  reset_text
end

#to_htmlObject

Return text as a HTML fragment with formatting based on properties.



87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/docx/containers/text_run.rb', line 87

def to_html
  html = @text
  html = html_tag(:em, content: html) if italicized?
  html = html_tag(:strong, content: html) if bolded?
  html = html_tag(:s, content: html) if striked?
  styles = {}
  styles['text-decoration'] = 'underline' if underlined?
  # No need to be granular with font size down to the span level if it doesn't vary.

  styles['font-size'] = "#{font_size}pt" if font_size != @font_size
  html = html_tag(:span, content: html, styles: styles) unless styles.empty?
  html = html_tag(:a, content: html, attributes: {href: href, target: "_blank"}) if hyperlink?
  return html
end

#to_sObject



82
83
84
# File 'lib/docx/containers/text_run.rb', line 82

def to_s
  @text
end

#underlined?Boolean

Returns:

  • (Boolean)


113
114
115
# File 'lib/docx/containers/text_run.rb', line 113

def underlined?
  @formatting[:underline]
end