lib/plurimath/latex/transform.rb in plurimath-0.2.1 vs lib/plurimath/latex/transform.rb in plurimath-0.2.2
- old
+ new
@@ -1,44 +1,60 @@
# frozen_string_literal: true
module Plurimath
class Latex
class Transform < Parslet::Transform
- rule(base: simple(:base)) { base }
- rule(over: simple(:over)) { over }
- rule(number: simple(:num)) { Math::Number.new(num) }
- rule(power: simple(:power)) { power }
- rule(unary: simple(:unary)) { Utility.get_class(unary).new }
- rule(operant: simple(:oper)) { Math::Symbol.new(oper) }
- rule("\\\\": simple(:slash)) { Math::Symbol.new(slash) }
- rule(limits: simple(:limits)) { limits }
+ rule(base: simple(:base)) { base }
+ rule(over: simple(:over)) { over }
+ rule(number: simple(:num)) { Math::Number.new(num) }
+ rule(power: simple(:power)) { power }
+ rule(unary: simple(:unary)) { Utility.get_class(unary).new }
+ rule(space: simple(:space)) { Math::Function::Text.new(" ") }
+ rule(operant: simple(:oper)) { Math::Symbol.new(oper) }
+ rule(symbol: simple(:symbol)) { Math::Symbol.new(symbol) }
+ rule(lparen: simple(:lparen)) { Math::Symbol.new(lparen) }
+ rule(rparen: simple(:rparen)) { Math::Symbol.new(rparen) }
+ rule(limits: simple(:limits)) { limits }
+ rule("\\\\" => simple(:slash)) { Math::Symbol.new(slash) }
+ rule(expression: simple(:expr)) { expr }
+ rule(environment: simple(:env)) { env }
rule(unary_functions: simple(:unary)) { unary }
rule(left_right: simple(:left_right)) { left_right }
rule(under_over: simple(:under_over)) { under_over }
rule(power_base: simple(:power_base)) { power_base }
rule(table_data: simple(:table_data)) { table_data }
- rule(environment: simple(:environment)) { environment }
+ rule(numeric_values: simple(:value)) do
+ Math::Symbol.new(value)
+ end
rule(text: simple(:text)) do
Math::Function::Text.new(text)
end
+ rule(unicode_symbols: simple(:unicode)) do
+ Math::Unicode.new(unicode)
+ end
+
rule(binary: simple(:binary)) do
- binary.is_a?(String) ? Math::Function::Text.new(binary) : binary
+ binary.is_a?(Parslet::Slice) ? Utility.get_class(binary).new : binary
end
rule(symbols: simple(:sym)) do
- Math::Symbol.new(
- Constants::SYMBOLS[sym.to_sym] || sym,
- )
+ if sym.is_a?(Parslet::Slice)
+ Math::Symbol.new(
+ Constants::UNICODE_SYMBOLS[sym.to_sym] || sym,
+ )
+ else
+ sym
+ end
end
rule(lparen: simple(:lparen),
rparen: simple(:rparen)) do
- Math::Formula.new
+ []
end
rule(left_right: simple(:left_right),
subscript: simple(:subscript)) do
Math::Function::Base.new(
@@ -69,10 +85,38 @@
)
end
rule(left: simple(:left),
lparen: simple(:lparen),
+ right: simple(:right)) do
+ Math::Formula.new(
+ [
+ Math::Function::Left.new(lparen),
+ Math::Function::Right.new,
+ ],
+ )
+ end
+
+ rule(left: simple(:left),
+ lparen: simple(:lparen),
+ right: simple(:right),
+ rparen: simple(:rparen)) do
+ Math::Formula.new(
+ [
+ Math::Function::Left.new(lparen),
+ Math::Function::Right.new(rparen),
+ ],
+ )
+ end
+
+ rule(left: simple(:left),
+ lparen: simple(:lparen)) do
+ Math::Function::Left.new(lparen)
+ end
+
+ rule(left: simple(:left),
+ lparen: simple(:lparen),
expression: simple(:expr),
right: simple(:right),
rparen: simple(:rparen)) do
Math::Formula.new(
[
@@ -89,33 +133,73 @@
power,
Math::Number.new(number),
)
end
+ rule(power: simple(:power),
+ expression: simple(:expr)) do
+ Math::Function::Power.new(
+ power,
+ expr,
+ )
+ end
+
+ rule(base: simple(:base),
+ expression: simple(:expr)) do
+ Math::Function::Base.new(
+ base,
+ expr,
+ )
+ end
+
+ rule(base: simple(:base),
+ expression: sequence(:expr)) do
+ Math::Function::Base.new(
+ base,
+ Utility.filter_values(expr),
+ )
+ end
+
+ rule(power: simple(:power),
+ expression: sequence(:expr)) do
+ Math::Function::Power.new(
+ power,
+ Utility.filter_values(expr),
+ )
+ end
+
rule(left: simple(:left),
lparen: simple(:lparen),
dividend: subtree(:dividend),
- divisor: sequence(:divisor),
+ divisor: subtree(:divisor),
right: simple(:right),
rparen: simple(:rparen)) do
Math::Formula.new(
[
Math::Function::Left.new(lparen),
Math::Function::Over.new(
- Math::Formula.new(dividend.flatten),
- Math::Formula.new(divisor),
+ Math::Formula.new(
+ Array(dividend).flatten,
+ ),
+ Math::Formula.new(
+ Array(divisor).flatten,
+ ),
),
Math::Function::Right.new(rparen),
],
)
end
rule(dividend: subtree(:dividend),
divisor: subtree(:divisor)) do
Math::Function::Over.new(
- Math::Formula.new(dividend.flatten),
- Math::Formula.new(divisor.flatten),
+ Math::Formula.new(
+ Array(dividend).flatten,
+ ),
+ Math::Formula.new(
+ Array(divisor).flatten,
+ ),
)
end
rule(over: simple(:over),
subscript: simple(:subscript)) do
@@ -141,37 +225,68 @@
)
end
rule(sequence: simple(:sequence),
expression: simple(:expr)) do
- [sequence, expr]
+ [sequence, expr].compact
end
rule(sequence: simple(:sequence),
expression: sequence(:expr)) do
[sequence] + expr
end
rule(unary_functions: simple(:unary),
subscript: simple(:subscript)) do
+ unary_function = if unary.is_a?(Parslet::Slice)
+ Utility.get_class(unary).new
+ else
+ unary
+ end
Math::Function::Base.new(
+ unary_function,
+ subscript,
+ )
+ end
+
+ rule(binary_functions: simple(:binary),
+ supscript: simple(:supscript)) do
+ Math::Function::Power.new(
+ binary,
+ supscript,
+ )
+ end
+
+ rule(unary_functions: simple(:unary),
+ supscript: simple(:supscript)) do
+ Math::Function::Power.new(
unary,
+ supscript,
+ )
+ end
+
+ rule(unary_functions: simple(:unary),
+ subscript: simple(:subscript),
+ supscript: simple(:supscript)) do
+ Math::Function::PowerBase.new(
+ unary,
subscript,
+ supscript,
)
end
rule(fonts: simple(:fonts),
intermediate_exp: simple(:int_exp)) do
if Utility::FONT_STYLES[fonts.to_sym]
Utility::FONT_STYLES[fonts.to_sym].new(
int_exp,
- fonts,
+ fonts.to_s,
)
else
Math::Function::FontStyle.new(
int_exp,
- fonts,
+ fonts.to_s,
)
end
end
rule(number: simple(:number),
@@ -180,46 +295,70 @@
Math::Number.new(number),
subscript,
)
end
+ rule(number: simple(:number),
+ supscript: simple(:supscript)) do
+ Math::Function::Power.new(
+ Math::Number.new(number),
+ supscript,
+ )
+ end
+
rule(symbols: simple(:sym),
subscript: simple(:subscript)) do
Math::Function::Base.new(
Math::Symbol.new(
- Constants::SYMBOLS[sym.to_sym] || sym,
+ Constants::UNICODE_SYMBOLS[sym.to_sym] || sym,
),
subscript,
)
end
+ rule(numeric_values: simple(:value),
+ subscript: simple(:subscript)) do
+ Math::Function::Base.new(
+ Math::Symbol.new(value),
+ subscript,
+ )
+ end
+
rule(symbols: simple(:sym),
supscript: simple(:supscript)) do
Math::Function::Power.new(
Math::Symbol.new(
- Constants::SYMBOLS[sym.to_sym] || sym,
+ Constants::UNICODE_SYMBOLS[sym.to_sym] || sym,
),
supscript,
)
end
- rule(text: simple(:text),
+ rule(unicode_symbols: simple(:sym),
subscript: simple(:subscript)) do
Math::Function::Base.new(
- Math::Function::Text.new(text),
+ Math::Unicode.new(sym),
subscript,
)
end
- rule(text: simple(:text),
+ rule(unicode_symbols: simple(:sym),
supscript: simple(:supscript)) do
Math::Function::Power.new(
- Math::Function::Text.new(text),
+ Math::Unicode.new(sym),
supscript,
)
end
+ rule(numeric_values: simple(:value),
+ supscript: simple(:supscript)) do
+ Math::Function::Power.new(
+ Math::Symbol.new(value),
+ supscript,
+ )
+ end
+
rule(unary: simple(:unary),
first_value: simple(:first_value)) do
Utility.get_class(
unary == "overline" ? "bar" : unary,
).new(first_value)
@@ -234,16 +373,16 @@
intermediate_exp: simple(:int_exp),
supscript: simple(:supscript)) do
font_style = if Utility::FONT_STYLES[fonts.to_sym].nil?
Math::Function::FontStyle.new(
int_exp,
- fonts,
+ fonts.to_s,
)
else
Utility::FONT_STYLES[fonts.to_sym].new(
int_exp,
- fonts,
+ fonts.to_s,
)
end
Math::Function::Power.new(
font_style,
supscript,
@@ -254,16 +393,16 @@
intermediate_exp: simple(:int_exp),
subscript: simple(:subscript)) do
font_style = if Utility::FONT_STYLES[fonts.to_sym].nil?
Math::Function::FontStyle.new(
int_exp,
- fonts,
+ fonts.to_s,
)
else
Utility::FONT_STYLES[fonts.to_sym].new(
int_exp,
- fonts,
+ fonts.to_s,
)
end
Math::Function::Base.new(
font_style,
subscript,
@@ -271,69 +410,88 @@
end
rule(root: simple(:root),
first_value: simple(:first_value),
second_value: simple(:second_value)) do
+ second = second_value.nil? ? Math::Formula.new : second_value
Math::Function::Root.new(
first_value,
+ second,
+ )
+ end
+
+ rule(root: simple(:root),
+ first_value: sequence(:first_value),
+ second_value: simple(:second_value)) do
+ first = Utility.filter_values(first_value)
+ first = first.nil? ? Math::Formula.new : first
+ Math::Function::Root.new(
+ first,
second_value,
)
end
- rule(unary_functions: simple(:unary),
+ rule(first_value: simple(:first_value),
base: simple(:base),
power: simple(:power)) do
Math::Function::Limits.new(
- Utility.get_class(unary).new,
+ first_value,
base,
power,
)
end
rule(lparen: simple(:lparen),
- mbox: simple(:mbox),
+ expression: sequence(:expr),
rparen: simple(:rparen)) do
- Math::Function::Text.new("\\mbox{#{mbox}}")
+ Math::Formula.new(expr)
end
- rule(lparen: simple(:lparen),
- symbols: simple(:sym),
- rparen: simple(:rparen)) do
- Math::Symbol.new(
- Constants::SYMBOLS[sym.to_sym] || sym,
+ rule(expression: sequence(:expr)) do
+ Math::Formula.new(expr)
+ end
+
+ rule(rule: simple(:rule),
+ first_value: simple(:first_value),
+ second_value: simple(:second_value),
+ third_value: simple(:third_value)) do
+ Math::Function::Rule.new(
+ first_value,
+ second_value,
+ third_value,
)
end
- rule(lparen: simple(:lparen),
- expression: simple(:expr),
- rparen: simple(:rparen)) do
- expr
+ rule(expression: simple(:expression),
+ subscript: simple(:subscript)) do
+ Math::Function::Base.new(
+ expression,
+ subscript,
+ )
end
- rule(lparen: simple(:lparen),
- expression: sequence(:expr),
- rparen: simple(:rparen)) do
- Math::Formula.new(expr)
+ rule(rparen: simple(:rparen),
+ supscript: simple(:supscript)) do
+ Math::Function::Power.new(
+ Math::Symbol.new(rparen),
+ supscript,
+ )
end
- rule(lparen: simple(:lparen),
- expression: simple(:expr),
- rparen: simple(:rparen),
+ rule(expression: simple(:expr),
supscript: simple(:supscript)) do
Math::Function::Power.new(
- Math::Formula.new(expr),
+ expr,
supscript,
)
end
- rule(lparen: simple(:lparen),
- expression: simple(:expr),
- rparen: simple(:rparen),
- subscript: simple(:subscript)) do
- Math::Function::Base.new(
- Math::Formula.new(expr),
- subscript,
+ rule(expression: sequence(:expr),
+ supscript: simple(:supscript)) do
+ Math::Function::Power.new(
+ Utility.filter_values(expr),
+ supscript,
)
end
rule(binary: simple(:binary),
subscript: simple(:subscript),
@@ -344,30 +502,37 @@
)
end
rule(binary: simple(:binary),
subscript: simple(:subscript)) do
- Utility.get_class(binary).new(subscript)
+ if binary.is_a?(Parslet::Slice)
+ Utility.get_class(binary).new(subscript)
+ else
+ Math::Function::Base.new(
+ binary,
+ subscript,
+ )
+ end
end
- rule(text: simple(:text),
+ rule(symbols: simple(:sym),
subscript: simple(:subscript),
supscript: simple(:supscript)) do
Math::Function::PowerBase.new(
- Math::Function::Text.new(text),
+ Math::Symbol.new(
+ Constants::UNICODE_SYMBOLS[sym.to_sym] || sym,
+ ),
subscript,
supscript,
)
end
- rule(symbols: simple(:sym),
+ rule(unicode_symbols: simple(:sym),
subscript: simple(:subscript),
supscript: simple(:supscript)) do
Math::Function::PowerBase.new(
- Math::Symbol.new(
- Constants::SYMBOLS[sym.to_sym] || sym,
- ),
+ Math::Unicode.new(sym),
subscript,
supscript,
)
end
@@ -375,84 +540,174 @@
first_value: simple(:first_value),
second_value: simple(:second_value)) do
if binary == "binom"
Math::Function::Table.new(
[
- Math::Function::Tr.new([first_value]),
- Math::Function::Tr.new([second_value]),
+ Math::Function::Tr.new(
+ Utility.table_td(first_value),
+ ),
+ Math::Function::Tr.new(
+ Utility.table_td(second_value),
+ ),
],
"(",
")",
)
else
Utility.get_class(
- binary.include?("mod") ? "mod" : binary,
+ binary.to_s.include?("mod") ? "mod" : binary,
).new(
first_value,
second_value,
)
end
end
- rule(begining: simple(:begining),
+ rule(underover: simple(:function),
+ first_value: simple(:first),
+ subscript: simple(:subscript),
+ supscript: simple(:supscript)) do
+ Math::Function::PowerBase.new(
+ Utility.get_class(function).new(first),
+ subscript,
+ supscript,
+ )
+ end
+
+ rule(environment: simple(:environment),
table_data: sequence(:table_data),
ending: simple(:ending)) do
- Utility.get_table_class(begining).new(
+ open_paren = Constants::MATRICES[environment.to_sym]
+ Utility.get_table_class(environment).new(
Utility.organize_table(table_data),
+ open_paren,
+ Constants::MATRICES_PARENTHESIS[open_paren&.to_sym]&.to_s,
+ {},
)
end
- rule(begining: simple(:begining),
+ rule(environment: simple(:environment),
args: simple(:args),
table_data: simple(:table_data),
ending: simple(:ending)) do
- Utility.get_table_class(begining).new(
+ third_value = args ? [args] : []
+ open_paren = Constants::MATRICES[environment.to_sym]
+ table = Utility.organize_table(
+ [table_data],
+ column_align: third_value,
+ )
+ Utility.get_table_class(environment).new(
+ table,
+ open_paren,
+ Constants::MATRICES_PARENTHESIS[open_paren&.to_sym]&.to_s,
+ Utility.table_options(table),
+ )
+ end
+
+ rule(environment: simple(:environment),
+ table_data: simple(:table_data),
+ ending: simple(:ending)) do
+ open_paren = Constants::MATRICES[environment.to_sym]
+ Utility.get_table_class(environment).new(
Utility.organize_table([table_data]),
- nil,
- [args],
+ open_paren,
+ Constants::MATRICES_PARENTHESIS[open_paren&.to_sym]&.to_s,
)
end
- rule(begining: simple(:begining),
+ rule(environment: simple(:environment),
args: sequence(:args),
table_data: sequence(:table_data),
ending: simple(:ending)) do
- Utility.get_table_class(begining).new(
- Utility.organize_table(table_data),
- nil,
- args,
+ open_paren = Constants::MATRICES[environment.to_sym]
+ table = Utility.organize_table(table_data, column_align: args)
+ Utility.get_table_class(environment).new(
+ table,
+ open_paren,
+ Constants::MATRICES_PARENTHESIS[open_paren&.to_sym]&.to_s,
+ Utility.table_options(table),
)
end
- rule(begining: simple(:begining),
+ rule(environment: simple(:environment),
args: simple(:args),
table_data: sequence(:table_data),
ending: simple(:ending)) do
- Utility.get_table_class(begining).new(
+ third_value = args ? [args] : []
+ open_paren = Constants::MATRICES[environment.to_sym]
+ table = Utility.organize_table(table_data, column_align: third_value)
+ Utility.get_table_class(environment).new(
+ table,
+ open_paren,
+ Constants::MATRICES_PARENTHESIS[open_paren&.to_sym]&.to_s,
+ Utility.table_options(table),
+ )
+ end
+
+ rule(environment: simple(:environment),
+ asterisk: simple(:asterisk),
+ options: simple(:options),
+ table_data: sequence(:table_data),
+ ending: simple(:ending)) do
+ third_value = options ? [options] : []
+ open_paren = Constants::MATRICES[environment.to_sym]
+ table = Utility.organize_table(
+ table_data,
+ column_align: third_value,
+ options: true,
+ )
+ Utility.get_table_class(environment).new(
+ table,
+ open_paren,
+ Constants::MATRICES_PARENTHESIS[open_paren&.to_sym]&.to_s,
+ { asterisk: true },
+ )
+ end
+
+ rule(environment: simple(:environment),
+ asterisk: simple(:asterisk),
+ table_data: sequence(:table_data),
+ ending: simple(:ending)) do
+ open_paren = Constants::MATRICES[environment.to_sym]
+ Utility.get_table_class(environment).new(
Utility.organize_table(table_data),
- nil,
- [args],
+ open_paren,
+ Constants::MATRICES_PARENTHESIS[open_paren&.to_sym]&.to_s,
+ { asterisk: true },
)
end
rule(environment: simple(:env),
- lparen: simple(:lparen),
- expression: sequence(:expr),
- rparen: simple(:rparen)) do
- left_paren = Constants::MATRICES[env.to_sym]
- Math::Function::Table.new(
- Utility.organize_table(expr),
- left_paren,
- Constants::PARENTHESIS[left_paren],
+ expression: simple(:expr)) do
+ open_paren = Constants::MATRICES[env.to_sym]
+ Utility.get_table_class(env).new(
+ Utility.organize_table(expr.nil? ? [] : [expr]),
+ open_paren,
+ Constants::MATRICES_PARENTHESIS[open_paren&.to_sym]&.to_s,
+ {},
)
end
- rule(lparen: simple(:lparen),
- expression: sequence(:expr),
- rparen: simple(:rparen),
- supscript: simple(:supscript)) do
- formula = Math::Formula.new(expr)
- Math::Function::Power.new(formula, supscript)
+ rule(environment: simple(:env),
+ expression: sequence(:expr)) do
+ open_paren = Constants::MATRICES[env.to_sym]
+ Utility.get_table_class(env).new(
+ Utility.organize_table(expr.compact),
+ open_paren,
+ Constants::MATRICES_PARENTHESIS[open_paren&.to_sym]&.to_s,
+ {},
+ )
+ end
+
+ rule(substack: simple(:substack),
+ expression: sequence(:value)) do
+ tds = Utility.td_values(value, "\\\\")
+
+ substack_values = tds.map { |td| Math::Function::Tr.new([td]) }
+ Math::Function::Substack.new(
+ substack_values.shift,
+ substack_values.shift,
+ )
end
end
end
end