Class: Plurimath::Utility
- Inherits:
-
Object
- Object
- Plurimath::Utility
- Defined in:
- lib/plurimath/utility.rb
Constant Summary collapse
- FONT_STYLES =
{ "double-struck": Math::Function::FontStyle::DoubleStruck, "sans-serif": Math::Function::FontStyle::SansSerif, monospace: Math::Function::FontStyle::Monospace, fraktur: Math::Function::FontStyle::Fraktur, script: Math::Function::FontStyle::Script, normal: Math::Function::FontStyle::Normal, bold: Math::Function::FontStyle::Bold, mathfrak: Math::Function::FontStyle::Fraktur, mathcal: Math::Function::FontStyle::Script, mathbb: Math::Function::FontStyle::DoubleStruck, mathtt: Math::Function::FontStyle::Monospace, mathsf: Math::Function::FontStyle::SansSerif, mathrm: Math::Function::FontStyle::Normal, textrm: Math::Function::FontStyle::Normal, mathbf: Math::Function::FontStyle::Bold, textbf: Math::Function::FontStyle::Bold, bbb: Math::Function::FontStyle::DoubleStruck, cal: Math::Function::FontStyle::Script, bf: Math::Function::FontStyle::Bold, sf: Math::Function::FontStyle::SansSerif, tt: Math::Function::FontStyle::Monospace, fr: Math::Function::FontStyle::Fraktur, rm: Math::Function::FontStyle::Normal, cc: Math::Function::FontStyle::Script, ii: Math::Function::FontStyle::Italic, bb: Math::Function::FontStyle::Bold, }.freeze
- ALIGNMENT_LETTERS =
{ c: "center", r: "right", l: "left", }.freeze
- UNARY_CLASSES =
%w[ arccos arcsin arctan right sech sinh tanh cosh coth csch left max min sec sin deg det dim exp gcd glb lub tan cos cot csc ln lg ].freeze
- MUNDER_CLASSES =
%w[ ubrace obrace right max min ].freeze
- OMML_FONTS =
{ "sans-serif-bi": Math::Function::FontStyle::SansSerifBoldItalic, "sans-serif-i": Math::Function::FontStyle::SansSerifItalic, "sans-serif-b": Math::Function::FontStyle::BoldSansSerif, "double-struck": Math::Function::FontStyle::DoubleStruck, "sans-serif-p": Math::Function::FontStyle::SansSerif, "fraktur-p": Math::Function::FontStyle::Fraktur, "fraktur-b": Math::Function::FontStyle::BoldFraktur, "script-b": Math::Function::FontStyle::BoldScript, "script-p": Math::Function::FontStyle::Script, monospace: Math::Function::FontStyle::Monospace, bi: Math::Function::FontStyle::BoldItalic, p: Math::Function::FontStyle::Normal, i: Math::Function::FontStyle::Italic, b: Math::Function::FontStyle::Bold, }.freeze
- PARENTHESIS =
{ "〈": "〉", "⌊": "⌋", "⌈": "⌉", "‖": "‖", "{": "}", "[": "]", "|": "|", "(": ")", "{": "}", "[": "]", }.freeze
Class Method Summary collapse
- .attr_is_accent(attrs, value) ⇒ Object
- .attr_is_function(attrs, value) ⇒ Object
- .binary_function_classes(mrow, under: false) ⇒ Object
- .fenceable_classes(mrow = []) ⇒ Object
- .filter_table_data(table_data) ⇒ Object
- .filter_values(array) ⇒ Object
- .find_class_name(object) ⇒ Object
- .find_pos_chr(fonts_array, key) ⇒ Object
- .frac_values(object) ⇒ Object
- .get_class(text) ⇒ Object
- .get_table_class(text) ⇒ Object
- .html_entity_to_unicode(string) ⇒ Object
- .join_attr_value(attrs, value) ⇒ Object
- .left_right_objects(paren, function) ⇒ Object
- .mathml_unary_classes(text_array, omml: false) ⇒ Object
- .mrow_left_right(mrow = []) ⇒ Object
- .multiscript(values) ⇒ Object
- .nary_fonts(nary) ⇒ Object
- .organize_options(table_data, column_align) ⇒ Object
- .organize_table(array, column_align: nil, options: nil) ⇒ Object
- .organize_tds(tr_array, column_align, options) ⇒ Object
- .ox_element(node, attributes: [], namespace: "") ⇒ Object
- .paren_able?(arr = [], mrow = []) ⇒ Boolean
- .populate_function_classes(mrow = []) ⇒ Object
- .pr_element(main_tag, wi_tag = false, namespace: "") ⇒ Object
- .rpr_element(wi_tag: false) ⇒ Object
- .string_to_html_entity(string) ⇒ Object
- .sub_sup_method?(sub_sup) ⇒ Boolean
- .symbol_object(value) ⇒ Object
- .symbol_value(object, value) ⇒ Object
- .table_options(table_data) ⇒ Object
- .table_separator(separator, value, symbol: "solid") ⇒ Object
- .table_td(object) ⇒ Object
- .td_value(td_object) ⇒ Object
- .td_values(objects, slicer) ⇒ Object
- .ternary_function_classes(mrow) ⇒ Object
- .text_classes(text) ⇒ Object
- .unary_function_classes(mrow) ⇒ Object
- .unfenced_value(object) ⇒ Object
- .update_nodes(element, nodes) ⇒ Object
- .valid_class(object) ⇒ Object
- .validate_left_right(fields = []) ⇒ Object
Class Method Details
.attr_is_accent(attrs, value) ⇒ Object
366 367 368 369 370 371 372 |
# File 'lib/plurimath/utility.rb', line 366 def attr_is_accent(attrs, value) if value.last.is_a?(Math::Function::UnaryFunction) value.last.parameter_one = value.shift if value.length > 1 value.last.attributes = attrs.transform_values { |v| YAML.safe_load(v) } end value end |
.attr_is_function(attrs, value) ⇒ Object
374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 |
# File 'lib/plurimath/utility.rb', line 374 def attr_is_function(attrs, value) case attrs when Math::Function::Menclose attrs.parameter_two = filter_values(value) attrs when Math::Function::Fenced attrs.parameter_two = value.compact attrs when Math::Function::FontStyle attrs.parameter_one = filter_values(value) attrs when Math::Function::Color color_value = filter_values(value) if attrs.parameter_two attrs.parameter_two.parameter_one = color_value else attrs.parameter_two = color_value end attrs end end |
.binary_function_classes(mrow, under: false) ⇒ Object
499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 |
# File 'lib/plurimath/utility.rb', line 499 def binary_function_classes(mrow, under: false) binary_class = Math::Function::BinaryFunction mrow.each_with_index do |object, ind| mrow[ind] = mathml_unary_classes([object]) if object.is_a?(String) object = mrow[ind] next unless object.is_a?(binary_class) if object.is_a?(Math::Function::Mod) next unless mrow.length >= 1 object.parameter_one = mrow.delete_at(ind - 1) unless ind.zero? object.parameter_two = mrow.delete_at(ind) elsif Mathml::Constants::UNICODE_SYMBOLS.invert[object.class_name] && mrow.length > 1 next if object.parameter_one || mrow.length > 2 next object.parameter_one = mrow.delete_at(ind - 1) if under && ind <= 1 object.parameter_one = mrow.delete_at(ind + 1) end end end |
.fenceable_classes(mrow = []) ⇒ Object
557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 |
# File 'lib/plurimath/utility.rb', line 557 def fenceable_classes(mrow = []) return false unless mrow.length > 1 if paren_able?(PARENTHESIS, mrow) open_paren = mrow.shift close_paren = mrow.pop if mrow.length == 1 && mrow.first.is_a?(Math::Function::Table) table = mrow.first table.open_paren = open_paren.value table.close_paren = close_paren.value else mrow.replace( [ Math::Function::Fenced.new(open_paren, mrow.dup, close_paren), ], ) end end end |
.filter_table_data(table_data) ⇒ Object
166 167 168 169 170 171 172 173 174 175 |
# File 'lib/plurimath/utility.rb', line 166 def filter_table_data(table_data) table_data.each_with_index do |object, ind| if symbol_value(object, "-") table_data[ind] = Math::Formula.new( [object, table_data.delete_at(ind.next)], ) end end table_data end |
.filter_values(array) ⇒ Object
235 236 237 238 239 240 241 242 243 244 |
# File 'lib/plurimath/utility.rb', line 235 def filter_values(array) return array unless array.is_a?(Array) array = array.flatten.compact if array.length > 1 return Math::Formula.new(array) end array.first end |
.find_class_name(object) ⇒ Object
270 271 272 273 |
# File 'lib/plurimath/utility.rb', line 270 def find_class_name(object) new_object = object.value.first.parameter_one if object.is_a?(Math::Formula) get_class(new_object) unless new_object.nil? end |
.find_pos_chr(fonts_array, key) ⇒ Object
275 276 277 |
# File 'lib/plurimath/utility.rb', line 275 def find_pos_chr(fonts_array, key) fonts_array.find { |d| d.is_a?(Hash) && d[key] } end |
.frac_values(object) ⇒ Object
425 426 427 428 429 430 431 432 |
# File 'lib/plurimath/utility.rb', line 425 def frac_values(object) case object when Math::Formula object.value.any? { |d| symbol_value(d, ",") } when Array object.any? { |d| symbol_value(d, ",") } end end |
.get_class(text) ⇒ Object
189 190 191 192 193 194 |
# File 'lib/plurimath/utility.rb', line 189 def get_class(text) text = text.to_s.split("_").map(&:capitalize).join Object.const_get( "Plurimath::Math::Function::#{text}", ) end |
.get_table_class(text) ⇒ Object
177 178 179 180 181 |
# File 'lib/plurimath/utility.rb', line 177 def get_table_class(text) Object.const_get( "Plurimath::Math::Function::Table::#{text.to_s.capitalize}", ) end |
.html_entity_to_unicode(string) ⇒ Object
330 331 332 333 |
# File 'lib/plurimath/utility.rb', line 330 def html_entity_to_unicode(string) entities = HTMLEntities.new entities.decode(string) end |
.join_attr_value(attrs, value) ⇒ Object
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 |
# File 'lib/plurimath/utility.rb', line 350 def join_attr_value(attrs, value) if value.any?(String) new_value = mathml_unary_classes(value) array_value = Array(new_value) attrs.nil? ? array_value : join_attr_value(attrs, array_value) elsif attrs.nil? value elsif attrs.is_a?(String) && ["solid", "none"].include?(attrs.split.first.downcase) table_separator(attrs.split, value) elsif attrs.is_a?(Hash) && (attrs.key?(:accent) || attrs.key?(:accentunder)) attr_is_accent(attrs, value) elsif attrs.is_a?(Math::Core) attr_is_function(attrs, value) end end |
.left_right_objects(paren, function) ⇒ Object
463 464 465 466 467 468 469 470 |
# File 'lib/plurimath/utility.rb', line 463 def left_right_objects(paren, function) paren = if paren.to_s.match?(/\\{|\\}/) paren.to_s.gsub(/\\/, "") else Latex::Constants::LEFT_RIGHT_PARENTHESIS[paren.to_sym] end get_class(function).new(paren) end |
.mathml_unary_classes(text_array, omml: false) ⇒ Object
302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 |
# File 'lib/plurimath/utility.rb', line 302 def mathml_unary_classes(text_array, omml: false) return [] if text_array.empty? compacted = text_array.compact string = if compacted.count == 1 compacted.first else compacted.join end return string unless string.is_a?(String) classes = Mathml::Constants::CLASSES unicode = string_to_html_entity(string) symbol = Mathml::Constants::UNICODE_SYMBOLS[unicode.strip.to_sym] if classes.include?(symbol&.strip) get_class(symbol.strip).new elsif classes.any?(string&.strip) get_class(string.strip).new else omml ? text_classes(string) : Math::Symbol.new(unicode) end end |
.mrow_left_right(mrow = []) ⇒ Object
478 479 480 481 482 483 484 485 486 487 488 489 |
# File 'lib/plurimath/utility.rb', line 478 def mrow_left_right(mrow = []) object = mrow.first !( ( ( object.is_a?(Math::Function::TernaryFunction) && object.any_value_exist? ) && (mrow.length <= 2) ) || (object.is_a?(Math::Function::UnaryFunction) && mrow.length == 1) ) end |
.multiscript(values) ⇒ Object
396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 |
# File 'lib/plurimath/utility.rb', line 396 def multiscript(values) values.slice_before("mprescripts").map do |value| base_value = value.shift part_val = value.partition.with_index { |_, i| i.even? } first_value = part_val[0].empty? ? nil : filter_values(part_val[0]) second_value = part_val[1].empty? ? nil : filter_values(part_val[1]) if base_value.to_s.include?("mprescripts") [first_value, second_value] else Math::Function::PowerBase.new( base_value, first_value, second_value, ) end end end |
.nary_fonts(nary) ⇒ Object
259 260 261 262 263 264 265 266 267 268 |
# File 'lib/plurimath/utility.rb', line 259 def nary_fonts(nary) narypr = nary.first.flatten.compact subsup = narypr.any?("undOvr") ? "underover" : "power_base" unicode = narypr.any?(Hash) ? narypr.first[:chr] : "∫" get_class(subsup).new( Math::Symbol.new(string_to_html_entity(unicode)), nary[1], nary[2], ) end |
.organize_options(table_data, column_align) ⇒ Object
134 135 136 137 138 139 140 |
# File 'lib/plurimath/utility.rb', line 134 def (table_data, column_align) return column_align if column_align.length <= 1 align = [column_align&.shift] table_data.insert(0, *column_align) align end |
.organize_table(array, column_align: nil, options: nil) ⇒ Object
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/plurimath/utility.rb', line 105 def organize_table(array, column_align: nil, options: nil) table = [] table_data = [] table_row = [] table_separators = ["&", "\\\\"].freeze (array, column_align) if string_columns = column_align&.map(&:value) array.each do |data| if data.is_a?(Math::Symbol) && table_separators.include?(data.value) table_row << Math::Function::Td.new(filter_table_data(table_data).compact) table_data = [] if data.value == "\\\\" organize_tds(table_row.flatten, string_columns.dup, ) table << Math::Function::Tr.new(table_row) table_row = [] end next end table_data << data end table_row << Math::Function::Td.new(table_data.compact) if table_data unless table_row.nil? || table_row.empty? organize_tds(table_row.flatten, string_columns.dup, ) table << Math::Function::Tr.new(table_row) end table_separator(string_columns, table, symbol: "|") unless column_align.nil? || column_align.empty? table end |
.organize_tds(tr_array, column_align, options) ⇒ Object
155 156 157 158 159 160 161 162 163 164 |
# File 'lib/plurimath/utility.rb', line 155 def organize_tds(tr_array, column_align, ) return tr_array if column_align.nil? || column_align.empty? column_align.reject! { |string| string == "|" } column_align = column_align * tr_array.length if tr_array.map.with_index do |td, ind| columnalign = ALIGNMENT_LETTERS[column_align[ind]&.to_sym] td.parameter_two = { columnalign: columnalign } if columnalign end end |
.ox_element(node, attributes: [], namespace: "") ⇒ Object
196 197 198 199 200 201 202 203 204 |
# File 'lib/plurimath/utility.rb', line 196 def ox_element(node, attributes: [], namespace: "") namespace = "#{namespace}:" unless namespace.empty? element = Ox::Element.new("#{namespace}#{node}") attributes&.each do |attr_key, attr_value| element[attr_key] = attr_value end element end |
.paren_able?(arr = [], mrow = []) ⇒ Boolean
551 552 553 554 555 |
# File 'lib/plurimath/utility.rb', line 551 def paren_able?(arr = [], mrow = []) arr.any? do |opening, closing| symbol_value(mrow.first, opening.to_s) && symbol_value(mrow.last, closing.to_s) end end |
.populate_function_classes(mrow = []) ⇒ Object
491 492 493 494 495 496 497 |
# File 'lib/plurimath/utility.rb', line 491 def populate_function_classes(mrow = []) flatten_mrow = mrow.flatten.compact unary_function_classes(flatten_mrow) binary_function_classes(flatten_mrow) ternary_function_classes(flatten_mrow) flatten_mrow end |
.pr_element(main_tag, wi_tag = false, namespace: "") ⇒ Object
227 228 229 230 231 232 233 |
# File 'lib/plurimath/utility.rb', line 227 def pr_element(main_tag, wi_tag = false, namespace: "") tag_name = "#{main_tag}Pr" ox_element( tag_name, namespace: namespace, ) << rpr_element(wi_tag: wi_tag) end |
.rpr_element(wi_tag: false) ⇒ Object
206 207 208 209 210 211 212 213 214 215 216 |
# File 'lib/plurimath/utility.rb', line 206 def rpr_element(wi_tag: false) rpr_element = ox_element("rPr", namespace: "w") attributes = { "w:ascii": "Cambria Math", "w:hAnsi": "Cambria Math" } rpr_element << ox_element( "rFonts", namespace: "w", attributes: attributes, ) rpr_element << ox_element("i", namespace: "w") if wi_tag rpr_element end |
.string_to_html_entity(string) ⇒ Object
325 326 327 328 |
# File 'lib/plurimath/utility.rb', line 325 def string_to_html_entity(string) entities = HTMLEntities.new entities.encode(string, :hexadecimal) end |
.sub_sup_method?(sub_sup) ⇒ Boolean
183 184 185 186 187 |
# File 'lib/plurimath/utility.rb', line 183 def sub_sup_method?(sub_sup) if sub_sup.methods.include?(:class_name) Html::Constants::SUB_SUP_CLASSES.value?(sub_sup.class_name.to_sym) end end |
.symbol_object(value) ⇒ Object
444 445 446 447 448 449 450 451 452 453 |
# File 'lib/plurimath/utility.rb', line 444 def symbol_object(value) value = case value when "ℒ" then "{:" when "ℛ" then ":}" when "ᑕ" then "〈" when "ᑐ" then "〉" else value end Math::Symbol.new(value) end |
.symbol_value(object, value) ⇒ Object
290 291 292 |
# File 'lib/plurimath/utility.rb', line 290 def symbol_value(object, value) object.is_a?(Math::Symbol) && object.value.include?(value) end |
.table_options(table_data) ⇒ Object
142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/plurimath/utility.rb', line 142 def (table_data) rowline = "" table_data.map do |tr| if symbol_value(tr&.parameter_one&.first&.parameter_one&.first, "⎯") rowline += "solid " else rowline += "none " end end = { rowline: rowline.strip } if rowline.include?("solid") || {} end |
.table_separator(separator, value, symbol: "solid") ⇒ Object
335 336 337 338 339 340 341 342 343 344 345 346 347 348 |
# File 'lib/plurimath/utility.rb', line 335 def table_separator(separator, value, symbol: "solid") sep_symbol = Math::Function::Td.new([Math::Symbol.new("|")]) separator&.each_with_index do |sep, ind| next unless sep == symbol value.map do |val| val.parameter_one.insert((ind + 1), sep_symbol) if symbol == "solid" val.parameter_one.insert(ind, sep_symbol) if symbol == "|" (val.parameter_one[val.parameter_one.index(nil)] = Math::Function::Td.new([])) rescue nil val end end value end |
.table_td(object) ⇒ Object
434 435 436 437 438 439 440 441 442 |
# File 'lib/plurimath/utility.rb', line 434 def table_td(object) new_object = case object when Math::Function::Td object else Math::Function::Td.new([object]) end Array(new_object) end |
.td_value(td_object) ⇒ Object
294 295 296 297 298 299 300 |
# File 'lib/plurimath/utility.rb', line 294 def td_value(td_object) if td_object.is_a?(String) && td_object.empty? return Math::Function::Text.new(nil) end td_object end |
.td_values(objects, slicer) ⇒ Object
279 280 281 282 283 284 285 286 287 288 |
# File 'lib/plurimath/utility.rb', line 279 def td_values(objects, slicer) sliced = objects.slice_when { |object, _| symbol_value(object, slicer) } tds = sliced.map do |slice| Math::Function::Td.new( slice.delete_if { |d| symbol_value(d, slicer) }.compact, ) end tds << Math::Function::Td.new([]) if symbol_value(objects.last, slicer) tds end |
.ternary_function_classes(mrow) ⇒ Object
536 537 538 539 540 541 542 543 544 545 546 547 548 549 |
# File 'lib/plurimath/utility.rb', line 536 def ternary_function_classes(mrow) ternary_class = Math::Function::TernaryFunction if mrow.any?(ternary_class) && mrow.length > 1 mrow.each_with_index do |object, ind| if object.is_a?(ternary_class) next if [Math::Function::Fenced, Math::Function::Multiscript].include?(object.class) next unless object.parameter_one || object.parameter_two next if object.parameter_three object.parameter_three = filter_values(mrow.delete_at(ind + 1)) end end end end |
.text_classes(text) ⇒ Object
246 247 248 249 250 251 252 253 254 255 256 257 |
# File 'lib/plurimath/utility.rb', line 246 def text_classes(text) return nil if text&.empty? text = filter_values(text) unless text.is_a?(String) if text&.scan(/[[:digit:]]/)&.length == text&.length Math::Number.new(text) elsif text&.match?(/[a-zA-Z]/) Math::Function::Text.new(text) else Math::Symbol.new(text) end end |
.unary_function_classes(mrow) ⇒ Object
520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 |
# File 'lib/plurimath/utility.rb', line 520 def unary_function_classes(mrow) unary_class = Math::Function::UnaryFunction if mrow.any?(String) || mrow.any?(unary_class) mrow.each_with_index do |object, ind| mrow[ind] = mathml_unary_classes([object]) if object.is_a?(String) object = mrow[ind] if object.is_a?(String) next unless object.is_a?(unary_class) next if object.is_a?(Math::Function::Text) next if object.parameter_one || mrow[ind + 1].nil? next unless ind.zero? object.parameter_one = mrow.delete_at(ind + 1) end end end |
.unfenced_value(object) ⇒ Object
414 415 416 417 418 419 420 421 422 423 |
# File 'lib/plurimath/utility.rb', line 414 def unfenced_value(object) case object when Math::Function::Fenced filter_values(object.parameter_two) when Array filter_values(object) else object end end |
.update_nodes(element, nodes) ⇒ Object
218 219 220 221 222 223 224 225 |
# File 'lib/plurimath/utility.rb', line 218 def update_nodes(element, nodes) nodes&.each do |node| next update_nodes(element, node) if node.is_a?(Array) element << node unless node.nil? end element end |