texml 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|