/itexToMML

To download this project, use:
bzr branch http://golem.ph.utexas.edu/~distler/code/itexToMML/
1 by Jacques Distler
Initial commit.
1
#  Ruby module for itex2MML
2
#
3
#  Installation
4
#  ------------
5
#    1. You need SWIG (>= 1.3) and GNU Make to install
6
#       the Ruby module.
7
#    2. Then type:
8
#            make ruby
9
#             make test_ruby
10
#            make install_ruby
11
#    3. This module can then be invoked like:
12
#
13
#            require 'itextomml'
14
#            
15
#            itex = Itex2MML::Parser.new
16
#            itex.html_filter(string)
17
#
18
#  Usage
19
#  -----
20
#
3 by Jacques Distler
Added two new methods to the Ruby bindings.
21
#      There are four public methods
1 by Jacques Distler
Initial commit.
22
#
23
#       itex.html_filter(a_string)
24
#               converts all itex equations in a_string to MathML, passing the
25
#               rest of a_string unmodified. Returns the converted string. 
26
#
27
#       itex.filter(a_string)
28
#               converts all itex equations in a_string to MathML. Returns just
29
#               the MathML equation(s), as a string.
30
#
3 by Jacques Distler
Added two new methods to the Ruby bindings.
31
#       itex.inline_filter(a_string)
32
#               treats a_string as an inline equation (automatically supplies
33
#               the surrounding $...$, so you don't have to) and converts it
34
#               MathML. Returns the MathML inline equation, as a string.
35
#
36
#       itex.block_filter(a_string)
37
#               treats a_string as a block equation (automatically supplies
38
#               the surrounding $$...$$, so you don't have to) and converts it
39
#               MathML. Returns the MathML block equation, as a string.
40
#
41
#  Authors: Justin Bonnar <jbonnar@berkeley.edu>
42
#           Jacques Distler <distler@golem.ph.utexas.edu>
43
#
1 by Jacques Distler
Initial commit.
44
#  Placed in the Public Domain
45
46
require 'itex2MML'
47
require 'thread'
48
49
module Itex2MML
50
  class Error < RuntimeError; end
51
 
52
  class Parser
53
    def self.semaphore
54
      @semaphore ||= Mutex.new
55
    end
56
   
57
    def html_filter(string)
58
      parse(string, :itex2MML_html_filter)
59
    end
60
   
61
    def filter(string)
62
      parse(string, :itex2MML_filter)
63
    end
64
 
3 by Jacques Distler
Added two new methods to the Ruby bindings.
65
    def inline_filter(string)
66
      parse("\$#{string}\$", :itex2MML_filter)
67
    end
68
 
69
    def block_filter(string)
70
      parse("\$\$#{string}\$\$", :itex2MML_filter)
71
    end
72
 
1 by Jacques Distler
Initial commit.
73
  private
74
 
75
    def parse(string, message)
44 by Jacques Distler
Fix Ruby bindings to work in Ruby 1.9
76
      str = as_bytes(string.to_str)
1 by Jacques Distler
Initial commit.
77
      self.class.semaphore.synchronize do
44 by Jacques Distler
Fix Ruby bindings to work in Ruby 1.9
78
        raise Itex2MML::Error unless Itex2MML.send(message, str, str.length) == 0
79
        as_utf8(Itex2MML.itex2MML_output)
80
      end
81
    end
82
    
83
    if "".respond_to?(:force_encoding)
84
      def as_bytes(string)
85
        string.force_encoding("ASCII-8BIT")
86
      end
87
      def as_utf8(string)
88
        string.force_encoding("UTF-8")
89
      end
90
    else
48 by Jacques Distler
Fix svg Environment
91
      def as_bytes(string)
92
        string
93
      end
44 by Jacques Distler
Fix Ruby bindings to work in Ruby 1.9
94
      def as_utf8(string)
95
        string
96
      end
97
    end
98
1 by Jacques Distler
Initial commit.
99
  end
100
end
101
102
## Unit Tests ##
103
if __FILE__ == $0
104
  require 'test/unit'
105
106
  class Itex2MMLTest < Test::Unit::TestCase
107
108
    def test_inline_html
109
      itex = Itex2MML::Parser.new
110
      assert_equal("Inline: <math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mi>sin</mi><mo stretchy=\"false\">(</mo><mi>x</mi><mo stretchy=\"false\">)</mo></math>", itex.html_filter('Inline: $\sin(x)$'))
111
    end
112
113
    def test_inline
114
      itex = Itex2MML::Parser.new
115
      assert_equal("<math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mi>sin</mi><mo stretchy=\"false\">(</mo><mi>x</mi><mo stretchy=\"false\">)</mo></math>", itex.filter('Inline: $\sin(x)$'))
116
    end
117
3 by Jacques Distler
Added two new methods to the Ruby bindings.
118
    def test_inline_inline
119
      itex = Itex2MML::Parser.new
120
      assert_equal("<math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mi>sin</mi><mo stretchy=\"false\">(</mo><mi>x</mi><mo stretchy=\"false\">)</mo></math>", itex.inline_filter('\sin(x)'))
121
    end
122
1 by Jacques Distler
Initial commit.
123
    def test_block_html
124
      itex = Itex2MML::Parser.new
125
      assert_equal("Block: <math xmlns='http://www.w3.org/1998/Math/MathML' display='block'><mi>sin</mi><mo stretchy=\"false\">(</mo><mi>x</mi><mo stretchy=\"false\">)</mo></math>", itex.html_filter('Block: $$\sin(x)$$'))
126
    end
127
128
    def test_block
129
      itex = Itex2MML::Parser.new
130
      assert_equal("<math xmlns='http://www.w3.org/1998/Math/MathML' display='block'><mi>sin</mi><mo stretchy=\"false\">(</mo><mi>x</mi><mo stretchy=\"false\">)</mo></math>", itex.filter('Block: $$\sin(x)$$'))
131
    end
132
3 by Jacques Distler
Added two new methods to the Ruby bindings.
133
    def test_block_block
134
      itex = Itex2MML::Parser.new
135
      assert_equal("<math xmlns='http://www.w3.org/1998/Math/MathML' display='block'><mi>sin</mi><mo stretchy=\"false\">(</mo><mi>x</mi><mo stretchy=\"false\">)</mo></math>", itex.block_filter('\sin(x)'))
136
    end
137
25 by Jacques Distler
Makefile Tweak
138
    def test_inline_utf8
139
      itex = Itex2MML::Parser.new
44 by Jacques Distler
Fix Ruby bindings to work in Ruby 1.9
140
      s = "".respond_to?(:force_encoding) ? "\u00F3" : "\303\263"
141
      assert_equal("ecuasi"+ s + "n <math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'>" +
142
             "<mi>sin</mi><mo stretchy=\"false\">(</mo><mi>x</mi><mo stretchy=\"false\">)</mo></math>",
143
              itex.html_filter("ecuasi\303\263n $\\sin(x)$"))
25 by Jacques Distler
Makefile Tweak
144
    end
145
146
    def test_inline_utf8_inline
147
      itex = Itex2MML::Parser.new
148
      assert_equal("<math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mi>sin</mi><mo stretchy=\"false\">(</mo><mi>x</mi><mo stretchy=\"false\">)</mo></math>", itex.filter("ecuasi\303\263n $\\sin(x)$"))
149
    end
44 by Jacques Distler
Fix Ruby bindings to work in Ruby 1.9
150
    
151
    def test_utf8_in_svg_foreignObject
152
      itex = Itex2MML::Parser.new
153
      s = "".respond_to?(:force_encoding) ? "\u2032" : "\342\200\262"
154
      assert_equal("<math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mi>g" +
155
          "</mi><mo>&prime;</mo><mo>=</mo><semantics><annotation-xml encoding=\"SVG1.1\"><svg w" +
156
          "idth='40' height='40' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3." +
157
          "org/1999/xlink'><foreignObject height='19' width='20' font-size='16' y='0' x='0'><ma" +
158
          "th display='inline' xmlns='http://www.w3.org/1998/Math/MathML'><mi>g</mi><mo>" +
159
          s + "</mo></math></foreignObject></svg></annotation-xml></semantics></math>",
160
        itex.filter("$g' = \\begin{svg}<svg width='40' height='40' xmlns='http://www.w3.org/20" +
161
          "00/svg' xmlns:xlink='http://www.w3.org/1999/xlink'><foreignObject height='19' width='" +
162
          "20' font-size='16' y='0' x='0'><math display='inline' xmlns='http://www.w3.org/1998/M" +
163
          "ath/MathML'><mi>g</mi><mo>\342\200\262</mo></math></foreignObject></svg>\\end{svg}$"))
164
    end
25 by Jacques Distler
Makefile Tweak
165
1 by Jacques Distler
Initial commit.
166
  end
167
end