runtex 0.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 (97) hide show
  1. data/lib/Code_zum_Pluendern_rtex4newrtex.rb +275 -0
  2. data/lib/catch_output.rb +99 -0
  3. data/lib/runtex.rb +221 -0
  4. data/lib/runtex_bibtex.rb +111 -0
  5. data/lib/runtex_job_chain.rb +371 -0
  6. data/lib/runtex_latex.rb +373 -0
  7. data/lib/runtex_makeindex.rb +114 -0
  8. data/lib/runtex_pathes.yaml +59 -0
  9. data/lib/runtex_rail.rb +116 -0
  10. data/lib/runtex_splitindex.rb +78 -0
  11. data/lib/runtex_tool.rb +128 -0
  12. data/lppl.txt +416 -0
  13. data/readme +73 -0
  14. data/unittest/expected/test_bibliography_babelbib.debug1.txt +31 -0
  15. data/unittest/expected/test_bibliography_babelbib.debug2.txt +16 -0
  16. data/unittest/expected/test_bibliography_babelbib.tex.runtex_summary.txt +19 -0
  17. data/unittest/expected/test_bibliography_babelbib_1.txt +15 -0
  18. data/unittest/expected/test_bibliography_babelbib_2.txt +11 -0
  19. data/unittest/expected/test_bibliography_plain.debug1.txt +45 -0
  20. data/unittest/expected/test_bibliography_plain.debug2.txt +16 -0
  21. data/unittest/expected/test_bibliography_plain.tex.runtex_summary.txt +18 -0
  22. data/unittest/expected/test_bibliography_plain_1.txt +19 -0
  23. data/unittest/expected/test_bibliography_plain_2.txt +11 -0
  24. data/unittest/expected/test_error.debug1.txt +22 -0
  25. data/unittest/expected/test_error.debug2.txt +12 -0
  26. data/unittest/expected/test_error.tex.runtex_summary.txt +15 -0
  27. data/unittest/expected/test_error_1.txt +15 -0
  28. data/unittest/expected/test_error_2.txt +12 -0
  29. data/unittest/expected/test_gloss.debug1.txt +45 -0
  30. data/unittest/expected/test_gloss.debug2.txt +16 -0
  31. data/unittest/expected/test_gloss.tex.runtex_summary.txt +18 -0
  32. data/unittest/expected/test_gloss_1.txt +19 -0
  33. data/unittest/expected/test_gloss_2.txt +11 -0
  34. data/unittest/expected/test_gloss_newgloss.debug1.txt +58 -0
  35. data/unittest/expected/test_gloss_newgloss.debug2.txt +20 -0
  36. data/unittest/expected/test_gloss_newgloss.tex.runtex_summary.txt +24 -0
  37. data/unittest/expected/test_gloss_newgloss_1.txt +23 -0
  38. data/unittest/expected/test_gloss_newgloss_2.txt +13 -0
  39. data/unittest/expected/test_glossaries.debug1.txt +56 -0
  40. data/unittest/expected/test_glossaries.debug2.txt +28 -0
  41. data/unittest/expected/test_glossaries.tex.runtex_summary.txt +30 -0
  42. data/unittest/expected/test_glossaries_1.txt +24 -0
  43. data/unittest/expected/test_glossaries_2.txt +19 -0
  44. data/unittest/expected/test_index.debug1.txt +35 -0
  45. data/unittest/expected/test_index.debug2.txt +18 -0
  46. data/unittest/expected/test_index.tex.runtex_summary.txt +24 -0
  47. data/unittest/expected/test_index2.debug1.txt +58 -0
  48. data/unittest/expected/test_index2.debug2.txt +29 -0
  49. data/unittest/expected/test_index2.tex.runtex_summary.txt +27 -0
  50. data/unittest/expected/test_index2_1.txt +23 -0
  51. data/unittest/expected/test_index2_2.txt +17 -0
  52. data/unittest/expected/test_index_1.txt +21 -0
  53. data/unittest/expected/test_index_2.txt +17 -0
  54. data/unittest/expected/test_makeindex.debug1.txt +35 -0
  55. data/unittest/expected/test_makeindex.debug2.txt +18 -0
  56. data/unittest/expected/test_makeindex.tex.runtex_summary.txt +18 -0
  57. data/unittest/expected/test_makeindex_1.txt +15 -0
  58. data/unittest/expected/test_makeindex_2.txt +11 -0
  59. data/unittest/expected/test_packagedoc_dtx.debug1.txt +54 -0
  60. data/unittest/expected/test_packagedoc_dtx.debug2.txt +27 -0
  61. data/unittest/expected/test_packagedoc_dtx.dtx.runtex_summary.txt +31 -0
  62. data/unittest/expected/test_packagedoc_dtx_1.txt +18 -0
  63. data/unittest/expected/test_packagedoc_dtx_2.txt +13 -0
  64. data/unittest/expected/test_rail.debug1.txt +35 -0
  65. data/unittest/expected/test_rail.debug2.txt +12 -0
  66. data/unittest/expected/test_rail.tex.runtex_summary.txt +12 -0
  67. data/unittest/expected/test_rail_1.txt +13 -0
  68. data/unittest/expected/test_rail_2.txt +9 -0
  69. data/unittest/expected/test_rail_error.debug1.txt +37 -0
  70. data/unittest/expected/test_rail_error.debug2.txt +35 -0
  71. data/unittest/expected/test_rail_error.tex.runtex_summary.txt +18 -0
  72. data/unittest/expected/test_rail_error_1.txt +18 -0
  73. data/unittest/expected/test_rail_error_2.txt +18 -0
  74. data/unittest/expected/test_splitindex.debug1.txt +64 -0
  75. data/unittest/expected/test_splitindex.debug2.txt +32 -0
  76. data/unittest/expected/test_splitindex.tex.runtex_summary.txt +31 -0
  77. data/unittest/expected/test_splitindex_1.txt +21 -0
  78. data/unittest/expected/test_splitindex_2.txt +15 -0
  79. data/unittest/expected/test_test.debug1.txt +32 -0
  80. data/unittest/expected/test_test.debug2.txt +12 -0
  81. data/unittest/expected/test_test.tex.runtex_summary.txt +12 -0
  82. data/unittest/expected/test_test_1.txt +15 -0
  83. data/unittest/expected/test_test_2.txt +9 -0
  84. data/unittest/expected/test_test_bibliography.debug1.txt +31 -0
  85. data/unittest/expected/test_test_gloss.debug1.txt +45 -0
  86. data/unittest/expected/test_test_gloss_newgloss.debug1.txt +58 -0
  87. data/unittest/expected/test_test_glossaries.debug1.txt +48 -0
  88. data/unittest/expected/test_test_index.debug1.txt +35 -0
  89. data/unittest/expected/test_test_index2.debug1.txt +58 -0
  90. data/unittest/expected/test_test_makeindex.debug1.txt +35 -0
  91. data/unittest/expected/test_test_rail.debug1.txt +35 -0
  92. data/unittest/expected/test_test_splitindex.debug1.txt +64 -0
  93. data/unittest/expected/test_test_test.debug1.txt +32 -0
  94. data/unittest/testcases.yaml +427 -0
  95. data/unittest/unittest_catch_output.rb +66 -0
  96. data/unittest/unittest_runtex.rb +282 -0
  97. metadata +149 -0
@@ -0,0 +1,373 @@
1
+ #
2
+ # This file is part of the runtex-bundle
3
+ #
4
+ module RunTeX
5
+
6
+ # This class provides (pdf|Xe|Lua)LaTeX.
7
+ class LaTeX < Tool
8
+ #Create a LaTeX-instance.
9
+ #
10
+ #The format is part of the options.
11
+ def initialize(job, options = {})
12
+ super(job, options, { :format => :pdflualatex,
13
+ :overfull => 100,
14
+ :underfull => 10000
15
+ })
16
+ @options.keys.each{|key|
17
+ case key
18
+ when :format
19
+ if ! Job_chain::Configuration["#{@options[key]}"]
20
+ @job.log.error( "#{@step} #{self.class}: Unknown format #{@options[key]}" ) if @job.log.error?
21
+ @options[key] = :pdflualatex
22
+ end
23
+ when :overfull, :underfull
24
+ @job.log.error( "#{@step} #{self.class}: option #{key} no integer" ) if @job.log.error? and ! @options[key].is_a?(Fixnum)
25
+ else
26
+ @job.log.error( "#{@step} #{self.class}: Unknown option #{key}" ) if @job.log.error?
27
+ end
28
+ }
29
+ end
30
+ #
31
+ #Call LaTeX and analyse the aux+logfile for additional tools.
32
+ def execute( step )
33
+ super(step)
34
+
35
+ auxfilename = "#{@job.basename}.aux"
36
+ logfilename = "#{@job.basename}.log"
37
+
38
+ #Read AUX-File if available
39
+ if File.exist?(auxfilename)
40
+ @job.add2zip( auxfilename )
41
+ auxfile_old = File.readlines(auxfilename)
42
+ end
43
+
44
+ #Build command line to call LaTeX
45
+ cmd = build_cmd(@options[:format], :filename => @job.filename)
46
+
47
+ @job.log.debug( "#{@step} Start LaTeX #{cmd}") if @job.log.debug?
48
+ STDOUT.flush
49
+ stdout, stderr = catch_screen_output{ `#{cmd}` }
50
+ @job.log.debug( "#{@step} LaTeX finished") if @job.log.debug?
51
+ STDOUT.flush
52
+
53
+ #Read AUX-File if available
54
+ if File.exist?(auxfilename)
55
+ @job.add2zip( auxfilename )
56
+ auxfile_new = File.readlines(auxfilename)
57
+ analyse_auxfile(auxfile_new)
58
+ @job.helpfiles << auxfilename
59
+ end
60
+
61
+ #Fill more helpfiles...
62
+ %w{out toc lof lot lox nav}.each{|ext|
63
+ @job.helpfiles << "#{@job.basename}.#{ext}"
64
+ }
65
+
66
+ #Read log-File if available
67
+ if File.exist?(logfilename)
68
+ @job.add2zip( logfilename )
69
+ @job.logfiles << logfilename
70
+ result = analyse_logfile(File.readlines(logfilename))
71
+ else
72
+ @job.log.error( "#{@step} Log-file #{logfilename} not found") if @job.log.error?
73
+ end
74
+
75
+
76
+ if auxfile_new != auxfile_old
77
+ @job.log.debug( "#{@step} Aux.file changed -> New TeX run") if @job.log.debug?
78
+ @job.please_rerun('Aux-File changed')
79
+ end
80
+
81
+ return result
82
+ end #LaTeX#execute
83
+
84
+ MAKEINDEX_PARAMETERS = Struct.new('Makeindex', :name, :log, :out, :in)
85
+ #
86
+ #Easy check: If the data changed (aux-File) a rerun is necesary.
87
+ #
88
+ #Analyse the AUX-File to detect:
89
+ #- glossaries from glossaries.sty (-> makeindex)
90
+ def analyse_auxfile(auxfile)
91
+
92
+ @job.log.debug( "#{@step} Analyse aux-file") if @job.log.debug?
93
+ makeindex = []
94
+ glossaries_format = nil
95
+ auxfile.each{|auxline|
96
+ case auxline
97
+ when /bibdata/ #Check for Standard bibliography
98
+ @job << BibTeX.new( @job, :source => "#{@job.basename}.aux", :target => "#{@job.basename}.bbl" )
99
+ #Example: \@newglossary{main}{glg}{gls}{glo}
100
+ when /\\@newglossary\{(.+)\}\{(.+)\}\{(.+)\}\{(.+)\}/
101
+ @job.log.debug( "#{@step} Find glossary #{$1}") if @job.log.debug?
102
+ makeindex << MAKEINDEX_PARAMETERS.new( $1, $2, $3, $4)
103
+ when /\\@istfilename\{(.+)\}/
104
+ glossaries_format = $1
105
+ end
106
+ }
107
+
108
+ makeindex.each{|idx|
109
+ if File.exist?("#{@job.basename}.#{idx.in}")
110
+ @job << Makeindex.new(
111
+ @job,
112
+ :name => ( idx.name == 'main' ? 'main glossary' : idx.name),
113
+ :file_in => "#{@job.basename}.#{idx.in}",
114
+ :file_out => "#{@job.basename}.#{idx.out}",
115
+ :file_log => "#{@job.basename}.#{idx.log}",
116
+ :format => glossaries_format
117
+ )
118
+ else
119
+ #Can happen, if defined, but no entries for the group are used.
120
+ @job.log.debug( "#{@step} glossaries.sty-entry #{idx.name} without entries") if @job.log.debug?
121
+ end
122
+ }
123
+ end #analyse_auxfile
124
+
125
+ #Analyse logfile
126
+ #1. Check the log-File if an additional run is necessary.
127
+ # - references
128
+ # - longtable.sty: balancing not finished
129
+ #2. Check different Tools if they must be active and if they force an additional run
130
+ # - BibTeX (bibliography)
131
+ # - makeindex (including multiind, glossaries)
132
+ # - rail-Diagramms
133
+ def analyse_logfile(logfile)
134
+ @job.log.debug( "#{@step} Analyse log-file") if @job.log.debug?
135
+ result = {
136
+ :error => [],
137
+ :warning => [],
138
+ :warning_hyper => [],
139
+ :label => [],
140
+ :citation => [],
141
+ :overfull => [],
142
+ :underfull => [],
143
+ }
144
+
145
+ #
146
+ #Help to test: Detect empty insertions
147
+ #
148
+ #~ class << result[:error]
149
+ #~ alias :oldpush :push
150
+ #~ def push (x)
151
+ #~ raise "Add nil-element (#{$logline.strip})" unless x
152
+ #~ oldpush(x)
153
+ #~ end
154
+ #~ alias :oldgg <<
155
+ #~ def << (x)
156
+ #~ raise "Add nil-element(#{$logline.strip})" unless x
157
+ #~ oldgg(x)
158
+ #~ end
159
+ #~ end
160
+
161
+
162
+ #Flag for continued messages
163
+ last_message = nil
164
+ get_next_lines = 0 #Number of lines, which should be added to last_message
165
+ jump_to_numberline = false
166
+
167
+ logfile.each{|logline|
168
+ #The previous message is continued, get the rest here
169
+ if get_next_lines > 0
170
+ get_next_lines -= 1
171
+ case logline
172
+ #Get the line number
173
+ when /l\.([0-9]*) (.*)/
174
+ last_message << " #{$2} (line #{$1})".strip
175
+ #fixme: get also next line (pdflualatex/invalid utf?)
176
+ else
177
+ last_message << " (#{logline.chomp()})"
178
+ end
179
+ last_message = nil
180
+ next #continue with the next warning/error
181
+ end #last_message
182
+
183
+ #In case of errors, get the line number where it happens
184
+ if jump_to_numberline
185
+ case logline
186
+ #skip text
187
+ when /Type H <return> for immediate help./,
188
+ /^[\.\s]*$/ #empty line
189
+ #Get the line number
190
+ when /l\.([0-9]*) (.*)/
191
+ last_message << " #{$2} (line #{$1})".strip
192
+ jump_to_numberline = false #numberline reached, continue with log-analyses
193
+ #fixme: collect text in between?
194
+ when /See the (.*) package documentation for explanation./
195
+ last_message << " (package #{$1})"
196
+ else
197
+ last_message << " #{logline.strip} ||"
198
+ end
199
+ next #continue with the next warning/error
200
+ end #jump_to_numberline = true; last_message = result[:error].last
201
+
202
+ last_message = nil
203
+ $logline = logline #Only for test surposes
204
+ case logline
205
+ when /^! (.*)/
206
+ case $1
207
+ #Error messages with line code
208
+ when /LaTeX Error:\s*(.*)/,
209
+ /(Undefined control sequence.)/,
210
+ /(Missing \$ inserted.)/,
211
+ /(Dimension too large.)/,
212
+ /(Text line contains an invalid utf-8 sequence.)/, #pdflualatex
213
+ /(Argument of .* has an extra \})./,
214
+ /(Paragraph ended before .* was complete.)/,
215
+ /(Misplaced .+)/,
216
+ /(Extra \}, or forgotten \$)/,
217
+ #~ /(! Emergency stop.)/,
218
+ #~ /(! Huge page cannot be shipped out.)/
219
+ :last_entry_to_avoid_comma_error
220
+ result[:error] << last_message = $1
221
+ jump_to_numberline = true;
222
+ #LaTeX-Errors without line.
223
+ when /(Emergency stop|Huge page cannot be.*)/,
224
+ /(File ended while scanning use of .*)/,
225
+ /(==> Fatal error occurred, no output PDF file produced!)/
226
+ result[:error] << last_message = $1
227
+ when /Package (.*) Error: (.*)/
228
+ result[:error] << last_message = "#{$1}.sty:\t#{$2}"
229
+ jump_to_numberline = true
230
+ when /Extra alignment tab has been changed to \\cr./
231
+ result[:error] << last_message = "tabular: wrong alignment"
232
+ when /pdfTeX warning .*?: (.*)/
233
+ result[:warning] << last_message = "pdftex: #{$1}"
234
+ else
235
+ result[:error] << last_message = "New error to runtex: #{logline.strip}"
236
+ #~ jump_to_numberline = true; last_message = result[:error].last = result[:error].last
237
+ @job.log.warn( "#{__FILE__} Uncatched error?? #{$1.inspect}") if @job.log.warn?
238
+ end
239
+ when /(job aborted, no legal \\end found)/,
240
+ /(==> Fatal error occurred, no output PDF file produced!)/
241
+ result[:error] << last_message = $1
242
+ when /Package gloss Info: Writing gloss file (.*).aux/ #Check for gloss.sty
243
+ @job << BibTeX.new( @job, :source => "#{$1}.aux", :target => "#{$1}.bbl", :log => "#{$1}.blg" )
244
+ when /Package hyperref Warning: old toc file detected, not used; run LaTeX again/
245
+ @job.please_rerun("(old toc)")
246
+ when /LaTeX Warning: Label(s) may have changed. Rerun to get cross-references right./
247
+ @job.please_rerun("Labels/Toc changed")
248
+ when /Package longtable Warning: Table widths have changed. Rerun LaTeX./
249
+ @job.please_rerun("Longtable requires additional calculation)")
250
+ when /LaTeX Warning: Label (.*)/
251
+ result[:label]<< last_message = $1
252
+ when /LaTeX Warning: (Reference .*)/
253
+ result[:label]<< last_message = $1
254
+ when /LaTeX Warning: Citation (.*)/
255
+ result[:citation]<< last_message = $1
256
+ when /LaTeX Warning: (.*)/
257
+ result[:warning] << last_message = $1
258
+ when /Package hyperref Warning: (.*)/
259
+ result[:warning_hyper]<< last_message = "#{$1}"
260
+ when /Package rail Warning: Railroad diagram \{(\d*)\} doesn't match on input line (\d*)./
261
+ @job.log.debug( "#{@step} Rerun necessary (Rail diagram #{$1} on line #{$2})") if @job.log.debug?
262
+ if @job.stop_rerun?(:rail)
263
+ @job.log.warn( "#{@step} Rail-Rerun blocked by previous error") if @job.log.warn?
264
+ else
265
+ @job.please_rerun( "Rail diagram #{$1} on line #{$2} changed")
266
+ @job << Rail.new( @job, :source => "#{@job.basename}.rai", :target => "#{@job.basename}.rao" )
267
+ end
268
+ when /Package rail Warning: Railroad diagram\(s\) may have changed./
269
+ @job.log.debug( "#{@step} Rerun necessary (Rail diagram changed)") if @job.log.debug?
270
+ if @job.stop_rerun?(:rail)
271
+ @job.log.warn( "#{@step} Rail-Rerun blocked by previous error") if @job.log.warn?
272
+ else
273
+ @job.please_rerun( "Rail diagram changed")
274
+ @job << Rail.new( @job, :source => "#{@job.basename}.rai", :target => "#{@job.basename}.rao" )
275
+ end
276
+ #~ when /Package: rail / #Package: rail 1998/05/19
277
+ #~ @job.log.debug( "#{@step} Package rail detected") if @job.log.debug?
278
+ #~ @job << Rail.new( @job ) ??
279
+ when /Package (.*) Warning: (.*)/
280
+ result[:warning] << last_message = "#{$1}:\t#{$2}"
281
+ when /Overfull \\hbox \((.*) too wide\) in paragraph at lines (.*)/
282
+ next if $1.to_i() < @options[:overfull]
283
+ result[:overfull] << last_message = "#{$1} at lines #{$2}"
284
+ get_next_lines = 1 #?test
285
+ when /Underfull (.*box) \(badness (.*)\) detected at line (.*)/
286
+ next if $1.to_i() < @options[:underfull]
287
+ result[:underfull] << last_message = "badness #{$2} at lines #{$3}"
288
+ get_next_lines = 1 #?test
289
+ when /Using splitted index at (.*)/ ##Find Splittindex
290
+ @job.log.debug( "#{@step} Found splitindex for #{$1}") if @job.log.debug?
291
+ @job << Splitindex.new(@job, :source => $1 )
292
+ #This message is posted, if index2 is used.
293
+ #I hope the responsible person for index.sty will take my changes.
294
+ #If the name is very long, there is a break in the Filename.
295
+ when /Package index2 Info: (.*) (.*)/
296
+ @job.log.debug( "#{@step} Index #{$1} detected (->#{$2})") if @job.log.debug?
297
+ @job.log.warn( "#{@step} Warning: Name #{$2} perhaps cutted") if @job.log.warn? and $1.size != $2.size
298
+ @job << Makeindex.new( @job,
299
+ :name => "Index2-#{$1}",
300
+ :file_in => $1, #"#{@job.basename}.idx",
301
+ :file_out => $2, #"#{@job.basename}.ind",
302
+ :file_log => "#{$1}.ilg"
303
+ #~ :format => glossaries_format
304
+ )
305
+ #If you use index.sty:
306
+ #Unfortenalty there are some missing information to complete the task.
307
+ #Please use index2.sty
308
+ when /Writing index file (\S*)/
309
+ @job.log.debug( "#{@step} Index #{$1} detected") if @job.log.debug?
310
+
311
+ if $1 == @job.basename + '.idx' #'normal' standard index
312
+ name = 'Index'
313
+ format = nil
314
+ if @job.filename =~ /\.dtx$/
315
+ name << '/dtx'
316
+ format = 'gind.ist'
317
+ end
318
+ @job << Makeindex.new( @job,
319
+ :name => name,
320
+ :file_in => "#{@job.basename}.idx",
321
+ :file_out => "#{@job.basename}.ind",
322
+ :file_log => "#{@job.basename}.ilg",
323
+ :format => format
324
+ )
325
+ else
326
+ @job.log.warn( "#{@step} Warning: index.sty is not supported, please use index2 (#{$1})") if @job.log.warn?
327
+ @job.helpfiles << $1
328
+ end
329
+ #This message is created by
330
+ #- glossaries (-> already catched by aux-analyses)
331
+ #- ltxdoc.cls (for dtx.files)
332
+ when /Writing glossary file (\S*)/
333
+ glossfile = $1
334
+ @job.log.debug( "#{@step} Glossary #{glossfile} detected") if @job.log.debug?
335
+
336
+ if @job.filename =~ /\.dtx$/ and glossfile =~ /.glo$/ #ltxdoc.cls
337
+ @job << Makeindex.new( @job,
338
+ :name => 'Glossary/dtx',
339
+ :file_in => glossfile,
340
+ :file_out => "#{@job.basename}.gls",
341
+ :file_log => "#{@job.basename}.glg",
342
+ :format => 'gglo.ist'
343
+ )
344
+ else
345
+ #Possible with usage of glossaries.sty -> catched by aux-analyses
346
+ @job.log.debug( "#{@step} Glossary in non-dtx found #{glossfile}") if @job.log.debug?
347
+ end
348
+ when /Output written on (.*) \((.*) pages?, (.*) bytes\)/
349
+ result[:file] = $1
350
+ result[:pages] = $2.to_i
351
+ result[:size] = "#{$3.to_i / 1024}KB"
352
+
353
+ filedata = []
354
+ filedata << "#{result[:file]}"
355
+ filedata << "#{result[:pages]} Page#{'s' if result[:pages] > 1}" if result[:pages]
356
+ filedata << result[:size] if result[:size]
357
+ filedata << "#{result[:error].size} Error#{'s' if result[:error].size > 1}" unless result[:error].empty?
358
+ filedata << "#{result[:overfull].size} Overfull box#{'es' if result[:overfull].size > 1} (> #{@options[:overfull]})" unless result[:overfull].empty?
359
+ filedata << "#{result[:underfull].size} Underfull box#{'es' if result[:underfull].size > 1} (> #{@options[:underfull]})" unless result[:underfull].empty?
360
+ #~ result[:fileinfo] = "#{result[:file]} (#{filedata.join(', ')})" unless filedata.empty?
361
+ result[:fileinfo] = filedata
362
+ last_message = nil
363
+ end #case logline
364
+ } #each.loglines
365
+ return result
366
+ end #analyse_logfile
367
+ #Used in logger
368
+ def inspect()
369
+ "(La)TeX<#{@options[:format]}>"
370
+ end
371
+
372
+ end #LaTeX
373
+ end #module RunTeX
@@ -0,0 +1,114 @@
1
+ #
2
+ # This file is part of the runtex-bundle
3
+ #
4
+
5
+ module RunTeX
6
+ #
7
+ # Makeindex is used by the standard LaTeX and by
8
+ #- index.sty (part of camel)
9
+ #- glossaries.sty
10
+ #
11
+ class Makeindex< Tool
12
+ def initialize(job, options = {})
13
+ super(job, options,
14
+ :file_in => "#{job.basename}.idx",
15
+ :file_out => "#{job.basename}.ind",
16
+ :file_log => "#{job.basename}.ilg"
17
+ )
18
+ @options.keys.each{|key|
19
+ case key
20
+ when :file_in # normally idx
21
+ when :file_out # normally ind
22
+ when :file_log # normally ilg
23
+ when :format
24
+ when :name
25
+ else
26
+ @job.log.error( "#{self.class}: Unknown option #{key}" ) if @job.log.error?
27
+ end
28
+ }
29
+ end
30
+ #Start makeindex
31
+ def execute( step )
32
+ super(step)
33
+ @result = {
34
+ :error => [],
35
+ :info => [],
36
+ }
37
+
38
+ #Get existing index-data first
39
+ if File.exist?( @options[:file_out] )
40
+ @job.add2zip( @options[:file_out] )
41
+ ind_old = File.readlines( @options[:file_out] )
42
+ end
43
+
44
+ #Build the call for makeindex
45
+ cmd = build_cmd('makeindex')
46
+ #~ cmd = build_cmd('makeindex', @options) )
47
+ @job.log.debug( "#{@step} Start Makeindex: #{cmd}") if @job.log.debug?
48
+ STDOUT.flush
49
+
50
+ #Execute makeindex
51
+ subrc = nil
52
+ stdout, stderr = catch_screen_output{ subrc = system(cmd) }
53
+ @job.log.error( "#{@step} Error Makeindex: #{cmd}") if !subrc and @job.log.error?
54
+
55
+ if File.exist?( @options[:file_out] )
56
+ @job.add2zip( @options[:file_out] )
57
+ ind_new = File.readlines( @options[:file_out] )
58
+ end
59
+
60
+ @job.logfiles << @options[:file_log]
61
+ @job.helpfiles << @options[:file_in]
62
+ @job.helpfiles << @options[:file_out]
63
+
64
+
65
+ if ind_old != ind_new
66
+ @job.please_rerun("Index #{@options[:file_out]} changed")
67
+ end
68
+
69
+ if File.exist?( @options[:file_log] )
70
+ @job.add2zip( @options[:file_log] )
71
+ @result = analyse_log( File.readlines( @options[:file_log] ) )
72
+ else
73
+ @job.log.error( "#{@step} Error Makeindex: No log #{@options[:file_log]}") if @job.log.error?
74
+ @result[:error] << "Error Makeindex: No log #{@options[:file_log]}"
75
+ end
76
+
77
+ return @result
78
+ end #Makeindex#execute()
79
+
80
+ #Analyse the makeindex-log
81
+ def analyse_log( logdata )
82
+ @job.log.debug( "#{@step} Analyse log-file") if @job.log.debug?
83
+ result = {
84
+ :error => [],
85
+ #~ :warning => [],
86
+ :info => [],
87
+ :rejected => 0,
88
+ }
89
+ error = nil
90
+ logdata.each{ |logline|
91
+ if error #Index error
92
+ result[:error] << "#{logline.chomp.sub(/.*--/, "")} #{error}"
93
+ error = nil
94
+ else
95
+ case logline
96
+ when /Scanning input file (.*)\...done \((.*) entries accepted, (.*) rejected\)./
97
+ result[:info] << "input file #{$1} (#{$2} entries accepted, #{$3} rejected)"
98
+ when /done \((.*) entries accepted, (.*) rejected\)./
99
+ result[:rejected] += $2.to_i() if $2.to_i() > 0
100
+ when /!! Input index error \(file = (.*), line = (.*)\):/
101
+ #Error-message on next line
102
+ error = "(file #{$1} line #{$2}: #{logline})"
103
+ end #case logline
104
+ end #if error
105
+ }
106
+ result[:error] << "#{logline.chomp.sub(/.*--/, "")} #{error}" if error
107
+ return result
108
+ end #analyse_log( logdata )
109
+ #Used in logger
110
+ def inspect()
111
+ "Makeindex<#{@options[:name]}>"
112
+ end
113
+ end #Makeindex
114
+ end #module RunTeX