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,1355 @@
1
+ # elements.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: 26-M�r-2004.
6
+ # @Last Change: 02-Nov-2005.
7
+ # @Revision: 0.3718
8
+
9
+
10
+ class Deplate::DontFormatException < Exception
11
+ end
12
+
13
+ Deplate::CaptionDef = Struct.new('DeplateCaptionDef', :elt, :args)
14
+
15
+ # Deplate::Elements are text entities at line or paragraph level.
16
+ class Deplate::Element < Deplate::BaseElement
17
+ @@elements = []
18
+
19
+ @@accumulate_pre = {}
20
+ @@accumulate_post = {}
21
+
22
+ #### attached labels
23
+ attr_accessor :label
24
+ #### an attached caption (for Table etc.)
25
+ attr_accessor :caption, :captionOptions
26
+ #### is this element in one-line format?
27
+ attr_accessor :multiliner
28
+ #### end pattern
29
+ attr_reader :endRx
30
+ #### the element's level of indentation or whatever
31
+ attr_accessor :level_heading, :top_heading_idx
32
+ #### an array of deferred formatting blocks
33
+ attr_accessor :postponed_format, :postponed_preformat
34
+ #### whether we can collapse this element with another one
35
+ attr_accessor :collapse
36
+ #### postponed registration of metadata
37
+ attr_accessor :registered_metadata
38
+
39
+ attr_reader :line_cont
40
+
41
+ # class methods & variables
42
+ class << self
43
+ # the regular expression for this class
44
+ attr_reader :rx
45
+ attr_reader :labelling
46
+
47
+ def match(text)
48
+ return @rx.match(text)
49
+ end
50
+
51
+ def elements
52
+ return @@elements
53
+ end
54
+
55
+ def is_volatile?(match)
56
+ false
57
+ end
58
+
59
+ def register_element(c=self)
60
+ @@elements << c
61
+ end
62
+
63
+ def set_labelling(val=true)
64
+ @labelling = val
65
+ end
66
+
67
+ def set_name(name)
68
+ @name=name
69
+ end
70
+
71
+ def accumulate(src, array, deplate, text, match, *args)
72
+ Deplate::Core.log(["New element", self.name, text], :debug)
73
+ e = self.new(deplate, src, text, match, *args)
74
+ if e
75
+ array << e
76
+ end
77
+ end
78
+
79
+ def accumulate_pre(klass, format, &block)
80
+ hooks = @@accumulate_pre[klass] || {}
81
+ pre = hooks[format] || []
82
+ hooks[format] = pre << block
83
+ @@accumulate_pre[klass] = hooks
84
+ end
85
+
86
+ def accumulate_post(klass, format, &block)
87
+ hooks = @@accumulate_post[klass] || {}
88
+ post = hooks[format] || []
89
+ hooks[format] = post << block
90
+ @@accumulate_post[klass] = hooks
91
+ end
92
+
93
+ def do_accumulate(src, array, deplate, *args)
94
+ run_accumulation_hooks(@@accumulate_pre[self], src, array, deplate, *args)
95
+ accumulate(src, array, deplate, *args)
96
+ run_accumulation_hooks(@@accumulate_post[self], src, array, deplate, *args)
97
+ end
98
+
99
+ def run_accumulation_hooks(all_hooks, src, array, deplate, *args)
100
+ if all_hooks
101
+ klass = deplate.formatter.class
102
+ begin
103
+ hooks = all_hooks[klass]
104
+ if hooks
105
+ for block in hooks
106
+ block.call(src, array, deplate, *args)
107
+ end
108
+ end
109
+ klass = klass.superclass
110
+ end until klass === Module
111
+ end
112
+ end
113
+
114
+ def get_date(arg, args)
115
+ case arg
116
+ when "now"
117
+ return Time.new.asctime
118
+ when "time"
119
+ return Time.new.strftime("%X")
120
+ when "today"
121
+ return Time.new.strftime("%d. %b %Y")
122
+ when "month"
123
+ return Time.new.strftime("%B %Y")
124
+ when "year"
125
+ return Time.new.strftime("%Y")
126
+ when "", nil
127
+ return ""
128
+ else
129
+ return Time.new.strftime(arg)
130
+ end
131
+ end
132
+ end
133
+
134
+ def initialize(deplate, src, text, match, *args)
135
+ super(deplate)
136
+ @source = src
137
+ @text = text
138
+ @match = match
139
+ @endRx = nil
140
+ @fmx = nil
141
+ @label = []
142
+ @collapse = nil
143
+ @caption = nil
144
+ @container = nil
145
+ @line_cont = true
146
+ @postponed_format = []
147
+ @postponed_preformat = []
148
+ @registered_metadata = []
149
+
150
+ set_instance_top
151
+
152
+ @deplate.call_methods_matching(self, /^hook_pre_setup_/)
153
+ setup(*args)
154
+ @deplate.call_methods_matching(self, /^hook_post_setup_/)
155
+ end
156
+
157
+ def set_instance_top
158
+ @top_heading_idx = @deplate.top_heading_idx
159
+ @top_heading = @deplate.top_heading_by_idx(@top_heading_idx)
160
+ @level_heading = @deplate.current_heading.dup
161
+ self.level_as_string = @deplate.get_current_heading
162
+ end
163
+
164
+ def setup
165
+ end
166
+
167
+ def level_as_string
168
+ @level_as_string
169
+ end
170
+
171
+ def level_as_string=(val)
172
+ @args[:level_as_string] = val
173
+ @level_as_string = val
174
+ end
175
+
176
+ def put_label(lab, anyway=false)
177
+ if lab
178
+ for l in lab.compact
179
+ # or @deplate.label_aliases.include?(l)
180
+ unless @label.include?(l)
181
+ @label << l
182
+ @deplate.add_label(self, l, @level_as_string, :anyway => anyway)
183
+ end
184
+ end
185
+ end
186
+ end
187
+
188
+ def collapsable?(other)
189
+ return @collapse && other.collapse && self.class == other.class
190
+ end
191
+
192
+ def drop?
193
+ return @collapse == :drop
194
+ end
195
+
196
+ def unify(other)
197
+ if other.drop?
198
+ other.container = self
199
+ return true
200
+ elsif collapsable?(other)
201
+ unify_now(other)
202
+ other.container = self
203
+ return true
204
+ else
205
+ return false
206
+ end
207
+ end
208
+
209
+ def <<(line)
210
+ @accum << line
211
+ end
212
+
213
+ def to_be_continued?(line)
214
+ return @multiliner
215
+ end
216
+
217
+ # compile the accumulated lines in @accum & put the result into @elt
218
+ def finish
219
+ elt = join_lines(@accum)
220
+ @elt = [ @deplate.parse(self, elt) ]
221
+ return self
222
+ end
223
+
224
+ def finished?
225
+ return defined?(@elt) && @elt != nil
226
+ end
227
+
228
+ def join_lines(accum)
229
+ if @deplate.options.keep_whitespace
230
+ return accum.join("\n")
231
+ else
232
+ return accum.join(" ")
233
+ end
234
+ end
235
+
236
+ def process
237
+ process_etc
238
+ process_particles do |e|
239
+ if e.kind_of?(String)
240
+ ### <+TBD+> This actually is more of an error and shouldn't be
241
+ e
242
+ else
243
+ rv = e.collect do |p|
244
+ # <+TBD+> begin
245
+ # p.container = self
246
+ p.process
247
+ # rescue Exception => e
248
+ # puts e.backtrace.join("\n")
249
+ # raise
250
+ # end
251
+ p.elt
252
+ end
253
+ @deplate.join_particles(rv)
254
+ end
255
+ end
256
+ return self
257
+ end
258
+
259
+ def print
260
+ unless @args['swallow']
261
+ for block in @postponed_preformat
262
+ block.call(self)
263
+ end
264
+ output(format_current)
265
+ for block in @postponed_format
266
+ block.call(self)
267
+ end
268
+ end
269
+ end
270
+
271
+ def format_current(formatting_method=nil)
272
+ formatting_method ||= self.class.formatter
273
+ if formatting_method
274
+ elt = format_element(formatting_method, self)
275
+ elsif self.respond_to?(:format_special)
276
+ elt = format_special
277
+ else
278
+ elt = @deplate.formatter.format_unknown(self)
279
+ end
280
+ if elt
281
+ acc = []
282
+ acc << format_prologue
283
+ acc << elt
284
+ acc << format_epilogue
285
+ label_accum(acc, formatting_method) if doc_type == :body
286
+ rv = @deplate.formatter.join_blocks(acc.compact)
287
+ else
288
+ rv = nil
289
+ end
290
+ register_metadata
291
+ return rv
292
+ # rescue Exception => e
293
+ # log(["Formatting failed", self.class.name, e], :error)
294
+ # format_element(:format_unknown, self)
295
+ # end
296
+ end
297
+
298
+ def register_metadata
299
+ @deplate.output.merge_metadata(@registered_metadata)
300
+ for l in @label
301
+ m = @deplate.get_metadata(@source,
302
+ 'type' => 'label',
303
+ 'name' => l
304
+ )
305
+ @deplate.output.push_metadata(m)
306
+ end
307
+ end
308
+
309
+ def label_accum(out, formatting_method)
310
+ fmt = @deplate.formatter
311
+ if fmt.label_once.include?(formatting_method)
312
+ l = format_element(:format_label, self, :once)
313
+ out.unshift(l) unless l.empty?
314
+ elsif fmt.label_delegate.include?(formatting_method)
315
+ else
316
+ case label_mode || fmt.label_mode
317
+ when :once
318
+ l = format_element(:format_label, self, :once)
319
+ out.unshift(l) unless l.empty?
320
+ when :before
321
+ l = format_element(:format_label, self, :before)
322
+ out.unshift(l) unless l.empty?
323
+ when :after
324
+ l = format_element(:format_label, self, :after)
325
+ out.push(l) unless l.empty?
326
+ when :delegate, :self
327
+ else
328
+ lb = format_element(:format_label, self, :before)
329
+ la = format_element(:format_label, self, :after)
330
+ out.unshift(lb) unless lb.empty?
331
+ out.push(la) unless la.empty?
332
+ end
333
+ end
334
+ end
335
+
336
+ def format_prologue
337
+ @prologue.empty? ? nil : @prologue
338
+ end
339
+
340
+ def format_epilogue
341
+ @epilogue.empty? ? nil : @epilogue
342
+ end
343
+
344
+ def destination
345
+ if @top_heading and @top_heading != self
346
+ @top_heading.destination
347
+ else
348
+ @destination
349
+ end
350
+ end
351
+
352
+ def register_caption
353
+ log(["Can't attach caption to", self.class.name], :error)
354
+ end
355
+
356
+ def to_plain_text
357
+ @accum.join("\n")
358
+ end
359
+
360
+ protected
361
+ def process_etc
362
+ if !@caption and @args["caption"]
363
+ caption = @deplate.parse(self, @args["caption"])
364
+ @caption = Deplate::CaptionDef.new(caption, @args)
365
+ end
366
+ if defined?(@caption) && @caption
367
+ elt = @caption.elt.collect {|p| p.process; p.elt}
368
+ @caption.elt = @deplate.join_particles(elt)
369
+ end
370
+ end
371
+ alias process_options process_etc
372
+
373
+ def unify_now(other)
374
+ unify_elt(other)
375
+ unify_props(other)
376
+ end
377
+
378
+ def unify_props(other)
379
+ put_label(other.label, true)
380
+ @args.update(other.args)
381
+ @level ||= other.level
382
+ @caption ||= other.caption
383
+ @captionOptions ||= other.captionOptions
384
+ @source.begin ||= other.source.begin
385
+ @source.end = other.source.end if other.source.end
386
+ if other.styles
387
+ update_styles(other.styles)
388
+ end
389
+ if !level_as_string and other.level_as_string
390
+ self.level_as_string = other.level_as_string
391
+ end
392
+ end
393
+
394
+ def unify_elt(other)
395
+ if @elt.nil?
396
+ @elt = other.elt
397
+ elsif !other.elt.nil?
398
+ @elt += other.elt
399
+ end
400
+ end
401
+
402
+ def container=(element)
403
+ @container = element
404
+ @args = element.args
405
+ @postponed_format = element.postponed_format
406
+ @postponed_preformat = element.postponed_preformat
407
+ end
408
+
409
+ def get_indent(text)
410
+ text = expand_tab(text)
411
+ /^\s*/.match(text)[0]
412
+ end
413
+
414
+ def expand_tab(text)
415
+ tabwidth = @deplate.variables['tabwidth'] || 4
416
+ accum = []
417
+ loop do
418
+ m = /\t/.match(text)
419
+ if m
420
+ pre = m.pre_match
421
+ text = m.post_match
422
+ add = tabwidth - pre.size % tabwidth
423
+ accum << pre + (" " * add)
424
+ else
425
+ return accum.join + text
426
+ end
427
+ end
428
+ return text
429
+ end
430
+
431
+ # call block on all text particles in the current element
432
+ def process_particles(&block)
433
+ if @elt
434
+ @elt = (@elt.collect(&block)).join
435
+ else
436
+ log(["Internal error: no @elt", self.class], :error)
437
+ @elt = ""
438
+ end
439
+ end
440
+ alias process_elements process_particles
441
+
442
+ def register_figure
443
+ @deplate.table_of_figures << self
444
+ @deplate.current_figure += 1
445
+ @level_as_string = [@deplate.current_heading[0], @deplate.current_figure].join(".")
446
+ @label << @deplate.elt_label("fig", @level_as_string)
447
+ end
448
+
449
+ def register_table
450
+ @deplate.table_of_tables << self
451
+ @deplate.current_table += 1
452
+ @level_as_string = [@deplate.current_heading[0], @deplate.current_table].join(".")
453
+ @label << @deplate.elt_label("tab", @level_as_string)
454
+ end
455
+ end
456
+
457
+ class Deplate::Element::Comment < Deplate::Element
458
+ register_element
459
+ set_rx(/^\s*(%+)[ \t]*(.*)$/)
460
+
461
+ # disappear
462
+ def self.accumulate(src, array, deplate, text, match)
463
+ Deplate::Core.log(["Hide comment", text], :debug)
464
+ end
465
+
466
+ def setup
467
+ @multiliner = false
468
+ @collapse = true
469
+ @level = get_level
470
+ @accum = [get_text]
471
+ end
472
+
473
+ def get_level
474
+ @match[1].size
475
+ end
476
+
477
+ def get_text
478
+ @match[2]
479
+ end
480
+ end
481
+
482
+ class Deplate::Element::Region < Deplate::Element
483
+ register_element
484
+ set_rx(/^(\s*)#([A-Z]([a-z][A-Za-z]*)?)\b(.*)(\<\<(.+)|:)\s*$/)
485
+ @rxi_name = 2
486
+ @rxi_args = 4
487
+ @rxi_endrx = 6
488
+ @rxi_indent = 1
489
+
490
+ attr_reader :specified, :regNote, :name
491
+
492
+ class << self
493
+ attr_reader :rxi_name, :rxi_args, :rxi_endrx, :rxi_indent
494
+
495
+ def pseudo_match(args)
496
+ [
497
+ nil,
498
+ args[:indent], #1
499
+ args[:name], #2
500
+ nil, #3
501
+ args[:args], #4
502
+ nil, #5
503
+ args[:endrx], #6
504
+ ]
505
+ end
506
+ end
507
+
508
+ def setup(name=nil)
509
+ @multiliner = true
510
+ @endRx = get_endrx
511
+ @accum = []
512
+ @name = name || get_name
513
+ begin
514
+ @args, @regNote = @deplate.input.parse_args(get_args)
515
+ @collapse = false
516
+ region = @deplate.input.regions[@name]
517
+ unless region
518
+ if @deplate.formatter.matches?(@name)
519
+ Deplate::Core.log(["Obsolete use of native regions. Please use", "#Native fmt=#{@deplate.formatter.formatter_name}"], :error, @source)
520
+ else
521
+ # We put a message to notify the user of an ignored class
522
+ # This should be a native class for an unused formatter
523
+ Deplate::Core.log(["Unknown region class", @name], :error, @source)
524
+ end
525
+ region = Deplate::Regions::UNKNOWN
526
+ end
527
+ rescue Deplate::DontFormatException
528
+ Deplate::Core.log(["Dropping", @match[0]], nil, @source)
529
+ region = Deplate::Regions::UNKNOWN
530
+ end
531
+ @specified = region.new(@deplate, @source, @text, @match, self)
532
+ @specified.indent = get_indent
533
+ @line_cont = region.line_cont
534
+ # @deplate.register_id(@args, @specified)
535
+ @deplate.register_id(@args, self)
536
+ end
537
+
538
+ def get_name
539
+ @match[self.class.rxi_name]
540
+ end
541
+
542
+ def get_args
543
+ @match[self.class.rxi_args]
544
+ end
545
+
546
+ def get_endrx
547
+ i = self.class.rxi_endrx
548
+ if @match[i - 1] == ":"
549
+ /^(#{get_indent})?#End\s*$/
550
+ else
551
+ erx = @match[i]
552
+ if erx
553
+ /^(#{get_indent})?#{Regexp.escape(erx)}\s*$/
554
+ end
555
+ end
556
+ end
557
+
558
+ def get_indent
559
+ @match[self.class.rxi_indent]
560
+ end
561
+
562
+ def finish
563
+ return @specified.finish
564
+ end
565
+ end
566
+
567
+ class Deplate::Element::Clip < Deplate::BaseElement
568
+ attr_reader :is_template
569
+ # attr_accessor :prototype
570
+
571
+ def initialize(acc, deplate, source)
572
+ super(deplate)
573
+ @acc = acc
574
+ @elt = nil
575
+ @source = source
576
+ @invoker = nil
577
+ @is_template = false
578
+ @prototype = nil
579
+ end
580
+
581
+ def process
582
+ unless @prototype
583
+ @prototype = @acc.first
584
+ @prototype.args.update(@args) if @prototype
585
+ end
586
+ unless @elt
587
+ @elt = @acc.collect{|p| p.process; p.elt}
588
+ @elt = @deplate.join_particles(@elt)
589
+ end
590
+ return self
591
+ end
592
+
593
+ def format_clip(invoker, expected)
594
+ unless @elt
595
+ log("We shouldn't be here. If you can track down when this happens, please send an example to the author.", :anyway)
596
+ process
597
+ end
598
+ if @elt
599
+ @prototype.match_expected(expected, invoker)
600
+ else
601
+ log("Clip is nil, which is quite strange and most likely deplate's error but as I haven't had the time yet to track this down this error still occurs.", :error)
602
+ end
603
+ @elt
604
+ end
605
+
606
+ def print
607
+ output(@elt)
608
+ end
609
+ end
610
+
611
+ class Deplate::Element::Command < Deplate::Element
612
+ register_element
613
+ set_rx /^\s*#([A-Z]+)((\s[^:]+)?(:\s*(.+?)\s*)?)$/
614
+ attr :name
615
+
616
+ class << self
617
+ def is_volatile?(match)
618
+ case match[1]
619
+ when "IDX", "NOIDX", "DONTIDX", "AUTOIDX", "DOC", "OPT", "AUTHOR",
620
+ "TITLE", "DATE", "ABBREV"
621
+ true
622
+ else
623
+ false
624
+ end
625
+ end
626
+
627
+ def accumulate(src, array, deplate, text, match)
628
+ cmd = match[1]
629
+ Deplate::Core.log(["Command", cmd, text], :debug)
630
+ begin
631
+ args, text = deplate.input.parse_args(match[2])
632
+ case cmd
633
+ when "IF"
634
+ deplate.switches << !check_switch(deplate, text)
635
+ when "ELSEIF"
636
+ if deplate.switches.empty?
637
+ Deplate::Core.log(["ELSEIF without IF", cmd, match[0]], :error, src)
638
+ else
639
+ case deplate.switches.last
640
+ when :skip
641
+ when true
642
+ deplate.switches.pop
643
+ deplate.switches << !check_switch(deplate, text)
644
+ else
645
+ deplate.switches.pop
646
+ deplate.switches << :skip
647
+ end
648
+ end
649
+ when "ELSE"
650
+ if deplate.switches.empty?
651
+ Deplate::Core.log(["ELSE without IF", cmd, match[0]], :error, src)
652
+ else
653
+ case deplate.switches.last
654
+ when :skip
655
+ when true
656
+ deplate.switches << !deplate.switches.pop
657
+ else
658
+ deplate.switches.pop
659
+ deplate.switches << :skip
660
+ end
661
+ end
662
+ when "ENDIF"
663
+ if deplate.switches.empty?
664
+ Deplate::Core.log(["ENDIF without IF", cmd, match[0]], :error, src)
665
+ else
666
+ deplate.switches.pop
667
+ end
668
+ else
669
+ if !deplate.switches.last
670
+ cc = deplate.input.commands[cmd]
671
+ if cc
672
+ cc.do_accumulate(src, array, deplate, text, match, args, cmd)
673
+ else
674
+ Deplate::Core.log(["Unknown command", cmd, match[0]], :error, src)
675
+ end
676
+ end
677
+ end
678
+ rescue Deplate::DontFormatException
679
+ Deplate::Core.log(["Dropping", match[0]], nil, src)
680
+ end
681
+ end
682
+
683
+ # return true if the test succeeds
684
+ def check_switch(deplate, text)
685
+ if text =~ /^\(.*\)$/
686
+ text = text[1..-2]
687
+ end
688
+ m = /^\s*([:]?\w+)\s*((!=~|=~|==|!=)\s*(.+)\s*|!)$/.match(text)
689
+ if m
690
+ var = m[1]
691
+ negate = /^no([A-Z].*)$/.match(var)
692
+ if negate
693
+ var = negate[1][0..0].downcase + negate[1][1..-1]
694
+ end
695
+ val = m[4]
696
+ op = val ? m[3] : m[2]
697
+ if op == "!"
698
+ return get_var_or_option(deplate, var)
699
+ else
700
+ case op
701
+ when "==", "!="
702
+ compare = Proc.new {|a, b| a == b}
703
+ when "=~", "!=~"
704
+ compare = Proc.new {|a, b| a =~ Regexp.new(b)}
705
+ else
706
+ raise "Internal error"
707
+ end
708
+ case var
709
+ when "fmt"
710
+ switch = compare.call(deplate.formatter.formatter_name, val)
711
+ else
712
+ switch = compare.call(get_var_or_option(deplate, var), val)
713
+ end
714
+ if op[0..0] == "!" or negate
715
+ return !switch
716
+ else
717
+ return switch
718
+ end
719
+ end
720
+ elsif text =~ /^\w+$/
721
+ return get_var_or_option(deplate, text)
722
+ else
723
+ Deplate::Core.log(["Malformed condition", text], :error)
724
+ return true
725
+ end
726
+ end
727
+
728
+ def get_var_or_option(deplate, key)
729
+ if deplate.variables.has_key?(key)
730
+ return deplate.variables[key]
731
+ elsif deplate.options.allow.include?(':') && key =~ /^:(.*)$/
732
+ return deplate.options.send($1)
733
+ end
734
+ Deplate::Core.log(["Unknown variable or option", key])
735
+ return nil
736
+ end
737
+ end
738
+ end
739
+
740
+ class Deplate::Element::Note < Deplate::Element
741
+ register_element
742
+ set_formatter :format_note
743
+ set_rx /^([ \t]+)([#!?+]{3,3})\s+(.*)$/
744
+
745
+ attr_reader :marker
746
+
747
+ def setup
748
+ @multiliner = true
749
+ @collapse = false
750
+ @level = get_level
751
+ @marker = get_marker
752
+ @accum = [get_text]
753
+ end
754
+
755
+ def to_be_continued?(line)
756
+ indent = get_indent(line).size
757
+ return indent >= @level
758
+ end
759
+
760
+ def get_level
761
+ expand_tab(@match[1]).size
762
+ end
763
+
764
+ def get_marker
765
+ @match[2][0..0]
766
+ end
767
+
768
+ def get_text
769
+ @match[3]
770
+ end
771
+ end
772
+
773
+ Deplate::ListItem = Struct.new("DeplateListItem", :item, :body, :listtype, :type,
774
+ :level, :max, :explicit, :label, :style)
775
+
776
+ class Deplate::List < Deplate::Element
777
+ set_formatter :format_list
778
+ set_labelling
779
+
780
+ attr_reader :levelRange, :item, :oitem
781
+
782
+ class << self
783
+ attr :name
784
+ end
785
+
786
+ def setup
787
+ @multiliner = true
788
+ @collapse = true
789
+ @level = get_level
790
+ if self.instance_of?(Deplate::List::Description)
791
+ @levelMax = @level + (@deplate.variables["tabwidth"] || 4)
792
+ else
793
+ @levelMax = get_level_max
794
+ end
795
+ @oitem = @item = get_item
796
+ @accum = [get_text]
797
+ end
798
+
799
+ def get_level
800
+ expand_tab(@match[2]).size
801
+ end
802
+
803
+ def get_level_max
804
+ expand_tab(@match[1]).size
805
+ end
806
+
807
+ def get_item
808
+ @match[3]
809
+ end
810
+
811
+ def get_text
812
+ @match[4]
813
+ end
814
+
815
+ def collapsable?(other)
816
+ if other.kind_of?(Deplate::List)
817
+ return true
818
+ elsif other.kind_of?(Deplate::Element::Paragraph)
819
+ return @elt.find do |i|
820
+ continuation_level_ok?(other.level, i.level, i.max)
821
+ end
822
+ elsif other.kind_of?(Deplate::Element::Whitespace)
823
+ return true
824
+ else
825
+ return false
826
+ end
827
+ end
828
+
829
+ def unify_now(other)
830
+ if other.kind_of?(Deplate::Element::Paragraph)
831
+ @elt << Deplate::ListItem.new([], other.elt.flatten, @elt.last.listtype,
832
+ "Paragraph", other.level, other.level,
833
+ other.is_explicit?, other.label)
834
+ other.label = []
835
+ unify_props(other)
836
+ elsif other.kind_of?(Deplate::Element::Whitespace)
837
+ else
838
+ super
839
+ end
840
+ end
841
+
842
+ def to_be_continued?(line)
843
+ linelevel = get_indent(line).size
844
+ return continuation_level_ok?(linelevel, @level, @levelMax)
845
+ end
846
+
847
+ def continuation_level_ok?(otherLevel, thisLevel, thisMaxLevel)
848
+ # return thisLevel <= otherLevel && otherLevel <= thisMaxLevel
849
+ return thisLevel <= otherLevel
850
+ end
851
+
852
+ def finish
853
+ @item = @deplate.parse(self, @item)
854
+ accum = @deplate.parse(self, @accum.join(" "))
855
+ name = self.class.name
856
+ @elt = [Deplate::ListItem.new(@item, accum, name, name, @level,
857
+ @levelMax, is_explicit?, @label)]
858
+ @label = []
859
+ return self
860
+ end
861
+
862
+ def process_particles(&block)
863
+ @elt.each do |e|
864
+ e.item = block.call(e.item)
865
+ e.body = block.call(e.body)
866
+ end
867
+ end
868
+ end
869
+
870
+ class Deplate::List::Numbered < Deplate::List
871
+ register_element
872
+ set_formatter :format_list
873
+ set_rx /^(([ \t]+)([0-9]+\.|[#\@?]\.?|[a-zA-Z?]\.)[ \t]+)(.+)$/
874
+ set_name "Numbered"
875
+
876
+ def is_explicit?
877
+ if @oitem =~ /^[0-9a-zA-Z]+\.$/
878
+ return true
879
+ else
880
+ return false
881
+ end
882
+ end
883
+ end
884
+
885
+ class Deplate::List::Itemize < Deplate::List
886
+ register_element
887
+ set_formatter :format_list
888
+ set_rx /^(([ \t]+)([-�+*])[ \t]+)(.+)$/
889
+ set_name "Itemize"
890
+ end
891
+
892
+ class Deplate::List::Description < Deplate::List
893
+ register_element
894
+ set_formatter :format_list
895
+ set_rx /^(([ \t]+)(.+?)[ \t]+::[ \t])(.*)$/
896
+ set_name "Description"
897
+ end
898
+
899
+
900
+
901
+ class Deplate::Element::Table < Deplate::Element
902
+ register_element
903
+ set_formatter :format_table
904
+ set_rx /^(\|\|?)([ \t]+.+[ \t]+)\1$/
905
+
906
+ TableRow = Struct.new("DeplateTableRow", :high, :cols, :head, :foot, :is_ruler,
907
+ :from_top, :from_bottom)
908
+ TableCell = Struct.new("DeplateTableCell", :cell,
909
+ :x, :y, :from_right, :from_bottom,
910
+ :high, :head, :foot,
911
+ :span_x, :span_y, :row)
912
+
913
+ attr_accessor :preNote, :postNote, :coordinates,
914
+ :contains_footnotes, :printed_header
915
+
916
+ def setup
917
+ @multiliner = false
918
+ @collapse = true
919
+ high = get_highlight
920
+ cols = get_cols
921
+ cols.collect! {|t| t.strip}
922
+ @accum = [ TableRow.new(high, cols) ]
923
+ @preNote = nil
924
+ @postNote = nil
925
+ @contains_footnotes = false
926
+ end
927
+
928
+ def get_highlight
929
+ @match[1].size == 2
930
+ end
931
+
932
+ def get_cols
933
+ @match[2].split(/[ \t]\|\|?[ \t]/)
934
+ end
935
+
936
+ def unify_now(other)
937
+ super
938
+ @contains_footnotes ||= other.contains_footnotes
939
+ end
940
+
941
+ def collapsable?(other)
942
+ return @collapse && other.collapse && self.class == other.class
943
+ end
944
+
945
+ def finish
946
+ @accum.each do |row|
947
+ row.is_ruler = false
948
+ row.cols.collect! do |c|
949
+ case c
950
+ when /^-+$/
951
+ row.is_ruler = true
952
+ :ruler
953
+ when "<"
954
+ log(["Malformed ruler definition (<)", col.cols], :error) if row.is_ruler
955
+ :join_left
956
+ when "^"
957
+ log(["Malformed ruler definition (^)", col.cols], :error) if row.is_ruler
958
+ :join_above
959
+ when /^\s*$/
960
+ if row.is_ruler
961
+ :noruler
962
+ else
963
+ @deplate.parse(self, c)
964
+ end
965
+ else
966
+ log(["Malformed ruler definition", c, col.cols], :error) if row.is_ruler
967
+ @deplate.parse(self, c)
968
+ end
969
+ end
970
+ end
971
+ @elt = @accum
972
+ return self
973
+ end
974
+
975
+ def process_particles(&block)
976
+ hiCol = get_table_args("hiCol")
977
+ hiRow = get_table_args("hiRow")
978
+ head = @args["head"]
979
+ head = head ? head.to_i : 0
980
+ foot = @args["foot"]
981
+ foot = foot ? foot.to_i : 0
982
+ rowmax = @elt.size
983
+ @coordinates = {}
984
+ y = 0
985
+ rown = @elt.size
986
+ for row in @elt
987
+ y += 1
988
+ x = 0
989
+ coln = row.cols.size
990
+ row.cols.collect! do |cell|
991
+ x += 1
992
+ case cell
993
+ when :join_left
994
+ parent = find_parent_cell(x, y, 1, 0)
995
+ if parent.kind_of?(Symbol)
996
+ elsif parent
997
+ parent.span_x += 1
998
+ else
999
+ log(["Table: Can't join with left cell", x, y], :error)
1000
+ end
1001
+ when :join_above
1002
+ parent = find_parent_cell(x, y, 0, 1)
1003
+ if parent.kind_of?(Symbol)
1004
+ elsif parent
1005
+ parent.span_y += 1
1006
+ else
1007
+ log(["Table: Can't join with above cell", x, y], :error)
1008
+ end
1009
+ when :ruler, :noruler
1010
+ row.is_ruler = true
1011
+ else
1012
+ cell = TableCell.new(block.call(cell), x, y)
1013
+ cell.from_bottom = rown - y
1014
+ cell.from_right = coln - x
1015
+ cell.span_x = 1
1016
+ cell.span_y = 1
1017
+ cell.row = row
1018
+ cell.high = check_table_opts(hiCol, x, coln)
1019
+ end
1020
+ @coordinates[[x,y]] = cell
1021
+ cell
1022
+ end
1023
+ if y <= head
1024
+ row.head = true
1025
+ elsif (rowmax - y + 1) <= foot
1026
+ row.foot = true
1027
+ elsif check_table_opts(hiRow, y, rowmax)
1028
+ row.high = true
1029
+ end
1030
+ row.from_top = y
1031
+ row.from_bottom = rowmax - y
1032
+ end
1033
+ for row in @elt
1034
+ if row.high
1035
+ row.head = true
1036
+ else
1037
+ break
1038
+ end
1039
+ end
1040
+ for row in @elt.reverse
1041
+ if row.high and !row.head
1042
+ row.foot = true
1043
+ else
1044
+ break
1045
+ end
1046
+ end
1047
+ end
1048
+
1049
+ def check_table_opts(args, nth, max)
1050
+ (nth == 1 and args.include?("first")) or
1051
+ (nth == max and args.include?("last")) or
1052
+ args.include?("%d" % nth)
1053
+ end
1054
+
1055
+ def get_table_args(name)
1056
+ args = @args[name]
1057
+ args ? args.split(/\s*,\s*/) : []
1058
+ end
1059
+
1060
+ def find_parent_cell(x, y, delta_x, delta_y)
1061
+ i = 1
1062
+ loop do
1063
+ xx = x - (delta_x * i)
1064
+ yy = y - (delta_y * i)
1065
+ c = @coordinates[[xx, yy]]
1066
+ case c
1067
+ when :join_left
1068
+ return c if delta_x == 0
1069
+ when :join_above
1070
+ return c if delta_y == 0
1071
+ when :ruler, :noruler
1072
+ when nil
1073
+ return nil
1074
+ else
1075
+ return c
1076
+ end
1077
+ i += 1
1078
+ end
1079
+ end
1080
+
1081
+ def register_caption
1082
+ register_table
1083
+ end
1084
+ end
1085
+
1086
+ class Deplate::Element::Heading < Deplate::Element
1087
+ attr_accessor :first_top, :last_top, :top_index, :abstract
1088
+ attr_writer :destination
1089
+
1090
+ register_element
1091
+ set_formatter :format_heading
1092
+ set_rx /^(\*+)[ \t]+(.*?)$/
1093
+
1094
+ class << self
1095
+ def accumulate(src, array, deplate, text, match)
1096
+ Deplate::Element::PotentialPageBreak.accumulate(src, array, deplate, text, match)
1097
+ ppb = array[-1]
1098
+ super
1099
+ hd = array[-1]
1100
+ if hd.is_top_heading?
1101
+ ppb.enabled = true
1102
+ end
1103
+ end
1104
+
1105
+ # Programmatically markup text as heading.
1106
+ def markup(text, level=1)
1107
+ ['*' * level, text].join(' ')
1108
+ end
1109
+ end
1110
+
1111
+ def set_instance_top
1112
+ @level = get_level
1113
+ ls = @deplate.variables["levelshift"]
1114
+ if ls
1115
+ @level += ls.to_i
1116
+ end
1117
+ if is_top_heading?
1118
+ @deplate.current_table = 0
1119
+ @deplate.current_figure = 0
1120
+ end
1121
+ @deplate.increase_current_heading(@level)
1122
+ super
1123
+ end
1124
+
1125
+ def setup
1126
+ @first_top = false
1127
+ @last_top = false
1128
+ @multiliner = false
1129
+ @collapse = false
1130
+ @abstract = nil
1131
+ @accum = [get_text]
1132
+ @args[:id] = @deplate.elt_label("hd", @level_as_string)
1133
+ @destination = @deplate.output.destination
1134
+ @top_index = [0, 0]
1135
+ @deplate.table_of_contents << self
1136
+ @deplate.headings[@level_heading] = self
1137
+ update_args
1138
+ end
1139
+
1140
+ def get_level
1141
+ @match[1].size
1142
+ end
1143
+
1144
+ def get_text
1145
+ @match[2]
1146
+ end
1147
+
1148
+ def is_top_heading?
1149
+ @level == 1
1150
+ end
1151
+
1152
+ def update_options(args)
1153
+ @args.update(args)
1154
+ update_args
1155
+ end
1156
+
1157
+ def update_args
1158
+ super
1159
+ register_heading
1160
+ end
1161
+
1162
+ def register_heading
1163
+ sc = @args['id'] || @args['shortcaption']
1164
+ log(['Register heading', level_as_string, sc], :debug)
1165
+ @deplate.set_top_heading(self, sc)
1166
+ end
1167
+
1168
+ def process
1169
+ rv = super
1170
+ if rv.is_top_heading?
1171
+ @deplate.options.heading_names[@top_heading_idx] = rv.elt
1172
+ if @deplate.variables['subToC']
1173
+ args = {'sub' => true, 'plain' => true}
1174
+ match = []
1175
+ toc = Deplate::Command::LIST.new(@deplate, @source, 'toc', match, args, 'LIST')
1176
+ toc.level = @level
1177
+ toc.level_as_string = @level_as_string
1178
+ rv = [rv, toc.finish.process].compact.flatten
1179
+ end
1180
+ end
1181
+ rv
1182
+ end
1183
+
1184
+ def register_metadata
1185
+ stats = @source.stats
1186
+ mtime = stats ? stats.mtime : nil
1187
+ args = {
1188
+ 'type' => 'heading',
1189
+ 'name' => description,
1190
+ 'id' => get_id
1191
+ }
1192
+ if @abstract
1193
+ args['abstract'] = @abstract.to_plain_text
1194
+ end
1195
+ @registered_metadata << @deplate.get_metadata(@source, args)
1196
+ super
1197
+ end
1198
+
1199
+ def description
1200
+ if @args['shortcaption']
1201
+ @args['shortcaption']
1202
+ elsif @caption
1203
+ @caption.elt
1204
+ else
1205
+ @elt
1206
+ end
1207
+ end
1208
+
1209
+ def register_caption
1210
+ @deplate.table_of_contents << self
1211
+ @label << @deplate.elt_label('hd', @level_as_string)
1212
+ end
1213
+ end
1214
+
1215
+ class Deplate::Element::Break < Deplate::Element
1216
+ register_element
1217
+ set_formatter :format_break
1218
+ set_rx /^\s*-{2,}8\<-{2,}\s*$/
1219
+
1220
+ def setup
1221
+ @multiliner = false
1222
+ @collapse = false
1223
+ @accum = []
1224
+ end
1225
+ end
1226
+
1227
+ # An anchor is not a proper element, but is attached to the preceding one
1228
+ class Deplate::Element::Anchor < Deplate::Element
1229
+ register_element
1230
+ set_formatter :format_anchor
1231
+ set_rx /^\s*%?#([a-z][a-zA-Z0-9:_-]+).*$/
1232
+
1233
+ class << self
1234
+ def accumulate(src, array, deplate, text, match)
1235
+ i = 0
1236
+ l = get_text(match)
1237
+ Deplate::Core.log(['New anchor', l], :debug)
1238
+ last = array.last
1239
+ if last and last.can_be_labelled
1240
+ last.put_label([l])
1241
+ # last.args["label"] ||= l
1242
+ deplate.labels_named << l
1243
+ else
1244
+ Deplate::Core.log(["Defer label", l], nil, src)
1245
+ deplate.labels_floating << l
1246
+ end
1247
+ end
1248
+
1249
+ def get_text(match)
1250
+ match[1]
1251
+ end
1252
+
1253
+ def is_volatile?(match)
1254
+ true
1255
+ end
1256
+ end
1257
+
1258
+ def setup
1259
+ put_label([@text])
1260
+ end
1261
+
1262
+ def process
1263
+ return self
1264
+ end
1265
+ end
1266
+
1267
+ # just disappear
1268
+ class Deplate::Element::Whitespace < Deplate::Element
1269
+ register_element
1270
+ set_rx /^\s*$/
1271
+
1272
+ class << self
1273
+ def accumulate(src, array, deplate, text, match)
1274
+ Deplate::Core.log(["Whitespace", text], :debug)
1275
+ le = array.last
1276
+ kw = deplate.options.keep_whitespace
1277
+ if le.kind_of?(Deplate::Element::Table) or (kw and !(le and le.collapse))
1278
+ e = self.new(deplate, src, text, match, kw)
1279
+ if e
1280
+ array << e
1281
+ end
1282
+ end
1283
+ end
1284
+ end
1285
+
1286
+ def setup(kw)
1287
+ @multiliner = false
1288
+ @collapse = true
1289
+ @accum = [@text]
1290
+ @can_be_labelled = false
1291
+ @keep_whitespace = kw
1292
+ end
1293
+
1294
+ def process
1295
+ return @keep_whitespace ? self : nil
1296
+ end
1297
+
1298
+ def print
1299
+ if @keep_whitespace
1300
+ output(@accum.join)
1301
+ end
1302
+ end
1303
+ alias :format_special :print
1304
+ end
1305
+
1306
+
1307
+ class Deplate::Element::PotentialPageBreak < Deplate::Element
1308
+ set_formatter :format_PAGEBREAK
1309
+ attr_accessor :enabled
1310
+
1311
+ def initialize(*args)
1312
+ @enabled = false
1313
+ super
1314
+ end
1315
+
1316
+ def process
1317
+ if @enabled and @deplate.options.multi_file_output
1318
+ self
1319
+ else
1320
+ nil
1321
+ end
1322
+ end
1323
+ end
1324
+
1325
+
1326
+ # Don't register Paragraph in @@elements -- it's assigned if nothing else
1327
+ # matches
1328
+ class Deplate::Element::Paragraph < Deplate::Element
1329
+ set_formatter :format_paragraph
1330
+ set_rx /^([ \t]*)(.+)[ \t]*$/
1331
+
1332
+ class << self
1333
+ def from_text(deplate, src, text)
1334
+ m = @rx.match(text)
1335
+ self.new(deplate, src, text, m)
1336
+ end
1337
+ end
1338
+
1339
+ def setup
1340
+ @multiliner = true
1341
+ @collapse = false
1342
+ @level = get_level
1343
+ @accum = [get_text]
1344
+ end
1345
+
1346
+ def get_level
1347
+ get_indent(@match[1]).size
1348
+ end
1349
+
1350
+ def get_text
1351
+ @deplate.options.keep_whitespace ? @match[0] : @match[2]
1352
+ end
1353
+ end
1354
+
1355
+ # vim: ff=unix