Class: MathTypeToMathMLPlus::Mover

Inherits:
Object
  • Object
show all
Defined in:
lib/mathtype_to_mathml_plus/mover.rb

Constant Summary collapse

PARENS_SELECTOR =
"selector='tmPARENS' or "\
"selector='tmBRACK' or " \
"selector='tmBRACE' or " \
"selector='tmOBRACK' or " \
"selector='tmOBRACE' or " \
"selector='tmHBRACK' or " \
"selector='tmHBRACE'"
SUBSUP_SELECTOR =
"selector='tmSUP' or " \
"selector='tmSUB' or " \
"selector='tmSUBSUP'"
PRE =
"variation='tvSU_PRECEDES'"
OPEN_PAREN =
"mt_code_value = '0x0028' or " \
"mt_code_value = '0x005B' or " \
"mt_code_value = '0x007B'"
CLOSE_PAREN =
"mt_code_value = '0x0029' or " \
"mt_code_value = '0x005D' or " \
"mt_code_value = '0x007D'"
OPEN_CLOSE_PAIRS =
{
  "0x0028" => "0x0029", # ( )

  "0x005B" => "0x005D", # [ ]

  "0x007B" => "0x007D", # { }

}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(mathtype) ⇒ Mover

Returns a new instance of Mover.



56
57
58
59
# File 'lib/mathtype_to_mathml_plus/mover.rb', line 56

def initialize(mathtype)
  @mathtype = mathtype
  @last_preceding_siblings = Nokogiri::XML::NodeSet.new(@mathtype)
end

Instance Attribute Details

#last_preceding_siblingsObject

Returns the value of attribute last_preceding_siblings.



26
27
28
# File 'lib/mathtype_to_mathml_plus/mover.rb', line 26

def last_preceding_siblings
  @last_preceding_siblings
end

#mathtypeObject (readonly)

Returns the value of attribute mathtype.



25
26
27
# File 'lib/mathtype_to_mathml_plus/mover.rb', line 25

def mathtype
  @mathtype
end

Instance Method Details

#invert_char_embellObject



131
132
133
134
135
136
137
138
139
# File 'lib/mathtype_to_mathml_plus/mover.rb', line 131

def invert_char_embell
  # Invert char -> embell to embell -> char.

  mathtype.xpath("//char[embell]").each do |el|
    embell = el.xpath("embell").first.remove
    char = el.clone
    char.parent = embell
    el.replace(embell)
  end
end

#moveObject



141
142
143
144
145
# File 'lib/mathtype_to_mathml_plus/mover.rb', line 141

def move
  move_following_subsup
  move_preceding_subsup
  invert_char_embell
end

#move_following_subsupObject



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/mathtype_to_mathml_plus/mover.rb', line 87

def move_following_subsup
  mathtype.xpath("//tmpl[(#{SUBSUP_SELECTOR}) and not(#{PRE})]").each do |el|
    siblings = new_preceding_siblings(el)

    node = Nokogiri::XML::Node.new "slot", mathtype

    if siblings.last.xpath(CLOSE_PAREN)
      siblings = siblings.reverse.take_while do |sibling|
        !sibling.next_element.xpath(OPEN_PAREN)
      end.reverse

      move_paren(siblings, node)
    elsif siblings.last.xpath("self::tmpl[#{PARENS_SELECTOR}]")
      siblings.last.parent = node
    else
      siblings.last.parent = node
    end

    el.at_css("slot").add_previous_sibling node
  end
end

#move_paren(siblings, node) ⇒ Object



68
69
70
71
72
73
74
# File 'lib/mathtype_to_mathml_plus/mover.rb', line 68

def move_paren(siblings, node)
  OPEN_CLOSE_PAIRS.each do |open, close|
    if siblings[0].xpath("mt_code_value = '#{open}'") # ( )

      move_until_mt_code(siblings, close, node)
    end
  end
end

#move_preceding_subsupObject



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/mathtype_to_mathml_plus/mover.rb', line 109

def move_preceding_subsup
  mathtype.xpath("//tmpl[(#{SUBSUP_SELECTOR}) and #{PRE}]").each do |el|
    siblings = new_following_siblings(el)

    node = Nokogiri::XML::Node.new "slot", mathtype

    if siblings.first.xpath(OPEN_PAREN)
      siblings = siblings.reverse.take_while do |sibling|
        !sibling.next_element.xpath(CLOSE_PAREN)
      end.reverse

      move_paren(siblings, node)
    elsif siblings.first.xpath("self::tmpl[#{PARENS_SELECTOR}]")
      siblings.first.parent = node
    else
      siblings.first.parent = node
    end

    el.at_css("slot").add_previous_sibling node
  end
end

#move_until_mt_code(elements, mt_code_value, parent) ⇒ Object



61
62
63
64
65
66
# File 'lib/mathtype_to_mathml_plus/mover.rb', line 61

def move_until_mt_code(elements, mt_code_value, parent)
  elements.each do |element|
    element.parent = parent
    break if element.xpath("mt_code_value = '#{mt_code_value}'")
  end
end

#new_following_siblings(el) ⇒ Object



83
84
85
# File 'lib/mathtype_to_mathml_plus/mover.rb', line 83

def new_following_siblings(el)
  el.xpath("following-sibling::tmpl | following-sibling::char")
end

#new_preceding_siblings(el) ⇒ Object



76
77
78
79
80
81
# File 'lib/mathtype_to_mathml_plus/mover.rb', line 76

def new_preceding_siblings(el)
  all_siblings = el.xpath("preceding-sibling::tmpl | preceding-sibling::char")
  siblings = all_siblings - last_preceding_siblings
  self.last_preceding_siblings = all_siblings
  siblings
end