texml 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/texml +12 -0
- data/lib/texml.rb +200 -0
- metadata +68 -0
data/bin/texml
ADDED
data/lib/texml.rb
ADDED
@@ -0,0 +1,200 @@
|
|
1
|
+
########################################
|
2
|
+
# texml.rb
|
3
|
+
# Author: Pierre-Charles David (pcdavid@gmail.com)
|
4
|
+
# Version: 0.4
|
5
|
+
# Web page: http://github.com/pcdavid/ruby-texml
|
6
|
+
# Depends on: xmlparser (available on RAA)
|
7
|
+
# License: WTFPL: http://sam.zoy.org/wtfpl/COPYING
|
8
|
+
|
9
|
+
# Based of Douglas Lovell's paper:
|
10
|
+
# "TeXML: Typesetting with TeX", Douglas Lovell, IBM Research
|
11
|
+
# in TUGboat, Volume 20 (1999), No. 3
|
12
|
+
#
|
13
|
+
# Original implementation in Java by D. Lovell, available on IBM
|
14
|
+
# alphaWorks: http://www.alphaworks.ibm.com/tech/texml
|
15
|
+
#
|
16
|
+
# Usage: % texml.rb < input.xml > output.tex
|
17
|
+
|
18
|
+
require "xmltreebuilder"
|
19
|
+
|
20
|
+
module TeXML
|
21
|
+
|
22
|
+
# Escaping sequences for LaTeX special characters
|
23
|
+
SPECIAL_CHAR_ESCAPES = {
|
24
|
+
'%'[0] => '\%{}',
|
25
|
+
'{'[0] => '\{',
|
26
|
+
'}'[0] => '\}',
|
27
|
+
'|'[0] => '$|${}',
|
28
|
+
'#'[0] => '\#{}',
|
29
|
+
'_'[0] => '\_{}',
|
30
|
+
'^'[0] => '\\char`\\^{}',
|
31
|
+
'~'[0] => '\\char`\\~{}',
|
32
|
+
'&'[0] => '\&{}',
|
33
|
+
'$'[0] => '\${}', #'
|
34
|
+
'<'[0] => '$<${}', #'
|
35
|
+
'>'[0] => '$>${}', #'
|
36
|
+
'\\'[0] => '$\\backslash${}'#'
|
37
|
+
}
|
38
|
+
|
39
|
+
# Converts a TeXML document, passed as a raw XML string, into the
|
40
|
+
# corresponding (La)TeX document.
|
41
|
+
def TeXML.convert(xml)
|
42
|
+
builder = XML::SimpleTreeBuilder.new
|
43
|
+
tree = builder.parse(xml)
|
44
|
+
TeXML::Node.create(tree.documentElement).to_tex
|
45
|
+
end
|
46
|
+
|
47
|
+
# Given a raw string, returns a copy with all (La)TeX special
|
48
|
+
# characters properly quoted.
|
49
|
+
def TeXML.quote(str)
|
50
|
+
tex = ''
|
51
|
+
str.each_byte do |char|
|
52
|
+
tex << (SPECIAL_CHAR_ESCAPES[char] or char)
|
53
|
+
end
|
54
|
+
return tex
|
55
|
+
end
|
56
|
+
|
57
|
+
# Keeps track of which classes can handle which type of nodes
|
58
|
+
NODE_HANDLERS = Hash.new
|
59
|
+
|
60
|
+
# Common node superclass (also node factory, see Node#create)
|
61
|
+
class Node
|
62
|
+
|
63
|
+
# Creates a node handler object appropriate for the specified XML
|
64
|
+
# node, based on the name of the node (uses information from
|
65
|
+
# NODE_HANDLERS).
|
66
|
+
def Node.create(domNode)
|
67
|
+
handlerClass = NODE_HANDLERS[domNode.nodeName]
|
68
|
+
if !handlerClass.nil?
|
69
|
+
handlerClass.new(domNode)
|
70
|
+
else
|
71
|
+
nil
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def initialize(node)
|
76
|
+
@node = node
|
77
|
+
end
|
78
|
+
|
79
|
+
# Aggregates the values of all the children of this Node whose
|
80
|
+
# node name is included in the parameters, in the document order
|
81
|
+
# of the children.
|
82
|
+
def childrenValue(*childTypes)
|
83
|
+
tex = ''
|
84
|
+
@node.childNodes do |kid|
|
85
|
+
if childTypes.include?(kid.nodeName)
|
86
|
+
node = Node.create(kid)
|
87
|
+
tex << node.to_tex unless node.nil?
|
88
|
+
end
|
89
|
+
end
|
90
|
+
return tex
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
class TexmlNode < Node
|
95
|
+
NODE_HANDLERS['TeXML'] = TexmlNode
|
96
|
+
|
97
|
+
def to_tex
|
98
|
+
return childrenValue('cmd', 'env', 'ctrl', 'spec', '#text')
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
class CmdNode < Node
|
103
|
+
NODE_HANDLERS['cmd'] = CmdNode
|
104
|
+
|
105
|
+
def to_tex
|
106
|
+
name = @node.getAttribute('name')
|
107
|
+
nl_before = (@node.getAttribute('nl1') == '1') ? "\n" : ''
|
108
|
+
nl_after = (@node.getAttribute('nl2') == '1') ? "\n" : ''
|
109
|
+
return nl_before + "\\#{name}" + childrenValue('opt') + childrenValue('parm') + ' ' + nl_after
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
class EnvNode < Node
|
114
|
+
NODE_HANDLERS['env'] = EnvNode
|
115
|
+
|
116
|
+
def to_tex
|
117
|
+
name = @node.getAttribute('name')
|
118
|
+
start = @node.getAttribute('begin')
|
119
|
+
start = 'begin' if start == ''
|
120
|
+
stop = @node.getAttribute('end')
|
121
|
+
stop = 'end' if stop == ''
|
122
|
+
return "\\#{start}{#{name}}\n" +
|
123
|
+
childrenValue('cmd', 'env', 'ctrl', 'spec', '#text') +
|
124
|
+
"\\#{stop}{#{name}}\n"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
class OptNode < Node
|
129
|
+
NODE_HANDLERS['opt'] = OptNode
|
130
|
+
|
131
|
+
def to_tex
|
132
|
+
return "[" + childrenValue('cmd', 'ctrl', 'spec', '#text') + "]"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
class ParmNode < Node
|
137
|
+
NODE_HANDLERS['parm'] = ParmNode
|
138
|
+
|
139
|
+
def to_tex
|
140
|
+
return "{" + childrenValue('cmd', 'ctrl', 'spec', '#text') + "}"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
class CtrlNode < Node
|
145
|
+
NODE_HANDLERS['ctrl'] = CtrlNode
|
146
|
+
|
147
|
+
def to_tex
|
148
|
+
ch = @node.getAttribute('ch')
|
149
|
+
unless ch.nil?
|
150
|
+
return ch & 0x9F # Control version of ch
|
151
|
+
else
|
152
|
+
nil
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
class GroupNode < Node
|
158
|
+
NODE_HANDLERS['group'] = GroupNode
|
159
|
+
|
160
|
+
def to_tex
|
161
|
+
return "{" + childrenValue('cmd', 'env', 'ctrl', 'spec', '#text') + "}"
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
class SpecNode < Node
|
166
|
+
NODE_HANDLERS['spec'] = SpecNode
|
167
|
+
|
168
|
+
SPECIAL_MAP = {
|
169
|
+
'esc' => "\\",
|
170
|
+
'bg' => '{',
|
171
|
+
'eg' => '}',
|
172
|
+
'mshift' => '$', # '
|
173
|
+
'align' => '&',
|
174
|
+
'parm' => '#',
|
175
|
+
'sup' => '^',
|
176
|
+
'sub' => '_',
|
177
|
+
'tilde' => '~',
|
178
|
+
'comment' => '%'
|
179
|
+
}
|
180
|
+
|
181
|
+
def to_tex
|
182
|
+
cat = @node.getAttribute('cat')
|
183
|
+
return (SPECIAL_MAP[cat] or '')
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
class TextNode < Node
|
188
|
+
NODE_HANDLERS['#text'] = TextNode
|
189
|
+
|
190
|
+
def to_tex
|
191
|
+
parent = @node.parentNode
|
192
|
+
if parent.nodeName == 'env' && parent.getAttribute('name') == 'verbatim'
|
193
|
+
return @node.nodeValue # TODO: is there /some/ quoting to do?
|
194
|
+
else
|
195
|
+
return TeXML.quote(@node.nodeValue)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
end
|
metadata
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: texml
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 15
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 4
|
9
|
+
- 0
|
10
|
+
version: 0.4.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Pierre-Charles David
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-11-21 00:00:00 +01:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: "This program converts an XML document conforming to the TeXML syntax into the corresponding (La)TeX document, ready to be typeset. It is based on Douglas Lovell's paper: \"TeXML: Typesetting with TeX\", Douglas Lovell, IBM Research in TUGboat, Volume 20 (1999), No. 3"
|
23
|
+
email: pcdavid@gmail.com
|
24
|
+
executables:
|
25
|
+
- texml
|
26
|
+
extensions: []
|
27
|
+
|
28
|
+
extra_rdoc_files: []
|
29
|
+
|
30
|
+
files:
|
31
|
+
- lib/texml.rb
|
32
|
+
- bin/texml
|
33
|
+
has_rdoc: true
|
34
|
+
homepage: http://github.com/pcdavid/ruby-texml
|
35
|
+
licenses: []
|
36
|
+
|
37
|
+
post_install_message:
|
38
|
+
rdoc_options: []
|
39
|
+
|
40
|
+
require_paths:
|
41
|
+
- lib
|
42
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
hash: 3
|
48
|
+
segments:
|
49
|
+
- 0
|
50
|
+
version: "0"
|
51
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
hash: 3
|
57
|
+
segments:
|
58
|
+
- 0
|
59
|
+
version: "0"
|
60
|
+
requirements: []
|
61
|
+
|
62
|
+
rubyforge_project:
|
63
|
+
rubygems_version: 1.3.7
|
64
|
+
signing_key:
|
65
|
+
specification_version: 3
|
66
|
+
summary: A TeXML to LaTeX converter.
|
67
|
+
test_files: []
|
68
|
+
|