deplate 0.7.3

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.
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
+