deplate 0.8 → 0.8.1

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 (163) hide show
  1. data/AUTHORS.TXT +19 -16
  2. data/CHANGES.TXT +214 -248
  3. data/NEWS.TXT +47 -30
  4. data/README.TXT +0 -1
  5. data/TODO.TXT +93 -20
  6. data/VERSION.TXT +1 -1
  7. data/bin/deplate.exy +192 -0
  8. data/etc/deplate.ini +70 -9
  9. data/lib/action_view/helpers/deplate.rb +33 -33
  10. data/lib/deplate.rb +2 -2
  11. data/lib/deplate/bib.rb +72 -41
  12. data/lib/deplate/builtin.rb +1 -1
  13. data/lib/deplate/cache.rb +1 -1
  14. data/lib/deplate/commands.rb +161 -102
  15. data/lib/deplate/common.rb +93 -7
  16. data/lib/deplate/converter.rb +10 -4
  17. data/lib/deplate/core.rb +215 -108
  18. data/lib/deplate/counters.rb +23 -8
  19. data/lib/deplate/css/article.css +9 -5
  20. data/lib/deplate/css/deplate.css +37 -3
  21. data/lib/deplate/css/heading-navbar.css +1 -1
  22. data/lib/deplate/css/highstep.css +18 -0
  23. data/lib/deplate/css/htmldoc.css +43 -0
  24. data/lib/deplate/css/layout-deplate-print.css +1 -1
  25. data/lib/deplate/css/layout-deplate.css +1 -1
  26. data/lib/deplate/css/play.css +101 -0
  27. data/lib/deplate/css/sans-serif.css +1 -1
  28. data/lib/deplate/css/serif-e.css +1 -1
  29. data/lib/deplate/css/serif-rel.css +1 -1
  30. data/lib/deplate/css/serif.css +1 -1
  31. data/lib/deplate/css/slides.css +1 -1
  32. data/lib/deplate/css/styles.css +4 -0
  33. data/lib/deplate/css/tabbar-right.css +54 -8
  34. data/lib/deplate/css/tabbar-top.css +28 -9
  35. data/lib/deplate/css/text-sans-serif.css +1 -1
  36. data/lib/deplate/css/text-serif.css +1 -1
  37. data/lib/deplate/define.rb +71 -38
  38. data/lib/deplate/deplate-string.rb +3 -3
  39. data/lib/deplate/docbook.rb +9 -9
  40. data/lib/deplate/elements.rb +173 -84
  41. data/lib/deplate/etc.rb +6 -8
  42. data/lib/deplate/external.rb +9 -5
  43. data/lib/deplate/fmt/dbk-article-4.1.2.rb +4 -3
  44. data/lib/deplate/fmt/dbk-article.rb +9 -8
  45. data/lib/deplate/fmt/dbk-book.rb +4 -3
  46. data/lib/deplate/fmt/dbk-ref.rb +5 -4
  47. data/lib/deplate/fmt/dbk-slides.rb +4 -3
  48. data/lib/deplate/fmt/dbk-snippet.rb +4 -3
  49. data/lib/deplate/fmt/html-snippet.rb +1 -1
  50. data/lib/deplate/fmt/html.rb +186 -46
  51. data/lib/deplate/fmt/htmlsite.rb +19 -9
  52. data/lib/deplate/fmt/htmlslides.rb +1 -1
  53. data/lib/deplate/fmt/htmlwebsite.rb +1 -1
  54. data/lib/deplate/fmt/latex-dramatist.rb +175 -0
  55. data/lib/deplate/fmt/latex-snippet.rb +1 -1
  56. data/lib/deplate/fmt/latex.rb +132 -80
  57. data/lib/deplate/fmt/null.rb +1 -1
  58. data/lib/deplate/fmt/php.rb +1 -1
  59. data/lib/deplate/fmt/phpsite.rb +1 -1
  60. data/lib/deplate/fmt/plain.rb +16 -9
  61. data/lib/deplate/fmt/template.rb +1 -1
  62. data/lib/deplate/fmt/xhtml10t.rb +1 -1
  63. data/lib/deplate/formatter-snippet.rb +1 -1
  64. data/lib/deplate/formatter.rb +272 -81
  65. data/lib/deplate/guesslanguage.rb +57 -0
  66. data/lib/deplate/input.rb +205 -50
  67. data/lib/deplate/input/deplate-headings.rb +9 -11
  68. data/lib/deplate/input/deplate-restricted.rb +3 -23
  69. data/lib/deplate/input/deplate.rb +1 -1
  70. data/lib/deplate/input/play.rb +208 -0
  71. data/lib/deplate/input/rdoc.rb +37 -15
  72. data/lib/deplate/input/template.rb +6 -11
  73. data/lib/deplate/lib/Makefile.config +53 -4
  74. data/lib/deplate/lib/html/parbreak +3 -0
  75. data/lib/deplate/lib/javascript/StepwiseNextPage.js +8 -0
  76. data/lib/deplate/lib/javascript/StepwiseNextPage_confirm.js +8 -0
  77. data/lib/deplate/lib/latex/deplate.sty +36 -0
  78. data/lib/deplate/lib/latex/parbreak +6 -0
  79. data/lib/deplate/lib/php/page-comment.inc.php +5 -5
  80. data/lib/deplate/lib/plain/parbreak +6 -0
  81. data/lib/deplate/locale/de.latin1 +87 -15
  82. data/lib/deplate/locale/de.latin1_data +60 -0
  83. data/lib/deplate/locale/en.latin1_data +46 -0
  84. data/lib/deplate/locale/fr.latin1_data +74 -0
  85. data/lib/deplate/locale/ru.koi8-r_data +63 -0
  86. data/lib/deplate/locale/{zh_cn.gb2312 → zh_CN.GB2312} +0 -0
  87. data/lib/deplate/macros.rb +106 -32
  88. data/lib/deplate/messages.rb +22 -8
  89. data/lib/deplate/metadata.rb +1 -1
  90. data/lib/deplate/metadata/marshal.rb +1 -1
  91. data/lib/deplate/metadata/xml.rb +1 -1
  92. data/lib/deplate/metadata/yaml.rb +1 -1
  93. data/lib/deplate/mod/anyword.rb +4 -4
  94. data/lib/deplate/mod/babelfish.rb +1 -1
  95. data/lib/deplate/mod/code-gvim.rb +14 -8
  96. data/lib/deplate/mod/code-gvim71.rb +52 -0
  97. data/lib/deplate/mod/code-highlight.rb +35 -19
  98. data/lib/deplate/mod/colored-log.rb +1 -1
  99. data/lib/deplate/mod/endnotes.rb +1 -1
  100. data/lib/deplate/mod/guesslanguage.rb +75 -0
  101. data/lib/deplate/mod/html-asciimath.rb +1 -1
  102. data/lib/deplate/mod/html-deplate-button.rb +1 -1
  103. data/lib/deplate/mod/html-headings-navbar.rb +1 -1
  104. data/lib/deplate/mod/html-highstep.rb +43 -0
  105. data/lib/deplate/mod/html-jsmath.rb +1 -1
  106. data/lib/deplate/mod/html-obfuscate-email.rb +1 -1
  107. data/lib/deplate/mod/html-sidebar.rb +1 -1
  108. data/lib/deplate/mod/iconv.rb +1 -1
  109. data/lib/deplate/mod/imgurl.rb +1 -1
  110. data/lib/deplate/mod/inlatex-compound.rb +1 -1
  111. data/lib/deplate/mod/koma.rb +4 -4
  112. data/lib/deplate/mod/{de.rb → lang-de.rb} +1 -1
  113. data/lib/deplate/mod/{en.rb → lang-en.rb} +1 -1
  114. data/lib/deplate/mod/{ru_koi8-r.rb → lang-ru-koi8-r.rb} +1 -1
  115. data/lib/deplate/mod/lang-ru.rb +9 -0
  116. data/lib/deplate/mod/{zh-cn-autospace.rb → lang-zh_CN-autospace.rb} +3 -3
  117. data/lib/deplate/mod/{zh-cn.rb → lang-zh_CN.rb} +8 -8
  118. data/lib/deplate/mod/latex-emph-table-head.rb +1 -1
  119. data/lib/deplate/mod/latex-styles.rb +6 -6
  120. data/lib/deplate/mod/latex-verbatim-small.rb +1 -1
  121. data/lib/deplate/mod/linkmap.rb +128 -0
  122. data/lib/deplate/mod/makefile.rb +23 -22
  123. data/lib/deplate/mod/mark-external-urls.rb +13 -7
  124. data/lib/deplate/mod/markup-1-warn.rb +1 -1
  125. data/lib/deplate/mod/markup-1.rb +1 -1
  126. data/lib/deplate/mod/navbar-png.rb +5 -4
  127. data/lib/deplate/mod/noindent.rb +1 -1
  128. data/lib/deplate/mod/numpara.rb +1 -1
  129. data/lib/deplate/mod/particle-math.rb +1 -1
  130. data/lib/deplate/mod/php-extra.rb +1 -1
  131. data/lib/deplate/mod/pstoedit.rb +1 -1
  132. data/lib/deplate/mod/recode.rb +1 -1
  133. data/lib/deplate/mod/smart-dash.rb +1 -1
  134. data/lib/deplate/mod/smiley.rb +1 -1
  135. data/lib/deplate/mod/soffice.rb +1 -1
  136. data/lib/deplate/mod/symbols-latin1.rb +1 -1
  137. data/lib/deplate/mod/symbols-od-utf-8.rb +1 -1
  138. data/lib/deplate/mod/symbols-plain.rb +1 -1
  139. data/lib/deplate/mod/symbols-sgml.rb +1 -1
  140. data/lib/deplate/mod/symbols-utf-8.rb +1 -1
  141. data/lib/deplate/mod/symbols-xml.rb +1 -1
  142. data/lib/deplate/mod/syntax-region-alt.rb +1 -1
  143. data/lib/deplate/mod/utf8.rb +1 -1
  144. data/lib/deplate/mod/validate-html.rb +1 -1
  145. data/lib/deplate/mod/xmlrpc.rb +37 -36
  146. data/lib/deplate/nukumi2.rb +4 -4
  147. data/lib/deplate/once-method.rb +1 -1
  148. data/lib/deplate/output.rb +12 -4
  149. data/lib/deplate/particles.rb +52 -22
  150. data/lib/deplate/regions.rb +160 -90
  151. data/lib/deplate/skeletons.rb +4 -3
  152. data/lib/deplate/structured.rb +19 -13
  153. data/lib/deplate/template.rb +17 -9
  154. data/lib/deplate/templates/html-doc.html +8 -11
  155. data/lib/deplate/templates/html-tabbar-right.html +1 -1
  156. data/lib/deplate/templates/html-tabbar-top.html +3 -3
  157. data/lib/deplate/variables.rb +25 -9
  158. data/lib/deplate/wiki-markup.rb +14 -3
  159. data/lib/deplate/xml.rb +3 -4
  160. data/lib/deplate/{zh-cn.rb → zh_CN.rb} +16 -16
  161. data/man/man1/deplate.1 +80 -65
  162. metadata +72 -48
  163. data/lib/deplate/mod/fr.rb +0 -46
@@ -1,10 +1,10 @@
1
1
  # common.rb -- The base class for deplate building blocks
2
- # @Author: Thomas Link (samul AT web.de)
2
+ # @Author: Thomas Link (micathom AT gmail com)
3
3
  # @Website: http://deplate.sf.net/
4
4
  # @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
5
5
  # @Created: 02-Aug-2004.
6
- # @Last Change: 05-Jun-2006.
7
- # @Revision: 0.805
6
+ # @Last Change: 2007-09-30.
7
+ # @Revision: 0.896
8
8
  #
9
9
  # = Description:
10
10
  # Misc classes
@@ -40,7 +40,21 @@ module Deplate::CommonGround
40
40
  @deplate = deplate
41
41
  # @args = {:class => self.class, :self => self, :deplate => deplate}
42
42
  @args = args[:args] || {:self => self, :deplate => deplate}
43
+ if (cn = self.class.name)
44
+ cn = cn.split(/::/)
45
+ if cn[0] == 'Deplate'
46
+ acc = []
47
+ cn[-2..-1].each do |cnpart|
48
+ acc << cnpart
49
+ globalargs = @deplate.variables["$#{acc.join}"]
50
+ if globalargs
51
+ @args.merge!(globalargs) {|k,o,n| o}
52
+ end
53
+ end
54
+ end
55
+ end
43
56
  self.level_as_string = args[:level_as_string] || deplate.get_current_heading
57
+ @heading = deplate.current_heading_element
44
58
  @level_as_list = args[:level_as_string] || deplate.current_heading.dup
45
59
  @elt = args[:elt] || nil
46
60
  @text = args[:text] || nil
@@ -63,17 +77,34 @@ module Deplate::CommonGround
63
77
  return nil
64
78
  end
65
79
  end
66
-
80
+
81
+ def top_container
82
+ c = container
83
+ return c && c.top_heading
84
+ end
85
+
86
+ def heading_level
87
+ @heading && @heading.level_as_string
88
+ end
89
+
67
90
  def update_args(opts={})
68
91
  update_styles
69
92
  update_id(opts)
70
93
  end
71
94
 
72
95
  def update_styles(styles=nil)
73
- styles ||= @args['style']
96
+ styles ||= @args['style'] || []
74
97
  case styles
75
98
  when String
76
- styles = styles.split(/[ ,;]/)
99
+ styles = Deplate::Core.split_list(styles, ',', ';', @source)
100
+ end
101
+ if @deplate.variables['styledTags']
102
+ tags = @args['tag']
103
+ if tags
104
+ tags = Deplate::Core.split_list(tags, ',', nil, @source)
105
+ tags.map! {|t| "TAG#{t}"}
106
+ styles += tags
107
+ end
77
108
  end
78
109
  if styles and !styles.empty?
79
110
  @styles += styles
@@ -93,7 +124,16 @@ module Deplate::CommonGround
93
124
  end
94
125
  end
95
126
  end
96
-
127
+
128
+ def tagged_as?(*tag)
129
+ tags = @args['tag']
130
+ if tags
131
+ tags = Deplate::Core.split_list(tags, ',', nil, @source)
132
+ return tags.any? {|t| tag.include?(t)}
133
+ end
134
+ false
135
+ end
136
+
97
137
  def get_explicit_id(args=@args)
98
138
  args[:id] || args['id']
99
139
  end
@@ -279,6 +319,20 @@ module Deplate::CommonGround
279
319
  text
280
320
  end
281
321
  module_function :post_process_text
322
+
323
+ def filter_template(template, vars=nil, args={})
324
+ d = args[:deplate] ||@deplate
325
+ v = vars || d.variables
326
+ s = args[:source] || @source
327
+ c = args[:container] || @container || self
328
+ t = Deplate::Template.new(:template => template,
329
+ :source => s,
330
+ :container => c)
331
+ Deplate::Define.let_variables(d, v) do
332
+ t = t.fill_in(d, :source => s)
333
+ end
334
+ t
335
+ end
282
336
  end
283
337
 
284
338
 
@@ -314,6 +368,8 @@ module Deplate::CommonElement
314
368
  attr_accessor :top_heading
315
369
  #### accumulated lines
316
370
  attr_accessor :accum
371
+ attr_reader :regNote
372
+ attr_accessor :indent
317
373
 
318
374
  def format_as_string
319
375
  klass = self.class
@@ -475,6 +531,36 @@ class Deplate::Base < Deplate::CommonObject
475
531
  self.class.label_mode
476
532
  end
477
533
 
534
+ def pop(array)
535
+ array.pop
536
+ end
537
+
538
+ def exclude?(filter, container=nil)
539
+ unless filter
540
+ return false
541
+ end
542
+ tags = @args['tag'] || 'any'
543
+ taglist = Deplate::Core.split_list(tags)
544
+ if container and (tags = @container.args['tag'])
545
+ taglist += Deplate::Core.split_list(tags)
546
+ end
547
+ if (globaltags = @deplate.variables['tag'])
548
+ taglist += Deplate::Core.split_list(globaltags)
549
+ end
550
+ Deplate::Core.split_list(filter).each do |ftag|
551
+ if ftag == 'any' and taglist.empty?
552
+ return false
553
+ else
554
+ taglist.each do |tag|
555
+ if ftag == tag
556
+ return false
557
+ end
558
+ end
559
+ end
560
+ end
561
+ return true
562
+ end
563
+
478
564
  class_attribute :formatter
479
565
  class_attribute :formatter2
480
566
  class_attribute :rx
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env ruby
2
2
  # converter.rb
3
- # @Author: Thomas Link (samul AT web.de)
3
+ # @Author: Thomas Link (micathom AT gmail com)
4
4
  # @Website: http://deplate.sf.net/
5
5
  # @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
6
6
  # @Created: 14-Okt-2004.
7
- # @Last Change: 07-Apr-2006.
8
- # @Revision: 0.128
7
+ # @Last Change: 2007-09-01.
8
+ # @Revision: 0.145
9
9
  #
10
10
  # = Description
11
11
  # = Usage
@@ -79,10 +79,16 @@ end
79
79
 
80
80
  # if __FILE__ == $0
81
81
  # t = <<EOF
82
+ # #DefCmd id=FOO <<
83
+ # FOO {arg: @body} FOO
84
+ #
82
85
  # * Introduction
83
86
  #
84
87
  # ''deplate'' is a tool for converting wiki-like markup to latex, html, or
85
88
  # "html-slides".
89
+ #
90
+ # #FOO: bla bla
91
+ #
86
92
  # EOF
87
93
  # to_html = Deplate::Converter.new
88
94
  # to_latex = Deplate::Converter.new("latex")
@@ -102,4 +108,4 @@ end
102
108
  # puts "----------------------------------------------------------------"
103
109
  #
104
110
  # end
105
- #
111
+ #
@@ -1,9 +1,9 @@
1
1
  # core.rb -- Convert wiki-like plain text pseudo markup to something else
2
- # @Author: Thomas Link (samul AT web.de)
2
+ # @Author: Thomas Link (micathom AT gmail com)
3
3
  # @Website: http://deplate.sf.net/
4
4
  # @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
5
5
  # @Created: 24-Feb-2004.
6
- # @Last Change: 07-Jun-2006.
6
+ # @Last Change: 2007-10-21.
7
7
 
8
8
  require 'uri'
9
9
  require 'optparse'
@@ -26,10 +26,10 @@ module Deplate; end
26
26
  class Deplate::Core
27
27
  extend Forwardable
28
28
 
29
- Version = '0.8'
29
+ Version = '0.8.1'
30
30
  # VersionSfx = 'a'
31
31
  VersionSfx = 'final'
32
- MicroRev = '2711'
32
+ MicroRev = '2965'
33
33
 
34
34
  if ENV['HOME']
35
35
  CfgDir = File.join(ENV['HOME'].gsub(/\\/, '/'), '.deplate')
@@ -43,7 +43,7 @@ class Deplate::Core
43
43
  end
44
44
  # CfgDir = File.join(Dir.pwd.gsub(/\\/, '/'), 'deplate.rc')
45
45
  puts <<MESSAGE
46
- Can't find your personal configuration directory. Neither HOME nor
46
+ Cannot find your personal configuration directory. Neither HOME nor
47
47
  USERPROFILE is set. I will look for configuration files in:
48
48
  #{CfgDir}
49
49
  MESSAGE
@@ -107,6 +107,7 @@ MESSAGE
107
107
  :user_packages => 20,
108
108
  :head => 30,
109
109
  :head_meta => 31,
110
+ :meta => 31,
110
111
  :head_identifier => 32,
111
112
  :head_title => 33,
112
113
  :head_extra => 34,
@@ -170,8 +171,9 @@ MESSAGE
170
171
  # arguments, sets up a Deplate::Core object, and makes it convert the
171
172
  # input files.
172
173
  def deplate(args=ARGV)
174
+ log(['Configuration directory', CfgDir], :debug)
173
175
  if ENV['DeplateOptions']
174
- for keyval in ENV['DeplateOptions'].split(/\s*;\s*/)
176
+ for keyval in Deplate::Core.split_list(ENV['DeplateOptions'], ';')
175
177
  key, val = keyval.split(/\s*=\s*/)
176
178
  case key
177
179
  when 'vanilla'
@@ -199,7 +201,7 @@ MESSAGE
199
201
 
200
202
  opts.on('-A', '--allow ALLOW',
201
203
  'Allow certain things: l, r, t, w, W, x, X, $') do |string|
202
- allow(options.allow, string)
204
+ allow(options.allow, string, '[COMMAND LINE ARGUMENT]')
203
205
  log("options.allow = #{string}")
204
206
  end
205
207
 
@@ -402,7 +404,7 @@ MESSAGE
402
404
  'Allow the execution of ruby code') do |level|
403
405
  if level
404
406
  options.allow_ruby = level
405
- allow(options.allow, level)
407
+ allow(options.allow, level, '[COMMAND LINE ARGUMENT]')
406
408
  else
407
409
  options.allow_ruby = true
408
410
  allow(options.allow, 'x')
@@ -413,7 +415,7 @@ MESSAGE
413
415
  opts.on('-X', '--[no-]allow-exec', '--[no-]external',
414
416
  'Allow the execution of helper applications') do |bool|
415
417
  options.allow_external = bool
416
- allow(options.allow, 'X')
418
+ allow(options.allow, 'X', '[COMMAND LINE ARGUMENT]')
417
419
  log("options.allow_external = #{bool}")
418
420
  end
419
421
 
@@ -538,26 +540,7 @@ MESSAGE
538
540
  # end
539
541
 
540
542
  if formatter_class
541
- f = options.files[0]
542
- case f
543
- when '-'
544
- options.ext = ''
545
- options.srcdir ||= Dir.pwd
546
- options.out ||= '-'
547
- else
548
- options.ext = File.extname(f)
549
- options.srcdir ||= File.dirname(f)
550
- options.suffix ||= formatter_class.suffix
551
- if options.out
552
- options.out = Deplate::Core.file_join(options.dir, options.out)
553
- # if options.out != '-'
554
- # options.out = options.dir ? Deplate::Core.file_join(options.dir, options.out) : options.out
555
- # end
556
- else
557
- options.out = get_out_fullname(f, options.suffix, options)
558
- end
559
- end
560
-
543
+ formatter_class.set_options_for_file(options, options.files[0])
561
544
  prc = Deplate::Core.new(options.fmt,
562
545
  :formatter => formatter_class,
563
546
  :options => options,
@@ -579,7 +562,8 @@ MESSAGE
579
562
  require_module(options, m) if m
580
563
  end
581
564
 
582
- require 'deplate/mod/en' unless @@messages_last
565
+ # require 'deplate/mod/en' unless @@messages_last
566
+ require_module(options, 'lang-en') unless @@messages_last
583
567
 
584
568
  # load general user config
585
569
  options.cfg ||= ['config.rb', CfgDir]
@@ -590,14 +574,14 @@ MESSAGE
590
574
  end
591
575
 
592
576
  # Set certain allow flags in array.
593
- def allow(arr, ids)
577
+ def allow(arr, ids, source=nil)
594
578
  case ids
595
579
  when String
596
- ids = ids.split(/[,; ]+/)
580
+ ids = Deplate::Core.split_list(ids, ',', '; ', source)
597
581
  # ids = ids.scan(/[a-zA-Z.:]/)
598
582
  when Array
599
583
  else
600
- log(['Internal error', 'allow', ids], :error)
584
+ log(['Internal error', 'allow', ids], :error, source)
601
585
  end
602
586
  ids.each do |i|
603
587
  m = i[0..0]
@@ -618,7 +602,7 @@ MESSAGE
618
602
  arr = options.allow
619
603
  case ids
620
604
  when String
621
- ids = ids.split(/[,; ]/)
605
+ ids = Deplate::Core.split_list(ids, ',', '; ')
622
606
  when Array
623
607
  else
624
608
  log(['Internal error', 'allow', ids], :error)
@@ -670,9 +654,14 @@ MESSAGE
670
654
  options.ini_command_line_arguments << $1
671
655
  options.ini_command_line_arguments << $3 if $3
672
656
  elsif line =~ /^\s*allow\s+(.+?)\s*$/
673
- allow(options.allow, $1)
657
+ allow(options.allow, $1, Deplate::Source.new(inifile))
674
658
  elsif line =~ /^\s*mod\s+(\S+)/
675
- options.modules << $1
659
+ mod = $1
660
+ if mod[0..0] == '-'
661
+ options.modules.delete(mod[1..-1])
662
+ else
663
+ options.modules << $1
664
+ end
676
665
  elsif line =~ /^\s*fmt\s+(\S+)/
677
666
  options.fmt = $1
678
667
  elsif line =~ /^\s*clip\s+([^\s=]+)\s*=\s*(.+)/
@@ -716,6 +705,8 @@ MESSAGE
716
705
  setter = lambda {|val| canonic_args(options.variables, $1, val)}
717
706
  elsif line =~ /^\s*(\S+)\s*=\s*(.+)/
718
707
  canonic_args(options.variables, $1, $2)
708
+ elsif !line.empty?
709
+ Deplate::Core.log(['Malformed configuration line', line], :error)
719
710
  end
720
711
  when :multiline
721
712
  if line == endm
@@ -753,15 +744,17 @@ MESSAGE
753
744
  fmtf = @@formatters[fmt]
754
745
  require fmtf
755
746
  end
756
- user_config(options, File.join('after', 'fmt', '%s.rb' % fmt), CfgDir)
757
- user_config(options, File.join('after', 'fmt', fmt), CfgDir)
747
+ for fmt in @@formatter_classes[fmt].formatter_family_members.reverse
748
+ user_config(options, File.join('after', 'fmt', '%s.rb' % fmt), CfgDir)
749
+ user_config(options, File.join('after', 'fmt', fmt), CfgDir)
750
+ end
758
751
  end
759
752
 
760
753
  # Load a module.
761
754
  # options:: A OpenStruct as returned by Deplate::Core.deplate_options
762
755
  # module_name:: The name of the module to be loaded
763
756
  def require_module(options, module_name)
764
- Deplate::Core.log(["Require module", module_name])
757
+ Deplate::Core.log(['Require module', module_name])
765
758
  mf = @@modules[module_name]
766
759
  vsave, $VERBOSE = $VERBOSE, false
767
760
  begin
@@ -770,7 +763,8 @@ MESSAGE
770
763
  user_config(options, File.join('after', 'mod', module_name), CfgDir)
771
764
  return true
772
765
  rescue Exception => e
773
- Deplate::Core.log(["Loading module failed", module_name, e], :error)
766
+ Deplate::Core.log(['Loading module failed', module_name, e], :error)
767
+ Deplate::Core.log(['Known modules', @@modules], :debug)
774
768
  return false
775
769
  ensure
776
770
  $VERBOSE = vsave
@@ -831,6 +825,7 @@ MESSAGE
831
825
  options.force ||= true
832
826
  options.css ||= []
833
827
  options.variables ||= Deplate::Variables.new
828
+ deplate_predefined_variables(options)
834
829
  options.clips ||= {}
835
830
  options.ext ||= ''
836
831
  # options.dir ||= '.'
@@ -839,11 +834,16 @@ MESSAGE
839
834
  options.split_level ||= 1
840
835
  options.disabled_particles ||= []
841
836
  options.autoindexed ||= []
837
+ options.abbrevs ||= {}
842
838
  reset_listings_and_counters(options, true)
843
839
  read_ini(options) unless inherit
844
840
  return options
845
841
  end
846
842
 
843
+ def deplate_predefined_variables(options)
844
+ options.variables['env'] = ENV
845
+ end
846
+
847
847
  def reset_listings_and_counters(options, conditionally=false)
848
848
  unless conditionally and options.counters
849
849
  c = options.counters = Deplate::Counters.new(self)
@@ -965,7 +965,7 @@ MESSAGE
965
965
  end
966
966
  end
967
967
 
968
- def canonic_args(hash, key, val)
968
+ def canonic_args(hash, key, val, source=nil)
969
969
  if key[-1..-1] == '!'
970
970
  key = key[0..-2]
971
971
  type = :bool
@@ -990,6 +990,14 @@ MESSAGE
990
990
  if val =~ /^"(.*?)"$/
991
991
  val = val[1..-2]
992
992
  else
993
+ # val.scan(/\\\\|\s/).each do |s|
994
+ # if s =~ /\s/
995
+ # Deplate::Core.log(['Deprecated syntax',
996
+ # 'Character should be preceded by a backslash',
997
+ # s.inspect, val],
998
+ # :anyway, source)
999
+ # end
1000
+ # end
993
1001
  val = val.strip
994
1002
  end
995
1003
  val = Deplate::Core.remove_backslashes(val)
@@ -1018,9 +1026,34 @@ MESSAGE
1018
1026
  return text.gsub(/\\(.)/, '\\1') if text
1019
1027
  end
1020
1028
 
1029
+ def split_list(string, chars=nil, deprecated=nil, source=nil, doubt=:use_deprecated)
1030
+ if string
1031
+ chars ||= ','
1032
+ list = string.scan(/((?:\\.|[^#{chars}\\]+)+)(?:[#{chars}]\s*|\Z)/).flatten
1033
+ list = list.map {|e| remove_backslashes(e)}
1034
+ if deprecated
1035
+ list1 = split_list(string, deprecated)
1036
+ if list1 != list and
1037
+ # (list1.size > 1 or list1[0] != string) and
1038
+ string !~ /[#{chars}]/ and string =~ /[#{deprecated}]/
1039
+ # case doubt
1040
+ # when :use_deprecated
1041
+ Deplate::Core.log(['Assuming the use of deprecated list separators', deprecated.inspect, string.inspect], :error, source)
1042
+ return list1
1043
+ # else
1044
+ # Deplate::Core.log(['Possible use of deprecated list separators', deprecated.inspect, string.inspect], :anyway, source)
1045
+ # end
1046
+ end
1047
+ end
1048
+ return list
1049
+ else
1050
+ return []
1051
+ end
1052
+ end
1053
+
1021
1054
  def escape_characters(text, args)
1022
1055
  esc = args[:esc] || args[:escape] || args['esc'] || args['escape'] || ''
1023
- ebs = args[:escapebackslash] || args['escapebackslash'] || 0
1056
+ ebs = args[:escapebackslash] || args['escapebackslash'] || args['template'] || 0
1024
1057
  case ebs
1025
1058
  when true
1026
1059
  ebs = 1
@@ -1054,7 +1087,7 @@ MESSAGE
1054
1087
  # specifying column widths in tables
1055
1088
  def props(proplist, field)
1056
1089
  if proplist
1057
- proplist.split(/\s*[,;]\s*/).collect do |c|
1090
+ Deplate::Core.split_list(proplist, ',', ';').collect do |c|
1058
1091
  rv = nil
1059
1092
  for key, val in c.scan(/(\w+?)[:.](\S+)/)
1060
1093
  if key == field
@@ -1073,7 +1106,7 @@ MESSAGE
1073
1106
  # correspond to section numbers.
1074
1107
  def canonic_file_name(name, sfx, maj=nil, min=nil, dir=nil)
1075
1108
  name = File.basename(name, '.*')
1076
- name = clean_file_name(name)
1109
+ name = clean_name(name)
1077
1110
  if !name or (maj and maj != 0)
1078
1111
  canonic_numbered_file_name(name, sfx, maj, min, dir)
1079
1112
  elsif min and min != 0
@@ -1085,10 +1118,18 @@ MESSAGE
1085
1118
  end
1086
1119
  end
1087
1120
 
1088
- # Return a valid file name based on +text+
1089
- def clean_file_name(text, replacement='_')
1090
- rx = /[[:cntrl:].+*:"?<>|&\\\/]/
1091
- text.gsub(rx, replacement) if text
1121
+ # Return an encoded name
1122
+ def clean_name(text, args={})
1123
+ if text
1124
+ replacement = args[:replacement] || '_'
1125
+ chars = args[:chars] || '_[:cntrl:].+*:"?<>|&\\\/'
1126
+ if (extrachars = args[:extra])
1127
+ chars += extrachars
1128
+ end
1129
+ text.gsub(/[#{chars}]/) do |text|
1130
+ replacement + "%02X" % text[0]
1131
+ end
1132
+ end
1092
1133
  end
1093
1134
 
1094
1135
  # Make sure +dir+ exists
@@ -1569,6 +1610,8 @@ MESSAGE
1569
1610
 
1570
1611
  def_delegator(:@input, :initialize_particles)
1571
1612
  def_delegator(:@input, :register_particle)
1613
+ def_delegator(:@input, :register_element)
1614
+ def_delegator(:@input, :register_region)
1572
1615
  def_delegator(:@input, :parse_with_particles)
1573
1616
  def_delegator(:@input, :parse_with_source)
1574
1617
  def_delegator(:@input, :parse)
@@ -1578,7 +1621,12 @@ MESSAGE
1578
1621
  def initialize_input(args=@args)
1579
1622
  @input = args[:input] || @options.input
1580
1623
  unless @input
1581
- input_class = args[:input_class] || @options.input_class || Deplate::Input
1624
+ # @options.input_class is only considered when defined on
1625
+ # startup (i.e. on the command-line), which is why we check
1626
+ # for :now
1627
+ input_class = args[:input_class] ||
1628
+ (args[:now] && @options.input_class) ||
1629
+ Deplate::Input
1582
1630
  @input = input_class.new(self, args)
1583
1631
  end
1584
1632
  end
@@ -1619,6 +1667,15 @@ MESSAGE
1619
1667
  end
1620
1668
  end
1621
1669
 
1670
+ def get_formatter_class(fmt)
1671
+ case fmt
1672
+ when String
1673
+ @@formatter_classes[fmt]
1674
+ else
1675
+ fmt
1676
+ end
1677
+ end
1678
+
1622
1679
  # Define a new slot or reset the position of an already known slot.
1623
1680
  # <+TBD+>There is no information on whether the slot belongs to the
1624
1681
  # prematter/postmatter/body.
@@ -1768,7 +1825,7 @@ MESSAGE
1768
1825
  if msg_class
1769
1826
  @options.messages = msg_class.new(self)
1770
1827
  @@message_object ||= @options.messages
1771
- elsif is_allowed?('l') and require_module(lang)
1828
+ elsif is_allowed?('l') and require_module("lang-#{lang}")
1772
1829
  set_lang(lang)
1773
1830
  else
1774
1831
  log(["Bad language definition", lang, "(#{@@messages.keys.join(', ')})"],
@@ -1888,7 +1945,7 @@ MESSAGE
1888
1945
  else
1889
1946
  prefix = @variables['prefixID']
1890
1947
  if prefix.nil?
1891
- prefix = Deplate::Core.clean_file_name(File.basename(@dest, '.*'))
1948
+ prefix = Deplate::Core.clean_name(File.basename(@dest, '.*'))
1892
1949
  end
1893
1950
  fn = [prefix]
1894
1951
  fn << ["_#{type}_#{idx}"]
@@ -1932,8 +1989,8 @@ MESSAGE
1932
1989
  pwd = Dir.pwd
1933
1990
  begin
1934
1991
  Dir.chdir(dir)
1935
- files = Dir["*"]
1936
- match = Dir[@options.file_pattern || "*"]
1992
+ files = Dir['*']
1993
+ match = Dir[@options.file_pattern || '*']
1937
1994
  files.delete_if {|f| File.stat(f).file? and !match.include?(f)}
1938
1995
  if @options.file_excl_pattern
1939
1996
  antilist = Dir[@options.file_excl_pattern]
@@ -1941,11 +1998,11 @@ MESSAGE
1941
1998
  files.delete(anti)
1942
1999
  end
1943
2000
  end
1944
- log(["DIR", dir])
2001
+ log(['DIR', dir])
1945
2002
  ensure
1946
2003
  Dir.chdir(pwd)
1947
2004
  end
1948
- unless dir == "."
2005
+ unless dir == '.'
1949
2006
  files.collect! {|f| File.join(dir, f)}
1950
2007
  end
1951
2008
  return files
@@ -1955,42 +2012,31 @@ MESSAGE
1955
2012
  if args[:pwd]
1956
2013
  fn = File.join(Deplate::Core.current_pwd(self), fname)
1957
2014
  if Deplate::Core.is_file?(fn)
2015
+ log(['File in CWD', fn])
1958
2016
  return fn
1959
2017
  end
1960
2018
  end
1961
2019
  files = []
1962
2020
  if @formatter
1963
- formatter_family_members do |myname|
2021
+ @formatter.class.formatter_family_members(:names => args[:formatters]) do |myname|
1964
2022
  dd = File.join('lib', myname, fname)
1965
2023
  files << dd unless files.include?(dd)
1966
2024
  end
1967
2025
  end
1968
- files << File.join('lib', fname)
2026
+ files << File.join(args['subdir'] || 'lib', fname)
1969
2027
  files = Deplate::Core.library_directories(true, *files)
1970
2028
  for fn in files
1971
2029
  if Deplate::Core.is_file?(fn)
2030
+ log(['File in lib', fn])
1972
2031
  return fn
1973
2032
  end
1974
2033
  end
1975
2034
  return nil
1976
2035
  end
1977
2036
 
1978
- def formatter_family_members(formatter_class=nil)
1979
- acc = []
1980
- fmt = formatter_class ||= @formatter.class
1981
- myname = fmt.myname
1982
- while myname
1983
- acc << myname
1984
- yield(myname) if block_given?
1985
- fmt = fmt.superclass
1986
- myname = fmt.myname
1987
- end
1988
- formatter_class.related.each do |myname|
1989
- acc << myname
1990
- yield(myname) if block_given?
1991
- end
1992
- acc
1993
- end
2037
+ # def formatter_family_members(args)
2038
+ # (args[:formatter_class] || @formatter.class).formatter_family_members(args)
2039
+ # end
1994
2040
 
1995
2041
  # Format either text or, if text is nil, the file "sourcename".
1996
2042
  # This is the method called by the Deplate::Formatter's
@@ -2005,14 +2051,14 @@ MESSAGE
2005
2051
 
2006
2052
  # Format a file by means of formatter_class that is a child of Deplate::Formatter
2007
2053
  def format_file_with_formatter(formatter_class, sourcename)
2008
- with_formatter(formatter_class) do
2054
+ with_formatter(formatter_class, sourcename) do
2009
2055
  go_each([sourcename])
2010
2056
  end
2011
2057
  end
2012
2058
 
2013
2059
  # Format text by means of formatter_class that is a child of Deplate::Formatter
2014
2060
  def format_string_with_formatter(formatter_class, text, sourcename=nil)
2015
- with_formatter(formatter_class) do
2061
+ with_formatter(formatter_class, sourcename) do
2016
2062
  format_string(text, sourcename)
2017
2063
  end
2018
2064
  end
@@ -2054,7 +2100,7 @@ MESSAGE
2054
2100
  end
2055
2101
 
2056
2102
  # Read a file and add the parsed elements to array
2057
- def include_file(array, filename)
2103
+ def include_file(array, filename, args={})
2058
2104
  maintain_current_source(filename) do
2059
2105
  log(['Including', filename])
2060
2106
  filename_abs = File.expand_path(filename)
@@ -2063,7 +2109,20 @@ MESSAGE
2063
2109
  @labels_floating << filename_label
2064
2110
  end
2065
2111
  File.open(filename, 'r') do |io|
2066
- text = io.read
2112
+ range = if (skip = args['skip'])
2113
+ skip.to_i..-1
2114
+ elsif (head = args['head'])
2115
+ 0..head.to_i
2116
+ elsif (tail = args['tail'])
2117
+ -tail.to_i..-1
2118
+ else
2119
+ nil
2120
+ end
2121
+ if range
2122
+ text = io.readlines[range].join
2123
+ else
2124
+ text = io.read
2125
+ end
2067
2126
  include_each(text, array, filename)
2068
2127
  end
2069
2128
  end
@@ -2144,7 +2203,7 @@ MESSAGE
2144
2203
  unless text or !@options.multi_file_output
2145
2204
  afn = @variables['autoFileNames']
2146
2205
  if afn
2147
- fname = Deplate::Core.clean_file_name(heading.get_text)[0..20]
2206
+ fname = Deplate::Core.clean_name(heading.get_text)[0..20]
2148
2207
  c = auto_numbered(fname)
2149
2208
  if c
2150
2209
  fname = Deplate::Core.canonic_file_name(fname, sfx, c, 0)
@@ -2190,6 +2249,7 @@ MESSAGE
2190
2249
  if fname
2191
2250
  fname = Deplate::Core.get_out_fullname(fname, nil, @options)
2192
2251
  end
2252
+ @output.simulate_reset
2193
2253
  end
2194
2254
  # if fname and @options.multi_file_output
2195
2255
  if fname
@@ -2322,8 +2382,13 @@ MESSAGE
2322
2382
 
2323
2383
  # Get a clip.
2324
2384
  # id:: The clip's name
2385
+ # FIXME: This check for @elt should not be necessary.
2325
2386
  def get_clip(id)
2326
- @clips[id]
2387
+ c = @clips[id]
2388
+ if c and !c.elt
2389
+ c = @clips[id] = c.process
2390
+ end
2391
+ c
2327
2392
  end
2328
2393
 
2329
2394
  # Set all clips.
@@ -2392,14 +2457,14 @@ MESSAGE
2392
2457
 
2393
2458
  # Amend +file+'s suffix.
2394
2459
  def file_with_suffix(file, sfx=nil, filename_only=false)
2395
- sfx = sfx || ""
2460
+ sfx = sfx || ''
2396
2461
  fn = File.basename(file, '.*')
2397
2462
  if filename_only
2398
2463
  return fn + sfx
2399
2464
  else
2400
2465
  dir = File.dirname(file)
2401
2466
  fname = fn + sfx
2402
- if dir == "."
2467
+ if dir == '.'
2403
2468
  return fname
2404
2469
  else
2405
2470
  return File.join(dir, fname)
@@ -2427,7 +2492,7 @@ MESSAGE
2427
2492
  throw :ok
2428
2493
  end
2429
2494
  end
2430
- raise "Internal error: unknown level: #{level_as_string}"
2495
+ # raise "Internal error: unknown level: #{level_as_string}"
2431
2496
  log(['Internal error: Unknown level', level_as_string], :error)
2432
2497
  return nil
2433
2498
  end
@@ -2462,6 +2527,7 @@ MESSAGE
2462
2527
  @collected_output << @output
2463
2528
  @output.top_heading = top_heading_by_idx(@collected_output.size - 1)
2464
2529
  @output.index = @output_maj_min.dup
2530
+ @output.reset
2465
2531
  increase_maj_min
2466
2532
  end
2467
2533
 
@@ -2562,15 +2628,24 @@ MESSAGE
2562
2628
  if file
2563
2629
  # pwd = Dir.pwd
2564
2630
  begin
2565
- # Dir.chdir(@options.dir)
2566
- ensure_dir_exists(File.dirname(file))
2567
- ok = if File.exist?(file)
2568
- Deplate::Core.query_user(@options,
2631
+ case file
2632
+ when 1, 2, 3, '-'
2633
+ ok = true
2634
+ case file
2635
+ when String
2636
+ file = mode =~ /r/ ? 1 : 2
2637
+ end
2638
+ else
2639
+ # Dir.chdir(@options.dir)
2640
+ ensure_dir_exists(File.dirname(file))
2641
+ ok = if File.exist?(file)
2642
+ Deplate::Core.query_user(@options,
2569
2643
  "File '#{file}' already exists. Overwrite (y/N)? ",
2570
2644
  'y')
2571
- else
2572
- true
2573
- end
2645
+ else
2646
+ true
2647
+ end
2648
+ end
2574
2649
  if ok
2575
2650
  log(['Writing file', file], :debug)
2576
2651
  File.open(file, mode) do |io|
@@ -2608,7 +2683,7 @@ MESSAGE
2608
2683
  if ok
2609
2684
  ensure_dir_exists(dir)
2610
2685
  File.copy(from, to)
2611
- log(['Copy file', to])
2686
+ log(['Copy file', from, to])
2612
2687
  end
2613
2688
  end
2614
2689
  end
@@ -2617,14 +2692,19 @@ MESSAGE
2617
2692
  @options.counters.get('toc')
2618
2693
  end
2619
2694
 
2695
+ def current_heading_element
2696
+ e = @options.counters.get('toc', true)
2697
+ e && e[:container]
2698
+ end
2699
+
2620
2700
  # Get the current section's level as string.
2621
2701
  def get_current_heading
2622
2702
  @options.counters.get_s('toc')
2623
2703
  end
2624
2704
 
2625
2705
  # Increase the heading level.
2626
- def increase_current_heading(level)
2627
- @options.counters.increase('toc', :level => level)
2706
+ def increase_current_heading(container, level)
2707
+ @options.counters.increase('toc', :container => container, :level => level)
2628
2708
  end
2629
2709
 
2630
2710
  # Get the current top heading object.
@@ -2773,11 +2853,14 @@ MESSAGE
2773
2853
  id = "idx00#{@index_last_idx}"
2774
2854
  words = names.split(/\s*\|\s*/)
2775
2855
  lname = Deplate::Core.remove_backslashes(words[0])
2776
- level_as_string = container ? container.level_as_string : level_as_string
2856
+ if container
2857
+ # container = container.top_container || container
2858
+ level_as_string = container.level_as_string
2859
+ end
2777
2860
  if @options.dont_index.delete(lname)
2778
2861
  return nil
2779
2862
  else
2780
- i = @index[lname]
2863
+ i = @index[lname]
2781
2864
  unless i
2782
2865
  i = @index.find do |k, a|
2783
2866
  a.find do |i|
@@ -2923,15 +3006,21 @@ MESSAGE
2923
3006
  end
2924
3007
 
2925
3008
  def set_standard_clips
2926
- if defined?(@input) and @input
2927
- for id, text in @options.clips
2928
- src = '[clip]'
2929
- text = parse_with_source(src, text, false)
2930
- @options.clips[id] = Deplate::Element::Clip.new(text, self, src)
3009
+ unless @options.clips_initialized
3010
+ if defined?(@input) and @input
3011
+ for id, text in @options.clips
3012
+ if text.kind_of?(Deplate::Element::Clip)
3013
+ @options.clips[id] = text
3014
+ else
3015
+ src = '[clip]'
3016
+ text = parse_with_source(src, text, false)
3017
+ @options.clips[id] = Deplate::Element::Clip.new(text, self, src)
3018
+ end
3019
+ end
3020
+ @options.clips_initialized = true
2931
3021
  end
2932
- options.clips_initialized = true
3022
+ @clips = @options.clips.dup
2933
3023
  end
2934
- @clips = @options.clips.dup if options.clips_initialized
2935
3024
  end
2936
3025
 
2937
3026
  def reset_footnotes
@@ -2959,8 +3048,9 @@ MESSAGE
2959
3048
 
2960
3049
  # Set @formatter to an instance of formatter_class, call block, and
2961
3050
  # restore the old @formatter
2962
- def with_formatter(formatter_class, &block)
3051
+ def with_formatter(formatter_class, sourcename=nil, &block)
2963
3052
  formatter_orig = @formatter
3053
+ options_orig = @options
2964
3054
  begin
2965
3055
  if @formatter.instance_of?(formatter_class)
2966
3056
  @formatter = @formatter.dup
@@ -2968,9 +3058,11 @@ MESSAGE
2968
3058
  else
2969
3059
  @formatter = formatter_class.new(self, @args)
2970
3060
  end
2971
- block.call
3061
+ @options = formatter_class.set_options_for_file(options.dup, sourcename)
3062
+ rv = block.call
2972
3063
  ensure
2973
3064
  @formatter = formatter_orig
3065
+ @options = options_orig
2974
3066
  end
2975
3067
  end
2976
3068
 
@@ -3013,9 +3105,23 @@ MESSAGE
3013
3105
  @output_headings.first.first_top = true
3014
3106
  @output_headings.last.last_top = true
3015
3107
  end
3016
-
3108
+
3109
+ filter = @variables['efilter']
3110
+
3017
3111
  for p in preprocess
3018
- p.call
3112
+ p.call unless p.exclude?(filter)
3113
+ end
3114
+
3115
+ for hd in @headings.keys
3116
+ if @headings[hd].exclude?(filter)
3117
+ @headings.delete(hd)
3118
+ end
3119
+ end
3120
+
3121
+ # Basically, this shouldn't be necessary as a filtered element
3122
+ # should never make it into the listing.
3123
+ for name,_ in @options.listings
3124
+ @options.listings.get(name).delete_if {|e| e.exclude?(filter)}
3019
3125
  end
3020
3126
 
3021
3127
  for fn in @footnotes.keys
@@ -3031,17 +3137,18 @@ MESSAGE
3031
3137
 
3032
3138
  # process elts
3033
3139
  def process
3034
- log("Processing elements")
3140
+ log('Processing elements')
3035
3141
  call_methods_matching(@formatter, /^hook_pre_process_/)
3142
+ filter = @variables['efilter']
3036
3143
  @accum_elements.collect! do |e|
3037
- e.process
3144
+ e.process unless e.exclude?(filter)
3038
3145
  end
3039
3146
  @accum_elements.flatten!
3040
3147
  @accum_elements.compact!
3041
3148
  end
3042
3149
 
3043
3150
  def print_prepare
3044
- log("Preparing formatting")
3151
+ log('Preparing formatting')
3045
3152
  call_methods_matching(@formatter, /^hook_pre_prepare_/)
3046
3153
  @formatter.prepare
3047
3154
  call_methods_matching(@formatter, /^prepare_/)