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,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