deplate 0.7.3 → 0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (160) hide show
  1. data/AUTHORS.TXT +3 -0
  2. data/CHANGES.TXT +248 -175
  3. data/LICENSE.TXT +0 -0
  4. data/NEWS.TXT +28 -24
  5. data/README.TXT +0 -0
  6. data/TODO.TXT +174 -88
  7. data/VERSION.TXT +1 -1
  8. data/bin/deplate +0 -0
  9. data/bin/deplate.bat +0 -0
  10. data/etc/deplate.ini +91 -3
  11. data/lib/action_view/helpers/deplate.rb +45 -0
  12. data/lib/deplate.rb +6 -1
  13. data/lib/deplate/abstract-class.rb +0 -0
  14. data/lib/deplate/bib.rb +576 -0
  15. data/lib/deplate/builtin.rb +0 -0
  16. data/lib/deplate/cache.rb +55 -5
  17. data/lib/deplate/commands.rb +346 -183
  18. data/lib/deplate/common.rb +209 -48
  19. data/lib/deplate/converter.rb +12 -6
  20. data/lib/deplate/core.rb +777 -378
  21. data/lib/deplate/counters.rb +254 -0
  22. data/lib/deplate/css/article.css +4 -3
  23. data/lib/deplate/css/deplate.css +121 -5
  24. data/lib/deplate/css/heading-navbar.css +0 -0
  25. data/lib/deplate/css/layout-deplate-print.css +0 -0
  26. data/lib/deplate/css/layout-deplate.css +0 -0
  27. data/lib/deplate/css/sans-serif.css +0 -0
  28. data/lib/deplate/css/serif-e.css +0 -0
  29. data/lib/deplate/css/serif-rel.css +0 -0
  30. data/lib/deplate/css/serif.css +9 -3
  31. data/lib/deplate/css/slides.css +0 -0
  32. data/lib/deplate/css/tabbar-left.css +0 -0
  33. data/lib/deplate/css/tabbar-right-ie.css +3 -9
  34. data/lib/deplate/css/tabbar-right.css +51 -18
  35. data/lib/deplate/css/tabbar-top.css +7 -1
  36. data/lib/deplate/css/tabbar.css +0 -0
  37. data/lib/deplate/css/text-sans-serif.css +0 -0
  38. data/lib/deplate/css/text-serif.css +0 -0
  39. data/lib/deplate/define.rb +183 -177
  40. data/lib/deplate/deplate-string.rb +82 -0
  41. data/lib/deplate/docbook.rb +236 -128
  42. data/lib/deplate/elements.rb +584 -417
  43. data/lib/deplate/etc.rb +163 -101
  44. data/lib/deplate/external.rb +42 -11
  45. data/lib/deplate/fmt/dbk-article-4.1.2.rb +0 -0
  46. data/lib/deplate/fmt/dbk-article.rb +0 -0
  47. data/lib/deplate/fmt/dbk-book.rb +0 -0
  48. data/lib/deplate/fmt/dbk-ref.rb +3 -3
  49. data/lib/deplate/fmt/dbk-slides.rb +0 -0
  50. data/lib/deplate/fmt/dbk-snippet.rb +0 -0
  51. data/lib/deplate/fmt/html-snippet.rb +0 -0
  52. data/lib/deplate/fmt/html.rb +783 -550
  53. data/lib/deplate/fmt/htmlsite.rb +192 -199
  54. data/lib/deplate/fmt/htmlslides.rb +0 -0
  55. data/lib/deplate/fmt/htmlwebsite.rb +3 -3
  56. data/lib/deplate/fmt/latex-snippet.rb +0 -0
  57. data/lib/deplate/fmt/latex.rb +242 -83
  58. data/lib/deplate/fmt/null.rb +32 -0
  59. data/lib/deplate/fmt/php.rb +4 -4
  60. data/lib/deplate/fmt/phpsite.rb +6 -5
  61. data/lib/deplate/fmt/plain.rb +160 -106
  62. data/lib/deplate/fmt/template.rb +0 -0
  63. data/lib/deplate/fmt/xhtml10t.rb +0 -0
  64. data/lib/deplate/formatter-snippet.rb +0 -0
  65. data/lib/deplate/formatter.rb +613 -301
  66. data/lib/deplate/input.rb +202 -142
  67. data/lib/deplate/input/deplate-headings.rb +4 -6
  68. data/lib/deplate/input/deplate-restricted.rb +15 -9
  69. data/lib/deplate/input/deplate.rb +2 -4
  70. data/lib/deplate/input/rdoc.rb +39 -38
  71. data/lib/deplate/input/template.rb +0 -0
  72. data/lib/deplate/lib/Makefile.config +29 -0
  73. data/lib/deplate/lib/latex/deplate.sty +54 -0
  74. data/lib/deplate/lib/latex/highlight-extra.sty +0 -0
  75. data/lib/deplate/lib/latex/highlight-typical.sty +0 -0
  76. data/lib/deplate/lib/php/page-comment.inc.php +216 -0
  77. data/lib/deplate/lib/tabmenu.js +0 -0
  78. data/lib/deplate/locale/de.latin1 +155 -17
  79. data/lib/deplate/locale/ru.koi8-r +0 -0
  80. data/lib/deplate/locale/zh_cn.gb2312 +0 -0
  81. data/lib/deplate/macros.rb +133 -82
  82. data/lib/deplate/messages.rb +6 -4
  83. data/lib/deplate/metadata.rb +0 -0
  84. data/lib/deplate/metadata/marshal.rb +0 -0
  85. data/lib/deplate/metadata/xml.rb +0 -0
  86. data/lib/deplate/metadata/yaml.rb +0 -0
  87. data/lib/deplate/mod/anyword.rb +3 -3
  88. data/lib/deplate/mod/babelfish.rb +4 -4
  89. data/lib/deplate/mod/code-gvim.rb +8 -4
  90. data/lib/deplate/mod/code-highlight.rb +3 -3
  91. data/lib/deplate/mod/colored-log.rb +0 -0
  92. data/lib/deplate/mod/de.rb +2 -2
  93. data/lib/deplate/mod/en.rb +0 -0
  94. data/lib/deplate/mod/endnotes.rb +0 -0
  95. data/lib/deplate/mod/fr.rb +0 -0
  96. data/lib/deplate/mod/html-asciimath.rb +0 -0
  97. data/lib/deplate/mod/html-deplate-button.rb +0 -0
  98. data/lib/deplate/mod/html-headings-navbar.rb +5 -13
  99. data/lib/deplate/mod/html-jsmath.rb +39 -0
  100. data/lib/deplate/mod/html-obfuscate-email.rb +3 -3
  101. data/lib/deplate/mod/html-sidebar.rb +0 -0
  102. data/lib/deplate/mod/htmlslides-navbar-fh.rb +3 -3
  103. data/lib/deplate/mod/iconv.rb +0 -0
  104. data/lib/deplate/mod/imgurl.rb +4 -4
  105. data/lib/deplate/mod/inlatex-compound.rb +7 -10
  106. data/lib/deplate/mod/koma.rb +0 -0
  107. data/lib/deplate/mod/latex-emph-table-head.rb +0 -0
  108. data/lib/deplate/mod/latex-styles.rb +7 -4
  109. data/lib/deplate/mod/latex-verbatim-small.rb +0 -0
  110. data/lib/deplate/mod/makefile.rb +23 -7
  111. data/lib/deplate/mod/mark-external-urls.rb +3 -3
  112. data/lib/deplate/mod/markup-1-warn.rb +10 -10
  113. data/lib/deplate/mod/markup-1.rb +0 -0
  114. data/lib/deplate/mod/navbar-png.rb +24 -8
  115. data/lib/deplate/mod/noindent.rb +0 -0
  116. data/lib/deplate/mod/numpara.rb +0 -0
  117. data/lib/deplate/mod/particle-math.rb +4 -4
  118. data/lib/deplate/mod/php-extra.rb +46 -6
  119. data/lib/deplate/mod/pstoedit.rb +0 -0
  120. data/lib/deplate/mod/recode.rb +0 -0
  121. data/lib/deplate/mod/ru_koi8-r.rb +0 -0
  122. data/lib/deplate/mod/smart-dash.rb +26 -0
  123. data/lib/deplate/mod/smiley.rb +69 -7
  124. data/lib/deplate/mod/soffice.rb +0 -0
  125. data/lib/deplate/mod/symbols-latin1.rb +14 -23
  126. data/lib/deplate/mod/symbols-od-utf-8.rb +5 -3
  127. data/lib/deplate/mod/symbols-plain.rb +5 -35
  128. data/lib/deplate/mod/symbols-sgml.rb +8 -9
  129. data/lib/deplate/mod/symbols-utf-8.rb +8 -9
  130. data/lib/deplate/mod/symbols-xml.rb +5 -9
  131. data/lib/deplate/mod/syntax-region-alt.rb +5 -5
  132. data/lib/deplate/mod/utf8.rb +0 -0
  133. data/lib/deplate/mod/validate-html.rb +0 -0
  134. data/lib/deplate/mod/xmlrpc.rb +0 -0
  135. data/lib/deplate/mod/zh-cn-autospace.rb +18 -20
  136. data/lib/deplate/mod/zh-cn.rb +4 -6
  137. data/lib/deplate/nukumi2.rb +71 -0
  138. data/lib/deplate/once-method.rb +0 -0
  139. data/lib/deplate/output.rb +19 -21
  140. data/lib/deplate/particles.rb +178 -116
  141. data/lib/deplate/regions.rb +99 -58
  142. data/lib/deplate/skeletons.rb +122 -0
  143. data/lib/deplate/structured.rb +164 -106
  144. data/lib/deplate/template.rb +67 -43
  145. data/lib/deplate/templates/html-doc.html +0 -0
  146. data/lib/deplate/templates/html-left-tabbar-js.html +0 -0
  147. data/lib/deplate/templates/html-left-tabbar.html +0 -0
  148. data/lib/deplate/templates/html-tabbar-right-pcomments.php +22 -0
  149. data/lib/deplate/templates/html-tabbar-right-step.html +24 -0
  150. data/lib/deplate/templates/html-tabbar-right-table.html +0 -0
  151. data/lib/deplate/templates/html-tabbar-right.html +2 -4
  152. data/lib/deplate/templates/html-tabbar-top.html +0 -9
  153. data/lib/deplate/templates/html-tabbar.html +0 -0
  154. data/lib/deplate/variables.rb +127 -0
  155. data/lib/deplate/wiki-markup.rb +99 -33
  156. data/lib/deplate/xml.rb +18 -18
  157. data/lib/deplate/zh-cn.rb +0 -0
  158. data/lib/ps2ppm.rb +0 -0
  159. data/man/man1/deplate.1 +564 -474
  160. metadata +201 -186
File without changes
File without changes
File without changes
@@ -3,10 +3,11 @@
3
3
  # @Website: http://deplate.sf.net/
4
4
  # @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
5
5
  # @Created: 31-Okt-2004.
6
- # @Last Change: 02-Nov-2005.
7
- # @Revision: 0.923
6
+ # @Last Change: 05-Jun-2006.
7
+ # @Revision: 0.1443
8
8
 
9
- require "deplate/abstract-class"
9
+ require 'deplate/abstract-class'
10
+ require 'deplate/common'
10
11
 
11
12
  # Description:
12
13
  # An abstract formatter class
@@ -18,7 +19,32 @@ require "deplate/abstract-class"
18
19
  # CHANGES:
19
20
  #
20
21
 
21
- class Deplate::Formatter
22
+ class Deplate::Formatter < Deplate::CommonObject
23
+ class_attribute :formatter
24
+
25
+ class_attribute :suffix
26
+ class_attribute :myname
27
+ class_attribute :related, []
28
+ class_attribute :rx
29
+ class_attribute :label_mode, :enclose
30
+ class_attribute :label_delegate, []
31
+ class_attribute :label_once, []
32
+
33
+ class_attribute :naked_agents, [
34
+ :format_label,
35
+ :format_index,
36
+ ]
37
+
38
+ class_attribute :blacklist_latex, [
39
+ 'include', 'def', 'command', 'loop', 'repeat',
40
+ 'open', 'toks', 'output', 'input', 'catcode', 'name', '^^',
41
+ '\\every', '\\errhelp', '\\errorstopmode', '\\scrollmode',
42
+ '\\nonstopmode', '\\batchmode', '\\read', '\\write', 'csname',
43
+ '\\newhelp', '\\uppercase', '\\lowercase', '\\relax',
44
+ '\\aftergroup', '\\afterassignment', '\\expandafter',
45
+ '\\noexpand', '\\special', '\\usepackage'
46
+ ]
47
+
22
48
  class << self
23
49
  def noop(context, name)
24
50
  context.module_eval %{
@@ -28,67 +54,54 @@ class Deplate::Formatter
28
54
  }
29
55
  end
30
56
 
31
- attr_writer :suffix, :myname, :rx, :label_mode, :label_delegate, :label_once
57
+ def hook_post_myname=(name)
58
+ klass = self
59
+ Deplate::Core.class_eval {declare_formatter(klass)}
60
+ end
32
61
 
33
- def get_class_attrib(name, default=nil)
34
- if self == Deplate::Formatter
35
- return default
62
+ # <+TBD+>Shouldn't services belong to the formatter?
63
+ def def_service(name, &block)
64
+ # prefix = @formatter.class.myname.gsub('\W', '__')
65
+ # method = ['svc', prefix, name].join('_')
66
+ method = ['svc', name].join('_')
67
+ self.class_eval do
68
+ define_method(method, &block)
36
69
  end
37
- iv = "@#{name}"
38
- if self.instance_variables.include?(iv)
39
- val = self.instance_variable_get(iv)
40
- if val
41
- return val
70
+ init = ['formatter_initialize', method].join('_')
71
+ sname = name.gsub(/_(.)/) {$1.capitalize}
72
+ self.class_eval do
73
+ define_method(init) do
74
+ @doc_services[name] = method
75
+ @doc_services[sname] = method
42
76
  end
43
77
  end
44
- return self.superclass.get_class_attrib(name, default)
45
- end
46
-
47
- def suffix
48
- get_class_attrib('suffix')
49
- end
50
-
51
- def myname
52
- get_class_attrib('myname')
53
- end
54
-
55
- def myname=(name)
56
- @myname = name
57
- klass = self
58
- Deplate::Core.class_eval {declare_formatter(klass)}
59
- end
60
-
61
- def rx
62
- get_class_attrib('rx')
63
- end
64
-
65
- def label_mode
66
- get_class_attrib('label_mode', :enclose)
67
- end
68
-
69
- def label_delegate
70
- get_class_attrib('label_delegate', [])
71
- end
72
-
73
- def label_once
74
- get_class_attrib('label_once', [])
75
78
  end
76
79
  end
77
80
 
78
81
  @@custom_particles = {}
79
82
 
80
- attr_reader :deplate
81
- attr_reader :advices
83
+ attr_reader :deplate
84
+ attr_reader :advices
85
+ attr_reader :expander
82
86
  attr_accessor :special_symbols
87
+ attr_accessor :bibentries
88
+ # A hash holding all known document services (names => method).
89
+ attr_accessor :doc_services
83
90
 
84
91
  def initialize(deplate, args={})
85
- @deplate = deplate
86
- @variables = deplate.variables
87
- @bibentries = {}
88
- @open_labels = []
89
- @advices = args[:advices] || {}
90
- @inlatex_idx = 0
91
- @encodings = {}
92
+ @deplate = deplate
93
+ @variables = deplate.variables
94
+ @advices = args[:advices] || {}
95
+ @doc_services = args[:doc_services] || initialize_services
96
+ @inlatex_idx = 0
97
+ @encodings = {}
98
+ @symbol_proxy = nil
99
+ reset!
100
+ end
101
+
102
+ def reset!
103
+ @bibentries = {}
104
+ @open_labels = []
92
105
  @consumed_labels = []
93
106
  @consumed_ids = []
94
107
  end
@@ -139,6 +152,24 @@ class Deplate::Formatter
139
152
  end
140
153
  end
141
154
 
155
+ # Run a "service", i.e., a small, mostly autonomous function/method that
156
+ # usually yields some formatted output.
157
+ def invoke_service(name, args={}, text='')
158
+ method = @doc_services[name]
159
+ if method
160
+ begin
161
+ return send(method, args || {}, text || '')
162
+ rescue Exception => e
163
+ puts e.backtrace[0..10].join("\n")
164
+ log(['Calling service failed', name, e], :error)
165
+ end
166
+ else
167
+ p "DBG"
168
+ puts @doc_services.keys.sort.join("\n")
169
+ log(['Unknown service', name], :error)
170
+ end
171
+ end
172
+
142
173
  def log(*args)
143
174
  Deplate::Core.log(*args)
144
175
  end
@@ -162,6 +193,10 @@ class Deplate::Formatter
162
193
  return table[cen] || cen
163
194
  end
164
195
 
196
+ def output_destination
197
+ @deplate.output.top_heading.destination || @deplate.options.out
198
+ end
199
+
165
200
  def join_blocks(blocks)
166
201
  blocks.flatten.compact.join("\n")
167
202
  end
@@ -173,23 +208,37 @@ class Deplate::Formatter
173
208
  def format_particle(agent, invoker, *args)
174
209
  # rv = with_agent(agent, Array, invoker, *args)
175
210
  # rv.empty? ? format_unknown_particle(invoker) : rv.join
176
- with_agent(agent, Array, invoker, *args)
211
+ rv = with_agent(agent, Array, invoker, *args)
212
+ if rv and !rv.empty? and !self.class.naked_agents.include?(agent)
213
+ wa = {}
214
+ wa[:styles] = invoker.styles if invoker.respond_to?(:styles)
215
+ rv = methods.find_all {|m| m =~ /^wrap_formatted_particle_/ }.
216
+ inject(rv) {|rv, m| send(m, invoker, rv, wa)}
217
+ end
218
+ rv
177
219
  end
178
220
 
179
- def format_particle_as_string(agent, object, *args)
180
- join_inline(format_particle(agent, object, *args))
221
+ def format_particle_as_string(agent, invoker, *args)
222
+ join_inline(format_particle(agent, invoker, *args))
181
223
  end
182
-
224
+
183
225
  def format_element(agent, invoker, *args)
184
226
  # rv = with_agent(agent, Array, invoker, *args)
185
227
  # rv.empty? ? format_unknown(invoker) : join_blocks(rv)
186
- with_agent(agent, Array, invoker, *args)
228
+ rv = with_agent(agent, Array, invoker, *args)
229
+ if rv and !rv.empty? and !self.class.naked_agents.include?(agent)
230
+ wa = {}
231
+ wa[:styles] = invoker.styles if invoker.respond_to?(:styles)
232
+ rv = methods.find_all {|m| m =~ /^wrap_formatted_element_/ }.
233
+ inject(rv) {|rv, m| send(m, invoker, rv, wa)}
234
+ end
235
+ rv
187
236
  end
188
237
 
189
- def format_element_as_string(agent, object, *args)
190
- format_element(agent, object, *args)
238
+ def format_element_as_string(agent, invoker, *args)
239
+ format_element(agent, invoker, *args)
191
240
  end
192
-
241
+
193
242
  def with_agent(agent, prototype, invoker, *args)
194
243
  log(["Call with agent", agent, invoker.class, args], :debug)
195
244
  if respond_to?(agent)
@@ -209,7 +258,7 @@ class Deplate::Formatter
209
258
  prototype ||= inner.class
210
259
  around = stylish[:wrap]
211
260
  if around
212
- inner = around.inject(inner) do |acc, advice|
261
+ inner = around.inject(inner) do |acc, advice|
213
262
  advice[:prc].call(agent, acc, invoker, *args)
214
263
  end
215
264
  end
@@ -247,7 +296,11 @@ class Deplate::Formatter
247
296
  return nil
248
297
  end
249
298
  end
250
-
299
+
300
+ def dummy(invoker, *args)
301
+ args
302
+ end
303
+
251
304
  def output(invoker, *body)
252
305
  output_at(invoker.doc_type, invoker.doc_slot, *body)
253
306
  end
@@ -318,6 +371,77 @@ class Deplate::Formatter
318
371
  end
319
372
  end
320
373
 
374
+ def check_symbol_proxy
375
+ unless @symbol_proxy
376
+ pre_process
377
+ end
378
+ end
379
+
380
+ def symbol_quote(invoker)
381
+ check_symbol_proxy
382
+ @symbol_proxy.symbol_quote(invoker)
383
+ end
384
+
385
+ def symbol_gt(invoker)
386
+ check_symbol_proxy
387
+ @symbol_proxy.symbol_gt(invoker)
388
+ end
389
+
390
+ def symbol_lt(invoker)
391
+ check_symbol_proxy
392
+ @symbol_proxy.symbol_lt(invoker)
393
+ end
394
+
395
+ def symbol_amp(invoker)
396
+ check_symbol_proxy
397
+ @symbol_proxy.symbol_amp(invoker)
398
+ end
399
+
400
+ def doublequote_open(invoker)
401
+ check_symbol_proxy
402
+ @symbol_proxy.doublequote_open(invoker)
403
+ end
404
+
405
+ def doublequote_close(invoker)
406
+ check_symbol_proxy
407
+ @symbol_proxy.doublequote_close(invoker)
408
+ end
409
+
410
+ def singlequote_open(invoker)
411
+ check_symbol_proxy
412
+ @symbol_proxy.singlequote_open(invoker)
413
+ end
414
+
415
+ def singlequote_close(invoker)
416
+ check_symbol_proxy
417
+ @symbol_proxy.singlequote_close(invoker)
418
+ end
419
+
420
+ def nonbreakingspace(invoker)
421
+ check_symbol_proxy
422
+ @symbol_proxy.nonbreakingspace(invoker)
423
+ end
424
+
425
+ def symbol_paragraph(invoker)
426
+ check_symbol_proxy
427
+ @symbol_proxy.symbol_paragraph(invoker)
428
+ end
429
+
430
+ def format_symbol(invoker, sym)
431
+ check_symbol_proxy
432
+ @symbol_proxy.format_symbol(invoker, sym)
433
+ end
434
+
435
+ def format_plain_text(invoker, text=nil, escaped=false)
436
+ text ||= invoker.match
437
+ # <+TBD+> escaped
438
+ plain_text(text, escaped)
439
+ end
440
+
441
+ def format_void(invoker, text=nil)
442
+ text || invoker.elt
443
+ end
444
+
321
445
  # Recode normal text for #plain_text
322
446
  def plain_text_recode(text)
323
447
  text
@@ -381,17 +505,27 @@ class Deplate::Formatter
381
505
  def format_LIST(invoker)
382
506
  acc = []
383
507
  elt = invoker.elt
508
+ case elt
509
+ when 'contents'
510
+ elt = 'toc'
511
+ when 'tables'
512
+ elt = 'lot'
513
+ when 'figures'
514
+ elt = 'lof'
515
+ end
384
516
  meth = "format_list_of_" + elt
385
- if respond_to?(meth)
386
- args = invoker.args
387
- begin
517
+ args = invoker.args
518
+ begin
519
+ if respond_to?(meth)
388
520
  acc << send(meth, invoker)
389
- acc << format_pagebreak(invoker) if args["page"]
390
- rescue StandardError => e
391
- log(["Formatting on LIST failed", elt.inspect, e, e.backtrace[0..10]], :error)
521
+ elsif @deplate.options.listings.is_defined?(elt)
522
+ acc << format_custom_list(invoker, elt)
523
+ else
524
+ log(["Unknown list type", elt.inspect], :error)
392
525
  end
393
- else
394
- log(["Unknown LIST type", elt.inspect], :error)
526
+ acc << format_pagebreak(invoker) if args["page"]
527
+ rescue StandardError => e
528
+ log(["Formatting on LIST failed", elt.inspect, e, e.backtrace[0..10]], :error)
395
529
  end
396
530
  join_blocks(acc)
397
531
  end
@@ -407,6 +541,20 @@ class Deplate::Formatter
407
541
  def read_bib(bibfiles)
408
542
  end
409
543
 
544
+ def bib_entry(key)
545
+ b = @bibentries[key] || []
546
+ crossref = b.assoc('crossref')
547
+ if crossref
548
+ cb = @bibentries[crossref[1]]
549
+ b += cb if cb
550
+ end
551
+ return b
552
+ end
553
+
554
+ def referenced_bib_entry(invoker, key, text)
555
+ text
556
+ end
557
+
410
558
  def format_unknown(invoker)
411
559
  log(["Unknown element", invoker.class], :error, invoker.source)
412
560
  elt = invoker.elt
@@ -426,7 +574,7 @@ class Deplate::Formatter
426
574
 
427
575
 
428
576
  ### General
429
- def_abstract :format_label, :format_figure, :include_image
577
+ def_abstract :format_label, :format_figure, :include_image, :image_suffixes
430
578
 
431
579
  ### Elements
432
580
  def_abstract :format_note, :format_table, :format_heading, :format_list,
@@ -441,8 +589,9 @@ class Deplate::Formatter
441
589
  :format_pagebreak
442
590
 
443
591
  ### Particles
444
- def_abstract :format_emphasize, :format_code, :format_url, :format_wiki, :format_symbol,
445
- :doublequote_open, :doublequote_close, :singlequote_open, :singlequote_close
592
+ def_abstract :format_emphasize, :format_code, :format_url, :format_wiki
593
+ # def_abstract :format_symbol, :doublequote_open, :doublequote_close,
594
+ # :singlequote_open, :singlequote_close
446
595
 
447
596
  ### Macros
448
597
  def_abstract :format_index, :format_footnote, :format_ref,
@@ -450,48 +599,7 @@ class Deplate::Formatter
450
599
  :format_pagenumber
451
600
 
452
601
  def format_cite(invoker)
453
- container = invoker.container
454
- args = invoker.args
455
- n = args['n']
456
- p = args['p']
457
- np = args['np']
458
- y = args['y']
459
- acc = []
460
- pmsg = @deplate.msg('p.\\ ')
461
- for c in invoker.elt
462
- cc = bib_entry(c)
463
- if cc
464
- yr = cc.assoc('year')
465
- yr = if yr then yr[1] else '' end
466
- if p
467
- p = @deplate.parse_and_format_without_wikinames(container, "#{pmsg}#{p}")
468
- yr += ": #{p}"
469
- # yr += ": " + p if p
470
- end
471
- if y
472
- acc << referenced_bib_entry(invoker, c, yr)
473
- else
474
- nm = cc.assoc('author') || cc.assoc('editor') || cc.assoc('howpublished')
475
- if nm
476
- nm = nm[1]
477
- nm = nm.gsub(/\s+/, ' ').split(' and ').collect do |a|
478
- a.scan(/\w+$/)
479
- end
480
- nm = nm.join(', ')
481
- acc << referenced_bib_entry(invoker, c, [nm, yr].join(' '))
482
- else
483
- acc << referenced_bib_entry(invoker, c, c)
484
- end
485
- end
486
- end
487
- end
488
- n &&= n + plain_text(' ', true)
489
- acc = acc.join('; ')
490
- if np
491
- return %{#{plain_text(' ', true)}#{n}#{acc}}
492
- else
493
- return %{#{plain_text(' ', true)}(#{n}#{acc})}
494
- end
602
+ bib_styler.bib_cite(invoker)
495
603
  end
496
604
 
497
605
  # Check if ch (a number representing a character) is a multi-byte leader.
@@ -532,14 +640,18 @@ class Deplate::Formatter
532
640
  max
533
641
  end
534
642
 
643
+ def table_empty_cell
644
+ ''
645
+ end
646
+
535
647
  # Takes an optional block that takes a string as argument and returns
536
648
  # true if we shouldn't wrap the text at this position
537
649
  def wrap_text(text, args={})
538
- moreIndent = args[:indent] || ""
650
+ moreIndent = args[:indent] || ''
539
651
  innerMargin = args[:margin] || 66
540
652
  outerMargin = args[:maxmargin] || 72
541
653
  hanging = args[:hanging] || nil
542
- hang_idt = hanging ? " " * hanging : nil
654
+ hang_idt = hanging ? ' ' * hanging : nil
543
655
  acc = []
544
656
  block = args[:check]
545
657
  break_at = args[:break_at]
@@ -571,6 +683,7 @@ class Deplate::Formatter
571
683
 
572
684
  def break_line(line, rx, inner_margin, block=nil, delta=-1)
573
685
  max = line.size
686
+ # p "DBG #{max} -- #{inner_margin}: #{line}"
574
687
  if inner_margin >= max
575
688
  return line, nil
576
689
  else
@@ -606,7 +719,7 @@ class Deplate::Formatter
606
719
  acc = []
607
720
  elt = invoker.elt
608
721
  if elt
609
- for i in elt
722
+ elt.each do |i|
610
723
  acc << format_element(:format_figure, invoker, inline, i)
611
724
  end
612
725
  else
@@ -627,7 +740,7 @@ class Deplate::Formatter
627
740
  acc << invoker.text
628
741
  else
629
742
  for i in inlatex
630
- # acc << @deplate.formatter.include_image(i, args, true)
743
+ # acc << @deplate.formatter.include_image(invoker, i, args, true)
631
744
  acc << format_element(:format_figure, invoker, true, i)
632
745
  end
633
746
  end
@@ -667,10 +780,13 @@ class Deplate::Formatter
667
780
  raise "Unknown device/suffix: #{sfx}"
668
781
  end
669
782
 
783
+ pointsize = invoker.args['pointsize'] ||
784
+ @deplate.variables['latexPointsize'] || '10'
670
785
  acc = [
671
- "\\documentclass[12pt,a4paper,notitlepage]{article}",
786
+ "\\documentclass[#{pointsize}pt,a4paper,notitlepage]{article}",
672
787
  "\\usepackage{amsmath}",
673
788
  "\\usepackage{amsfonts}",
789
+ "\\usepackage{amssymb}",
674
790
  ]
675
791
  acc += pkgs
676
792
  acc << "\\begin{document}" << "\\pagestyle{empty}"
@@ -719,7 +835,7 @@ class Deplate::Formatter
719
835
  @inlatex_idx += 1
720
836
  end
721
837
  id = @deplate.auxiliary_auto_filename('ltx', @inlatex_idx, invoker.accum)
722
- invoker.log(["No id given", invoker.accum])
838
+ invoker.log(["No ID given", invoker.accum])
723
839
  end
724
840
  id
725
841
  end
@@ -741,6 +857,7 @@ class Deplate::Formatter
741
857
  pkgs = []
742
858
  body = []
743
859
  for l in accum.join("\n")
860
+ l = inlatex_clean(l)
744
861
  if l =~ /^\s*\\(usepackage|input)\s*(\[.*?\])?\s*\{.+?\}\s*$/
745
862
  pkgs << l.chomp
746
863
  elsif l =~ /%%%\s*$/
@@ -751,10 +868,30 @@ class Deplate::Formatter
751
868
  end
752
869
  return pkgs.uniq, body
753
870
  end
871
+
872
+ rx = self.blacklist_latex.collect! do |c|
873
+ if c =~ /^\\(.+)$/
874
+ "\\\\\\s*#$1\\b"
875
+ elsif c =~ /\w$/
876
+ # "(\\\\\\s*)?\\b#{Regexp.escape(c)}\\b"
877
+ "\\\\\\s*#{Regexp.escape(c)}\\b"
878
+ else
879
+ Regexp.escape(c)
880
+ end
881
+ end
882
+ INLATEX_RX = Regexp.new(rx.join('|'))
754
883
 
884
+ def inlatex_clean(line)
885
+ line = line.chomp
886
+ unless @deplate.options.allow.include?('t')
887
+ line.gsub!(INLATEX_RX, '+++disabled+++')
888
+ end
889
+ line
890
+ end
891
+
755
892
  # The default suffix/device to be used for inlatex output.
756
893
  def inlatex_sfx
757
- "jpeg"
894
+ 'jpeg'
758
895
  end
759
896
 
760
897
  def latex2dvi(invoker, ftex, faux, flog)
@@ -783,12 +920,6 @@ class Deplate::Formatter
783
920
  end
784
921
  end
785
922
 
786
-
787
- private
788
- def referenced_bib_entry(invoker, key, text)
789
- text
790
- end
791
-
792
923
  def formatted_block(env, text, opts=nil, args=nil, no_id=false, no_indent=false)
793
924
  text = indent_text(text) unless no_indent
794
925
  return join_blocks([get_open(env, opts, args, :no_id => no_id), text, get_close(env, args)])
@@ -804,6 +935,184 @@ class Deplate::Formatter
804
935
  return get_open(env, opts, args, :single => true, :no_id => no_id)
805
936
  end
806
937
 
938
+ def indent_text(text, args={})
939
+ if text
940
+ mult = args[:mult] || 1
941
+ shift = args[:shift]
942
+ hanging = args[:hanging]
943
+ indent = args[:indent] || format_indent(mult, shift)
944
+ return text.collect do |l|
945
+ rv = '%s%s' % [indent, l.chomp]
946
+ if hanging
947
+ indent = args[:indenttail] || \
948
+ if args[:indent]
949
+ args[:indent] +
950
+ case hanging
951
+ when Integer
952
+ ' ' * hanging
953
+ else
954
+ ' '
955
+ end
956
+ else
957
+ format_indent(mult + 1, shift)
958
+ end
959
+ hanging = false
960
+ end
961
+ rv
962
+ end.join("\n")
963
+ end
964
+ end
965
+
966
+ def_service('object') do |args, text|
967
+ id = args['id']
968
+ if id
969
+ return @deplate.object_by_id(id)
970
+ elsif args['array']
971
+ text = args['array']
972
+ sep = args['sep']
973
+ if sep
974
+ sep = sep ? Regexp.escape(sep) : '\\s+'
975
+ else
976
+ sep = args['rx']
977
+ end
978
+ if sep
979
+ return text.split(Regexp.new(sep))
980
+ else
981
+ log('No separator', :error)
982
+ end
983
+ end
984
+ end
985
+
986
+ def_service('output_filename') do |args, text|
987
+ output_destination
988
+ end
989
+
990
+ def_service('output_basename') do |args, text|
991
+ sfx = args['sfx']
992
+ if sfx
993
+ File.basename(output_destination, sfx)
994
+ else
995
+ File.basename(output_destination)
996
+ end
997
+ end
998
+
999
+ # <+TBD+>
1000
+ # def_service('format') do |args, text|
1001
+ # id = args['id'] || text
1002
+ # # o = @variables[id]
1003
+ # o = object_by_id(id)
1004
+ # if o
1005
+ # o.format_as_string
1006
+ # end
1007
+ # end
1008
+
1009
+
1010
+ private
1011
+ def initialize_services
1012
+ services = {}
1013
+ return services
1014
+ end
1015
+
1016
+ def format_custom_list(invoker, elt)
1017
+ listing = @deplate.options.listings.get(elt, true)
1018
+ props = listing[:props]
1019
+ format_list_of(invoker,
1020
+ :title => props['title'],
1021
+ :prefix => props['prefix'] || elt,
1022
+ :data => listing[:value],
1023
+ :flat => props['flat'],
1024
+ :style => (props['style'] || props['prefix'])
1025
+ )
1026
+ end
1027
+
1028
+ def format_list_of(invoker, other_args)
1029
+ args = invoker.args
1030
+ name = other_args[:title]
1031
+ prefix = other_args[:prefix]
1032
+ data = other_args[:data]
1033
+ unless data
1034
+ list = other_args[:listing]
1035
+ data = invoker.deplate.options.listings.get(list)
1036
+ unless data
1037
+ invoker.log(['Unknown list', list], :error)
1038
+ end
1039
+ end
1040
+ name = args['title'] || name
1041
+ id = (name || prefix).gsub(/\W/, '_')
1042
+
1043
+ acc = []
1044
+ consume_label(id, true)
1045
+ consume_label("#{id}Block", true)
1046
+ acc << listing_prematter(invoker, other_args, id)
1047
+ unless args['plain'] || args['noTitle']
1048
+ acc << listing_title(invoker, other_args, name)
1049
+ end
1050
+
1051
+ ll = 1
1052
+ levels = args['levels']
1053
+ if levels
1054
+ range_from, range_to, rest = levels.split(/\.\./)
1055
+ if rest
1056
+ log(['Malformed range', levels], :error)
1057
+ end
1058
+ end
1059
+ range_from ||= args['min']
1060
+ if range_from
1061
+ range_from = range_from.to_i
1062
+ end
1063
+ range_to ||= args['max']
1064
+ if range_to
1065
+ range_to = range_to.to_i
1066
+ end
1067
+ top = args['top']
1068
+ if top
1069
+ top = /^#{Regexp.escape(top)}/
1070
+ end
1071
+ sub = args['sub']
1072
+ if sub
1073
+ sub = /^#{Regexp.escape(invoker.level_as_string)}\./
1074
+ end
1075
+ accData = []
1076
+ for elt in data
1077
+ if elt.nil? or elt.args['noList']
1078
+ next
1079
+ end
1080
+ if range_from and elt.level < range_from
1081
+ next
1082
+ end
1083
+ if range_to and elt.level > range_to
1084
+ next
1085
+ end
1086
+ if top and elt.level_as_string !~ top
1087
+ next
1088
+ end
1089
+ if sub and elt.level_as_string !~ sub
1090
+ next
1091
+ end
1092
+ title = block_given? ? yield(elt) : elt.element_caption
1093
+ level = other_args[:flat] ? 1 : elt.level
1094
+ accData << listing_item(invoker, args, prefix, title, elt, level, other_args)
1095
+ end
1096
+ acc << printable_list(invoker, accData)
1097
+ acc << listing_postmatter(invoker, other_args)
1098
+ join_blocks(acc)
1099
+ end
1100
+
1101
+ def_abstract :listing_prematter, :listing_postmatter, :listing_title, \
1102
+ :listing_item
1103
+
1104
+ def consume_label(label, warn=false)
1105
+ if !label
1106
+ return false
1107
+ elsif @consumed_labels.include?(label)
1108
+ log(['Duplicate label'], label, :error) if warn
1109
+ return false
1110
+ else
1111
+ @consumed_labels << label
1112
+ return true
1113
+ end
1114
+ end
1115
+
807
1116
  def use_id(args, opts={}, set=true)
808
1117
  if args
809
1118
  set &&= !args[:id]
@@ -841,24 +1150,17 @@ class Deplate::Formatter
841
1150
 
842
1151
  def format_indent(level, shift=false)
843
1152
  if level < 0
844
- log(["Negative indentation level", level], :error)
845
- return ""
1153
+ log(['Negative indentation level', level], :error)
1154
+ return ''
846
1155
  else
847
1156
  l = level * 2
848
1157
  # l += 1 if shift
849
- return " " * l
1158
+ return ' ' * l
850
1159
  end
851
1160
  end
852
1161
 
853
- def indent_text(text, mult=1, shift=false)
854
- if text
855
- indent = format_indent(mult)
856
- return text.collect {|l| "%s%s" % [indent, l.chomp]}.join("\n")
857
- end
858
- end
859
-
860
1162
  def keywords
861
- kw = @deplate.variables["keywords"]
1163
+ kw = @deplate.variables['keywords']
862
1164
  if kw.kind_of?(Array)
863
1165
  kw
864
1166
  elsif kw.kind_of?(String)
@@ -873,11 +1175,16 @@ class Deplate::Formatter
873
1175
  # Create @plain_text_rx, which contains the keys of @special_symbols
874
1176
  # in a group. This rx will be used by #plain_text.
875
1177
  def build_plain_text_rx
876
- @plain_text_rx = Regexp.new("(%s)" % @special_symbols.keys.collect {|x| Regexp.escape(x)}.join("|"))
1178
+ @plain_text_rx = Regexp.new('(%s)' % @special_symbols.keys.collect {|x| Regexp.escape(x)}.join('|'))
877
1179
  end
878
1180
 
879
1181
 
880
1182
  ################################################ Bibliography {{{1
1183
+ def bib_styler
1184
+ style = @deplate.variables['bibStyle']
1185
+ @deplate.bib_styler(style)
1186
+ end
1187
+
881
1188
  def simple_bibtex_reader(bibfiles)
882
1189
  acc = []
883
1190
  for b in bibfiles
@@ -890,11 +1197,22 @@ class Deplate::Formatter
890
1197
  end
891
1198
  File.open(b) {|io| acc << io.read}
892
1199
  end
893
- acc = acc.join("\n")
1200
+ strings = {}
1201
+ acc = acc.join("\n")
894
1202
  loop do
895
- m = /^\s*(@\w+\{\s*(\S+?)\s*,.*?)(?=(^@|\z))/m.match(acc)
1203
+ m = /^\s*@string\{\s*(\S+?)\s*=\s*(.+?)\s*\}/m.match(acc)
1204
+ if m
1205
+ r = m[2]
1206
+ if r =~ /^(".*?"|'.*?'|\{.*?\})$/
1207
+ r = r[1..-2]
1208
+ end
1209
+ strings[m[1]] = r
1210
+ acc = m.post_match
1211
+ next
1212
+ end
1213
+ m = /^\s*(@(\w+)\{\s*(\S+?)\s*,.*?)(?=(^@|\z))/m.match(acc)
896
1214
  if m
897
- id = m[2]
1215
+ id = m[3]
898
1216
  e = m[1]
899
1217
  arr = e.scan(/^\s*(\w+)\s*=\s*(\{.*?\}|\d+)\s*[,}]\s*$/m)
900
1218
  arr.collect! do |var, val, rest|
@@ -902,9 +1220,12 @@ class Deplate::Formatter
902
1220
  if n
903
1221
  val = n[1]
904
1222
  end
1223
+ if strings[val]
1224
+ val = strings[val]
1225
+ end
905
1226
  [var, val]
906
1227
  end
907
- arr << ["type", m[2]]
1228
+ arr << ['@type', m[2]] << ['@id', id]
908
1229
  @bibentries[id] = arr
909
1230
  acc = m.post_match
910
1231
  else
@@ -921,7 +1242,7 @@ class Deplate::Formatter
921
1242
  acc = []
922
1243
  for k in cited_keys
923
1244
  b = bib_entry(k)
924
- bb = format_bib_entry(invoker, b)
1245
+ bb = format_bib_entry(invoker, k, b)
925
1246
  i = encode_id(k)
926
1247
  l = format_label(invoker, :string, [i])
927
1248
  if block_given?
@@ -934,47 +1255,15 @@ class Deplate::Formatter
934
1255
  acc.collect! {|e| e[0]}
935
1256
  join_blocks(acc)
936
1257
  end
937
-
938
- def format_bib_entry(invoker, bibdef)
939
- key, author = bibdef.assoc("author")
940
- key, editor = bibdef.assoc("editor")
941
- key, how = bibdef.assoc("howpublished")
942
- author = reformat_authors(author)
943
- editor = reformat_authors(editor)
944
- au = [nil, author || editor || how || "???"]
945
- yr = bibdef.assoc("year")
946
- au[1] = "%s (%s)" % [au, yr[1]] if yr
947
- ti = bibdef.assoc("title")
948
- bt = bibdef.assoc("booktitle")
949
- pu = bibdef.assoc("publisher")
950
- i = bibdef.assoc("journal")
951
- if i
952
- vol = bibdef.assoc("volume")
953
- vol &&= vol[1]
954
- nr = bibdef.assoc("number")
955
- nr &&= "(" + nr[1] +")"
956
- i[1] += [" ", vol, nr].join if vol or nr
957
- elsif author and editor
958
- i = [nil, editor]
959
- t = bt || ti
960
- if t
961
- i << ": " << t[1]
962
- end
963
- end
964
- p = bibdef.assoc("pages")
965
- if i
966
- hi = "journal"
967
- elsif bt
968
- hi = "booktitle"
1258
+
1259
+ def format_bib_entry(invoker, key, bibdef)
1260
+ if bibdef.empty?
1261
+ # text = "#{key}??? (#{@deplate.msg('Unknown bib entry')})"
1262
+ text = "#{key}???"
969
1263
  else
970
- hi = "title"
1264
+ text = bib_styler.bib_format(bibdef)
971
1265
  end
972
- bb = [au, ti, bt, pu, i, p].compact.collect do |key, val|
973
- val = simple_latex_reformat(val)
974
- val = %{__#{val}__} if key == hi
975
- val
976
- end
977
- return @deplate.parse_and_format_without_wikinames(invoker, bb.join(". ") + ".")
1266
+ return @deplate.parse_and_format_without_wikinames(invoker, text)
978
1267
  end
979
1268
 
980
1269
  def simple_latex_reformat(text)
@@ -989,105 +1278,76 @@ class Deplate::Formatter
989
1278
  return text
990
1279
  end
991
1280
 
992
- def bib_entry(key)
993
- b = @bibentries[key] || []
994
- crossref = b.assoc("crossref")
995
- if crossref
996
- cb = @bibentries[crossref[1]]
997
- b += cb if cb
998
- end
999
- return b
1000
- end
1001
-
1002
- def reformat_authors(text)
1003
- if text
1004
- au = []
1005
- for a in text.split(/ and /)
1006
- m = /^((.+?)?\s+)?(\S+)$/.match(a.strip)
1007
- if m[2]
1008
- au << m[3] + ", " + m[2]
1009
- else
1010
- au << a
1011
- end
1012
- end
1013
- return au.join("; ")
1014
- end
1015
- end
1016
-
1017
- def authors_split(text)
1018
- text.split(/ and /) if text
1019
- end
1020
-
1021
-
1022
1281
  # this is the general function used for formatting lists of any kind; it
1023
1282
  # relies on #format_list, #format_indent and #format_list_item to
1024
1283
  # do the actual output
1025
1284
  def printable_list(invoker, list=nil)
1026
1285
  list ||= invoker.elt
1027
1286
  unless list.nil? or list.empty?
1028
- @levels = []
1029
- @types = []
1030
- @endTags = []
1287
+ list_tags = {
1288
+ :levels => [],
1289
+ :types => [],
1290
+ :end_tags => []
1291
+ }
1031
1292
  accum = []
1032
1293
  # level0 = list.sort {|a,b| a.level <=> b.level}[0].level
1033
- level0 = list.min {|a,b| a.level <=> b.level}.level
1294
+ level0 = list.min do |a,b|
1295
+ if a.level and b.level
1296
+ a.level <=> b.level
1297
+ elsif a
1298
+ 1
1299
+ else
1300
+ -1
1301
+ end
1302
+ end.level
1034
1303
  ind = 0
1035
1304
  max = list.size - 1
1036
1305
 
1037
1306
  list.each_with_index do |i, idx|
1038
1307
  # :listtype, :type, :level, :item, :body
1039
1308
  t = i.type
1040
- s = list_subtype(t, i.item)
1309
+ s = list_subtype(t, i)
1041
1310
  c = [i.listtype, s]
1042
1311
  l = i.level
1043
- if last_listtype
1312
+ if last_listtype(list_tags)
1313
+ special = ['Paragraph', 'Container'].include?(t)
1044
1314
  # there is a list environment, so this isn't the first item
1045
- if last_level and l != last_level
1046
- if l < last_level
1315
+ if last_level(list_tags) and l != last_level(list_tags)
1316
+ if l < last_level(list_tags)
1047
1317
  # close a nested list
1048
- ind = printable_close_lists_until(invoker, accum, ind, l)
1049
- elsif l > last_level and t != "Paragraph"
1318
+ ind = printable_close_lists_until(invoker, list_tags, accum, ind, l)
1319
+ elsif l > last_level(list_tags) and !special
1050
1320
  # open a new nested list
1051
- # p "DBG --- 1054: #{c} != #{last_listtype}"
1052
- ind = printable_open_list(invoker, accum, c, ind, l, s)
1053
- @endTags << nil
1321
+ # p "DBG --- 1054: #{c} != #{last_listtype(list_tags)}"
1322
+ ind = printable_open_list(invoker, list_tags, accum, c, ind, l, s)
1323
+ list_tags[:end_tags] << nil
1054
1324
  end
1055
1325
  end
1056
- if last_level and last_listtype and c != last_listtype and t != "Paragraph"
1057
- if l <= last_level
1326
+ if last_level(list_tags) and last_listtype(list_tags) and c != last_listtype(list_tags) and !special
1327
+ if l <= last_level(list_tags)
1058
1328
  # close the previous list and start a new one
1059
- ind = printable_list_close_endtag(invoker, accum, ind)
1060
- # p "DBG ---- #{last_listtype} #{t}"
1329
+ ind = printable_list_close_endtag(invoker, list_tags, accum, ind)
1330
+ # p "DBG ---- #{last_listtype(list_tags)} #{t}"
1061
1331
  end
1062
- if c != last_listtype and l <= last_level
1063
- # p "DBG --- 1067: #{c} != #{last_listtype}"
1064
- ind = printable_close_list(invoker, accum, ind)
1065
- ind = printable_open_list(invoker, accum, c, ind, l, s)
1066
- @endTags << nil
1332
+ if c != last_listtype(list_tags) and l <= last_level(list_tags)
1333
+ # p "DBG --- 1067: #{c} != #{last_listtype(list_tags)}"
1334
+ ind = printable_close_list(invoker, list_tags, accum, ind)
1335
+ ind = printable_open_list(invoker, list_tags, accum, c, ind, l, s)
1336
+ list_tags[:end_tags] << nil
1067
1337
  end
1068
1338
  end
1069
1339
  else
1070
1340
  # start a new list
1071
- ind = printable_open_list(invoker, accum, c, ind, l, s)
1341
+ ind = printable_open_list(invoker, list_tags, accum, c, ind, l, s)
1072
1342
  end
1073
- if @levels.empty? and idx < max
1343
+ if list_tags[:levels].empty? and idx < max
1074
1344
  # something weired happened (e.g. the previous list item was
1075
1345
  # deeper nested, but this item doesn't continue anything --
1076
1346
  # which should probably considered as a syntax error anyway)
1077
- invoker.log(["Malformed list hierarchy", last_listtype, idx], :error)
1078
- ind = printable_open_list(invoker, accum, c, ind, l, s)
1079
- end
1080
- if t == "Paragraph"
1081
- acc, etag = format_list_item(invoker, t, ind, i)
1082
- accum << acc
1083
- else
1084
- ind = printable_list_close_endtag(invoker, accum, ind)
1085
- # p "DBG #{' ' * l} Item (#{@types} #{@levels})"
1086
- acc, etag = format_list_item(invoker, t, ind, i)
1087
- @endTags << [etag, l, ind]
1088
- accum << acc
1089
- ind += 1
1347
+ invoker.log(['Malformed list hierarchy', last_listtype(list_tags), idx], :error)
1348
+ ind = printable_open_list(invoker, list_tags, accum, c, ind, l, s)
1090
1349
  end
1350
+ ind = printable_list_item(invoker, list_tags, accum, t, ind, l, i)
1091
1351
  if i.label and !i.label.empty?
1092
1352
  lab = format_label(invoker, :string, i.label)
1093
1353
  if lab
@@ -1097,100 +1357,135 @@ class Deplate::Formatter
1097
1357
  end
1098
1358
 
1099
1359
  # close all open tags & lists
1100
- while !@endTags.empty?
1101
- ind = printable_list_close_endtag(invoker, accum, ind)
1360
+ while !list_tags[:end_tags].empty?
1361
+ ind = printable_list_close_endtag(invoker, list_tags, accum, ind)
1102
1362
  end
1103
- while !@levels.empty?
1104
- ind = printable_close_list(invoker, accum, ind)
1363
+ while !list_tags[:levels].empty?
1364
+ ind = printable_close_list(invoker, list_tags, accum, ind)
1105
1365
  end
1106
1366
  if ind < 0
1107
- invoker.log("Malformed list or internal error", :error)
1367
+ invoker.log(['Malformed list or internal error', invoker.class], :error)
1108
1368
  end
1109
1369
 
1110
1370
  accum.delete_if {|e| e == :empty}
1111
- return accum.join("\n")
1371
+ return join_blocks(accum)
1112
1372
  else
1113
- return ""
1373
+ return ''
1114
1374
  end
1115
1375
  end
1116
1376
 
1117
- def last_level
1118
- @levels.last
1377
+ def last_level(list_tags)
1378
+ list_tags[:levels].last
1119
1379
  end
1120
1380
 
1121
- def last_listtype
1122
- @types.last
1381
+ def last_listtype(list_tags)
1382
+ list_tags[:types].last
1123
1383
  end
1124
1384
 
1125
- # def last_type
1126
- # @types.last
1127
- # end
1128
-
1129
- # def last_listtype
1130
- # c, s = last_type
1131
- # c
1132
- # end
1133
-
1134
- # def last_subtype
1135
- # c, s = last_type
1136
- # s
1137
- # end
1138
-
1139
1385
  def list_subtype(type, item)
1140
1386
  case type
1141
- when "Numbered"
1142
- if item =~ /^[A-Z]\.?$/
1387
+ when "Ordered"
1388
+ if item.item =~ /^[A-Z]\.?$/
1143
1389
  return "A"
1144
- elsif item =~ /^[a-z?@]\.?$/
1390
+ elsif item.item =~ /^[a-z?@]\.?$/
1145
1391
  return "a"
1146
1392
  else
1147
1393
  return "1"
1148
1394
  end
1149
- when "Itemize"
1150
- return nil
1151
- when "Description"
1152
- return nil
1153
- when "Paragraph"
1154
- return nil
1395
+ # when "Itemize"
1396
+ # return nil
1397
+ # when "Description"
1398
+ # return nil
1399
+ # when 'Task'
1400
+ # return nil
1401
+ # when "Paragraph"
1402
+ # return nil
1403
+ # when 'Container'
1404
+ # return nil
1155
1405
  else
1156
- raise "Unknown list type: #{type}"
1406
+ if item.opts and item.opts[:subtype]
1407
+ return item.opts[:subtype]
1408
+ else
1409
+ return nil
1410
+ end
1411
+ # raise "Unknown list type: #{type}"
1157
1412
  end
1158
1413
  end
1159
1414
 
1160
- def printable_close_lists_until(invoker, accum, ind, level)
1415
+ def printable_list_item(invoker, list_tags, accum, type, indentation, level, item)
1416
+ case type
1417
+ when 'Paragraph'
1418
+ args = {}
1419
+ if @list_last_type == 'Container'
1420
+ args[:follow_container] = true
1421
+ end
1422
+ acc, etag = format_list_item(invoker, type, indentation, item, args)
1423
+ accum << acc
1424
+ when 'Container'
1425
+ item_copy = item.dup
1426
+ # idt = item_copy.body.indentation
1427
+ # idt_level = item_copy.body.indentation_level
1428
+ idt_mode = invoker.args['indentation']
1429
+ if item_copy.body
1430
+ idt_mode ||= item_copy.body.class.indentation_mode.to_s
1431
+ item_copy.body = item_copy.body.format_current
1432
+ end
1433
+ case idt_mode
1434
+ when 'auto'
1435
+ item_copy.body = indent_text(item_copy.body, :mult => indentation)
1436
+ when 'none'
1437
+ else
1438
+ invoker.log(['Unknown indentation mode', idt_mode], :error)
1439
+ end
1440
+ # p "DBG #{' ' * level} Container (#{list_tags[:types]} #{@list_levels})"
1441
+ acc, etag = format_list_item(invoker, type, indentation, item_copy)
1442
+ accum << acc
1443
+ else
1444
+ indentation = printable_list_close_endtag(invoker, list_tags, accum, indentation)
1445
+ # p "DBG #{' ' * level} Item (#{list_tags[:types]} #{@list_levels})"
1446
+ acc, etag = format_list_item(invoker, type, indentation, item)
1447
+ list_tags[:end_tags] << [etag, level, indentation]
1448
+ accum << acc
1449
+ indentation += 1
1450
+ end
1451
+ @list_last_type = type
1452
+ indentation
1453
+ end
1454
+
1455
+ def printable_close_lists_until(invoker, list_tags, accum, ind, level)
1161
1456
  begin
1162
- ind = printable_list_close_endtag(invoker, accum, ind)
1163
- ind = printable_close_list(invoker, accum, ind)
1164
- end until @levels.empty? or @levels.last <= level
1457
+ ind = printable_list_close_endtag(invoker, list_tags, accum, ind)
1458
+ ind = printable_close_list(invoker, list_tags, accum, ind)
1459
+ end until list_tags[:levels].empty? or list_tags[:levels].last <= level
1165
1460
  ind
1166
1461
  end
1167
1462
 
1168
- def printable_close_list(invoker, accum, ind)
1463
+ def printable_close_list(invoker, list_tags, accum, ind)
1169
1464
  ind -= 1
1170
- lev = @levels.pop
1171
- tp, sp = @types.pop
1465
+ lev = list_tags[:levels].pop
1466
+ tp, sp = list_tags[:types].pop
1172
1467
  # p "DBG #{' ' * (lev || 1)}>close #{lev} #{tp} #{sp} #{caller[0]}"
1173
1468
  le = format_list_env(invoker, tp, ind, :close, sp)
1174
1469
  accum << le if le
1175
1470
  ind
1176
1471
  end
1177
1472
 
1178
- def printable_open_list(invoker, accum, type, ind, level, subtype=nil)
1473
+ def printable_open_list(invoker, list_tags, accum, type, ind, level, subtype=nil)
1179
1474
  t, s = type
1180
1475
  le = format_list_env(invoker, t, ind, :open, subtype)
1181
1476
  accum << le if le
1182
1477
  ind += 1
1183
- @levels << level
1184
- @types << type
1478
+ list_tags[:levels] << level
1479
+ list_tags[:types] << type
1185
1480
  # p "DBG #{' ' * (level || 1)}<open #{level} #{type} #{subtype} #{caller[0]}"
1186
1481
  ind
1187
1482
  end
1188
1483
 
1189
- def printable_list_close_endtag(invoker, accum, ind)
1190
- tag, level, ind0 = @endTags.pop
1484
+ def printable_list_close_endtag(invoker, list_tags, accum, ind)
1485
+ tag, level, ind0 = list_tags[:end_tags].pop
1191
1486
  if tag
1192
- while @levels.last and @levels.last > level
1193
- ind = printable_close_list(invoker, accum, ind)
1487
+ while list_tags[:levels].last and list_tags[:levels].last > level
1488
+ ind = printable_close_list(invoker, list_tags, accum, ind)
1194
1489
  end
1195
1490
  accum << tag unless tag == :none
1196
1491
  end
@@ -1206,5 +1501,22 @@ class Deplate::Formatter
1206
1501
  nil
1207
1502
  end
1208
1503
  end
1504
+
1505
+ def use_image_filename(filename, args={})
1506
+ unless args['noGuess'] or args[:raw]
1507
+ fext = File.extname(filename)
1508
+ fname = fext.empty? ? filename : filename[0..(-1 - fext.size)]
1509
+ for sfx in image_suffixes
1510
+ fs = [fname, sfx].join
1511
+ ff = @deplate.auxiliary_filename(fs)
1512
+ fff = @deplate.auxiliary_filename(fs, true)
1513
+ if File.exist?(fff)
1514
+ return ff
1515
+ end
1516
+ end
1517
+ end
1518
+ return filename
1519
+ end
1520
+
1209
1521
  end
1210
1522