maruku 0.4.2.1 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/maruku +66 -20
- data/bin/marutest +12 -2
- data/docs/changelog.html +188 -23
- data/docs/changelog.md +128 -5
- data/docs/entity_test.html +245 -240
- data/docs/entity_test.md +2 -0
- data/docs/exd.html +181 -23
- data/docs/index.html +130 -349
- data/docs/markdown_syntax.html +55 -51
- data/docs/maruku.html +130 -349
- data/docs/maruku.md +154 -339
- data/docs/math.md +143 -0
- data/docs/proposal.html +16 -12
- data/lib/maruku.rb +6 -3
- data/lib/maruku/attributes.rb +7 -2
- data/lib/maruku/defaults.rb +27 -27
- data/lib/maruku/errors_management.rb +10 -9
- data/lib/maruku/ext/diagrams/diagrams.rb +8 -0
- data/lib/maruku/ext/diagrams/grid.rb +78 -0
- data/lib/maruku/ext/diagrams/inspect.rb +11 -0
- data/lib/maruku/ext/diagrams/layout.rb +105 -0
- data/lib/maruku/ext/diagrams/parser.rb +219 -0
- data/lib/maruku/ext/diagrams/structures.rb +168 -0
- data/lib/maruku/ext/diagrams/to_html.rb +37 -0
- data/lib/maruku/ext/diagrams/to_latex.rb +308 -0
- data/lib/maruku/ext/diagrams/unittest.rb +123 -0
- data/lib/maruku/ext/math.rb +11 -0
- data/lib/maruku/ext/math/elements.rb +26 -0
- data/lib/maruku/ext/math/mathml_engines/blahtex.rb +108 -0
- data/lib/maruku/ext/math/mathml_engines/itex2mml.rb +29 -0
- data/lib/maruku/ext/math/mathml_engines/none.rb +20 -0
- data/lib/maruku/ext/math/mathml_engines/ritex.rb +24 -0
- data/lib/maruku/ext/math/parsing.rb +82 -0
- data/lib/maruku/ext/math/to_html.rb +178 -0
- data/lib/maruku/ext/math/to_latex.rb +21 -0
- data/lib/maruku/helpers.rb +11 -0
- data/lib/maruku/input/charsource.rb +1 -1
- data/lib/maruku/input/extensions.rb +68 -0
- data/lib/maruku/input/html_helper.rb +91 -60
- data/lib/maruku/input/parse_block.rb +10 -9
- data/lib/maruku/input/parse_doc.rb +21 -13
- data/lib/maruku/input/parse_span_better.rb +19 -8
- data/lib/maruku/input/type_detection.rb +5 -3
- data/lib/maruku/output/to_html.rb +236 -67
- data/lib/maruku/output/to_latex.rb +69 -26
- data/lib/maruku/output/to_latex_entities.rb +14 -2
- data/lib/maruku/output/to_s.rb +8 -0
- data/lib/maruku/structures.rb +1 -1
- data/lib/maruku/tests/benchmark.rb +2 -2
- data/lib/maruku/tests/new_parser.rb +13 -5
- data/lib/maruku/version.rb +1 -1
- data/lib/sort_prof.rb +22 -0
- data/tests/diagrams/diagrams.md +54 -0
- data/tests/math/syntax.md +46 -0
- data/tests/math_usage/document.md +13 -0
- data/tests/unittest/attributes/attributes.md +50 -6
- data/tests/unittest/easy.md +1 -1
- data/tests/unittest/email.md +3 -3
- data/tests/unittest/entities.md +12 -7
- data/tests/unittest/escaping.md +4 -4
- data/tests/unittest/extra_table1.md +3 -1
- data/tests/unittest/footnotes.md +5 -5
- data/tests/unittest/headers.md +3 -3
- data/tests/unittest/images.md +7 -7
- data/tests/unittest/inline_html.md +51 -5
- data/tests/unittest/links.md +7 -7
- data/tests/unittest/list2.md +1 -1
- data/tests/unittest/lists.md +1 -1
- data/tests/unittest/lists_after_paragraph.md +1 -1
- data/tests/unittest/lists_ol.md +1 -1
- data/tests/unittest/math/equations.md +82 -0
- data/tests/unittest/math/inline.md +80 -0
- data/tests/unittest/math/table.md +51 -0
- data/tests/unittest/math/table2.md +67 -0
- data/tests/unittest/misc_sw.md +24 -24
- data/tests/unittest/notyet/ticks.md +1 -1
- data/tests/unittest/references/long_example.md +2 -2
- data/tests/unittest/smartypants.md +4 -4
- data/tests/unittest/xml.md +68 -0
- data/tests/unittest/xml2.md +36 -0
- data/tests/unittest/xml3.md +52 -0
- data/tests/unittest/xml_instruction.md +5 -5
- metadata +33 -4
- data/docs/a.html +0 -6
- data/docs/char.html +0 -1924
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'rexml/document'
|
2
|
+
|
3
|
+
module Diagrams
|
4
|
+
|
5
|
+
class Diagram
|
6
|
+
|
7
|
+
|
8
|
+
include REXML
|
9
|
+
def to_html
|
10
|
+
div = Element.new 'div'
|
11
|
+
div.add_element 'div', {'style'=>'width: 1em', 'id'=>'emtest'}
|
12
|
+
div.attributes['style'] =
|
13
|
+
"position:relative; display: block; width: #{@width}em; height: #{@height}em;"
|
14
|
+
div.attributes['class'] = 'diagram'
|
15
|
+
@boxes.each_with_index do |b, i|
|
16
|
+
box = Element.new 'div'
|
17
|
+
box.attributes['class'] = 'box'
|
18
|
+
|
19
|
+
w = b.width
|
20
|
+
box.attributes['id'] = "box#{i}"
|
21
|
+
box.attributes['style'] =
|
22
|
+
"position:absolute; left:#{b.x}em; top:#{b.y}em; border:solid 1px black;"
|
23
|
+
content = Element.new 'div', box
|
24
|
+
content.attributes['class'] = 'inner'
|
25
|
+
content << Text.new( b.content )
|
26
|
+
div << box
|
27
|
+
div << Text.new("\n")
|
28
|
+
end
|
29
|
+
div
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,308 @@
|
|
1
|
+
|
2
|
+
module Diagrams
|
3
|
+
|
4
|
+
class Diagram
|
5
|
+
|
6
|
+
def write_tex_discovery(diag_id, output_file)
|
7
|
+
fid = 10
|
8
|
+
s = ("\\immediate\\openout%d=%s\n" % [fid, output_file])
|
9
|
+
@boxes.each_with_index do |b, i|
|
10
|
+
s += ("\\setbox0=\\hbox{%s}\n" % b.content)
|
11
|
+
s += "\\immediate\\write%d{%s,%d,\\the\\wd0,\\the\\ht0,\\the\\dp0 ,%s}\n" %
|
12
|
+
[fid, diag_id, i, b.content]
|
13
|
+
end
|
14
|
+
s += "\\end\n"
|
15
|
+
s
|
16
|
+
end
|
17
|
+
|
18
|
+
def write_latex_discovery(diag_id, output_file)
|
19
|
+
fid = 10
|
20
|
+
s=""
|
21
|
+
# s +="\\documentclass{article}\\begin{document}"
|
22
|
+
s += ("\\immediate\\openout%d=%s\n" % [fid, output_file])
|
23
|
+
# s+= "\\ifx\\already\\empty"
|
24
|
+
# s+="\\def\\already{1}"
|
25
|
+
# s+= "\\newlength{\\mywd}\n"
|
26
|
+
# s+= "\\newlength{\\myht}\n"
|
27
|
+
# s+= "\\newlength{\\mydp}\n"
|
28
|
+
# s+="\\fi"
|
29
|
+
@boxes.each_with_index do |b, i|
|
30
|
+
s += ("\\settowidth{\\mywd}{\\hbox{%s}}\n" % b.content)
|
31
|
+
s += ("\\settoheight{\\myht}{\\hbox{%s}}\n" % b.content)
|
32
|
+
s += ("\\settodepth{\\mydp}{\\hbox{%s}}\n" % b.content)
|
33
|
+
s += "\\immediate\\write%d{%s,%d,\\the\\mywd,\\the\\myht,\\the\\mydp}\n" %
|
34
|
+
[fid, diag_id, i]
|
35
|
+
end
|
36
|
+
s+=("\\immediate\\closeout%d\n" % fid)
|
37
|
+
# s+="\\end{document}"
|
38
|
+
s
|
39
|
+
end
|
40
|
+
|
41
|
+
def read_tex_discovery(my_diag_id, s)
|
42
|
+
s.split("\n").each do |l|
|
43
|
+
diag_id, box_index, wd, ht, dp, text = l.split(",")
|
44
|
+
if diag_id == my_diag_id
|
45
|
+
puts "found box #{box_index}: #{wd} #{ht} #{dp}"
|
46
|
+
wd,ht,dp = wd.to_f,ht.to_f,dp.to_f
|
47
|
+
width = wd
|
48
|
+
height = ht+dp
|
49
|
+
puts "found box #{box_index}: #{width}x#{height}"
|
50
|
+
i = box_index.to_i
|
51
|
+
@boxes[i].hs.min = width
|
52
|
+
@boxes[i].hs.shrink = 1
|
53
|
+
@boxes[i].hs.pref = width*1.2
|
54
|
+
@boxes[i].hs.stretch = 0.1
|
55
|
+
@boxes[i].hs.max = 1000
|
56
|
+
@boxes[i].vs.min = height
|
57
|
+
@boxes[i].vs.shrink = 1
|
58
|
+
@boxes[i].vs.pref = height*1.2
|
59
|
+
@boxes[i].vs.stretch = 0.1
|
60
|
+
@boxes[i].vs.max = 1000
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def to_latex(job="anon_diagram")
|
66
|
+
do_discovery = true
|
67
|
+
|
68
|
+
tmp_out = "#{job}.dia"
|
69
|
+
|
70
|
+
diag_id = "dia"
|
71
|
+
s = write_latex_discovery(diag_id, tmp_out)
|
72
|
+
|
73
|
+
if File.exist?(tmp_out)
|
74
|
+
File.open(tmp_out, 'r') do |f|
|
75
|
+
read_tex_discovery(diag_id, f.read)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
do_layout(job)
|
80
|
+
|
81
|
+
@boxes.each_with_index do |b, i|
|
82
|
+
width = b.hs.min
|
83
|
+
height = b.vs.min
|
84
|
+
s << ("\\framebox[%fpt]{\\rule{10pt}{%fpt}%s}"% [width,height, b.content])
|
85
|
+
end
|
86
|
+
|
87
|
+
s+="\n\nCiao\n\n"
|
88
|
+
s
|
89
|
+
end
|
90
|
+
|
91
|
+
class Layout
|
92
|
+
def initialize
|
93
|
+
@hlink,@vlink = {},{}
|
94
|
+
@hsprings,@vsprings={},{}
|
95
|
+
end
|
96
|
+
|
97
|
+
def to_dot()
|
98
|
+
return to_dot_links(@hlink,@hsprings), to_dot_links(@vlink,@vsprings)
|
99
|
+
end
|
100
|
+
|
101
|
+
def to_dot_links(links, springs)
|
102
|
+
s = "digraph diagram {\n"
|
103
|
+
links.each do |var, to_other|
|
104
|
+
if not to_other.empty?
|
105
|
+
var_ = var.gsub(/^[^_]+_/,'')
|
106
|
+
s += "\t#{var} [label = \"#{var_}\" ];\n"
|
107
|
+
to_other.each do |v2, spring|
|
108
|
+
s += "\t #{var} -> #{v2} [ label = \"#{spring.inspect}\"];\n"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
s += "}\n"
|
113
|
+
end
|
114
|
+
|
115
|
+
def add_var(s)
|
116
|
+
@hlink[s]=[] if not @hlink[s]
|
117
|
+
@vlink[s]=[] if not @vlink[s]
|
118
|
+
end
|
119
|
+
|
120
|
+
# var2-var1 = spring
|
121
|
+
def add_con_h(var1,var2,hspring)
|
122
|
+
add_var var1; add_var var2;
|
123
|
+
@hlink[var1].push [var2, hspring]
|
124
|
+
@hsprings[[var1,var2]] = hspring
|
125
|
+
end
|
126
|
+
|
127
|
+
def add_con_v(var1,var2,vspring)
|
128
|
+
add_var var1; add_var var2;
|
129
|
+
@vlink[var1].push [var2, vspring]
|
130
|
+
@vsprings[[var1,var2]] = vspring
|
131
|
+
end
|
132
|
+
|
133
|
+
def get_preferred(var1, var2)
|
134
|
+
hpaths = rec_paths(@hlink, var1, var2)
|
135
|
+
vpaths = rec_paths(@vlink, var1, var2)
|
136
|
+
puts inspect
|
137
|
+
hpaths.each do |h|
|
138
|
+
puts "H: #{h.inspect}"
|
139
|
+
end
|
140
|
+
vpaths.each do |v|
|
141
|
+
puts "V: #{v.inspect}"
|
142
|
+
end
|
143
|
+
|
144
|
+
hsprings =
|
145
|
+
hpaths.map do |h|
|
146
|
+
ss = []
|
147
|
+
for i in 0..(h.size-2)
|
148
|
+
v1,v2 = h[i],h[i+1]
|
149
|
+
ss.push @hsprings[[v1,v2]]
|
150
|
+
end
|
151
|
+
ss
|
152
|
+
end
|
153
|
+
vsprings =
|
154
|
+
vpaths.map do |h|
|
155
|
+
ss = []
|
156
|
+
for i in 0..(h.size-2)
|
157
|
+
v1,v2 = h[i],h[i+1]
|
158
|
+
ss.push @vsprings[[v1,v2]]
|
159
|
+
end
|
160
|
+
ss
|
161
|
+
end
|
162
|
+
|
163
|
+
|
164
|
+
def go_up_parallel(par)
|
165
|
+
final = par[0]
|
166
|
+
for i in 1..(par.size-1)
|
167
|
+
final = Spring.parallel(final, par[i])
|
168
|
+
end
|
169
|
+
final
|
170
|
+
end
|
171
|
+
|
172
|
+
def go_up_series(series)
|
173
|
+
tot = series[0]
|
174
|
+
for i in 1..(series.size-1)
|
175
|
+
tot = Spring.series(tot, series[i])
|
176
|
+
end
|
177
|
+
tot
|
178
|
+
end
|
179
|
+
|
180
|
+
def compress(x)
|
181
|
+
t = x.map do |s| go_up_series(s) end
|
182
|
+
final = go_up_parallel(t)
|
183
|
+
end
|
184
|
+
|
185
|
+
def sum_of_shrink(series)
|
186
|
+
sum = 0
|
187
|
+
series.each do |s| sum += s.shrink end
|
188
|
+
sum
|
189
|
+
end
|
190
|
+
|
191
|
+
def sum_of_stretch(series)
|
192
|
+
sum = 0
|
193
|
+
series.each do |s| sum += s.stretch end
|
194
|
+
sum
|
195
|
+
end
|
196
|
+
|
197
|
+
def go_back(imposed, series)
|
198
|
+
pref = go_up_series(series)
|
199
|
+
if pref.pref > imposed
|
200
|
+
# must shrink
|
201
|
+
shrink = pref.pref - imposed
|
202
|
+
sum = sum_of_shrink(series)
|
203
|
+
series.each do |s|
|
204
|
+
its_shrink = (s.shrink / sum) * shrink
|
205
|
+
its_imposed = s.pref - its_shrink
|
206
|
+
if s.imposed
|
207
|
+
s.imposed = (its_imposed+ s.imposed)*0.5
|
208
|
+
else
|
209
|
+
s.imposed = its_imposed
|
210
|
+
end
|
211
|
+
s.pref = s.pref*0.5 + s.imposed*0.5
|
212
|
+
end
|
213
|
+
else
|
214
|
+
# must stretch
|
215
|
+
stretch = imposed - pref.pref
|
216
|
+
sum = sum_of_stretch(series)
|
217
|
+
series.each do |s|
|
218
|
+
its_stretch = (s.stretch / sum) * stretch
|
219
|
+
its_imposed = s.pref + its_stretch
|
220
|
+
if s.imposed
|
221
|
+
s.imposed = (its_imposed+ s.imposed)*0.5
|
222
|
+
else
|
223
|
+
s.imposed = its_imposed
|
224
|
+
end
|
225
|
+
s.pref = s.pref*0.5 + s.imposed*0.5
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
for i in 0..100
|
231
|
+
hpref = compress(hsprings)
|
232
|
+
vpref = compress(vsprings)
|
233
|
+
|
234
|
+
width = hpref.pref
|
235
|
+
height = vpref.pref
|
236
|
+
|
237
|
+
hsprings.each do |series| go_back(height, series) end
|
238
|
+
vsprings.each do |series| go_back(width, series) end
|
239
|
+
end
|
240
|
+
|
241
|
+
hpaths.each do |h|
|
242
|
+
ss = []
|
243
|
+
len = 0
|
244
|
+
for i in 0..(h.size-2)
|
245
|
+
v1,v2 = h[i],h[i+1]
|
246
|
+
this = @hsprings[[v1,v2]].imposed
|
247
|
+
puts "#{v1} - #{v2} | "+ ("%0.2f" % this)
|
248
|
+
len += this
|
249
|
+
end
|
250
|
+
puts "LEN: #{len}"
|
251
|
+
ss
|
252
|
+
end
|
253
|
+
|
254
|
+
return hpref,vpref
|
255
|
+
end
|
256
|
+
|
257
|
+
# returns [] if there isn't one
|
258
|
+
def rec_paths(links, var1, var2)
|
259
|
+
all_paths = []
|
260
|
+
(links[var1] || []).each do |v, spring|
|
261
|
+
if v == var2
|
262
|
+
all_paths.push [var2]
|
263
|
+
else
|
264
|
+
all_paths = all_paths + rec_paths(links, v, var2)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
all_paths.map{|x| [var1]+x}
|
268
|
+
end
|
269
|
+
|
270
|
+
def inspect
|
271
|
+
s = ""
|
272
|
+
@hlink.each do |v1,a|
|
273
|
+
a.each do |v2, spring|
|
274
|
+
s += "#{v1.inspect} -> #{v2.inspect} (#{spring.inspect})\n"
|
275
|
+
end
|
276
|
+
end
|
277
|
+
s
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
def top_right(i); "#{@diag_id}_b#{i}_tr"; end
|
282
|
+
|
283
|
+
def assign_variables(diag_id)
|
284
|
+
@boxes.each_with_index do |b, i|
|
285
|
+
b.v_tl = "#{diag_id}_b#{i}_tl"
|
286
|
+
b.v_br = "#{diag_id}_b#{i}_br"
|
287
|
+
end
|
288
|
+
@arrows.each_with_index do |a, i|
|
289
|
+
a.v_start = "#{diag_id}_a#{i}_start"
|
290
|
+
a.v_end = "#{diag_id}_a#{i}_end"
|
291
|
+
end
|
292
|
+
@points.each_with_index do |p, i|
|
293
|
+
p.v_p = "#{diag_id}_p#{i}_p"
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
# in points
|
298
|
+
def to_dev(x)
|
299
|
+
x * 10
|
300
|
+
end
|
301
|
+
|
302
|
+
|
303
|
+
end
|
304
|
+
|
305
|
+
end
|
306
|
+
|
307
|
+
|
308
|
+
|
@@ -0,0 +1,123 @@
|
|
1
|
+
|
2
|
+
Test0 = <<-EOF
|
3
|
+
+-+
|
4
|
+
|A|
|
5
|
+
+-+
|
6
|
+
|
7
|
+
+-++
|
8
|
+
|AB|
|
9
|
+
+-++
|
10
|
+
|
11
|
+
+---+
|
12
|
+
|ABC|
|
13
|
+
+---+
|
14
|
+
|
15
|
+
+----+
|
16
|
+
|ABCD|
|
17
|
+
+----+
|
18
|
+
EOF
|
19
|
+
|
20
|
+
Test1 = <<-EOF
|
21
|
+
/---------\\
|
22
|
+
| Start |
|
23
|
+
\\----+----/
|
24
|
+
|
|
25
|
+
V
|
26
|
+
+----+----+
|
27
|
+
| Init |
|
28
|
+
+----+----+
|
29
|
+
|
|
30
|
+
+<-----------+
|
31
|
+
| ^
|
32
|
+
V |
|
33
|
+
+----+----+ |
|
34
|
+
| Process | |
|
35
|
+
+----+----+ |
|
36
|
+
| |
|
37
|
+
V |
|
38
|
+
+----+----+ yes |
|
39
|
+
| more? +-------+
|
40
|
+
+----+----+
|
41
|
+
| no
|
42
|
+
V
|
43
|
+
/----+----\\
|
44
|
+
| End |
|
45
|
+
\\---------/
|
46
|
+
EOF
|
47
|
+
|
48
|
+
Test2=<<-EOF
|
49
|
+
+---------+ +---------+ +---------+
|
50
|
+
| Shape | | Line | | Point |
|
51
|
+
+---------+ +---------+ 2 +---------+
|
52
|
+
| draw +<--------+ start +----O+ x |
|
53
|
+
| move +<-+ | end | | y |
|
54
|
+
+---------+ \\ +---------+ +---------+
|
55
|
+
\\
|
56
|
+
\\ +---------+
|
57
|
+
+--+ Circle |
|
58
|
+
+---------+
|
59
|
+
| center |
|
60
|
+
| radius |
|
61
|
+
+---------+
|
62
|
+
EOF
|
63
|
+
|
64
|
+
Test3=(<<-EOF
|
65
|
+
/-----------M yes /----------M
|
66
|
+
+-->| then this |--->*--->| and this |
|
67
|
+
/ M-----------/ |no M----------/
|
68
|
+
/------------M / |
|
69
|
+
| First this |-->+ |
|
70
|
+
M------------/ M |
|
71
|
+
M /---------M V /------M
|
72
|
+
+-->| or that |----->*------->| Done |
|
73
|
+
M---------/ M------/
|
74
|
+
EOF
|
75
|
+
).gsub(/M/,"\\")
|
76
|
+
|
77
|
+
require 'diagrams'
|
78
|
+
|
79
|
+
include Diagrams
|
80
|
+
|
81
|
+
|
82
|
+
Tests = [Test0, Test1 , Test3]
|
83
|
+
|
84
|
+
diagrams = Tests.map{|s| Diagram.new(s)}
|
85
|
+
|
86
|
+
|
87
|
+
|
88
|
+
require 'rexml/document'
|
89
|
+
include REXML
|
90
|
+
|
91
|
+
doc = Document.new
|
92
|
+
html = Element.new 'html', doc
|
93
|
+
head = Element.new 'head', html
|
94
|
+
body = Element.new 'body', html
|
95
|
+
title = Element.new 'title', head
|
96
|
+
title << Text.new("Titolo")
|
97
|
+
style=Element.new 'link', head
|
98
|
+
style.attributes['href'] = 'style.css'
|
99
|
+
style.attributes['rel'] = 'stylesheet'
|
100
|
+
style.attributes['type'] = 'text/css'
|
101
|
+
head.add_element 'script', {'src'=>'adjust.js', 'type'=>"text/javascript"}
|
102
|
+
|
103
|
+
diagrams.each do |d|
|
104
|
+
body << Text.new("Diagram ")
|
105
|
+
body << d.to_html
|
106
|
+
#\ body.add_element 'hr', {'style'=>'clear:both'}
|
107
|
+
end
|
108
|
+
|
109
|
+
File.open("tests.html",'w') do |f|
|
110
|
+
f.write '<?xml version="1.0" encoding="utf-8"?>
|
111
|
+
<!DOCTYPE html PUBLIC
|
112
|
+
"-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN"
|
113
|
+
"http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">' unless true
|
114
|
+
doc.write(f)
|
115
|
+
end
|
116
|
+
|
117
|
+
|
118
|
+
|
119
|
+
diagrams.each_with_index do |d, i|
|
120
|
+
File.open("test#{i}.tex", 'w') do |f|
|
121
|
+
f.write d.to_latex
|
122
|
+
end
|
123
|
+
end
|