Version 1.3
[lematema] / crea_numero.rb
1 #!/usr/bin/ruby
2 #
3 # Le Matematiche
4 #
5 # Crea un numero per la rivista Le Matematiche, usando le informazioni contenute in una specifica cartella
6 #
7 # Author: Giuseppe Bilotta <bilotta@dmi.unict.it>
8 #
9 # Created: 20070317
10 #
11 # Last Modified: 20070317
12 #
13 # Copyright: (C) 2007 Giuseppe Bilotta
14 #
15
16 SCRIPT_DIR = File.expand_path File.dirname(__FILE__)
17
18 $:.unshift SCRIPT_DIR
19
20 require 'yaml'
21 require 'roman_numerals'
22
23 def uso
24         puts "#{$0} <nome cartella>"
25         puts "\tcrea un numero per la rivista Le Matematiche, usando le informazioni contenute nella cartella"
26 end
27
28 def errore(msg)
29         $stderr.puts "ERRORE: %s" % msg
30         exit 2
31 end
32
33 def avviso(msg)
34         $stderr.puts "AVVISO: %s" % msg
35 end
36
37 NOT_BRACE = /[^\{]/
38 SIMPLE_GROUP = /#{NOT_BRACE}+?|\{#{NOT_BRACE}*?\}/
39 NESTED_GROUP = /#{SIMPLE_GROUP}+?|\{#{SIMPLE_GROUP}*?\}/
40 TITLE_RX = /\\title\{(#{NESTED_GROUP})\}/m
41 AUTHOR_RX = /\\author\{(#{NESTED_GROUP})\}/m
42
43 def titolo_e_autore(name, file)
44         res = Hash.new
45         content = File.open(file).read
46
47         titoli = content.scan(TITLE_RX)
48         case titoli.length
49         when 0
50                 errore "Impossibile determinare il titolo di %s" % name
51         when 1
52                 res[:titolo] = titoli.first.first.gsub("\\\\", "\n").gsub(/\n|\r/, " ").gsub(/\s+/, " ")
53         else
54                 avviso "%s sembra avere più d'un titolo." % name
55                 res[:titolo] = titoli.first.first.gsub("\\\\", "\n").gsub(/\n|\r/, " ").gsub(/\s+/, " ")
56         end
57
58         autori = content.scan(AUTHOR_RX)
59         case autori.length
60         when 0
61                 avviso "Impossibile determinare l'autore di %s" % name
62     res[:autori] =[]
63         else
64                 res[:autori] = autori.map { |ar|
65                         ar.first
66                 }
67         end
68         return res
69 end
70
71 $pg = 3
72
73 def compila(name)
74         puts "Prossimo articolo: %s a pagina %d" % [name, $pg]
75         tex_file = name.dup
76         tex_file << '.tex'
77         if File.exists?(tex_file)
78                 begin
79                         art_info =  titolo_e_autore(name, tex_file)
80                         puts "\tTitolo:\n\t\t"+art_info[:titolo]
81                         puts "\tAutori:\n\t\t"+art_info[:autori].join("\n\t\t")
82                 rescue
83                         errore "Impossibile trovare titolo o autore per l'articolo \"%s\" (\"%s\")" % [name, tex_file]
84                 end
85
86                 begin
87                         if !art_info[:autori].empty?
88                                 $sommario << "\\articolo{#{art_info[:autori].join(' - ')} --\\ \\textit{#{art_info[:titolo]}}}{#{$pg}}\n"
89                         else
90                                 $sommario << "\\articolo{#{art_info[:titolo]}}{#{$pg}}\n"
91                         end
92                 rescue
93                         errore "Impossibile aggiornare il sommario con le informazioni sull'articolo \"%s\" (\"%s\")" % [name, tex_file]
94                 end
95         else
96                 errore "Impossibile trovare l'articolo \"%s\" (\"%s\")" % [name, tex_file]
97                 exit 2
98         end
99
100         pub_file = name.dup
101         pub_file << '.pub'
102         begin
103                 pub = File.new(pub_file, 'w')
104                 pub.puts $yvn
105                 pub.puts "\\gdef\\LM@FirstPg{#{$pg}}%"
106                 pub.close
107         rescue
108                 errore "Impossibile impostare le informazioni sull'articolo \"%s\" (\"%s\")" % [name, pub_file]
109         end
110
111         begin
112                 compile = system 'pdflatex', "-interaction=batchmode", tex_file
113                 raise if not compile
114         rescue
115                 errore "Errore durante la compilazione dell'articolo \"%s\" (\"%s\")" % [name, tex_file]
116         end
117
118         aux_file = name.dup
119         aux_file << '.aux'
120
121         log_file = name.dup
122         log_file << '.log'
123
124         begin
125                 if File.exists?(aux_file)
126                         File.open(aux_file) do |io|
127                                 io.each_line do |l|
128                                         if l[1,7] == 'bibdata'
129                                                 system 'bibtex', name
130                                                 break true
131                                         end
132                                 end
133                         end
134                 end
135
136                 compile = system 'pdflatex', "-interaction=batchmode", tex_file
137
138                 raise if not compile
139
140                 compile = system 'pdflatex', "-interaction=batchmode", tex_file
141
142                 raise if not compile
143
144                 log = File.new(log_file).read
145                 if log.match(/Output written on .+ \((\d+) pages?, (\d+) bytes\).\s*\r?\n?/)
146                         pagine = $1.to_i
147                         puts "Ok! %d pagine" % pagine
148                 else
149                         errore "Impossibile determinare il numero di pagine per l'articolo \"%s\" (\"%s\")" % [name, tex_file]
150                 end
151         rescue
152                 errore "Errore durante la compilazione dell'articolo \"%s\" (\"%s\"). Consultare il file di log \"%s\" per maggiori informazioni" % [name, tex_file, log_file]
153         end
154         return pagine
155 end
156
157 cartella = ARGV[0]
158
159 if !cartella or cartella.empty?
160         uso
161         exit 1
162 end
163
164 begin
165         Dir.chdir(cartella)
166 rescue
167         errore "Impossibile accedere alla cartella \"#{cartella}\""
168 end
169
170 indice = './indice'
171
172 if not File.exists?(indice)
173         errore "La cartella \"%s\" non contiene il file di indice!" % cartella
174 end
175
176 begin
177         info = YAML.load(File.read(indice))
178 rescue
179         errore "Impossibile leggere il file di indice in \"%s\"" % cartella
180 end
181
182 if info.has_key?(:anno)
183         anno = info[:anno].to_i
184 else
185         errore "Il file di indice in \"%s\" non specifica l'anno!" % cartella
186 end
187 if info.has_key?(:volume)
188         vol = info[:volume].to_i
189         vol_rm = vol.to_s_roman
190 else
191         errore "Il file di indice in \"%s\" non specifica il volume!" % cartella
192 end
193 if info.has_key?(:fasc)
194         num = info[:fasc].to_i
195         num_rm = num.to_s_roman
196 else
197         errore "Il file di indice in \"%s\" non specifica il fascicolo!" % cartella
198 end
199 if info.has_key?(:articoli)
200         articoli = info[:articoli]
201 else
202         errore "Il file di indice in \"%s\" non specifica alcun articolo!" % cartella
203 end
204
205 puts "Preparazione: Le Matematiche, volume #{vol_rm}, fascicolo #{num_rm}, anno #{anno}"
206
207 $yvn = <<EOS
208 \\gdef\\LM@Year{#{anno}}%
209 \\gdef\\LM@Vol{#{vol_rm}}%
210 \\gdef\\LM@Num{#{num_rm}}%
211 EOS
212
213 tex_sommario = 'sommario.tex'
214
215 puts info.inspect
216
217 $somm_begin = <<EOS
218 \\documentclass{lematema}
219 \\usepackage[latin1]{inputenc}
220 \\let\\maketitle\\relax
221 \\newif\\ifpag\\pagtrue
222 \\makeatletter
223 \\setbox\\@tempboxa\\hbox{pag}
224 \\newlength\\paglength
225 \\paglength\\wd\\@tempboxa
226 \\makeatother
227 \\newlength\\pnumlength
228
229 \\def\\articolo#1#2{%
230 \\hangindent0.8cm\\hangafter1\\noindent
231 #1\\dotfill &
232 \\parbox[b]{\\paglength}{\\ifpag pag.\\global\\pagfalse\\else\\hfil"\\hfil\\fi}
233 &\\hfil#2\\cr
234 }
235 \\begin{document}
236 \\pagestyle{empty}
237 \\makeatletter
238 \\renewcommand{\\@oddfoot}{%
239 \\parbox[t]{\\textwidth}{%
240 \\hrule\\medskip\\baselineskip11pt
241 \\centerline{Pubblicazione realizzata con il contributo finanziario}
242 \\centerline{dell'Universt\\`a degli Studi di Catania}
243 }}%
244 \\makeatother
245 \\centerline{\\Large S O M M A R I O}
246 \\vskip0.5cm\\relax
247 \\pnumlength\\textwidth
248 \\advance\\pnumlength-11cm\\relax
249 \\advance\\pnumlength-\\paglength\\relax
250 #{info[:small] ? "\\small" : ""}
251 \\begin{tabular*}{\\textwidth}{p{11cm}p{\\paglength}p{\\pnumlength}}
252 EOS
253
254 $somm_end = <<EOS
255 \\end{tabular*}
256 \\end{document}
257 EOS
258
259 tex_fasc = "le_matematiche_#{vol_rm}_#{num_rm}.tex"
260
261 $fasc_begin = <<EOS
262 \\documentclass{lematema}
263 \\usepackage[final]{pdfpages}
264 \\let\\maketitle\\relax
265
266 \\begin{document}
267 \\pagestyle{empty}
268 EOS
269
270 $fasc_end = <<EOS
271 \\end{document}
272 EOS
273
274 begin
275         $sommario = File.open(tex_sommario, 'w')
276         $sommario << $somm_begin
277 rescue
278         errore "Impossibile creare il sommario in \"%s\"" % cartella
279 end
280
281 begin
282         $fasc = File.open(tex_fasc, 'w')
283         $fasc << $fasc_begin
284 rescue
285         errore "Impossibile creare il fascicolo in \"%s\"" % cartella
286 end
287
288 articoli.each { |art|
289         puts "\n\n"
290         puts "=" * 80
291         puts "\n\n"
292         pagine = compila art
293         $pg += pagine
294         $fasc << "\\includepdf[fitpaper=true,pages=-]{#{art}}\n"
295         if $pg % 2 == 0
296                 $pg += 1
297                 $fasc << "\\null\\cleardoublepage\n"
298         end
299 }
300
301 puts "\n\n"
302 puts "=" * 80
303 puts "\n\n"
304
305 puts "Compilo il fascicolo . . ."
306 begin
307         $fasc << $fasc_end
308         $fasc.close
309         compile = system 'pdflatex', "-interaction=batchmode", tex_fasc
310         raise if not compile
311 rescue
312         errore "Errore durante la compilazione del fascicolo (\"%s\")" % tex_fasc
313 end
314
315 puts "Compilo il sommario . . ."
316
317 log_sommario = 'sommario.log'
318 begin
319         $sommario << $somm_end
320         $sommario.close
321         compile = system 'pdflatex', "-interaction=batchmode", tex_sommario
322         raise if not compile
323 rescue
324         errore "Errore durante la compilazione del sommario (\"%s\")" % tex_sommario
325 end
326
327 puts "Fatto!"