deplate 0.7.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (145) hide show
  1. data/AUTHORS.TXT +26 -0
  2. data/CHANGES.TXT +177 -0
  3. data/LICENSE.TXT +340 -0
  4. data/NEWS.TXT +29 -0
  5. data/README.TXT +86 -0
  6. data/TODO.TXT +202 -0
  7. data/VERSION.TXT +1 -0
  8. data/bin/deplate +3 -0
  9. data/bin/deplate.bat +2 -0
  10. data/etc/deplate.ini +361 -0
  11. data/lib/deplate.rb +31 -0
  12. data/lib/deplate/abstract-class.rb +30 -0
  13. data/lib/deplate/builtin.rb +11 -0
  14. data/lib/deplate/cache.rb +59 -0
  15. data/lib/deplate/commands.rb +693 -0
  16. data/lib/deplate/common.rb +335 -0
  17. data/lib/deplate/converter.rb +99 -0
  18. data/lib/deplate/core.rb +2705 -0
  19. data/lib/deplate/css/article.css +545 -0
  20. data/lib/deplate/css/deplate.css +699 -0
  21. data/lib/deplate/css/heading-navbar.css +29 -0
  22. data/lib/deplate/css/layout-deplate-print.css +540 -0
  23. data/lib/deplate/css/layout-deplate.css +764 -0
  24. data/lib/deplate/css/sans-serif.css +160 -0
  25. data/lib/deplate/css/serif-e.css +170 -0
  26. data/lib/deplate/css/serif-rel.css +121 -0
  27. data/lib/deplate/css/serif.css +190 -0
  28. data/lib/deplate/css/slides.css +11 -0
  29. data/lib/deplate/css/tabbar-left.css +91 -0
  30. data/lib/deplate/css/tabbar-right-ie.css +14 -0
  31. data/lib/deplate/css/tabbar-right.css +118 -0
  32. data/lib/deplate/css/tabbar-top.css +64 -0
  33. data/lib/deplate/css/tabbar.css +81 -0
  34. data/lib/deplate/css/text-sans-serif.css +154 -0
  35. data/lib/deplate/css/text-serif.css +175 -0
  36. data/lib/deplate/define.rb +439 -0
  37. data/lib/deplate/docbook.rb +738 -0
  38. data/lib/deplate/elements.rb +1355 -0
  39. data/lib/deplate/etc.rb +199 -0
  40. data/lib/deplate/external.rb +135 -0
  41. data/lib/deplate/fmt/dbk-article-4.1.2.rb +21 -0
  42. data/lib/deplate/fmt/dbk-article.rb +46 -0
  43. data/lib/deplate/fmt/dbk-book.rb +46 -0
  44. data/lib/deplate/fmt/dbk-ref.rb +105 -0
  45. data/lib/deplate/fmt/dbk-slides.rb +47 -0
  46. data/lib/deplate/fmt/dbk-snippet.rb +21 -0
  47. data/lib/deplate/fmt/html-snippet.rb +21 -0
  48. data/lib/deplate/fmt/html.rb +1696 -0
  49. data/lib/deplate/fmt/htmlsite.rb +419 -0
  50. data/lib/deplate/fmt/htmlslides.rb +21 -0
  51. data/lib/deplate/fmt/htmlwebsite.rb +70 -0
  52. data/lib/deplate/fmt/latex-snippet.rb +22 -0
  53. data/lib/deplate/fmt/latex.rb +1242 -0
  54. data/lib/deplate/fmt/php.rb +19 -0
  55. data/lib/deplate/fmt/phpsite.rb +19 -0
  56. data/lib/deplate/fmt/plain.rb +598 -0
  57. data/lib/deplate/fmt/template.rb +34 -0
  58. data/lib/deplate/fmt/xhtml10t.rb +41 -0
  59. data/lib/deplate/formatter-snippet.rb +17 -0
  60. data/lib/deplate/formatter.rb +1210 -0
  61. data/lib/deplate/input.rb +492 -0
  62. data/lib/deplate/input/deplate-headings.rb +48 -0
  63. data/lib/deplate/input/deplate-restricted.rb +70 -0
  64. data/lib/deplate/input/deplate.rb +28 -0
  65. data/lib/deplate/input/rdoc.rb +277 -0
  66. data/lib/deplate/input/template.rb +29 -0
  67. data/lib/deplate/lib/latex/highlight-extra.sty +15 -0
  68. data/lib/deplate/lib/latex/highlight-typical.sty +15 -0
  69. data/lib/deplate/lib/tabmenu.js +146 -0
  70. data/lib/deplate/locale/de.latin1 +708 -0
  71. data/lib/deplate/locale/ru.koi8-r +48 -0
  72. data/lib/deplate/locale/zh_cn.gb2312 +35 -0
  73. data/lib/deplate/macros.rb +639 -0
  74. data/lib/deplate/messages.rb +120 -0
  75. data/lib/deplate/metadata.rb +77 -0
  76. data/lib/deplate/metadata/marshal.rb +24 -0
  77. data/lib/deplate/metadata/xml.rb +42 -0
  78. data/lib/deplate/metadata/yaml.rb +26 -0
  79. data/lib/deplate/mod/anyword.rb +56 -0
  80. data/lib/deplate/mod/babelfish.rb +27 -0
  81. data/lib/deplate/mod/code-gvim.rb +52 -0
  82. data/lib/deplate/mod/code-highlight.rb +91 -0
  83. data/lib/deplate/mod/colored-log.rb +17 -0
  84. data/lib/deplate/mod/de.rb +19 -0
  85. data/lib/deplate/mod/en.rb +17 -0
  86. data/lib/deplate/mod/endnotes.rb +60 -0
  87. data/lib/deplate/mod/fr.rb +46 -0
  88. data/lib/deplate/mod/html-asciimath.rb +40 -0
  89. data/lib/deplate/mod/html-deplate-button.rb +15 -0
  90. data/lib/deplate/mod/html-headings-navbar.rb +39 -0
  91. data/lib/deplate/mod/html-obfuscate-email.rb +47 -0
  92. data/lib/deplate/mod/html-sidebar.rb +232 -0
  93. data/lib/deplate/mod/htmlslides-navbar-fh.rb +32 -0
  94. data/lib/deplate/mod/iconv.rb +35 -0
  95. data/lib/deplate/mod/imgurl.rb +30 -0
  96. data/lib/deplate/mod/inlatex-compound.rb +69 -0
  97. data/lib/deplate/mod/koma.rb +109 -0
  98. data/lib/deplate/mod/latex-emph-table-head.rb +38 -0
  99. data/lib/deplate/mod/latex-styles.rb +461 -0
  100. data/lib/deplate/mod/latex-verbatim-small.rb +29 -0
  101. data/lib/deplate/mod/makefile.rb +194 -0
  102. data/lib/deplate/mod/mark-external-urls.rb +38 -0
  103. data/lib/deplate/mod/markup-1-warn.rb +37 -0
  104. data/lib/deplate/mod/markup-1.rb +41 -0
  105. data/lib/deplate/mod/navbar-png.rb +33 -0
  106. data/lib/deplate/mod/noindent.rb +32 -0
  107. data/lib/deplate/mod/numpara.rb +40 -0
  108. data/lib/deplate/mod/particle-math.rb +34 -0
  109. data/lib/deplate/mod/php-extra.rb +44 -0
  110. data/lib/deplate/mod/pstoedit.rb +71 -0
  111. data/lib/deplate/mod/recode.rb +57 -0
  112. data/lib/deplate/mod/ru_koi8-r.rb +20 -0
  113. data/lib/deplate/mod/smiley.rb +50 -0
  114. data/lib/deplate/mod/soffice.rb +23 -0
  115. data/lib/deplate/mod/symbols-latin1.rb +58 -0
  116. data/lib/deplate/mod/symbols-od-utf-8.rb +16 -0
  117. data/lib/deplate/mod/symbols-plain.rb +58 -0
  118. data/lib/deplate/mod/symbols-sgml.rb +97 -0
  119. data/lib/deplate/mod/symbols-utf-8.rb +81 -0
  120. data/lib/deplate/mod/symbols-xml.rb +34 -0
  121. data/lib/deplate/mod/syntax-region-alt.rb +37 -0
  122. data/lib/deplate/mod/utf8.rb +49 -0
  123. data/lib/deplate/mod/validate-html.rb +35 -0
  124. data/lib/deplate/mod/xmlrpc.rb +233 -0
  125. data/lib/deplate/mod/zh-cn-autospace.rb +108 -0
  126. data/lib/deplate/mod/zh-cn.rb +59 -0
  127. data/lib/deplate/once-method.rb +44 -0
  128. data/lib/deplate/output.rb +249 -0
  129. data/lib/deplate/particles.rb +815 -0
  130. data/lib/deplate/regions.rb +1076 -0
  131. data/lib/deplate/structured.rb +763 -0
  132. data/lib/deplate/template.rb +430 -0
  133. data/lib/deplate/templates/html-doc.html +28 -0
  134. data/lib/deplate/templates/html-left-tabbar-js.html +37 -0
  135. data/lib/deplate/templates/html-left-tabbar.html +31 -0
  136. data/lib/deplate/templates/html-tabbar-right-table.html +43 -0
  137. data/lib/deplate/templates/html-tabbar-right.html +23 -0
  138. data/lib/deplate/templates/html-tabbar-top.html +43 -0
  139. data/lib/deplate/templates/html-tabbar.html +31 -0
  140. data/lib/deplate/wiki-markup.rb +117 -0
  141. data/lib/deplate/xml.rb +109 -0
  142. data/lib/deplate/zh-cn.rb +59 -0
  143. data/lib/ps2ppm.rb +239 -0
  144. data/man/man1/deplate.1 +692 -0
  145. metadata +210 -0
@@ -0,0 +1,1076 @@
1
+ # regions.rb
2
+ # @Author: Thomas Link (samul AT web.de)
3
+ # @Website: http://deplate.sf.net/
4
+ # @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
5
+ # @Created: 08-Mai-2004.
6
+ # @Last Change: 27-Okt-2005.
7
+ # @Revision: 0.1530
8
+
9
+ # Description:
10
+ #
11
+ # Usage:
12
+ #
13
+ # TODO:
14
+ #
15
+ # CHANGES:
16
+ #
17
+
18
+ class Deplate::Region < Deplate::Element
19
+ @@regions = {}
20
+
21
+ class << self
22
+ attr_reader :line_cont
23
+
24
+ def regions
25
+ @@regions
26
+ end
27
+
28
+ def register_as(name, c=self)
29
+ @@regions[name] = self
30
+ end
31
+
32
+ def set_line_cont(val=true)
33
+ @line_cont=val
34
+ end
35
+ end
36
+
37
+ attr_reader :regNote
38
+ attr_accessor :indent
39
+
40
+ def setup(region=nil)
41
+ if region
42
+ @region = region
43
+ @args = region.args
44
+ update_args
45
+ end
46
+ end
47
+
48
+ def finish_accum
49
+ if @region
50
+ unify_now(@region)
51
+ @regNote = @region.regNote ? @region.regNote.strip : ""
52
+ @accum = @region.accum
53
+ else
54
+ @regNote = ""
55
+ end
56
+ if defined?(@indent)
57
+ rx = /^#{@indent}/
58
+ @accum.each do |l|
59
+ l.gsub!(rx, "")
60
+ end
61
+ end
62
+ end
63
+
64
+ def finish
65
+ finish_accum
66
+ return super
67
+ end
68
+
69
+ def format_compound
70
+ acc = []
71
+ prototype = @expected || @prototype.class
72
+ for e in @elt
73
+ e.match_expected(prototype, self) # if prototype
74
+ # e.doc_type = doc_type
75
+ # e.doc_slot = doc_slot
76
+ acc << e.format_current
77
+ end
78
+ fmt = self.class.formatter2 || self.class.formatter
79
+ if fmt
80
+ @elt = @deplate.formatter.join_blocks(acc)
81
+ return format_current(fmt)
82
+ else
83
+ return @deplate.formatter.join_blocks(acc)
84
+ end
85
+ end
86
+
87
+ class << self
88
+ def check_file(container, out, file, source)
89
+ if Dir[out].empty?
90
+ container.log(["Output not found", out, Dir.pwd])
91
+ return false
92
+ elsif file and source
93
+ if File.exist?(file)
94
+ accum = File.open(file) {|io| io.read}.split(/[\n\r]+/)
95
+ clean_strings(accum)
96
+ clean_strings(source)
97
+ if accum === source
98
+ container.log(["Output exists and source matches", file])
99
+ return true
100
+ else
101
+ container.log(["Source has changed", file, accum.size, source.size])
102
+ for i in 0..[accum.size, source.size].max
103
+ unless accum[i] === source[i]
104
+ container.log("%S != %S", [accum[i], source[i]])
105
+ end
106
+ end
107
+ end
108
+ else
109
+ container.log(["Source not found; assume that output is okay", file])
110
+ return true
111
+ end
112
+ end
113
+ container.log(["Output needs updating", file])
114
+ return false
115
+ end
116
+
117
+ def clean_strings(strings)
118
+ strings.delete("")
119
+ strings.each {|l| l.chomp!}
120
+ end
121
+ end
122
+ end
123
+
124
+
125
+ class Deplate::Region::SecondOrder < Deplate::Region
126
+ def finish
127
+ finish_accum
128
+ @elt = @deplate.parsed_array_from_strings(@accum, @source.begin, @source.file)
129
+ return self
130
+ end
131
+
132
+ def process
133
+ process_etc
134
+ @elt = @elt.collect {|e| e.process}.compact
135
+ @prototype = @elt.first
136
+ @prototype.put_label(@label) if @prototype
137
+ return self
138
+ end
139
+
140
+ alias format_special format_compound
141
+ end
142
+
143
+
144
+ module Deplate::Regions; end
145
+
146
+ class Deplate::Regions::UNKNOWN < Deplate::Region
147
+ register_as 'UNKNOWN'
148
+ set_formatter :format_unknown
149
+ set_line_cont
150
+
151
+ def finish
152
+ # finish_accum
153
+ # @elt = @accum
154
+ # return self
155
+ ### !!! We drop it
156
+ return nil
157
+ end
158
+
159
+ def process
160
+ return self
161
+ end
162
+
163
+ def format_special
164
+ format_unknown(self)
165
+ end
166
+ end
167
+
168
+
169
+ class Deplate::Regions::Doc < Deplate::Region
170
+ register_as 'Doc'
171
+ register_as 'Var'
172
+ set_line_cont false
173
+
174
+ def finish
175
+ finish_accum
176
+ id = @args["id"] || @regNote
177
+ @deplate.variables[id] = @accum
178
+ @deplate.register_metadata(@source,
179
+ "type" => "variable",
180
+ "name" => id,
181
+ "value" => @accum
182
+ )
183
+ return nil
184
+ end
185
+ end
186
+
187
+
188
+ class Deplate::Regions::Native < Deplate::Region
189
+ register_as 'Native'
190
+ set_line_cont false
191
+
192
+ def finish
193
+ finish_accum
194
+ @elt = @accum
195
+ return self
196
+ end
197
+
198
+ def process
199
+ process_etc
200
+ @elt = @elt.join("\n")
201
+ return self
202
+ end
203
+
204
+ def format_special
205
+ @elt
206
+ end
207
+ end
208
+
209
+
210
+ class Deplate::Regions::Code < Deplate::Regions::Native
211
+ register_as 'Code'
212
+ set_line_cont false
213
+
214
+ @@code_idx = 0
215
+ @general_highlighter = {}
216
+ @syntax_highlighter = {}
217
+
218
+ class << self
219
+ attr_reader :syntax_highlighter, :general_highlighter
220
+ def add_highlighter(syntax, format, agent)
221
+ if syntax
222
+ @syntax_highlighter[syntax] ||= []
223
+ @syntax_highlighter[syntax] << [format, agent]
224
+ else
225
+ @general_highlighter[format] = agent
226
+ end
227
+ end
228
+ end
229
+
230
+ def setup(region)
231
+ super
232
+ @label_mode = :once
233
+ @syntax = @deplate.variables["codeSyntax"]
234
+ @style = @deplate.variables["codeStyle"]
235
+ end
236
+
237
+ def process
238
+ process_etc
239
+ text = @elt.join("\n")
240
+ if (s = @args["syntax"])
241
+ @syntax = s
242
+ end
243
+ if (s = @args["style"])
244
+ @style = s
245
+ end
246
+ if @style
247
+ @style = Deplate::Core.clean_file_name(@style)
248
+ @deplate.call_methods_matching(@deplate.formatter, /^hook_code_process_/, @style)
249
+ end
250
+ if @syntax
251
+ e = nil
252
+ @deplate.in_working_dir do
253
+ fmt_name = @deplate.formatter.formatter_name
254
+ id = @args["id"]
255
+ if id
256
+ id.gsub!(/\W/, "00")
257
+ fcode = @deplate.auxiliary_filename("code_#{id}")
258
+ fout = @deplate.auxiliary_filename("code_#{id}.#{fmt_name}")
259
+ else
260
+ log("No id given", :anyway)
261
+ @@code_idx += 1
262
+ fcode = @deplate.auxiliary_filename(@deplate.auxiliary_auto_filename('code', @@code_idx, @elt, @syntax))
263
+ fout = @deplate.auxiliary_filename(@deplate.auxiliary_auto_filename('code', @@code_idx, @elt, fmt_name))
264
+ end
265
+ if Deplate::Region.check_file(self, fout, fcode, @elt)
266
+ log(["Files exist! Using", fout], :anyway)
267
+ File.open(fout) {|io| @elt = io.read}
268
+ return self
269
+ else
270
+ begin
271
+ specialized_highlighter = self.class.syntax_highlighter[@syntax]
272
+ if specialized_highlighter
273
+ specialized_highlighter.each do |fmt, agent|
274
+ if @deplate.formatter.matches?(fmt)
275
+ e = send(agent, @syntax, @style, text)
276
+ break if e
277
+ end
278
+ end
279
+ end
280
+ unless e
281
+ agent = self.class.general_highlighter[fmt_name]
282
+ e = send(agent, @syntax, @style, text) if agent
283
+ end
284
+ rescue StandardError => e
285
+ log("#Code: #{e}", :error)
286
+ end
287
+ if e
288
+ File.open(fcode, "w") {|io| io.puts(text)} if fcode
289
+ File.open(fout, "w") {|io| io.puts(e)} if fout
290
+ end
291
+ end
292
+ end
293
+ if e
294
+ @elt = e
295
+ return self
296
+ end
297
+ else
298
+ log("Code: No syntax defined!", :error)
299
+ end
300
+ return Deplate::Regions::Verbatim.new(@deplate, @source, text, @match, self).finish.process
301
+ end
302
+ end
303
+
304
+
305
+ class Deplate::Regions::Inlatex < Deplate::Region
306
+ register_as 'Inlatex'
307
+ register_as 'Ltx'
308
+ set_line_cont
309
+ set_formatter :format_inlatex
310
+
311
+ attr_reader :content_type
312
+
313
+ def setup(region)
314
+ super
315
+ @content_type = @args["type"] || "fig"
316
+ @label_mode = :once
317
+ end
318
+
319
+ def finish
320
+ finish_accum
321
+ pre = @deplate.variables['inlatexPrelude']
322
+ @accum = [pre, @accum].flatten.compact if pre
323
+ @deplate.formatter.inlatex(self)
324
+ return self
325
+ end
326
+
327
+ def process
328
+ process_etc
329
+ return self
330
+ end
331
+
332
+ def register_caption
333
+ if @args["inline"]
334
+ log("Can't attach caption to a LaTeX fragment marked as inline", :error)
335
+ elsif @content_type == "table"
336
+ register_table
337
+ else
338
+ register_figure
339
+ end
340
+ end
341
+ end
342
+
343
+
344
+ class Deplate::Regions::Img < Deplate::Region
345
+ register_as 'Img'
346
+ register_as 'Image'
347
+ register_as 'Fig'
348
+ register_as 'Figure'
349
+ set_line_cont
350
+
351
+ @@ImgAutoN = 0
352
+ @@ImgSuffix = {}
353
+
354
+ def finish
355
+ finish_accum
356
+ nt = @regNote.split(/ /)
357
+ @prg = nt[0]
358
+ @cmdLineArgs = nt[1..-1]
359
+ unless @prg
360
+ log("No programm name given!", :error)
361
+ else
362
+ begin
363
+ @args["sfx"] ||= @deplate.variables["imgSfx"]
364
+ imgClass = Deplate::Regions.const_get("Img_" + @prg)
365
+ self.extend(imgClass)
366
+ i = img
367
+ i.args.update(@args)
368
+ i.update_args
369
+ return i
370
+ rescue StandardError => e
371
+ log(["Program call failed", e, e.backtrace[0..10]], :error)
372
+ end
373
+ end
374
+ return nil
375
+ end
376
+
377
+ def img
378
+ id = @args["id"]
379
+ unless id
380
+ @@ImgAutoN += 1
381
+ id = @deplate.auxiliary_auto_filename('img', @@ImgAutoN, @accum)
382
+ end
383
+ sfx = @args["sfx"] || suffix
384
+ src = "#{id}.#{@prg}"
385
+ out = "#{id}.#{sfx}"
386
+ pwd = Dir.pwd
387
+ d = @deplate.dest ? File.dirname(@deplate.dest) : "."
388
+ i = nil
389
+ @deplate.in_working_dir do
390
+ accum = prepare(@accum, out, sfx)
391
+ if Deplate::Region.check_file(self, out, src, accum)
392
+ log(["Files exist! Using", out], :anyway)
393
+ else
394
+ unless @deplate.options.force
395
+ for f in [src]
396
+ if File.exist?(f)
397
+ raise "Please delete '#{f}' or change the id before proceeding"
398
+ end
399
+ end
400
+ end
401
+ Deplate::External.write_file(self, src) {|io| io.puts(accum.join("\n"))}
402
+ run(src, out, sfx)
403
+ end
404
+ if block_given?
405
+ i = yield(id, out)
406
+ else
407
+ i = Deplate::Command::IMG.new(@deplate, @source, out, @match, @args, "IMG")
408
+ i.finish
409
+ end
410
+ end
411
+ return i
412
+ end
413
+
414
+ def suffix
415
+ block = @@ImgSuffix[@deplate.formatter.class]
416
+ if block
417
+ return block.call(self)
418
+ else
419
+ return "png"
420
+ end
421
+ end
422
+
423
+ end
424
+
425
+
426
+ module Deplate::Regions::Img_standard
427
+ def prepare(accum, out, sfx)
428
+ return accum
429
+ end
430
+
431
+ def run(dot, out, sfx)
432
+ raise "SubClassResponsibility"
433
+ end
434
+ end
435
+
436
+ module Deplate::Regions::Img_dot
437
+ include Deplate::Regions::Img_standard
438
+
439
+ def run(dot, out, sfx)
440
+ Deplate::External.dot(self, sfx, dot, out, @cmdLineArgs)
441
+ end
442
+ end
443
+
444
+ module Deplate::Regions::Img_neato
445
+ include Deplate::Regions::Img_standard
446
+
447
+ def run(dot, out, sfx)
448
+ Deplate::External.dot(self, sfx, dot, out, @cmdLineArgs)
449
+ end
450
+ end
451
+
452
+ module Deplate::Regions::Img_R
453
+ include Deplate::Regions::Img_standard
454
+
455
+ def prepare(accum, out, sfx)
456
+ pre = []
457
+ post = []
458
+
459
+ # trellis.device(jpeg, file="plotTrouble2.jpg",
460
+ # theme = col.whitebg(),height=480,width=480)
461
+ # trellis.last.object()
462
+ # dev.off()
463
+ case sfx
464
+ when "png"
465
+ args = check_arguments("png", ["width", "height", "pointsize",
466
+ "bg"])
467
+ pre << %{png(filename="#{out}"%s)} % args
468
+ when "jpg"
469
+ args = check_arguments("png", ["width", "height", "pointsize",
470
+ "bg", "pointsize", "quality", "res"])
471
+ pre << %{jpg(filename="#{out}"%s)} % args
472
+ when "bmp"
473
+ args = check_arguments("png", ["width", "height", "pointsize",
474
+ "bg", "pointsize", "res"])
475
+ pre << %{bmp(filename="#{out}"%s)} % args
476
+ when "pdf"
477
+ args = check_arguments("pdf", ["width", "height", "family",
478
+ "title", "encoding", "bg", "fg",
479
+ "pointsize"])
480
+ pre << %{pdf(file="#{out}", onefile=TRUE%s)} % args
481
+ when "ps"
482
+ args = check_arguments("ps", ["width", "height", "family",
483
+ "title", "encoding", "bg", "fg",
484
+ "pointsize", "horizontal"])
485
+ pre << %{postscript(file="#{out}", onefile=TRUE, paper="special"%s)} % args
486
+ when "wmf"
487
+ args = check_arguments("wmf", ["width", "height", "pointsize"])
488
+ pre << %{win.metafile(filename="#{out}"%s)} % args
489
+ else
490
+ log(["Unknown suffix", sfx], :error)
491
+ raise
492
+ end
493
+ post << "dev.off()"
494
+ return (pre + accum + post).flatten
495
+ end
496
+
497
+ def check_arguments(type, arr)
498
+ rv = []
499
+ for a in arr
500
+ v = @args["%s_%s" % [type, a]] || @args["_%s" % a]
501
+ rv << "%s=%s" % [a, v] if v
502
+ end
503
+ if rv.empty?
504
+ return nil
505
+ else
506
+ rv.unshift(nil)
507
+ return rv.join(", ")
508
+ end
509
+ end
510
+
511
+ def run(r, out, sfx)
512
+ Deplate::Regions::R.run(self, r, nil)
513
+ end
514
+ end
515
+
516
+
517
+ class Deplate::Regions::Footnote < Deplate::Region
518
+ register_as 'Footnote'
519
+ register_as 'Fn'
520
+ set_line_cont
521
+
522
+ FootnoteDef = Struct.new("DeplateFootnoteDef", :args, :body, :label, :n, :consumed)
523
+
524
+ def finish
525
+ finish_accum
526
+ accum = @deplate.parsed_array_from_strings(@accum, 1 + @source.begin, @source.file)
527
+ id = @args['id'] ||= @regNote
528
+ @elt = FootnoteDef.new(@args, [accum], id)
529
+ @deplate.footnotes[id] = self
530
+ # @deplate.register_metadata(src,
531
+ # "type" => "footnote",
532
+ # "name" => id,
533
+ # "value" => accum
534
+ # )
535
+ return nil
536
+ end
537
+
538
+ def process_particles(&block)
539
+ @elt.body = ( @elt.body.collect(&block) ).join
540
+ end
541
+ end
542
+
543
+
544
+ class Deplate::Regions::Foreach < Deplate::Region
545
+ register_as 'Foreach'
546
+ set_line_cont
547
+
548
+ def finish
549
+ finish_accum
550
+ @id = @args['@id'].split(/[\s,]+/)
551
+ unless @id
552
+ log('No id given', :error)
553
+ return nil
554
+ end
555
+ doc = @args['doc']
556
+ if doc
557
+ @list = @deplate.variables[doc]
558
+ else
559
+ @list = @regNote
560
+ end
561
+ if @list.kind_of?(Array)
562
+ @list = @list.flatten
563
+ else
564
+ rx = @args['rx']
565
+ if rx
566
+ @list = @list.split(Regexp.new(rx))
567
+ else
568
+ sep = @args['sep']
569
+ if sep
570
+ sep = Regexp.new(Regexp.escape(sep))
571
+ @list = @list.split(sep)
572
+ else
573
+ @list = [@list]
574
+ end
575
+ end
576
+ end
577
+ @foreach = []
578
+ while !@list.empty?
579
+ ids = {}
580
+ for i in @id
581
+ ids[i] = @list.shift
582
+ end
583
+ Deplate::Define.let_variables(@deplate, ids) do
584
+ acc = @deplate.parsed_array_from_strings(@accum, 1 + @source.begin, @source.file)
585
+ @prototype ||= acc[0]
586
+ @foreach << [ids, acc]
587
+ end
588
+ end
589
+ return self
590
+ end
591
+
592
+ def process_particles(&block)
593
+ @elt = []
594
+ for ids, acc in @foreach
595
+ Deplate::Define.let_variables(@deplate, ids) do
596
+ @elt << acc.collect {|e| e.process}
597
+ end
598
+ end
599
+ @elt = @elt.flatten.compact
600
+ end
601
+
602
+ alias format_special format_compound
603
+ end
604
+
605
+
606
+ class Deplate::Regions::Table < Deplate::Region
607
+ register_as 'Table'
608
+ set_line_cont
609
+
610
+ def finish
611
+ finish_accum
612
+ case @regNote.strip
613
+ when "limited"
614
+ log("Not yet implemented!", :error)
615
+ return nil
616
+ else
617
+ return Deplate::Regions::Table.make_char_separated(self, @accum, @args["sep"])
618
+ end
619
+ end
620
+
621
+ class << self
622
+ def make_char_separated(instance, accum, sep=nil)
623
+ sep = Regexp.new(sep || "\t")
624
+ acc = accum.collect {|l| %{| #{l.gsub(sep, " | ")} |}}
625
+ beg = 1 + instance.source.begin
626
+ file = instance.source.file
627
+ table = instance.deplate.parsed_array_from_strings(acc, beg, file)
628
+ n = table[0]
629
+ n.collapse = false
630
+ n.args = instance.args
631
+ return n
632
+ end
633
+ end
634
+ end
635
+
636
+
637
+ class Deplate::Regions::Verbatim < Deplate::Region
638
+ register_as 'Verbatim'
639
+ register_as 'Verb'
640
+ set_formatter :format_verbatim
641
+ set_line_cont false
642
+
643
+ def finish
644
+ finish_accum
645
+ @elt = [ @accum ]
646
+ @verbatimMargin = @deplate.variables['verbatimMargin']
647
+ return self
648
+ end
649
+
650
+ def process
651
+ process_etc
652
+ @elt = @elt.join("\n")
653
+ margin = @args["wrap"] || @verbatimMargin
654
+ if margin
655
+ @elt = @deplate.formatter.wrap_text(@elt, :margin => margin.to_i)
656
+ end
657
+ # @elt = Deplate::Core.remove_backslashes(@elt.join("\n"))
658
+ return self
659
+ end
660
+ end
661
+
662
+
663
+ class Deplate::Regions::Abstract < Deplate::Region::SecondOrder
664
+ register_as 'Abstract'
665
+ set_formatter :format_abstract, true
666
+ set_line_cont
667
+
668
+ def finish
669
+ rv = super
670
+ lang = @args['lang'] || @deplate.options.lang
671
+ hd = @deplate.headings[@level_heading]
672
+ if hd
673
+ hd.abstract = self
674
+ if hd != @top_heading
675
+ @top_heading.abstract ||= self
676
+ end
677
+ else
678
+ @deplate.register_metadata(@source,
679
+ "type" => "abstract",
680
+ "lang" => lang,
681
+ "value" => @accum
682
+ )
683
+ end
684
+ rv
685
+ end
686
+ end
687
+
688
+
689
+ # class Deplate::Regions::Quote < Deplate::Region
690
+ class Deplate::Regions::Quote < Deplate::Region::SecondOrder
691
+ register_as 'Quote'
692
+ register_as 'Qu'
693
+ set_formatter :format_quote, true
694
+ set_line_cont
695
+ end
696
+
697
+
698
+ class Deplate::Regions::R < Deplate::Region
699
+ register_as 'R'
700
+ set_line_cont
701
+
702
+ @@RAutoN = 0
703
+
704
+ def finish
705
+ finish_accum
706
+ begin
707
+ return do_R
708
+ rescue StandardError => e
709
+ log(["Program call failed", e, e.backtrace[0..10]], :error)
710
+ return nil
711
+ end
712
+ end
713
+
714
+ def do_R
715
+ pre = @deplate.variables['rPrelude']
716
+ if pre
717
+ @accum = [pre, @accum].flatten.compact
718
+ end
719
+ id = @args["id"]
720
+ unless id
721
+ @@RAutoN += 1
722
+ id = @deplate.auxiliary_auto_filename('r', @@RAutoN, @accum)
723
+ end
724
+ r = "#{id}.R"
725
+ out = "#{id}.Rout"
726
+ case @regNote.strip
727
+ when "xtable"
728
+ rOut = do_xtable(r, out)
729
+ when "drop"
730
+ rOut = do_drop(r, out)
731
+ when "verb", "verbatim"
732
+ rOut = do_verbatim(r, out)
733
+ else
734
+ rOut = do_normal(r, out)
735
+ end
736
+ if rOut
737
+ rOut.args.update(@args)
738
+ return rOut
739
+ end
740
+ end
741
+
742
+ def do_xtable(r, out)
743
+ @accum.unshift(%{library(xtable)})
744
+ if send_to_R(r, out)
745
+ table = []
746
+ pre = []
747
+ # cap = nil
748
+ post = []
749
+ mode = :pre
750
+ for l in @accum
751
+ xtable_postprocess_text(l)
752
+ m = /^\<([^> ]+).*?\>(.*)?(\<\/(\S+)\>)?$/.match(l)
753
+ if m
754
+ case m[1]
755
+ when "!--"
756
+ next
757
+ when "TABLE"
758
+ mode = :table
759
+ when "/TABLE"
760
+ mode = :post
761
+ when "TR"
762
+ row = l.scan(/\<TH.*?\>(\s+.*?)\<\/TH\>/).flatten
763
+ unless row.empty?
764
+ table << "|| #{row.join(" || ")} ||"
765
+ else
766
+ row = l.scan(/\<TD.*?\>(\s+.*?)\<\/TD\>/).flatten
767
+ table << "| #{row.join(" | ")} |" unless row.empty?
768
+ end
769
+ log(["R xtable: row", row], :debug)
770
+ # when "CAPTION"
771
+ # mc = /\<CAPTION.*?\> (.*) \<\/CAPTION\>$/.match(l)
772
+ # cap = mc[1]
773
+ else
774
+ log(["Skip", m[1]])
775
+ end
776
+ else
777
+ case mode
778
+ when :pre
779
+ pre << l
780
+ when :post
781
+ post << l
782
+ end
783
+ end
784
+ end
785
+ accum = @deplate.parsed_array_from_strings(table, 1 + @source.begin, @source.file)
786
+ if accum.size != 1
787
+ log(["Unexpected R output (too many elements)",
788
+ out, accum.collect {|e| e.class}], :error)
789
+ end
790
+ until accum.empty? or accum[0].kind_of?(Deplate::Element::Table)
791
+ e = accum.shift
792
+ log(["Unexpected R output (Please check the output for errors!)",
793
+ out, e.class], :error)
794
+ end
795
+ rOut = accum[0]
796
+ if rOut
797
+ rOut.collapse = false
798
+ rOut.preNote = pre.join("\n")
799
+ rOut.postNote = post.join("\n")
800
+ log(["R xtable: pre", rOut.preNote], :debug)
801
+ log(["R xtable: post", rOut.postNote], :debug)
802
+ return rOut
803
+ end
804
+ end
805
+ end
806
+
807
+ def do_drop(r, out)
808
+ send_to_R(r, out)
809
+ return nil
810
+ end
811
+
812
+ def do_verbatim(r, out)
813
+ if send_to_R(r, out)
814
+ @elt = @accum.join("\n")
815
+ rOut = Deplate::Regions::Verbatim.new(@deplate, @source, @text, @match, self)
816
+ rOut.finish
817
+ return rOut
818
+ end
819
+ end
820
+
821
+ def do_normal(r, out)
822
+ if send_to_R(r, out)
823
+ scn = table_scanner(@accum)
824
+ @accum.collect! do |r|
825
+ if r =~ /^\s*$/
826
+ "| |"
827
+ elsif @deplate.variables['rScanTable']
828
+ cells = scn.match(r)
829
+ if cells
830
+ cells = cells.captures.collect {|c| c.strip}
831
+ ['|', cells.join(' | '), '|'].join(' ')
832
+ else
833
+ puts @accum.join("\n")
834
+ raise 'DBG: Error in table scanner (please report)'
835
+ end
836
+ else
837
+ "| %s |" % Deplate::Particle::Code.markup(r.gsub(/ /, "\\\\ "))
838
+ end
839
+ end
840
+ accum = @deplate.parsed_array_from_strings(@accum, 1 + @source.begin, @source.file)
841
+ # if accum.size != 1 and accum[0].class != Deplate::Element::Table
842
+ if accum[0].class != Deplate::Element::Table
843
+ log(["Expected exactly one element of type Table", accum.collect {|e| e.class}.join(" ")], :error)
844
+ end
845
+ rOut = accum[0]
846
+ if rOut
847
+ rOut.collapse = false
848
+ else
849
+ log(["R yielded no output", out], :error)
850
+ end
851
+ return rOut
852
+ end
853
+ end
854
+
855
+ def table_scanner(strings)
856
+ max = 0
857
+ for l in strings
858
+ ls = l.size
859
+ if ls > max
860
+ max = ls
861
+ end
862
+ end
863
+ blanks = [true] * max
864
+ for l in strings
865
+ for i in 0..(l.size - 1)
866
+ if l[i] != 32
867
+ blanks[i] &&= false
868
+ end
869
+ end
870
+ end
871
+ lst = true
872
+ blanks.collect! do |c|
873
+ if c and lst
874
+ rv = false
875
+ else
876
+ rv = c
877
+ end
878
+ lst = c
879
+ rv
880
+ end
881
+ acc = []
882
+ lst = -1
883
+ blanks.each_with_index do |c, i|
884
+ if c
885
+ d = i - lst
886
+ lst = i
887
+ acc << ' ' unless acc.empty?
888
+ acc << '(' << '.' * (d - 1) << ')'
889
+ end
890
+ end
891
+ d = max - 1 - lst
892
+ if d > 1
893
+ acc << ' ' unless acc.empty?
894
+ acc << '(' << '.' * (d - 1) << ')'
895
+ end
896
+ Regexp.new(acc.join)
897
+ end
898
+
899
+ def xtable_postprocess_text(text)
900
+ text.gsub!(/&amp;?/, %{&})
901
+ text.gsub!(/&lt;?/, %{<})
902
+ text.gsub!(/&gt;?/, %{>})
903
+ text.gsub!(/&quot;?/, %{"})
904
+ text
905
+ end
906
+
907
+ def send_to_R(r, out)
908
+ pwd = Dir.pwd
909
+ d = File.dirname(@deplate.dest)
910
+ rv = false
911
+ @deplate.in_working_dir do
912
+ log(["Running R", d, r, out])
913
+ begin
914
+ @accum.unshift(%{deplate.fmt <- "#{@deplate.formatter.formatter_name}"})
915
+ if Deplate::Region.check_file(self, out, r, @accum)
916
+ log(["Files exist! Using", out], :anyway)
917
+ else
918
+ unless @deplate.options.force
919
+ for f in [r, out]
920
+ if File.exist?(f)
921
+ raise "Please delete '#{f}' or change the id before proceeding\nUse the --force option to avoid this message."
922
+ end
923
+ end
924
+ end
925
+ Deplate::External.write_file(self, r) {|io| io.puts(@accum.join("\n"))}
926
+ run(r, out)
927
+ end
928
+ @accum = File.open(out) {|io| io.read}.split(/[\n\r]+/)
929
+ skip = @args["skip"]
930
+ if skip
931
+ head, tail = skip.split(/,/).collect {|n| n.to_i}
932
+ @accum = @accum[(head || 0) .. (@accum.size - tail - 1 || -1)] || []
933
+ end
934
+ rv = true
935
+ rescue StandardError => e
936
+ log("#R: #{e}", :error)
937
+ end
938
+ end
939
+ return rv
940
+ end
941
+
942
+ def run(r, out)
943
+ return Deplate::Regions::R.run(self, r, out)
944
+ end
945
+
946
+ class << self
947
+ def run(container, r, out)
948
+ Deplate::External.r(container, r, out)
949
+ end
950
+ end
951
+ end
952
+
953
+
954
+ class Deplate::Regions::Ruby < Deplate::Region
955
+ register_as 'Ruby'
956
+ set_line_cont
957
+
958
+ def finish
959
+ finish_accum
960
+ @accum = [@deplate.eval_ruby(self, @args, @accum.join("\n")).to_s]
961
+ if @args["verb"]
962
+ return Deplate::Regions::Verbatim.new(@deplate, @source, @accum, @match, self).finish
963
+ elsif @args["img"] or @args["image"]
964
+ file = @args["img"] || @args["image"]
965
+ return Deplate::Command::IMG.new(@deplate, @source, file, nil, {}, "IMG").finish
966
+ elsif @args["native"]
967
+ return Deplate::Regions::Native.new(@deplate, @source, @accum, @match, self).finish
968
+ else
969
+ acc = []
970
+ @accum.collect! {|l| l.split(/\n/)}
971
+ @accum.flatten!
972
+ @deplate.include_stringarray(@accum, acc, @source.begin, @source.file)
973
+ return acc
974
+ end
975
+ end
976
+ end
977
+
978
+
979
+ class Deplate::Regions::Clip < Deplate::Region::SecondOrder
980
+ register_as 'Clip'
981
+ register_as 'Put'
982
+ register_as 'Set'
983
+ set_line_cont
984
+
985
+ # attr_accessor :prototype
986
+ attr_reader :is_template, :inline
987
+
988
+ def from_strings(strings)
989
+ @accum = strings
990
+ finish
991
+ end
992
+
993
+ def finish
994
+ finish_accum
995
+ id = @args["id"] || @regNote
996
+ @doc_type = :array
997
+ @processed = false
998
+ @elt = @deplate.parsed_array_from_strings(@accum, @source.begin, @source.file)
999
+ @deplate.set_clip(id, self)
1000
+ return nil
1001
+ end
1002
+
1003
+ def process
1004
+ unless @processed
1005
+ @processed = true
1006
+ return super
1007
+ else
1008
+ return self
1009
+ end
1010
+ end
1011
+
1012
+ def format_clip(invoker, expected)
1013
+ @expected = expected
1014
+ @invoker = invoker
1015
+ format_special
1016
+ end
1017
+
1018
+ def log(*args)
1019
+ if @invoker
1020
+ @invoker.log(*args)
1021
+ else
1022
+ super
1023
+ end
1024
+ end
1025
+ end
1026
+
1027
+
1028
+ class Deplate::Regions::Header < Deplate::Region
1029
+ register_as 'Header'
1030
+ set_formatter :format_header
1031
+ set_line_cont
1032
+
1033
+ def finish
1034
+ finish_accum
1035
+ @elt = @deplate.parsed_array_from_strings(@accum, 1 + @source.begin, @source.file)
1036
+ return self
1037
+ end
1038
+
1039
+ def process
1040
+ process_etc
1041
+ for e in @elt
1042
+ e.process
1043
+ end
1044
+ @elt.compact!
1045
+ return self
1046
+ end
1047
+ end
1048
+
1049
+
1050
+ class Deplate::Regions::Footer < Deplate::Regions::Header
1051
+ register_as 'Footer'
1052
+ set_formatter :format_footer
1053
+ set_line_cont
1054
+ end
1055
+
1056
+
1057
+ class Deplate::Regions::Swallow < Deplate::Region
1058
+ register_as 'Swallow'
1059
+ register_as 'Skip'
1060
+ set_line_cont
1061
+
1062
+ def finish
1063
+ finish_accum
1064
+ @elt = @deplate.parsed_array_from_strings(@accum, 1 + @source.begin, @source.file)
1065
+ return self
1066
+ end
1067
+
1068
+ def process
1069
+ process_etc
1070
+ for e in @elt
1071
+ e.process
1072
+ end
1073
+ return nil
1074
+ end
1075
+ end
1076
+