docgenerator 1.1.1 → 1.2.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 (179) hide show
  1. data/examples/docgenerator_example.rb +34 -17
  2. data/examples/docgenerator_example_footnote.rb +82 -61
  3. data/examples/docgenerator_example_list.rb +24 -18
  4. data/examples/docgenerator_example_restrictions.rb +17 -27
  5. data/examples/docgenerator_example_tabular.rb +20 -20
  6. data/examples/docgenerator_example_tripfalls.rb +28 -20
  7. data/examples/results/readme +1 -0
  8. data/examples/results_expected/docgenerator_example.html +39 -0
  9. data/examples/results_expected/docgenerator_example.pdf +0 -0
  10. data/examples/results_expected/docgenerator_example.tex +56 -0
  11. data/examples/results_expected/docgenerator_example_footnote.html +40 -0
  12. data/examples/results_expected/docgenerator_example_footnote.pdf +0 -0
  13. data/examples/results_expected/docgenerator_example_footnote.tex +50 -0
  14. data/examples/results_expected/docgenerator_example_list.html +18 -0
  15. data/examples/results_expected/docgenerator_example_list.pdf +0 -0
  16. data/examples/results_expected/docgenerator_example_list.tex +46 -0
  17. data/examples/results_expected/docgenerator_example_restrictions.html +22 -0
  18. data/examples/results_expected/docgenerator_example_restrictions.pdf +0 -0
  19. data/examples/results_expected/docgenerator_example_restrictions.tex +31 -0
  20. data/examples/results_expected/docgenerator_example_tabular.html +37 -0
  21. data/examples/results_expected/docgenerator_example_tabular.pdf +0 -0
  22. data/examples/results_expected/docgenerator_example_tabular.tex +41 -0
  23. data/examples/results_expected/docgenerator_example_tripfalls.html +27 -0
  24. data/examples/results_expected/docgenerator_example_tripfalls.pdf +0 -0
  25. data/examples/results_expected/docgenerator_example_tripfalls.tex +31 -0
  26. data/lib/creole/creole2doc.rb +291 -140
  27. data/lib/creole/creole_inclusion_and_plugins.rb +142 -39
  28. data/lib/creole/creole_placeholder.rb +92 -30
  29. data/lib/creole/creole_tabular.rb +119 -20
  30. data/lib/docgenerator.rb +209 -118
  31. data/lib/{docgenerator_attribute.rb → docgenerator/attribute.rb} +2 -1
  32. data/lib/{docgenerator_characters.rb → docgenerator/characters.rb} +75 -6
  33. data/lib/{docgenerator_css.rb → docgenerator/css.rb} +0 -0
  34. data/lib/docgenerator/document.rb +588 -0
  35. data/lib/{docgenerator_element.rb → docgenerator/element.rb} +52 -80
  36. data/lib/{docgenerator_elements.rb → docgenerator/elements.rb} +43 -17
  37. data/lib/{docgenerator_environments.rb → docgenerator/environments.rb} +20 -6
  38. data/lib/{docgenerator_footnote.rb → docgenerator/footnote.rb} +22 -18
  39. data/lib/{docgenerator_lists.rb → docgenerator/lists.rb} +17 -1
  40. data/lib/{docgenerator_sections.rb → docgenerator/sections.rb} +9 -1
  41. data/lib/docgenerator/standard.rb +81 -0
  42. data/lib/{docgenerator_tabular.rb → docgenerator/tabular.rb} +9 -5
  43. data/lib/packages/docgenerator_listings.rb +9 -5
  44. data/lib/packages/docgenerator_pdfpages.rb +17 -11
  45. data/lib/packages/docgenerator_url.rb +0 -2
  46. data/lib/templates/docgenerator_template.rb +66 -29
  47. data/lib/templates/docgenerator_template.yaml +18 -0
  48. data/lib/wiki2doc/wiki2docgenerator.rb +6 -2
  49. data/readme.rd +132 -0
  50. data/unittest/expected/test_document_usepackage_undefined.log +2 -0
  51. data/unittest/expected/test_enumerate.context +4 -0
  52. data/unittest/expected/test_footnote.html +4 -4
  53. data/unittest/expected/test_footnote.latex +4 -4
  54. data/unittest/expected/test_footnote_group.html +6 -6
  55. data/unittest/expected/test_footnote_group.latex +6 -6
  56. data/unittest/expected/test_href.html +2 -2
  57. data/unittest/expected/test_href.latex +2 -2
  58. data/unittest/expected/test_href.text +2 -2
  59. data/unittest/expected/test_itemize.context +4 -0
  60. data/unittest/expected/test_runtex.stdout +3 -0
  61. data/unittest/expected/test_runtex_2.stdout +3 -0
  62. data/unittest/expected/test_section.context +20 -0
  63. data/unittest/expected/test_tabular.html +2 -2
  64. data/unittest/expected/test_verbatim.html +3 -0
  65. data/unittest/expected/test_verbatim.latex +4 -0
  66. data/unittest/expected/test_verbatim_array.html +1 -0
  67. data/unittest/expected/test_verbatim_array.latex +2 -0
  68. data/unittest/expected_creole/test_creole_characters_all.html +12 -5
  69. data/unittest/expected_creole/test_creole_characters_all.latex +20 -6
  70. data/unittest/expected_creole/test_creole_comment.context +11 -0
  71. data/unittest/expected_creole/test_creole_comment.creole +12 -0
  72. data/unittest/expected_creole/test_creole_comment.html +9 -0
  73. data/unittest/expected_creole/test_creole_comment.latex +11 -0
  74. data/unittest/expected_creole/test_creole_creole1.0test.html +3 -3
  75. data/unittest/expected_creole/test_creole_creole1.0test.latex +3 -3
  76. data/unittest/expected_creole/test_creole_creole1.0test.text +4 -4
  77. data/unittest/expected_creole/test_creole_ignore.html +3 -0
  78. data/unittest/expected_creole/test_creole_ignore.latex +4 -0
  79. data/unittest/expected_creole/test_creole_ignore.text +2 -0
  80. data/unittest/expected_creole/test_creole_input.normsource +12 -12
  81. data/unittest/expected_creole/test_creole_input_file_simple.html +15 -0
  82. data/unittest/expected_creole/test_creole_input_file_simple_readlines.html +15 -0
  83. data/unittest/expected_creole/test_creole_links_external_implicit.html +2 -2
  84. data/unittest/expected_creole/test_creole_links_external_implicit.latex +2 -2
  85. data/unittest/expected_creole/test_creole_links_external_implicit.text +2 -2
  86. data/unittest/expected_creole/test_creole_links_implicit_end.creole +4 -0
  87. data/unittest/expected_creole/test_creole_links_implicit_end.html +3 -0
  88. data/unittest/expected_creole/test_creole_links_implicit_end.latex +4 -0
  89. data/unittest/expected_creole/test_creole_list_ul.normsource +42 -42
  90. data/unittest/expected_creole/test_creole_mix_titles_list.html +10 -0
  91. data/unittest/expected_creole/test_creole_mix_titles_list.latex +18 -0
  92. data/unittest/expected_creole/test_creole_mix_titles_list.text +12 -0
  93. data/unittest/expected_creole/test_creole_paragraphs.normsource +15 -15
  94. data/unittest/expected_creole/test_creole_pictures_css.html +4 -1
  95. data/unittest/expected_creole/test_creole_pictures_css.latex +5 -1
  96. data/unittest/expected_creole/test_creole_pictures_longdesc.html +3 -0
  97. data/unittest/expected_creole/test_creole_pictures_width.html +3 -0
  98. data/unittest/expected_creole/test_creole_pictures_width.latex +4 -0
  99. data/unittest/expected_creole/test_creole_short_html.html +3 -0
  100. data/unittest/expected_creole/test_creole_short_html.latex +4 -0
  101. data/unittest/expected_creole/test_creole_short_html.text +2 -0
  102. data/unittest/expected_creole/test_creole_shy.creole +6 -0
  103. data/unittest/expected_creole/test_creole_shy.html +6 -0
  104. data/unittest/expected_creole/test_creole_shy.latex +8 -0
  105. data/unittest/expected_creole/test_creole_shy.text +4 -0
  106. data/unittest/expected_creole/test_creole_tabular_with_cell_option.html +20 -0
  107. data/unittest/expected_creole/test_creole_toc.html +3 -1
  108. data/unittest/expected_creole/test_creole_toc.latex +1 -1
  109. data/unittest/expected_creole/test_creole_toc.text +1 -1
  110. data/unittest/expected_creole/test_creole_toc_level.html +7 -0
  111. data/unittest/expected_creole/test_creole_toc_level.latex +10 -0
  112. data/unittest/expected_creole/test_creole_toc_level.text +3 -0
  113. data/unittest/expected_creole/test_creole_toc_level_text.html +8 -0
  114. data/unittest/expected_creole/test_creole_toc_level_text.latex +9 -0
  115. data/unittest/expected_creole/test_creole_verbatim.html +1 -1
  116. data/unittest/expected_creole/test_creole_verbatim.latex +1 -1
  117. data/unittest/expected_creole/test_creole_verbatim.text +1 -1
  118. data/unittest/expected_creole/test_creole_verbatim_inline.html +1 -1
  119. data/unittest/expected_creole/test_creole_verbatim_inline.latex +1 -1
  120. data/unittest/expected_wiki/test_wiki_description.html +5 -5
  121. data/unittest/expected_wiki/test_wiki_description.latex +5 -5
  122. data/unittest/expected_wiki/test_wiki_description.text +5 -5
  123. data/unittest/expected_wiki/test_wiki_description.wiki +5 -5
  124. data/unittest/test_rakefile_docgenerator.rb +43 -0
  125. data/unittest/unittest_creole2doc.rb +415 -27
  126. data/unittest/unittest_docgenerator.rb +256 -23
  127. data/unittest/unittest_docgenerator_runtex.rb +83 -0
  128. data/unittest/unittest_versions.rb +44 -0
  129. data/unittest/unittest_wiki2doc.rb +28 -27
  130. metadata +473 -106
  131. data/lib/docgenerator_document.rb +0 -525
  132. data/lib/packages/docgenerator_beamer.rb +0 -253
  133. data/lib/yaml2presentation/yaml2presentation.rb +0 -1091
  134. data/unittest/expected/beamer_01_article.tex +0 -13
  135. data/unittest/expected/beamer_01_attachment.tex +0 -15
  136. data/unittest/expected/beamer_01_doc.html +0 -13
  137. data/unittest/expected/beamer_01_doc.tex +0 -18
  138. data/unittest/expected/beamer_01_notes_only.tex +0 -13
  139. data/unittest/expected/beamer_01_notes_onlyslideswithnotes.tex +0 -13
  140. data/unittest/expected/beamer_01_notes_show.tex +0 -13
  141. data/unittest/expected/beamer_01_presentation.tex +0 -13
  142. data/unittest/expected/beamer_02_doc.html +0 -29
  143. data/unittest/expected/beamer_02_doc.tex +0 -34
  144. data/unittest/expected/beamer_block.html +0 -1
  145. data/unittest/expected/beamer_block.latex +0 -1
  146. data/unittest/expected/beamer_doc_fragile_doc.tex +0 -33
  147. data/unittest/expected/beamer_doc_html_overview_with_detailpic_and_text_doc.html +0 -34
  148. data/unittest/expected/beamer_doc_html_overview_with_detailpic_doc.html +0 -34
  149. data/unittest/expected/beamer_doc_key_doc.html +0 -20
  150. data/unittest/expected/beamer_doc_key_doc.tex +0 -29
  151. data/unittest/expected/beamer_doc_note_doc.html +0 -30
  152. data/unittest/expected/beamer_doc_note_doc.tex +0 -37
  153. data/unittest/expected/beamer_doc_pic_bottom_doc.html +0 -24
  154. data/unittest/expected/beamer_doc_pic_doc.html +0 -24
  155. data/unittest/expected/beamer_doc_pic_doc.tex +0 -28
  156. data/unittest/expected/beamer_doc_pic_left_doc.html +0 -24
  157. data/unittest/expected/beamer_doc_pic_left_doc.tex +0 -28
  158. data/unittest/expected/beamer_doc_pic_ratio_doc.tex +0 -29
  159. data/unittest/expected/beamer_doc_pic_right_doc.html +0 -24
  160. data/unittest/expected/beamer_doc_pic_right_doc.tex +0 -28
  161. data/unittest/expected/beamer_doc_pic_top_doc.html +0 -24
  162. data/unittest/expected/beamer_frame.html +0 -5
  163. data/unittest/expected/beamer_frame.tex +0 -11
  164. data/unittest/expected/beamer_frame_fragile.tex +0 -7
  165. data/unittest/expected/beamer_frame_id.html +0 -1
  166. data/unittest/expected/beamer_frame_id.tex +0 -4
  167. data/unittest/expected/beamer_framepic.html +0 -5
  168. data/unittest/expected/beamer_framepic.latex +0 -1
  169. data/unittest/expected/beamer_framepic_link.html +0 -5
  170. data/unittest/expected/beamer_framepic_link.latex +0 -1
  171. data/unittest/expected/beamer_frametitle.html +0 -1
  172. data/unittest/expected/beamer_frametitle.latex +0 -1
  173. data/unittest/expected/beamer_note.html +0 -1
  174. data/unittest/expected/beamer_note.latex +0 -1
  175. data/unittest/expected_privat/test_creole_test_document.html +0 -6
  176. data/unittest/expected_wiki/test_wiki_amazon.html +0 -10
  177. data/unittest/expected_wiki/test_wiki_link.log +0 -3
  178. data/unittest/test_docgenerator.rb +0 -107
  179. data/unittest/unittest_yaml2pres.rb +0 -336
File without changes
@@ -0,0 +1,588 @@
1
+ #encoding: utf-8
2
+ =begin rdoc
3
+ Container for a document.
4
+
5
+ Each document contains a header and a body. Both are special Element classes.
6
+ =end
7
+ class Document
8
+ include Docgenerator #get VERSION
9
+
10
+ #Valid meta tags, used for HTML
11
+ #
12
+ #This meta-tags are used by sitegenerator
13
+ VALID_META_TAGS = %w{
14
+ keywords
15
+ description
16
+ id
17
+ altlang
18
+ toc
19
+ pdf
20
+ odp
21
+ amazon
22
+ forum
23
+ feed
24
+ }
25
+ class << VALID_META_TAGS
26
+ # Return true if self is part of the given parameter.
27
+ def ===(o)
28
+ return self.include?(o)
29
+ end
30
+ end
31
+
32
+ #Create a new document.
33
+ #There are different document templates supported.
34
+ #The templates refer to the corresponding TeX-classes.
35
+ #- article
36
+ #- report
37
+ #- book
38
+ def initialize( settings = {} )
39
+ #Set template defaults
40
+ @template = {
41
+ :html => DocumentTemplate[:html],
42
+ :latex => DocumentTemplate[:article],
43
+ :text => DocumentTemplate[:text],
44
+ :wiki => DocumentTemplate[:wiki],
45
+ }
46
+ @language = 'ngerman' #default
47
+ @date = nil
48
+
49
+ ##>>>>temporary check, old interface
50
+ #~ puts settings.inspect
51
+ if ! settings.is_a?(Hash)
52
+ #Make an exception to correct data
53
+ raise "Old interface for Document#new, use :template => "
54
+ settings = { :template => settings }
55
+ end
56
+ ##<<<<temporary check, old interface
57
+
58
+ @log = settings[:log]
59
+ if ! @log
60
+ @log = Log4r::Logger.new( 'Doc', Log4r::WARN )
61
+ @log.outputters = Log4r::StdoutOutputter.new('log_xxx')
62
+ end
63
+ @meta = {} #some meta-Tags for HTML
64
+ @body = element( :body, { :log => @log } )
65
+ @head = element( :head, { :log => @log } )
66
+ #~ @body.part_of << self
67
+ #~ @head.part_of << self
68
+ @options = []
69
+ #Flag to avoid double definition of docinfo()
70
+ @docinfo_called = false
71
+ @creator = nil
72
+
73
+ settings.each{|key, value|
74
+ case key
75
+ when :title, :shorttitle, :author, :date, :keywords, :description, :creator, :language
76
+ self.send("#{key}=".to_sym, value)
77
+ #~ when :odp, :pdf, :amazon #VALID_META_TAGS
78
+ when *VALID_META_TAGS.map{|mkey|mkey.to_sym}
79
+ self.meta( key, value )
80
+ when :template
81
+ [value].flatten.each{|template|
82
+ case template
83
+ when DocumentTemplate
84
+ @template[template.target] = template
85
+ when Symbol
86
+ templ = DocumentTemplate[template]
87
+ if ! templ.is_a?( DocumentTemplate )
88
+ @log.fatal("Unknown template #{template}, valid:\n\t#{DocumentTemplate.keys.join("\n\t")}") if @log.fatal?
89
+ else
90
+ @template[templ.target] = templ
91
+ end
92
+ end
93
+ } #templates
94
+ when :css
95
+ if ! File.exist?(value)
96
+ @log.warn("CSS-Reference not found (#{value})") if @log.warn?
97
+ end
98
+ #~ @head << element(:htmlonly,{}, <<css
99
+ #~ <meta http-equiv="Content-Style-Type" content="text/css">
100
+ #~ css
101
+ #~ <link rel="stylesheet" type="text/css" href="#{value}">
102
+ #~ ).cr
103
+ @head << element( :link, {
104
+ :href => value,
105
+ :rel => 'stylesheet',
106
+ :type => "text/css" } ).cr. restrict_to(:html)
107
+ when :maketitle
108
+ #:maketitle is defined, but we have also to check, if it is true
109
+ @body << element(:maketitle ).cr if settings[key]
110
+ when :log
111
+ else
112
+ @log.warn("Document.new: Unknown setting #{key.inspect} (=#{value.inspect})") if @log.warn?
113
+ end
114
+ } #settings
115
+
116
+ end
117
+ #body and head are lists, containing elements.
118
+ attr_reader :body, :head
119
+ attr_reader :template
120
+ #Logger for the document
121
+ attr_reader :log
122
+ #Document title
123
+ attr_accessor :title, :shorttitle
124
+ #Set document description
125
+ attr_writer :author, :date, :keywords, :description, :creator
126
+ attr_writer :language
127
+ #Flag, if tex should be started immediate after document creation.
128
+ attr_writer :runtex
129
+ #Add more keywords
130
+ def keyword_add( keyword )
131
+ @keywords << ", #{keyword}"
132
+ end
133
+
134
+ #Constant to detect the generated header
135
+ PREFIX_ENDFLAG = 'Generation-Info-End'
136
+ #
137
+ #Define, if there should be a message in case of:
138
+ #-:change Document changed
139
+ #-:nochange Document existed, but is unchanged
140
+ #Give an array with the wanted values.
141
+ def Document.givemessage=( value = [:change, :nochange] )
142
+ @@givemessage = value
143
+ end
144
+ @@givemessage = [:change, :nochange]
145
+ def Document.givemessage(); @@givemessage; end
146
+ #Add a meta-tag-information for the HTML-Output.
147
+ def meta( key, content )
148
+ key = key.to_s
149
+
150
+ if ! VALID_META_TAGS.include?(key)
151
+ @log.warn("Unknown meta-tag #{key} (#{content})") if @log.warn?
152
+ @log.info("\tAllowed meta-tags: #{VALID_META_TAGS.join(', ')}") if @log.info?
153
+ end
154
+ if @meta[key]
155
+ @log.warn("Double definition meta-tag #{key} (old: #{@meta[key]}, new: #{content})") if @log.warn? and @meta[key] != content
156
+ end
157
+
158
+ @meta[key] = content
159
+ end
160
+ #Prepare the docinfo.
161
+ #May be called only once.
162
+ #
163
+ #If the title should change (e.g. when you save the document twice in different versions)
164
+ #you can do it via the parameter.
165
+ def docinfo()
166
+ #If this method is called twice (e.g. with save to tex and html),
167
+ #then the title is doubled in the second output.
168
+ #(Elements are added to @head)
169
+ return nil if @docinfo_called
170
+ @docinfo_called = true
171
+
172
+ #Build docinfo.
173
+ result = []
174
+ result << element( :title, {:short => shorttitle }, @title).CR if @title
175
+ result << element( :author, {}, @author).cr if @author
176
+ result << element( :date, {}, @date).cr if @date
177
+ result << element( :keywords, {}, @keywords).cr if @keywords
178
+ result << element( :metadescription, {}, @description).cr if @description
179
+ result << element( :creator, {}, @creator).cr if @creator
180
+ @meta.each{ |key, content|
181
+ result << element( :meta, { :name => key, :content => content } ).cr
182
+ }
183
+ return result
184
+ end
185
+ def add_option( option)
186
+ @options << option
187
+ end
188
+ #Prepare a table of content.
189
+ #
190
+ #There is no sense to use it with LaTeX, better you use \tableofcontents
191
+ #
192
+ #Options:
193
+ #- id: Id of div, needed for CSS-formatting
194
+ #- tocfilename: Added as prefix to link.
195
+ # can be used to make toc for in another file (cross-referencing)
196
+ #- level: Depth of toc
197
+ #The document should be filled before you add the toc.
198
+ #You an use Element#insertbefore:
199
+ # doc.body.insertbefore(start, doc.toc)
200
+ def toc( options = {} )
201
+ opt = {
202
+ :id => 'toc',
203
+ :tocfilename => nil, #Can be used to build cross references
204
+ :level => 3,
205
+ :log => @log
206
+ }.update(options)
207
+
208
+ opt[:level] = 3 unless opt[:level]
209
+ opt[:log].info("Prepare Table of contents, options: #{options.keys.inspect}") if opt[:log].info?
210
+ opt[:log].debug("Options: #{[:id, :level, :tocfilename].map{|k| "#{k}: #{opt[k].inspect}"}.join(',')}") if opt[:log].debug?
211
+
212
+ toc = element(:div, { :id => opt[:id] }).cR
213
+ opt[:pre].is_a?(String) ? toc << element(:p, {}, opt[:pre] ).cr : toc << opt[:pre]
214
+
215
+ toc_uls = [ toc ]
216
+
217
+ #fixme
218
+ #It would be nicer to get something like 1-1-1 instead of a counter.
219
+ toccnt = 0
220
+ toc_ids = [ :chapter, :section,:subsection, :subsubsection, :paragraph, :subparagraph,:minisec]
221
+ @body.content.flatten.each{|el|
222
+ if ! el.respond_to?(:ids)
223
+ #e.g. Wikitext. Has a to_doc, but doesn't react on flatten.
224
+ opt[:log].error("Toc: Element ohne :ids #{el.class}") if opt[:log].error?
225
+ next
226
+ end
227
+ depth = toc_ids.index((el.ids & toc_ids)[0])
228
+ next if ! depth #Element is no header
229
+
230
+ opt[:log].debug("Toc: Found entry on level #{depth}: <#{el.content}>") if opt[:log].debug?
231
+ #Create an id if not already defined
232
+ if el[:id].content.empty?
233
+ el[:id] << "toc#{toccnt += 1}"
234
+ end
235
+ if depth > opt[:level]
236
+ opt[:log].debug("Toc: Reject by level #{el.content}") if opt[:log].debug?
237
+ next
238
+ end
239
+
240
+ #Check missing levels
241
+ (depth - toc_uls.size).times{|i|
242
+ opt[:log].warn("Toc: Jump over section level #{depth-1+i} (#{opt[:tocfilename]})") if opt[:log].warn?
243
+ toc_uls << element(:ul, {}, element(:li ).cr ).cR
244
+ if toc_uls.size == 2 #First entry
245
+ toc_uls.first << toc_uls.last
246
+ else
247
+ toc_uls[-2].content.last << toc_uls.last
248
+ end
249
+ }
250
+
251
+ #Build new toc-list and deletet bigger ones
252
+ if ! toc_uls[depth]
253
+ opt[:log].debug("Toc: Start new level #{depth}") if opt[:log].debug?
254
+ toc_uls << element(:ul).cR
255
+ if depth == 1
256
+ toc << toc_uls[depth]
257
+ else
258
+ toc_uls[depth -1 ].content.last << toc_uls[depth]
259
+ end
260
+ else #delete levels under actual level
261
+ if toc_uls.slice!(depth+1..toc_uls.size+1)
262
+ opt[:log].debug("Toc: Stop level > #{depth}") if opt[:log].debug?
263
+ end
264
+ end
265
+ toc_uls[depth] << element(:li, {}, element(:a, {:href => "#{opt[:tocfilename]}##{el[:id]}" }, el.content ) ).cr
266
+ }
267
+ opt[:post].is_a?(String) ? toc << element(:p, {}, opt[:post] ).cr : toc << opt[:post]
268
+
269
+ return toc
270
+ end #toc
271
+ =begin rdoc
272
+ Save the file.
273
+ The type of the document is determined by the file extensison.
274
+ Supported document types are:
275
+ - tex
276
+ - html
277
+ - (wiki)
278
+ - (text)
279
+ Depending on a template, different results are created.
280
+
281
+ There is a comparison between an already existing file and the new one.
282
+ To write a new version, the document must change and overwrite must be true.
283
+
284
+ Valid options:
285
+ - :replacements
286
+ It is possible to give pairs of RegExp (pattern) and replacements to the result.
287
+ - overwrite [true]
288
+ allows to overwrite
289
+ - target
290
+ In most cases this is defined by the extension.
291
+ Main usage will be for ConTeXt (shares the extension with LaTeX)
292
+ - :additional_options
293
+ List of options.
294
+ If you want to give parameters to specific 'Element'-objects you can define the keys here.
295
+ If you don't make it, you get warnings about undefined options.
296
+ =end
297
+ def save( filename, options = {} )
298
+ #check old interface before 1.1.0
299
+ case options
300
+ when true, false
301
+ @log.warn( "Old interface for Document.save, use :overwrite => true/false" ) if @log.error?
302
+ options = { :overwrite => options }
303
+ end
304
+
305
+ options = {
306
+ :overwrite => true,
307
+ :replacements => {} ,
308
+ :additional_options => [],
309
+ :target => nil, #Will be set by extension
310
+ :runtex => @runtex,
311
+ }.update(options)
312
+
313
+ #Check valid options
314
+ options.each{|key,value|
315
+ case key
316
+ when :overwrite, :replacements, :target
317
+ when :additional_options
318
+ else
319
+ if options[:additional_options].include?(key)
320
+ @log.warn( "unknown option #{key.inspect} for Document.save" ) if @log.warn?
321
+ else
322
+ @log.debug( "Save-Specific option #{key.inspect} in Document.save" ) if @log.debug?
323
+ end
324
+ end
325
+ }
326
+
327
+ if ! @template
328
+ @log.error( "No template available to create #{filename}" ) if @log.error?
329
+ return false
330
+ end
331
+
332
+ prefix = [ nil,
333
+ "Build by\t#{__FILE__}",
334
+ "Dir:\t\t#{Dir.pwd}",
335
+ "Creator:\t#{$0}",
336
+ "Target:\t\t#{filename}",
337
+ "#{Time.now.strftime('%Y/%m/%d %H:%M:%S')}",
338
+ nil,
339
+ "#{PREFIX_ENDFLAG}"
340
+ ].join("\n\t")
341
+
342
+ #Determine the target document type, depending on extension.
343
+ extension = File.basename( filename ).split( /\./).last
344
+ case extension
345
+ when /tex/i
346
+ target = :latex
347
+ #Take context if requested.
348
+ target = :context if options[:target] == :context
349
+ when /miv/i #Mark IV
350
+ target = :context
351
+ when /htm[l]?/i
352
+ target = :html
353
+ when /txt/
354
+ target = :text
355
+ when /wiki/
356
+ target = :wiki
357
+ target = :creole if options[:target] == :creole
358
+ when /creole/
359
+ target = :creole
360
+ else
361
+ @log.fatal( "Unknown Extension #{extension} for #{File.basename( filename )}" ) if @log.fatal?
362
+ raise "Unknown Extension #{extension}"
363
+ end
364
+
365
+ #Check if the wanted target makes sense
366
+ case options[:target]
367
+ when nil #nothing predefined -> no check necessary
368
+ when target #Same as determined by extension -> no check necessary
369
+ else #Requested target is another one.
370
+ @log.warn( "Target #{options[:target]} doesn't match extension. Recommended: #{target}" ) if @log.warn?
371
+ target = options[:target]
372
+ end
373
+
374
+ #Create new version.
375
+ new = to_doc( target, {
376
+ :template=> @template[target],
377
+ :filename => filename,
378
+ :replacements => options[:replacements],
379
+ :log => @log
380
+ })
381
+ #Get previous content if available
382
+ old = nil
383
+ if File.exist?( filename )
384
+ #read the file. We expect to have the same encoding.
385
+ File.open(filename, 'r', :external_encoding => new.encoding){|f| old = f.read }
386
+ old = File.read(filename) unless old.valid_encoding? #
387
+ end
388
+ prefix.encode!(new.encoding) #for later sub...
389
+ case target
390
+ when :latex, :context
391
+ prefix.gsub!( /^/, '%' )
392
+ old.sub!(/\A.*#{PREFIX_ENDFLAG}/m, '<<prefix>>' ) if old
393
+ when :html
394
+ #Delete prefix (with generation time) for later compare.
395
+ old.sub!(/\A.*#{PREFIX_ENDFLAG}/m, "<!--\n<<prefix>>" ) if old
396
+ when :text
397
+ when :wiki
398
+ when :creole
399
+ #~ new.squeeze!("\n")
400
+ else
401
+ @log.fatal( "Unknown target #{target} for #{File.basename( filename )}" ) if @log.fatal?
402
+ raise "Unknown target #{target}"
403
+ end
404
+ #Make it a bit more compact.
405
+ #TeX requires at least 2 \n for paragraph changes
406
+ new.gsub!(/\n+\n\n/, "\n\n")
407
+
408
+ if ! new.kind_of?( String )
409
+ @log.error( "New is wrong type: #{new.inspect}" ) if @log.error?
410
+ end
411
+
412
+ if new != old
413
+ new.sub!( '<<prefix>>', prefix)
414
+ if ( File.exist?( filename ) and ! options[:overwrite] )
415
+ puts "Datei #{filename} exist already \nContinue [yn]?"
416
+ answer = $stdin.gets() if $stdin.tty? #only when called in a shell
417
+ if ! ( answer =~ /[YyjJ].*/ )
418
+ puts "Bye"
419
+ @log.info( "Overwrite #{filename} after confirmation" ) if @log.info?
420
+ return false
421
+ end
422
+ end
423
+ File.open( filename, 'w', :external_encoding => new.encoding ){|f|
424
+ f << new
425
+ }
426
+ @log.info( "Save changed\t#{filename}") if @log.info?
427
+ puts "Save changed\t#{filename}" if @@givemessage.include?(:change)
428
+ #Save copy of old version (attention, *.bak makes no control on tex or html)
429
+ #~ f = File.new( filename.sub( extension, 'bak'), 'w' )
430
+ #~ f << old
431
+ #~ f.close
432
+ Document.runtex( filename, options[:runtex] ) if options[:runtex] and [:latex, :context].include?(target)
433
+ return true
434
+ elsif old
435
+ @log.info("Unchanged\t#{filename}") if @log.info?
436
+ puts "Unchanged\t#{filename}" if @@givemessage.include?(:nochange)
437
+ return false
438
+ end
439
+ end #Document#save
440
+ =begin rdoc
441
+ Build the content for the target format.
442
+ Supported target formats are:
443
+ - :latex
444
+ - :html
445
+ - :text
446
+ If the standard templates are used, there is a <<prefix>> left
447
+ (used from Document#save to include some additional information).
448
+
449
+ If the method is called directly to prepare document snipplets, you can use:
450
+ puts Document#to_doc( :latex, '<<body>>')
451
+
452
+ It is possible to give pairs of RegExp (pattern) and a replacement to the result.
453
+ =end
454
+ def to_doc( target, options )
455
+ #~ o = Docgenerator_logger.set_option_defaults(options)
456
+ options[:log].info( "Build document for #{target.inspect}" ) if options[:log].info?
457
+ template = options[:template]
458
+ if ! template
459
+ options[:log].error( "No template available to create #{target.inspect} #{self.class}" ) if options[:log].error?
460
+ return ''
461
+ end
462
+ replacements = options[:replacements] || {}
463
+ options[:log].warn( "No filename given " ) if options[:log].warn? and ! options[:filename]
464
+
465
+ new = template.template
466
+ encoding = template.template.encoding
467
+ case target
468
+ when :latex
469
+ add_option( @language )
470
+ when :context
471
+ options[:log].warn( "Support for #{target} under development" ) if options[:log].warn?
472
+ when :html
473
+ when :text
474
+ when :wiki
475
+ when :creole
476
+ options[:log].warn( "Support for #{target} under development" ) if options[:log].warn?
477
+ else
478
+ options[:log].fatal( "Unknown target #{target} for #{options[:filename]}" ) if options[:log].fatal?
479
+ return ''
480
+ end
481
+ if ! new.kind_of?( String )
482
+ options[:log].error( "New is wrong type: #{new.inspect}") if options[:log].error?
483
+ end
484
+
485
+ options[:document] = self
486
+ @head << self.docinfo()
487
+ options[:log].debug( "Build header data") if options[:log].debug?
488
+ new.sub!( '<<head>>', @head.to_doc(target, options ).encode(encoding))
489
+ options[:log].debug( "Build body") if options[:log].debug?
490
+ new.sub!( '<<body>>', @body.to_doc(target, options).encode(encoding))
491
+ new.sub!( '<<classoptions>>', @options.uniq.join(',').encode(encoding))
492
+
493
+
494
+ replacements.each{|pattern, replace |
495
+ options[:log].info("Replace text #{pattern.source} with #{replace}" ) if options[:log].info?
496
+ new.gsub!( pattern, replace ) if replace
497
+ }
498
+ return new
499
+ end #Document#to_doc
500
+ #Return the actual target type.
501
+ #Needed by Element#to_s to decide which method is used to prepare the output.
502
+ #
503
+ #The usage of this technic makes similar processing unposibble.
504
+ #Set in Document#save.
505
+ attr_reader :target
506
+ =begin rdoc
507
+ Call rake4latex to translate the file.
508
+ =end
509
+ def Document.runtex( filename, options = [:touch, :statistic, :clean])
510
+ if ! defined? Rake4LaTeX
511
+ puts <<warning
512
+ Rake4LaTeX not loaded!
513
+ Please use one of the following commands:
514
+ require 'rake4latex'
515
+ require 'rake4latex_latex'
516
+ require 'rake4latex_pdflatex'
517
+ require 'rake4latex_xelatex'
518
+ ...
519
+ Document.save(
520
+ :runtex => [:statistic, :clean]
521
+ #or with more options:
522
+ #:runtex => [:touch, :texerrors_allowed, :statistic, :clean]
523
+ )
524
+ warning
525
+ begin
526
+ #interprete old interface before 1.2.0
527
+ gem 'rake4latex', '>= 0.1.2'
528
+ case options
529
+ when :latex; require 'rake4latex_latex'
530
+ when :pdflatex; require 'rake4latex_pdflatex'
531
+ when :xelatex; require 'rake4latex_xelatex'
532
+ else; require 'rake4latex'
533
+ end #format
534
+ options = [:touch, :statistic, :clean]
535
+ rescue LoadError
536
+ puts "Sorry, I didn't find the rake4latex to translate #{filename}"
537
+ puts "I try to use the old 'RunTeX'"
538
+ runtex_old( filename, options[:format] )
539
+ return false
540
+ end unless defined? Rake4LaTeX
541
+ end # ! defined? Rake4LaTeX
542
+
543
+ case options
544
+ when Array #ok
545
+ when true; options = [:touch, :statistic, :clean]
546
+ else
547
+ options = [:touch, :statistic, :clean]
548
+ puts "Please change runtex-options to: #{options.inspect}"
549
+ end
550
+ #Taskname must be uniq for this file.
551
+ runtex = "Define TeX-task #{filename.ext('pdf')}"
552
+ rake4latex = Rake4LaTeX::Basefile.set(filename)#needed for clean...
553
+ rake4latex [:texerrors_allowed] = true if options.delete(:texerrors_allowed)
554
+ rake4latex[:loglevel] = Log4r::WARN
555
+
556
+ if options.delete(:touch)
557
+ task :touch => filename.ext('tex')
558
+ task runtex => :touch
559
+ end #if options.delete(:touch)
560
+ task runtex => filename.ext('pdf')
561
+ task runtex => options
562
+
563
+ Rake.application[runtex].invoke
564
+ options.each{|option| Rake.application[option].reenable }
565
+ end
566
+ =begin rdoc
567
+ Make some basic replacements for TeX.
568
+ There is no sense to use it with HTML.
569
+
570
+ Better solution: Puts String into \path, \verb or similar.
571
+ =end
572
+ def Document.texify( input )
573
+ out = input.strip
574
+ #~ out.gsub!( /&/, '\\\&') #geht schief. erzeugt <<body>>...
575
+ #~ out.gsub!( /\\/, '\\\\')
576
+ out.gsub!( /%/, '\%')
577
+ out.gsub!( /\$/, '\$')
578
+ out.gsub!( /&/, '\\\\&')
579
+ out.gsub!( /_/, '\_')
580
+ out.gsub!( /#/, '\#')
581
+ out.gsub!( /€/, '\euro ')
582
+ return out
583
+ end
584
+ def inspect()
585
+ return "#<Document '#{@title}'>"
586
+ #~ return "#<Document '#{@title} #{@body.inspect}>'"
587
+ end
588
+ end #Document