Class: Ritex::Parser

Inherits:
Racc::Parser
  • Object
show all
Defined in:
lib/ritex.rb,
lib/ritex/parser.rb

Overview

The parser for itex and the main entry point for Ritex. This class is partially defined here and partially generated by Racc from lib/parser.y.

Create the parser with #new. Parse strings with #parse. That’s all there is to it.

Constant Summary collapse

FORMATS =
[:mathml, :raw]
Racc_arg =
[
racc_action_table,
racc_action_check,
racc_action_default,
racc_action_pointer,
racc_goto_table,
racc_goto_check,
racc_goto_default,
racc_goto_pointer,
racc_nt_base,
racc_reduce_table,
racc_token_table,
racc_shift_n,
racc_reduce_n,
racc_use_result_var ]
Racc_token_to_s_table =
[
"$end",
"error",
"NUMBER",
"VAR",
"SYMBOL",
"FUNC0",
"FUNC1",
"FUNC2",
"FUNC3",
"MACRO0",
"MACRO1",
"MACRO2",
"MACRO3",
"ENV",
"DOUBLEBACK",
"DEFINE",
"LEFT",
"RIGHT",
"ARRAY",
"ARRAYOPTS",
"ROWOPTS",
"CELLOPTS",
"COLALIGN",
"ROWALIGN",
"ALIGN",
"PADDING",
"EQUALCOLS",
"EQUALROWS",
"ROWLINES",
"COLLINES",
"FRAME",
"ROWSPAN",
"COLSPAN",
"SPACE",
"OPERATOR",
"\"-\"",
"\"^\"",
"\"_\"",
"\"{\"",
"\"}\"",
"\".\"",
"\"[\"",
"\"]\"",
"\"&\"",
"\",\"",
"\";\"",
"\":\"",
"\"<\"",
"\">\"",
"\"=\"",
"\"#\"",
"\"!\"",
"\"+\"",
"\"*\"",
"\"/\"",
"\"(\"",
"\")\"",
"\"|\"",
"$start",
"exp",
"atom",
"nontoken",
"subsup",
"symbol",
"func",
"macro",
"arg",
"array",
"macrodef",
"delim",
"token",
"string",
"stringel",
"escapeme",
"rawtoken",
"rawdelimtoken",
"symspec",
"arrayopts",
"ainnards",
"arrayoptsinnards",
"arow",
"arow1",
"acell",
"cellopts",
"celloptsinnards" ]
Racc_debug_parser =
false

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(format = :mathml) ⇒ Parser

format is the desired output format and must be in the FORMATS list. Right now that’s just :mathml.



39
40
41
42
43
# File 'lib/ritex.rb', line 39

def initialize format = :mathml
  self.format = format
  @macros = {}
  @merror = false
end

Instance Attribute Details

#formatObject

Returns the value of attribute format.



67
68
69
# File 'lib/ritex.rb', line 67

def format
  @format
end

#merrorObject

If true, Ritex will output a <merror>…</merror> message in the MathML if an unknown entity is encountered. If false (the default), Ritex will throw a Ritex::Error.



35
36
37
# File 'lib/ritex.rb', line 35

def merror
  @merror
end

Instance Method Details

#_reduce_none(val, _values, result) ⇒ Object



1181
1182
1183
# File 'lib/ritex/parser.rb', line 1181

def _reduce_none(val, _values, result)
  val[0]
end

#envsObject

:nodoc:



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

def envs #:nodoc:
  case @format
  when :mathml, :raw; MathML::ENVS
  end
end

#flush_macrosObject

Delete all macros



74
# File 'lib/ritex.rb', line 74

def flush_macros; @macros = {}; end

#funcsObject

:nodoc:



135
136
137
138
139
# File 'lib/ritex.rb', line 135

def funcs #:nodoc:
  case @format
  when :mathml, :raw; MathML::FUNCTIONS
  end
end

#handle_mathml_markup(what, tag, opts) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/ritex.rb', line 83

def handle_mathml_markup what, tag, opts
  tag, opts = case tag
    when String
      [tag, opts]
    when Symbol
      a, b = MathML::MARKUP[tag]
      [a, [b, opts].flatten.compact.join(" ")]
    end
  unless opts.empty?
    "<#{tag} #{opts}>#{what}</#{tag}>"
  else
    "<#{tag}>#{what}</#{tag}>"
  end
end

#handle_raw_markup(what, tag, opts) ⇒ Object

this is a great example of how much a horrible hack raw mode is



99
100
101
102
103
104
105
106
107
108
109
# File 'lib/ritex.rb', line 99

def handle_raw_markup what, tag, opts #:nodoc:
  case tag
  when :var; what
  when :subsup; "#{what[0]}_#{what[1]}^#{what[2]}"
  when :sub; "#{what[0]}_#{what[1]}"
  when :sup; "#{what[0]}^#{what[1]}"
  when :unaryminus; "-#{what[0]}"
  when :group; "{#{raw_blob_to_string what}}"
  else; what
  end
end

#lookup(sym) ⇒ Object

:nodoc:



111
112
113
114
115
116
117
118
119
# File 'lib/ritex.rb', line 111

def lookup sym #:nodoc:
  case @format
  when :mathml
    return error("unknown entity #{sym.inspect}") unless MathML::ENTITIES.member? sym
    MathML::ENTITIES[sym]
  when :raw
    "\\" + sym
  end
end

#macrosObject

:nodoc:



147
148
149
# File 'lib/ritex.rb', line 147

def macros #:nodoc:
  @macros
end

#markup(what, tag, opts = []) ⇒ Object

:nodoc:



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

def markup what, tag, opts=[] #:nodoc:
  case @format
  when :mathml; handle_mathml_markup what, tag, opts
  when :raw; handle_raw_markup what, tag, opts
  end
end

#op(o, opts = []) ⇒ Object



128
129
130
131
132
133
# File 'lib/ritex.rb', line 128

def op o, opts=[]
  case @format
  when :mathml; markup(token(o), "mo", opts)
  when :raw; o
  end
end

#op_symbolsObject

:nodoc:



151
152
153
154
155
# File 'lib/ritex.rb', line 151

def op_symbols #:nodoc:
  case @format
  when :mathml, :raw; MathML::OPERATORS.merge(MathML::UNARY_OPERATORS).merge(MathML::MATH_FUNCTIONS)
  end
end

#parse(s, opts = {}) ⇒ Object

Parse a string. Returns the MathML output in string form. Note that macro definitions are cumulative and persistent across calls to #parse. If you don’t want this behavior, you must explicitly call #flush_macros after every #parse call.

opts is a hash of options:

nowrap, if true, will omit wrapping the output in a top-level XML math tag. Only useful if you’re generating these tags yourself.

display, if true, emits display markup, as opposed to inline markup. For mathml output this only has an effect if nowrap is true.



57
58
59
60
61
62
63
64
65
# File 'lib/ritex.rb', line 57

def parse s, opts={}
  nowrap = opts[:nowrap]
  display = opts[:display]
  @lex = Lexer.new self, s
  r = yyparse @lex, :lex
  r = markup r, (display ? :displaymath : :math) unless nowrap
  r = raw_blob_to_string(r) if @format == :raw
  r
end

#token(o) ⇒ Object

:nodoc:



121
122
123
124
125
126
# File 'lib/ritex.rb', line 121

def token o #:nodoc:
  case @format
  when :mathml; MathML::TOKENS[o] || o
  when :raw; o
  end
end