Bring up to current.
This commit is contained in:
parent
69b62b6f33
commit
b19e1e4f47
71 changed files with 8305 additions and 39 deletions
10
lib/maruku/ext/math.rb
Normal file
10
lib/maruku/ext/math.rb
Normal file
|
@ -0,0 +1,10 @@
|
|||
|
||||
|
||||
require 'maruku/ext/math/elements'
|
||||
require 'maruku/ext/math/parsing'
|
||||
require 'maruku/ext/math/to_latex'
|
||||
require 'maruku/ext/math/to_html'
|
||||
|
||||
require 'maruku/ext/math/mathml_engines/none'
|
||||
require 'maruku/ext/math/mathml_engines/ritex'
|
||||
require 'maruku/ext/math/mathml_engines/itex2mml'
|
26
lib/maruku/ext/math/elements.rb
Normal file
26
lib/maruku/ext/math/elements.rb
Normal file
|
@ -0,0 +1,26 @@
|
|||
module MaRuKu; class MDElement
|
||||
|
||||
def md_inline_math(math)
|
||||
self.md_el(:inline_math, [], meta={:math=>math})
|
||||
end
|
||||
|
||||
def md_equation(math, label=nil)
|
||||
reglabel= /\\label\{(\w+)\}/
|
||||
if math =~ reglabel
|
||||
label = $1
|
||||
math.gsub!(reglabel,'')
|
||||
end
|
||||
# puts "Found label = #{label} math #{math.inspect} "
|
||||
num = nil
|
||||
if label && @doc #take number
|
||||
@doc.eqid2eq ||= {}
|
||||
num = @doc.eqid2eq.size + 1
|
||||
end
|
||||
e = self.md_el(:equation, [], meta={:math=>math, :label=>label,:num=>num})
|
||||
if label && @doc #take number
|
||||
@doc.eqid2eq[label] = e
|
||||
end
|
||||
e
|
||||
end
|
||||
|
||||
end end
|
35
lib/maruku/ext/math/mathml_engines/itex2mml.rb
Normal file
35
lib/maruku/ext/math/mathml_engines/itex2mml.rb
Normal file
|
@ -0,0 +1,35 @@
|
|||
|
||||
module MaRuKu; module Out; module HTML
|
||||
|
||||
def convert_to_mathml_itex2mml(tex, method)
|
||||
begin
|
||||
if not $itex2mml_parser
|
||||
require 'itextomml'
|
||||
$itex2mml_parser = Itex2MML::Parser.new
|
||||
end
|
||||
|
||||
mathml = $itex2mml_parser.send(method, tex)
|
||||
doc = Document.new(mathml, {:respect_whitespace =>:all}).root
|
||||
return doc
|
||||
rescue LoadError => e
|
||||
maruku_error "Could not load package 'itex2mml'.\n"+
|
||||
"Please install it."
|
||||
rescue REXML::ParseException => e
|
||||
maruku_error "Invalid MathML TeX: \n#{add_tabs(tex,1,'tex>')}"+
|
||||
"\n\n #{e.inspect}"
|
||||
rescue
|
||||
maruku_error "Could not produce MathML TeX: \n#{tex}"+
|
||||
"\n\n #{e.inspect}"
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
def to_html_inline_math_itex2mml
|
||||
convert_to_mathml_itex2mml(self.math, :inline_filter)
|
||||
end
|
||||
|
||||
def to_html_equation_itex2mml
|
||||
convert_to_mathml_itex2mml(self.math, :block_filter)
|
||||
end
|
||||
|
||||
end end end
|
20
lib/maruku/ext/math/mathml_engines/none.rb
Normal file
20
lib/maruku/ext/math/mathml_engines/none.rb
Normal file
|
@ -0,0 +1,20 @@
|
|||
module MaRuKu; module Out; module HTML
|
||||
|
||||
def to_html_inline_math_none
|
||||
# You can: either return a REXML::Element
|
||||
# return Element.new 'div'
|
||||
# or return an empty array on error
|
||||
# return []
|
||||
# or have a string parsed by REXML:
|
||||
tex = self.math
|
||||
tex.gsub!('&','&')
|
||||
mathml = "<code>#{tex}</code>"
|
||||
return Document.new(mathml).root
|
||||
end
|
||||
|
||||
def to_html_equation_none
|
||||
return to_html_inline_math_none
|
||||
end
|
||||
|
||||
end end end
|
||||
|
34
lib/maruku/ext/math/mathml_engines/ritex.rb
Normal file
34
lib/maruku/ext/math/mathml_engines/ritex.rb
Normal file
|
@ -0,0 +1,34 @@
|
|||
module MaRuKu; module Out; module HTML
|
||||
def convert_to_mathml_ritex(tex)
|
||||
begin
|
||||
if not $ritex_parser
|
||||
require 'ritex'
|
||||
$ritex_parser = Ritex::Parser.new
|
||||
end
|
||||
|
||||
mathml = $ritex_parser.parse(tex.strip)
|
||||
doc = Document.new(mathml, {:respect_whitespace =>:all}).root
|
||||
return doc
|
||||
rescue LoadError => e
|
||||
maruku_error "Could not load package 'ritex'.\n"+
|
||||
"Please install it using:\n"+
|
||||
" $ gem install ritex\n\n"+e.inspect
|
||||
rescue Racc::ParseError => e
|
||||
maruku_error "Could not parse TeX: \n#{tex}"+
|
||||
"\n\n #{e.inspect}"
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
def to_html_inline_math_ritex
|
||||
tex = self.math
|
||||
mathml = convert_to_mathml_ritex(tex)
|
||||
return mathml || []
|
||||
end
|
||||
|
||||
def to_html_equation_ritex
|
||||
tex = self.math
|
||||
mathml = convert_to_mathml_ritex(tex)
|
||||
return mathml || []
|
||||
end
|
||||
end end end
|
82
lib/maruku/ext/math/parsing.rb
Normal file
82
lib/maruku/ext/math/parsing.rb
Normal file
|
@ -0,0 +1,82 @@
|
|||
module MaRuKu
|
||||
class MDDocument
|
||||
# Hash equation id (String) to equation element (MDElement)
|
||||
attr_accessor :eqid2eq
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# At least one slash inside
|
||||
#RegInlineMath1 = /\$([^\$]*[\\][^\$]*)\$/
|
||||
# No spaces around the delimiters
|
||||
#RegInlineMath2 = /\$([^\s\$](?:[^\$]*[^\s\$])?)\$/
|
||||
#RegInlineMath = Regexp::union(RegInlineMath1,RegInlineMath2)
|
||||
|
||||
# Everything goes; takes care of escaping the "\$" inside the expression
|
||||
RegInlineMath = /\${1}((?:[^\$]|\\\$)+)\$/
|
||||
|
||||
MaRuKu::In::Markdown::
|
||||
register_span_extension(:chars => ?$, :regexp => RegInlineMath) do
|
||||
|doc, src, con|
|
||||
if m = src.read_regexp(RegInlineMath)
|
||||
math = m.captures.compact.first
|
||||
con.push doc.md_inline_math(math)
|
||||
true
|
||||
else
|
||||
#puts "not math: #{src.cur_chars 10}"
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
EquationStart = /^[ ]{0,3}(?:\\\[|\$\$)(.*)$/
|
||||
|
||||
EqLabel = /(?:\((\w+)\))/
|
||||
OneLineEquation = /^[ ]{0,3}(?:\\\[|\$\$)(.*)(?:\\\]|\$\$)\s*#{EqLabel}?\s*$/
|
||||
EquationEnd = /^(.*)(?:\\\]|\$\$)\s*#{EqLabel}?\s*$/
|
||||
|
||||
MaRuKu::In::Markdown::
|
||||
register_block_extension(:regexp => EquationStart) do |doc, src, con|
|
||||
# puts "Equation :#{self}"
|
||||
first = src.shift_line
|
||||
if first =~ OneLineEquation
|
||||
math = $1
|
||||
label = $2
|
||||
con.push doc.md_equation($1, $2)
|
||||
else
|
||||
first =~ EquationStart
|
||||
math = $1
|
||||
label = nil
|
||||
while true
|
||||
if not src.cur_line
|
||||
maruku_error "Stream finished while reading equation\n\n"+
|
||||
add_tabs(math,1,'$> '), src, con
|
||||
break
|
||||
end
|
||||
line = src.shift_line
|
||||
if line =~ EquationEnd
|
||||
math += $1 + "\n"
|
||||
label = $2 if $2
|
||||
break
|
||||
else
|
||||
math += line + "\n"
|
||||
end
|
||||
end
|
||||
con.push doc.md_equation(math, label)
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
|
||||
# This adds support for \eqref
|
||||
RegEqrefLatex = /\\eqref\{(\w+)\}/
|
||||
RegEqPar = /\(eq:(\w+)\)/
|
||||
RegEqref = Regexp::union(RegEqrefLatex, RegEqPar)
|
||||
|
||||
MaRuKu::In::Markdown::
|
||||
register_span_extension(:chars => [?\\, ?(], :regexp => RegEqref) do
|
||||
|doc, src, con|
|
||||
eqid = src.read_regexp(RegEqref).captures.compact.first
|
||||
r = doc.md_el(:eqref, [], meta={:eqid=>eqid})
|
||||
con.push r
|
||||
true
|
||||
end
|
107
lib/maruku/ext/math/to_html.rb
Normal file
107
lib/maruku/ext/math/to_html.rb
Normal file
|
@ -0,0 +1,107 @@
|
|||
|
||||
=begin maruku_doc
|
||||
Attribute: html_math_engine
|
||||
Scope: document, element
|
||||
Output: html
|
||||
Summary: Select the rendering engine for math.
|
||||
Default: <?mrk Globals[:html_math_engine].to_s ?>
|
||||
|
||||
Select the rendering engine for math.
|
||||
|
||||
If you want to use your engine `foo`, then set:
|
||||
|
||||
HTML math engine: foo
|
||||
{:lang=markdown}
|
||||
|
||||
and then implement two functions:
|
||||
|
||||
def to_html_inline_math_foo
|
||||
# You can: either return a REXML::Element
|
||||
# return Element.new 'div'
|
||||
# or return an empty array on error
|
||||
# return []
|
||||
# or have a string parsed by REXML:
|
||||
tex = self.math
|
||||
tex.gsub!('&','&')
|
||||
mathml = "<code>#{tex}</code>"
|
||||
return Document.new(mathml).root
|
||||
end
|
||||
|
||||
def to_html_equation_foo
|
||||
# same thing
|
||||
...
|
||||
end
|
||||
{:lang=ruby}
|
||||
|
||||
=end
|
||||
|
||||
module MaRuKu; module Out; module HTML
|
||||
|
||||
def to_html_inline_math
|
||||
s = get_setting(:html_math_engine)
|
||||
method = "to_html_inline_math_#{s}".to_sym
|
||||
if self.respond_to? method
|
||||
self.send method || to_html_equation_none
|
||||
else
|
||||
puts "A method called #{method} should be defined."
|
||||
return []
|
||||
end
|
||||
end
|
||||
|
||||
def add_class_to(el, cl)
|
||||
el.attributes['class'] =
|
||||
if already = el.attributes['class']
|
||||
already + " " + cl
|
||||
else
|
||||
cl
|
||||
end
|
||||
end
|
||||
|
||||
def to_html_equation
|
||||
s = get_setting(:html_math_engine)
|
||||
method = "to_html_equation_#{s}".to_sym
|
||||
if self.respond_to? method
|
||||
mathml = self.send(method) || to_html_equation_none
|
||||
div = create_html_element 'div'
|
||||
add_class_to(div, 'maruku-equation')
|
||||
if self.label # then numerate
|
||||
span = Element.new 'span'
|
||||
span.attributes['class'] = 'maruku-eq-number'
|
||||
num = self.num
|
||||
span << Text.new("(#{num})")
|
||||
div << span
|
||||
div.attributes['id'] = "eq:#{self.label}"
|
||||
end
|
||||
div << mathml
|
||||
|
||||
source_div = Element.new 'div'
|
||||
add_class_to(source_div, 'maruku-eq-tex')
|
||||
code = to_html_equation_none
|
||||
code.attributes['style'] = 'display: none'
|
||||
source_div << code
|
||||
div << source_div
|
||||
div
|
||||
else
|
||||
puts "A method called #{method} should be defined."
|
||||
return []
|
||||
end
|
||||
end
|
||||
|
||||
def to_html_eqref
|
||||
if eq = self.doc.eqid2eq[self.eqid]
|
||||
num = eq.num
|
||||
a = Element.new 'a'
|
||||
a.attributes['class'] = 'maruku-eqref'
|
||||
a.attributes['href'] = "#eq:#{self.eqid}"
|
||||
a << Text.new("(#{num})")
|
||||
a
|
||||
else
|
||||
maruku_error "Cannot find equation #{self.eqid.inspect}"
|
||||
Text.new "(#{self.eqid})"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end end end
|
||||
|
||||
|
21
lib/maruku/ext/math/to_latex.rb
Normal file
21
lib/maruku/ext/math/to_latex.rb
Normal file
|
@ -0,0 +1,21 @@
|
|||
|
||||
module MaRuKu; module Out; module Latex
|
||||
|
||||
def to_latex_inline_math
|
||||
"$#{self.math.strip}$"
|
||||
end
|
||||
|
||||
def to_latex_equation
|
||||
if self.label
|
||||
l = "\\label{#{self.label}}"
|
||||
"\\begin{equation}\n#{self.math.strip}\n#{l}\\end{equation}\n"
|
||||
else
|
||||
"\\begin{displaymath}\n#{self.math.strip}\n\\end{displaymath}\n"
|
||||
end
|
||||
end
|
||||
|
||||
def to_latex_eqref
|
||||
"\\eqref{#{self.eqid}}"
|
||||
end
|
||||
|
||||
end end end
|
Loading…
Add table
Add a link
Reference in a new issue