runtex 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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