#=begin maruku_doc # Extension: math # Attribute: html_math_engine # Scope: document, element # Output: html # Summary: Select the rendering engine for MathML. # Default: # # Select the rendering engine for math. # # If you want to use your custom engine `foo`, then set: # # HTML math engine: foo # {:lang=markdown} # # and then implement two functions: # # def convert_to_mathml_foo(kind, tex) # ... # end #=end #=begin maruku_doc # Extension: math # Attribute: html_png_engine # Scope: document, element # Output: html # Summary: Select the rendering engine for math. # Default: # # Same thing as `html_math_engine`, only for PNG output. # # def convert_to_png_foo(kind, tex) # # same thing # ... # end # {:lang=ruby} # #=end module MaRuKu module Out module HTML # Creates an xml Mathml document of this node's TeX code. # # @return [MaRuKu::Out::HTML::HTMLElement] def render_mathml(kind, tex) engine = get_setting(:html_math_engine) method = "convert_to_mathml_#{engine}" if self.respond_to? method mathml = self.send(method, kind, tex) return mathml || convert_to_mathml_none(kind, tex) end # TODO: Warn here raise "A method called #{method} should be defined." convert_to_mathml_none(kind, tex) end # Renders a PNG image of this node's TeX code. # Returns # # @return [MaRuKu::Out::HTML::PNG, nil] # A struct describing the location and size of the image, # or nil if no library is loaded that can render PNGs. def render_png(kind, tex) engine = get_setting(:html_png_engine) method = "convert_to_png_#{engine}".to_sym return self.send(method, kind, tex) if self.respond_to? method raise "A method called #{method} should be defined." nil end def pixels_per_ex $pixels_per_ex ||= render_png(:inline, "x").height end def adjust_png(png, use_depth) src = png.src height_in_px = png.height depth_in_px = png.depth height_in_ex = height_in_px / pixels_per_ex depth_in_ex = depth_in_px / pixels_per_ex total_height_in_ex = height_in_ex + depth_in_ex style = "" style << "vertical-align: -#{depth_in_ex}ex;" if use_depth style << "height: #{total_height_in_ex}ex;" img = xelem('img') img['src'] = src img['style'] = style img['alt'] = "$#{self.math.strip}$" img['class'] = 'maruku-png' img end def to_html_inline_math mathml = get_setting(:html_math_output_mathml) && render_mathml(:inline, self.math) if mathml mathml.add_class('maruku-mathml') return mathml.to_html end png = get_setting(:html_math_output_png) && render_png(:inline, self.math) HTMLElement.new 'span', 'class' => 'maruku-inline' do # TODO: It seems weird that we output an empty span if there's no PNG if png adjust_png(png, true) end end end def to_html_equation mathml = get_setting(:html_math_output_mathml) && render_mathml(:equation, self.math) png = get_setting(:html_math_output_png) && render_png(:equation, self.math) div = xelem('div') div['class'] = 'maruku-equation' if mathml if self.label # then numerate span = xelem('span') span['class'] = 'maruku-eq-number' span << xtext("(#{self.num})") div << span div['id'] = "eq:#{self.label}" end mathml.add_class('maruku-mathml') div << mathml.to_html end if png img = adjust_png(png, false) div << img if self.label # then numerate span = xelem('span') span['class'] = 'maruku-eq-number' span << xtext("(#{self.num})") div << span div['id'] = "eq:#{self.label}" end end div end def to_html_eqref unless eq = self.doc.eqid2eq[self.eqid] maruku_error "Cannot find equation #{self.eqid.inspect}" return xtext("(eq:#{self.eqid})") end a = xelem('a') a['class'] = 'maruku-eqref' a['href'] = "#eq:#{self.eqid}" a << xtext("(#{eq.num})") a end def to_html_divref unless hash = self.doc.refid2ref.values.find {|h| h.has_key?(self.refid)} maruku_error "Cannot find div #{self.refid.inspect}" return xtext("\\ref{#{self.refid}}") end ref= hash[self.refid] a = xelem('a') a['class'] = 'maruku-ref' a['href'] = "#" + self.refid a << xtext(ref.num.to_s) a end end end end