/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
    else
88
      def as_bytes(string)
89
        string
90
      end
91
    end
92
93
    if "".respond_to?(:force_encoding)
94
      def as_utf8(string)
95
        string.force_encoding("UTF-8")
96
      end
97
    else
98
      def as_utf8(string)
99
        string
100
      end
101
    end
102
1 by Jacques Distler
Initial commit.
103
  end
104
end
105
106
## Unit Tests ##
107
if __FILE__ == $0
108
  require 'test/unit'
109
110
  class Itex2MMLTest < Test::Unit::TestCase
111
112
    def test_inline_html
113
      itex = Itex2MML::Parser.new
114
      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)$'))
115
    end
116
117
    def test_inline
118
      itex = Itex2MML::Parser.new
119
      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)$'))
120
    end
121
3 by Jacques Distler
Added two new methods to the Ruby bindings.
122
    def test_inline_inline
123
      itex = Itex2MML::Parser.new
124
      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)'))
125
    end
126
1 by Jacques Distler
Initial commit.
127
    def test_block_html
128
      itex = Itex2MML::Parser.new
129
      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)$$'))
130
    end
131
132
    def test_block
133
      itex = Itex2MML::Parser.new
134
      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)$$'))
135
    end
136
3 by Jacques Distler
Added two new methods to the Ruby bindings.
137
    def test_block_block
138
      itex = Itex2MML::Parser.new
139
      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)'))
140
    end
141
25 by Jacques Distler
Makefile Tweak
142
    def test_inline_utf8
143
      itex = Itex2MML::Parser.new
44 by Jacques Distler
Fix Ruby bindings to work in Ruby 1.9
144
      s = "".respond_to?(:force_encoding) ? "\u00F3" : "\303\263"
145
      assert_equal("ecuasi"+ s + "n <math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'>" +
146
             "<mi>sin</mi><mo stretchy=\"false\">(</mo><mi>x</mi><mo stretchy=\"false\">)</mo></math>",
147
              itex.html_filter("ecuasi\303\263n $\\sin(x)$"))
25 by Jacques Distler
Makefile Tweak
148
    end
149
150
    def test_inline_utf8_inline
151
      itex = Itex2MML::Parser.new
152
      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)$"))
153
    end
44 by Jacques Distler
Fix Ruby bindings to work in Ruby 1.9
154
    
155
    def test_utf8_in_svg_foreignObject
156
      itex = Itex2MML::Parser.new
157
      s = "".respond_to?(:force_encoding) ? "\u2032" : "\342\200\262"
158
      assert_equal("<math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mi>g" +
159
          "</mi><mo>&prime;</mo><mo>=</mo><semantics><annotation-xml encoding=\"SVG1.1\"><svg w" +
160
          "idth='40' height='40' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3." +
161
          "org/1999/xlink'><foreignObject height='19' width='20' font-size='16' y='0' x='0'><ma" +
162
          "th display='inline' xmlns='http://www.w3.org/1998/Math/MathML'><mi>g</mi><mo>" +
163
          s + "</mo></math></foreignObject></svg></annotation-xml></semantics></math>",
164
        itex.filter("$g' = \\begin{svg}<svg width='40' height='40' xmlns='http://www.w3.org/20" +
165
          "00/svg' xmlns:xlink='http://www.w3.org/1999/xlink'><foreignObject height='19' width='" +
166
          "20' font-size='16' y='0' x='0'><math display='inline' xmlns='http://www.w3.org/1998/M" +
167
          "ath/MathML'><mi>g</mi><mo>\342\200\262</mo></math></foreignObject></svg>\\end{svg}$"))
168
    end
25 by Jacques Distler
Makefile Tweak
169
1 by Jacques Distler
Initial commit.
170
  end
171
end