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