imposition 0.8.8.alpha
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/impostor +171 -0
- data/lib/imposition.rb +16 -0
- data/lib/imposition/clases.rb +360 -0
- data/lib/imposition/metodos.rb +695 -0
- metadata +126 -0
data/bin/impostor
ADDED
@@ -0,0 +1,171 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
begin
|
3
|
+
#require 'rubygems'
|
4
|
+
require 'imposition'
|
5
|
+
#METHODS
|
6
|
+
def input(nombre)
|
7
|
+
retorno=Hash.new
|
8
|
+
STDOUT.puts(nombre)
|
9
|
+
input=STDIN.gets
|
10
|
+
if input[0]==10 then #no input
|
11
|
+
retorno["numero"]=0.point
|
12
|
+
retorno["unidad"]="point"#default
|
13
|
+
return retorno
|
14
|
+
else
|
15
|
+
regex = /(\d+\.*\d*)\s*(\w*)/
|
16
|
+
split = regex.match(input)
|
17
|
+
if split!=nil then
|
18
|
+
retorno["numero"]=split[1].to_f
|
19
|
+
if split[2]=="" then
|
20
|
+
retorno["unidad"]="point"#default
|
21
|
+
else
|
22
|
+
retorno["unidad"]=input2alchemist(split[2])
|
23
|
+
end
|
24
|
+
return retorno
|
25
|
+
else
|
26
|
+
puts "la unidad de #{input} no es correcta"
|
27
|
+
input(nombre)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
#
|
32
|
+
def enBooklets()
|
33
|
+
STDOUT.puts("¿imponer en cuadernillos? (y/n)")
|
34
|
+
bookies=STDIN.gets.to_s
|
35
|
+
if bookies[0]==121 then#Y
|
36
|
+
return true
|
37
|
+
elsif bookies[0]==110 then#N
|
38
|
+
return false
|
39
|
+
else
|
40
|
+
enBooklets()
|
41
|
+
end
|
42
|
+
end
|
43
|
+
#
|
44
|
+
def exigePar(nX)
|
45
|
+
nX=input("nX:")
|
46
|
+
nX=nX["numero"]
|
47
|
+
if nX%2!=0 then
|
48
|
+
exigePar(nX)
|
49
|
+
end
|
50
|
+
return nX
|
51
|
+
end
|
52
|
+
#
|
53
|
+
def escalado(tipo)
|
54
|
+
if tipo=="horizontalmente" then
|
55
|
+
puts "no especifico ancho de pagina pero si ancho de pliego y numero de paginas por pliego "+tipo
|
56
|
+
else
|
57
|
+
puts "no especifico alto de pagina pero si alto de pliego y numero de paginas por pliego "+tipo
|
58
|
+
end
|
59
|
+
STDOUT.puts("¿escalar "+tipo+"? (y/n)")
|
60
|
+
escalar=STDIN.gets.to_s
|
61
|
+
if escalar[0]==121 then#Y
|
62
|
+
return true
|
63
|
+
elsif escalar[0]==110 then#N
|
64
|
+
return false
|
65
|
+
else
|
66
|
+
escalado(tipo)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
#
|
70
|
+
def todasPag(nPliegos, nX, nY, caben, tiene)
|
71
|
+
STDOUT.puts("el pdf tiene #{tiene.to_i} paginas, pero en #{nPliegos.to_i} de #{nX}x#{nY} caben #{caben.to_i} paginas ¿usar las del pdf? (y/n)")
|
72
|
+
escalar=STDIN.gets.to_s
|
73
|
+
if escalar[0]==121 then#Y
|
74
|
+
return true
|
75
|
+
elsif escalar[0]==110 then#N
|
76
|
+
return false
|
77
|
+
else
|
78
|
+
todasPag(nPliegos, nX, nY, caben, tiene)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
#
|
82
|
+
def reducirUltimo(cuadernillosPorCostura, paginasSobran, nCuad, sobranMenos)
|
83
|
+
puts "al ultimo grupo de #{cuadernillosPorCostura} cuadernillos le sobraran #{paginasSobran}p"
|
84
|
+
puts "podemos reducirlo a #{nCuad} cuadernillos, asi sobrarian #{sobranMenos}. ¿0K? (y/n)"
|
85
|
+
ok=STDIN.gets.to_s
|
86
|
+
if ok[0]==121 then#Y
|
87
|
+
return true
|
88
|
+
elsif ok[0]==110 then#N
|
89
|
+
return false
|
90
|
+
else
|
91
|
+
reducirUltimo(cuadernillosPorCostura, paginasSobran, nCuad, sobranMenos)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
########
|
96
|
+
#CONSOLA
|
97
|
+
#
|
98
|
+
entrada=ARGV.shift
|
99
|
+
$salida=ARGV.shift
|
100
|
+
check=Metodos.checksRun(entrada,$salida)
|
101
|
+
if check.instance_of? Clases::Mensaje then
|
102
|
+
puts check.mensaje
|
103
|
+
exit
|
104
|
+
end
|
105
|
+
#
|
106
|
+
puts "::::::::::::impostor::::::::::::"#blink blink
|
107
|
+
#
|
108
|
+
w_=input("w:")
|
109
|
+
h_=input("h:")
|
110
|
+
wP_=input("W:")
|
111
|
+
hP_=input("H:")
|
112
|
+
nX_=input("nX:")
|
113
|
+
nY_=input("nY:")
|
114
|
+
nPaginas_=input("nPaginas:")
|
115
|
+
nPliegos_=input("nPliegos:")
|
116
|
+
cuadernillos = enBooklets()
|
117
|
+
#
|
118
|
+
def recursivo(w_,h_,wP_,hP_,nX,nY,nPaginas,nPliegos,cuadernillos, preguntas)
|
119
|
+
impostor=Metodos.funcionar(w_,h_,wP_,hP_,nX,nY,nPaginas,nPliegos,cuadernillos,preguntas)
|
120
|
+
if impostor.preguntasOk then
|
121
|
+
if impostor.valido then
|
122
|
+
puts "::::::::::::mensajes:::::::::::::"#blink blink
|
123
|
+
impostor.mensajes.each do |mensaje|
|
124
|
+
puts mensaje.mensaje
|
125
|
+
end
|
126
|
+
else
|
127
|
+
impostor.errores().each do |error|
|
128
|
+
puts error.mensaje
|
129
|
+
end
|
130
|
+
puts "el programa no se ejecutara"
|
131
|
+
exit
|
132
|
+
end
|
133
|
+
else
|
134
|
+
if !impostor.preguntas["par"].ok then
|
135
|
+
puts impostor.preguntas["par"].mensaje
|
136
|
+
impostor.preguntas["par"].metodo(exigePar(nX))
|
137
|
+
recursivo(w_,h_,wP_,hP_,nX,nY,nPaginas,nPliegos,cuadernillos,impostor.preguntas)
|
138
|
+
elsif !impostor.preguntas["cXC"].ok then
|
139
|
+
puts impostor.preguntas["cXC"].mensaje
|
140
|
+
impostor.preguntas["cXC"].metodo(input("cXC:"))
|
141
|
+
recursivo(w_,h_,wP_,hP_,nX,nY,nPaginas,nPliegos,cuadernillos,impostor.preguntas)
|
142
|
+
elsif !impostor.preguntas["escaladoH"].ok then
|
143
|
+
puts !impostor.preguntas["escaladoH"].mensaje
|
144
|
+
impostor.preguntas["escaladoH"].metodo(escalado(impostor.preguntas["escaladoH"].tipo))
|
145
|
+
impostor.preguntas["escaladoH"].ok=true
|
146
|
+
recursivo(w_,h_,wP_,hP_,nX,nY,nPaginas,nPliegos,cuadernillos,impostor.preguntas)
|
147
|
+
elsif !impostor.preguntas["escaladoV"].ok then
|
148
|
+
puts impostor.preguntas["escaladoV"].mensaje
|
149
|
+
impostor.preguntas["escaladoV"].metodo(escalado(impostor.preguntas["escaladoV"].tipo))
|
150
|
+
recursivo(w_,h_,wP_,hP_,nX,nY,nPaginas,nPliegos,cuadernillos,impostor.preguntas)
|
151
|
+
elsif !impostor.preguntas["todasPag"].ok then
|
152
|
+
puts impostor.preguntas["todasPag"].mensaje
|
153
|
+
impostor.preguntas["todasPag"].metodo(todasPag(impostor.preguntas["todasPag"].nPliegos, impostor.preguntas["todasPag"].nX, impostor.preguntas["todasPag"].nY, impostor.preguntas["todasPag"].caben, impostor.preguntas["todasPag"].tiene))
|
154
|
+
recursivo(w_,h_,wP_,hP_,nX,nY,nPaginas,nPliegos,cuadernillos,impostor.preguntas)
|
155
|
+
elsif !impostor.preguntas["reducir"].ok then
|
156
|
+
puts impostor.preguntas["reducir"].mensaje
|
157
|
+
impostor.preguntas["reducir"].metodo(reducirUltimo(impostor.preguntas["reducir"].cuadernillosPorCostura, impostor.preguntas["reducir"].paginasSobran, impostor.preguntas["reducir"].nCuad, impostor.preguntas["reducir"].sobranMenos))
|
158
|
+
recursivo(w_,h_,wP_,hP_,nX,nY,nPaginas,nPliegos,cuadernillos,impostor.preguntas)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
recursivo(w_,h_,wP_,hP_,nX_,nY_,nPaginas_,nPliegos_,cuadernillos, nil)
|
163
|
+
#
|
164
|
+
puts "::::::::::::Game Over::::::::::::"#blink blink
|
165
|
+
ensure
|
166
|
+
#limpio todo, aunque se caiga
|
167
|
+
if $dir!=nil then
|
168
|
+
`rm -r #{$dir}`
|
169
|
+
end
|
170
|
+
end
|
171
|
+
#GAME OVER
|
data/lib/imposition.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#GEMA
|
2
|
+
require 'imposition/clases'
|
3
|
+
require 'imposition/metodos'
|
4
|
+
#
|
5
|
+
$requerimientos=Hash.new
|
6
|
+
$requerimientos["pdflatex"]="pdflatex"
|
7
|
+
$requerimientos["pdfinfo"]="pdfinfo"
|
8
|
+
#
|
9
|
+
work="/tmp/impostor"
|
10
|
+
#
|
11
|
+
check=Metodos.checksCompile($requerimientos,work)
|
12
|
+
if check.instance_of? Clases::Mensaje then
|
13
|
+
puts check.mensaje
|
14
|
+
exit#TODO raise
|
15
|
+
end
|
16
|
+
|
@@ -0,0 +1,360 @@
|
|
1
|
+
#Ruby without rails
|
2
|
+
module Clases
|
3
|
+
|
4
|
+
class Imposicion
|
5
|
+
attr_accessor :w, :w_, :wP, :wP_, :nX, :wReal, :h, :h_, :hP, :hP_, :nY, :hReal, :size, :cuadernillos, :nPaginas, :nPliegos, :nPaginasReal, :cuadernillosPorCostura, :bookletz
|
6
|
+
def initialize(w_,h_,wP_,hP_,nX,nY,nPaginas,nPliegos,cuadernillos)
|
7
|
+
@w_=w_
|
8
|
+
@h_=h_
|
9
|
+
@wP_=wP_
|
10
|
+
@hP_=hP_
|
11
|
+
@nX=nX
|
12
|
+
@nY=nY
|
13
|
+
@nPaginas=nPaginas
|
14
|
+
@nPliegos=nPliegos
|
15
|
+
@cuadernillos=cuadernillos
|
16
|
+
#con unidad
|
17
|
+
@w=@w_["numero"].send(@w_["unidad"])
|
18
|
+
@h=@h_["numero"].send(@h_["unidad"])
|
19
|
+
@wP=@wP_["numero"].send(@wP_["unidad"])
|
20
|
+
@hP=@hP_["numero"].send(@hP_["unidad"])
|
21
|
+
#sin unidad
|
22
|
+
@nX=@nX["numero"].to_f.floor
|
23
|
+
@nY=@nY["numero"].to_f.floor
|
24
|
+
@nPaginas=@nPaginas["numero"].to_f.floor
|
25
|
+
@nPliegos=@nPliegos["numero"].to_f.floor
|
26
|
+
end
|
27
|
+
def to_s
|
28
|
+
nXm=@nX
|
29
|
+
if @cuadernillos then
|
30
|
+
nXm*=2
|
31
|
+
end
|
32
|
+
str=":::::::::::::::vars::::::::::::::\n"
|
33
|
+
str+="nX:"+nXm.to_s+"\n"
|
34
|
+
str+="nY:"+@nY.to_s+"\n"
|
35
|
+
str+="nPaginas:"+@nPaginas.to_s+"\n"
|
36
|
+
str+="nPliegos:"+@nPliegos.to_s+"\n"
|
37
|
+
str+="ancho:"+@w.to_s+" "+@w_["unidad"]+"\n"
|
38
|
+
str+="alto:"+@h.to_s+" "+@h_["unidad"]+"\n"
|
39
|
+
str+="anchoPliego:"+@wP.to_s+" "+@wP_["unidad"]+"\n"
|
40
|
+
str+="altoPliego:"+@hP.to_s+" "+@hP_["unidad"]+"\n"
|
41
|
+
return str
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class Posicion
|
46
|
+
def initialize(mC,mP,t)
|
47
|
+
@mC=mC
|
48
|
+
@mP=mP
|
49
|
+
@t=t
|
50
|
+
end
|
51
|
+
attr_reader :mC, :mP, :t
|
52
|
+
def to_s
|
53
|
+
"mC=#{@mC} mP=#{@mP} t=#{@t}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
#
|
57
|
+
class Coordenada
|
58
|
+
def initialize(x,y)
|
59
|
+
@x=x
|
60
|
+
@y=y
|
61
|
+
end
|
62
|
+
attr_reader :x, :y
|
63
|
+
def to_s
|
64
|
+
"x=#{@x} y=#{@y}"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
#
|
68
|
+
class Mix
|
69
|
+
def initialize(n,x,y,t)
|
70
|
+
@n=n
|
71
|
+
@x=x
|
72
|
+
@y=y
|
73
|
+
@t=t
|
74
|
+
end
|
75
|
+
attr_reader :n, :x, :y, :t
|
76
|
+
def to_s
|
77
|
+
"n=#{@n}, x=#{@x}, y=#{@y}, t=#{@t}"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
class Mensaje
|
82
|
+
attr_reader :level, :mensaje
|
83
|
+
def initialize(level, mensaje)
|
84
|
+
@level=level #1=info, 2=warn, 3=error
|
85
|
+
@mensaje=mensaje
|
86
|
+
end
|
87
|
+
def to_s
|
88
|
+
if @level==1 then
|
89
|
+
@retorno="info: "
|
90
|
+
elsif @level==2 then
|
91
|
+
@retorno="Warn: "
|
92
|
+
elsif @level==3 then
|
93
|
+
@retorno="ERROR: "
|
94
|
+
end
|
95
|
+
@retorno+=@mensaje
|
96
|
+
return @retorno
|
97
|
+
end
|
98
|
+
def ==(msg)
|
99
|
+
return (!(msg.instance_of? MensajeDato) and !(msg.instance_of? MensajeMedida) and !(msg.instance_of? MensajeTiempo) and !(msg.instance_of? MensajeLadoLado) and @level===msg.level)# and @mensaje==msg.mensaje)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
#
|
103
|
+
class MensajeDato < Mensaje
|
104
|
+
attr_reader :tipo, :numero
|
105
|
+
def initialize(level, tipo, numero)
|
106
|
+
@tipo=tipo
|
107
|
+
@numero=numero
|
108
|
+
@mensaje=deducirMensaje(tipo,level,numero)
|
109
|
+
super(level, @mensaje)
|
110
|
+
end
|
111
|
+
def ==(msg)
|
112
|
+
#super(?)
|
113
|
+
return (msg.instance_of? MensajeDato and @level==msg.level and @tipo==msg.tipo and @numero==msg.numero)# and @mensaje==msg.mensaje)
|
114
|
+
end
|
115
|
+
def deducirMensaje(tipo, level, numero)
|
116
|
+
if tipo=="horizontal" then
|
117
|
+
if level==1 then#info
|
118
|
+
if numero==1 then
|
119
|
+
return "se calcula la cantidad de paginas por pliego horizontalmente en base al ancho del pliego y el de la pagina"
|
120
|
+
elsif numero==2 then
|
121
|
+
return "se calcula el ancho del pliego en base al de la pagina y la cantidad de paginas por pliego horizontalmente"
|
122
|
+
elsif numero==3 then
|
123
|
+
return "se calcula el ancho de la pagina en base al del pliego y la cantidad de paginas por pliego horizontalmente"
|
124
|
+
elsif numero==4 then
|
125
|
+
return "se toma el ancho real de la pagina"
|
126
|
+
end
|
127
|
+
elsif level==3 then#error
|
128
|
+
if numero==1 then
|
129
|
+
return "ha especificado ancho de pagina pero no de pliego ni cuantas paginas por pliego horizontalmente"
|
130
|
+
elsif numero==2 then
|
131
|
+
return "ha especificado ancho de pliego pero no de pagina ni cuantas paginas por pliego horizontalmente"
|
132
|
+
elsif numero==3 then
|
133
|
+
return "ha especificado cuantas paginas por pliego horizontalmente pero no ancho de pagina ni de pliego"
|
134
|
+
elsif numero==4 then
|
135
|
+
return "no ha especificado ni ancho de pagina, ni ancho de pliego, ni cuantos paginas por pliego horizontalmente"
|
136
|
+
elsif numero==5 then
|
137
|
+
return "no cabe ninguna pagina horizontalmente"
|
138
|
+
end
|
139
|
+
end
|
140
|
+
elsif tipo=="vertical" then
|
141
|
+
if level==1 then#info
|
142
|
+
if numero==1 then
|
143
|
+
return "se calcula la cantidad de paginas por pliego verticalmente en base al alto del pliego y el de la pagina"
|
144
|
+
elsif numero==2 then
|
145
|
+
return "se calcula el alto del pliego en base al de la pagina y la cantidad de paginas por pliego verticalmente"
|
146
|
+
elsif numero==3 then
|
147
|
+
return "se calcula el alto de la pagina en base al del pliego y la cantidad de paginas por pliego verticalmente"
|
148
|
+
elsif numero==4 then
|
149
|
+
return "se toma el alto real de la pagina"
|
150
|
+
end
|
151
|
+
elsif level==3 then#error
|
152
|
+
if numero==1 then
|
153
|
+
return "ha especificado alto de pagina pero no de pliego ni cuantas paginas por pliego verticalmente"
|
154
|
+
elsif numero==2 then
|
155
|
+
return "ha especificado alto de pliego pero no de pagina ni cuantas paginas por pliego verticalmente"
|
156
|
+
elsif numero==3 then
|
157
|
+
return "ha especificado cuantas paginas por pliego verticalmente pero no alto de pagina ni de pliego"
|
158
|
+
elsif numero==4 then
|
159
|
+
return "no ha especificado ni alto de pagina, ni alto de pliego, ni cuantos paginas por pliego verticalmente"
|
160
|
+
elsif numero==5 then
|
161
|
+
return "no cabe ninguna pagina verticalmente"
|
162
|
+
end
|
163
|
+
end
|
164
|
+
elsif tipo=="paginas" then
|
165
|
+
if level==1 then
|
166
|
+
if numero==1 then
|
167
|
+
return "se calcula el numero de paginas a partir del numero de pliegos y de la cantidad de paginas por pliego"
|
168
|
+
elsif numero==2 then
|
169
|
+
return "se calcula el numero de pliegos a partir del numero de paginas y de la cantidad de paginas por pliego"
|
170
|
+
elsif numero==3 then
|
171
|
+
return "se usan todas las paginas del pdf"
|
172
|
+
end
|
173
|
+
elsif level==3 then
|
174
|
+
if numero==1 then
|
175
|
+
return "esta especificando mas paginas de las que tiene el documento"
|
176
|
+
else
|
177
|
+
return "no ha especificado numero de paginas ni de pliegos"
|
178
|
+
end
|
179
|
+
end
|
180
|
+
elsif tipo=="pliegos" then
|
181
|
+
if level==1 then
|
182
|
+
return "se toman los #{numero} pliegos necesarios"
|
183
|
+
elsif level==2 then
|
184
|
+
return "sobran #{numero} pliegos"
|
185
|
+
elsif level==3 then
|
186
|
+
return "faltan #{numero} pliegos"
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
end
|
191
|
+
end
|
192
|
+
#
|
193
|
+
class MensajeMedida < Mensaje
|
194
|
+
def initialize(level, tipo, args)
|
195
|
+
@mensaje=deducirMensaje(level, tipo, args)
|
196
|
+
super(level, @mensaje)
|
197
|
+
end
|
198
|
+
def ==(msg)
|
199
|
+
return (msg.instance_of? MensajeMedida and @level==msg.level and @tipo==msg.tipo) #!args ?
|
200
|
+
end
|
201
|
+
def deducirMensaje(level, tipo, args)
|
202
|
+
if tipo=="horizontal" then
|
203
|
+
if level==3 then
|
204
|
+
return "no caben #{args[0]} paginas de #{args[1]["numero"].to_s+args[1]["unidad"]} de ancho en un pliego de #{args[2]["numero"].to_s+args[2]["unidad"]}"
|
205
|
+
elsif level==2 then
|
206
|
+
return "sobra #{args[0].to_s+args[1]} de ancho"
|
207
|
+
end
|
208
|
+
elsif tipo=="vertical" then
|
209
|
+
if level==3 then
|
210
|
+
return "no caben #{args[0]} paginas de #{args[1]["numero"].to_s+args[1]["unidad"]} de alto en un pliego de #{args[2]["numero"].to_s+args[2]["unidad"]}"
|
211
|
+
elsif level==2 then
|
212
|
+
return "sobra #{args[0].to_s+args[1]} de alto"
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
#
|
218
|
+
class MensajeTiempo < Mensaje
|
219
|
+
attr_reader :tipo
|
220
|
+
def initialize(tipo,tiempo)
|
221
|
+
@tiempo=tiempo
|
222
|
+
@level=1
|
223
|
+
if tipo==1 then#booklets
|
224
|
+
@mensaje="::::::::::::booklets:::::::::::::\n"#blink blink
|
225
|
+
@mensaje+="booklets: "
|
226
|
+
elsif tipo==2 then
|
227
|
+
@mensaje="::::::::::::cut&Stack::::::::::::\n"#blink blink
|
228
|
+
@mensaje+="cut&Stack: "
|
229
|
+
end
|
230
|
+
@mensaje+=@tiempo.to_s+" segundos"
|
231
|
+
@tiempo=tiempo
|
232
|
+
super(level,mensaje)
|
233
|
+
end
|
234
|
+
def ==(msg)
|
235
|
+
return (msg.instance_of? MensajeTiempo and @tipo==msg.tipo)
|
236
|
+
end
|
237
|
+
end
|
238
|
+
#
|
239
|
+
class MensajeLadoLado < Mensaje
|
240
|
+
attr_reader :nP
|
241
|
+
def initialize(nP)
|
242
|
+
@nP=nP
|
243
|
+
@mensaje="como son cuadernillos lado y lado los pliegos no pueden ser impares, se toman #{@nP}+1"
|
244
|
+
super(1,@mensaje)
|
245
|
+
end
|
246
|
+
def ==(msg)
|
247
|
+
return (msg.instance_of? MensajeLadoLado and @nP==msg.nP)
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
class Pregunta
|
252
|
+
attr_accessor :ok, :yn, :mensaje
|
253
|
+
def initialize(mensaje)
|
254
|
+
@mensaje=mensaje
|
255
|
+
end
|
256
|
+
def metodo()
|
257
|
+
end
|
258
|
+
end
|
259
|
+
#
|
260
|
+
#TODO sugerencia si + o -
|
261
|
+
class PreguntaExigePar < Pregunta
|
262
|
+
attr_accessor :nX
|
263
|
+
def initialize(nX)
|
264
|
+
@nX=nX
|
265
|
+
@mensaje="para imponer en cuadernillos tienen que caber horizontalmente en numeros pares pero ud especifico nX:#{@nX}."
|
266
|
+
@ok=false
|
267
|
+
end
|
268
|
+
def metodo(nX)
|
269
|
+
@nX=nX.to_i
|
270
|
+
@ok=true
|
271
|
+
end
|
272
|
+
end
|
273
|
+
#
|
274
|
+
#TODO COSTURAS en total
|
275
|
+
class PreguntaCXC < Pregunta
|
276
|
+
attr_reader :cXC
|
277
|
+
def initialize()
|
278
|
+
@mensaje="cXC - cuadernillos por costura (0->todos unos dentro de otros, 1->todos uno al lado de otro o n-> de a n cuadernillos uno dentro de otro)"
|
279
|
+
end
|
280
|
+
def metodo(cXC)
|
281
|
+
@cXC=cXC["numero"].to_i
|
282
|
+
@ok=true
|
283
|
+
end
|
284
|
+
end
|
285
|
+
#
|
286
|
+
class PreguntaEscalado < Pregunta
|
287
|
+
attr_accessor :tipo
|
288
|
+
def initialize(tipo)
|
289
|
+
@mensaje="en duro"
|
290
|
+
@tipo=tipo
|
291
|
+
end
|
292
|
+
def metodo(yn)
|
293
|
+
@yn=yn
|
294
|
+
@ok=true
|
295
|
+
end
|
296
|
+
end
|
297
|
+
#
|
298
|
+
class PreguntaTodasPag < Pregunta
|
299
|
+
attr_accessor :nPliegos, :nX, :nY, :caben, :tiene
|
300
|
+
def initialize(nPliegos, nX, nY, caben, tiene)
|
301
|
+
@nPliegos=nPliegos
|
302
|
+
@nX=nX
|
303
|
+
@nY=nY
|
304
|
+
@caben=caben
|
305
|
+
@tiene=tiene
|
306
|
+
end
|
307
|
+
def metodo(yn)
|
308
|
+
@yn=yn
|
309
|
+
@ok=true
|
310
|
+
end
|
311
|
+
end
|
312
|
+
#
|
313
|
+
class PreguntaReducir < Pregunta
|
314
|
+
attr_reader :q, :cuadernillosPorCostura, :paginasSobran, :nCuad, :sobranMenos
|
315
|
+
def initialize(cuadernillosPorCostura, paginasSobran, nCuad, sobranMenos, q)
|
316
|
+
@mensaje="en duro"
|
317
|
+
@cuadernillosPorCostura=cuadernillosPorCostura
|
318
|
+
@paginasSobran=paginasSobran
|
319
|
+
@nCuad=nCuad
|
320
|
+
@sobranMenos=sobranMenos
|
321
|
+
@q=q
|
322
|
+
super(@mensaje)
|
323
|
+
end
|
324
|
+
def metodo(yn)
|
325
|
+
@yn=yn
|
326
|
+
@ok=true
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
class RespuestaImpostor
|
331
|
+
attr_accessor :mensajes, :preguntas
|
332
|
+
def initialize(preguntas,mensajes)
|
333
|
+
@preguntas=preguntas
|
334
|
+
@mensajes=mensajes
|
335
|
+
end
|
336
|
+
def preguntasOk()
|
337
|
+
todoOk=true
|
338
|
+
@preguntas.each do |k,v|
|
339
|
+
if v!=nil and !v.ok then
|
340
|
+
todoOk=false
|
341
|
+
end
|
342
|
+
end
|
343
|
+
return todoOk
|
344
|
+
end
|
345
|
+
def errores()
|
346
|
+
errores=[]
|
347
|
+
@mensajes.each do |mensaje|
|
348
|
+
if mensaje.level==3 then
|
349
|
+
errores.push(mensaje)
|
350
|
+
end
|
351
|
+
end
|
352
|
+
return errores
|
353
|
+
end
|
354
|
+
def valido()
|
355
|
+
return errores().size==0
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
end#fin módulo
|
360
|
+
|
@@ -0,0 +1,695 @@
|
|
1
|
+
module Metodos
|
2
|
+
|
3
|
+
#WORK
|
4
|
+
def funcionar(w_,h_,wP_,hP_,nX,nY,nPaginas,nPliegos,cuadernillos,preguntas)
|
5
|
+
impostor=Clases::Imposicion.new(w_,h_,wP_,hP_,nX,nY,nPaginas,nPliegos,cuadernillos)
|
6
|
+
pdfinfo(impostor, $temp)
|
7
|
+
retorno=validacion(impostor, preguntas)
|
8
|
+
if retorno.preguntasOk then
|
9
|
+
retorno.mensajes.push(Clases::Mensaje.new(1,impostor.to_s))
|
10
|
+
if impostor.cuadernillos then
|
11
|
+
retorno.mensajes.push(imponerBooklet(impostor, $temp))
|
12
|
+
end
|
13
|
+
retorno.mensajes.push(imponerStack(impostor, $temp))
|
14
|
+
#lo devuelvo
|
15
|
+
if $salida != nil then
|
16
|
+
entrada=$salida
|
17
|
+
end
|
18
|
+
FileUtils.mv($dir+"/"+"cutStack.pdf", entrada)
|
19
|
+
end
|
20
|
+
return retorno
|
21
|
+
end
|
22
|
+
|
23
|
+
def checksCompile(requerimientos, work)
|
24
|
+
#paquetes
|
25
|
+
$requerimientos.each do |k,v|
|
26
|
+
`which #{v}`
|
27
|
+
if !$?.success? then
|
28
|
+
return Clases::Mensaje.new(3,"#{v} no es ejecutable")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
#archivos
|
32
|
+
#probamos que exista el directorio de trabajo
|
33
|
+
if File.exists?(work) then
|
34
|
+
#y que sea escribible
|
35
|
+
if File.writable?(work) and File.writable_real?(work) then
|
36
|
+
#creo mi directorio
|
37
|
+
$dir=work+"/"+UUIDTools::UUID.random_create
|
38
|
+
Dir.mkdir($dir)
|
39
|
+
$codeDir = Dir.pwd
|
40
|
+
else
|
41
|
+
return Clases::Mensaje.new(3,"el directorio de trabajo "+work+" no se puede escribir")
|
42
|
+
end
|
43
|
+
else
|
44
|
+
return Clases::Mensaje.new(3,"el directorio de trabajo "+work+ " no existe")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def checksRun(entrada, salida)
|
49
|
+
#la entrada
|
50
|
+
if entrada != nil then
|
51
|
+
if File.file?(entrada) then
|
52
|
+
if File.owned?(entrada) then
|
53
|
+
busca = /.*(.pdf)/
|
54
|
+
if busca.match(File.basename(entrada)) then
|
55
|
+
$temp=$dir+"/"+File.basename(entrada)#me lo llevo
|
56
|
+
FileUtils.cp(entrada, $temp)
|
57
|
+
else
|
58
|
+
return Clases::Mensaje.new(3,"el archivo "+entrada+" no es pdf")
|
59
|
+
end
|
60
|
+
else
|
61
|
+
return Clases::Mensaje.new(3,"el archivo "+entrada+" no es mío")
|
62
|
+
end
|
63
|
+
else
|
64
|
+
return Clases::Mensaje.new(3,entrada+" no es un archivo")
|
65
|
+
end
|
66
|
+
else
|
67
|
+
return Clases::Mensaje.new(3,"no ha especificado archivo a imponer")
|
68
|
+
end
|
69
|
+
#y la salida, de haberla
|
70
|
+
if $salida!=nil then
|
71
|
+
#if File.exists?(salida) then #TODO crearla si es escribible
|
72
|
+
salidaDir=File.dirname($salida)
|
73
|
+
if !File.writable?(salidaDir) or !File.writable_real?(salidaDir) then
|
74
|
+
return Clases::Mensaje.new(3,"el directorio de salida "+$salida+" no se puede escribir")
|
75
|
+
end
|
76
|
+
#else
|
77
|
+
# puts salida+ " no existe"
|
78
|
+
# exit
|
79
|
+
#end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
#########
|
84
|
+
module_function :funcionar, :checksCompile, :checksRun
|
85
|
+
#########
|
86
|
+
|
87
|
+
def self.pdfinfo(impostor, temp)
|
88
|
+
Dir.chdir($dir)
|
89
|
+
pdfinfo = `#{$requerimientos["pdfinfo"]} -box #{temp}`
|
90
|
+
impostor.nPaginasReal=paginasdelpdf(pdfinfo)
|
91
|
+
impostor.size=Metodos.pagesize(pdfinfo)
|
92
|
+
impostor.wReal=impostor.size["ancho"]
|
93
|
+
impostor.hReal=impostor.size["alto"]
|
94
|
+
Dir.chdir($codeDir)
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.paginasdelpdf(pdfinfo)
|
98
|
+
info = pdfinfo.chomp
|
99
|
+
busca = /pages\s*\:\s*(\d+)/moi
|
100
|
+
pags = busca.match(info)
|
101
|
+
paginas = pags[1]
|
102
|
+
return paginas.to_i
|
103
|
+
end
|
104
|
+
|
105
|
+
#tamaño de página
|
106
|
+
def self.pagesize(pdfinfo)
|
107
|
+
info = pdfinfo.chomp
|
108
|
+
busca = /Page size\s*\:\s*([\d\.]+)\s*x\s*([\d\.]+).*/
|
109
|
+
pags = busca.match(info)
|
110
|
+
retorno=Hash.new
|
111
|
+
splitted=pags[0].split(" ")
|
112
|
+
unidad=splitted[5]
|
113
|
+
#unidades pdfinfo 2 alchemist
|
114
|
+
if unidad=="pts" then
|
115
|
+
unidad="point"
|
116
|
+
#TODO elsif...
|
117
|
+
else#default
|
118
|
+
unidad="point"
|
119
|
+
end
|
120
|
+
retorno["unidad"]=unidad
|
121
|
+
#con unidad
|
122
|
+
retorno["ancho"]=pags[1].to_f.send(unidad)
|
123
|
+
retorno["alto"]=pags[2].to_f.send(unidad)
|
124
|
+
if splitted[6]!=nil then
|
125
|
+
retorno["nombre"]=splitted[6].delete("(").delete(")")
|
126
|
+
end
|
127
|
+
return retorno
|
128
|
+
end
|
129
|
+
|
130
|
+
def self.imponerStack(impostor, temp)
|
131
|
+
|
132
|
+
wPC=pdflatexUnit(impostor.wP, impostor.wP_["unidad"])
|
133
|
+
impostor.wP=wPC[0]
|
134
|
+
impostor.wP_["unidad"]=wPC[1]
|
135
|
+
hPC=pdflatexUnit(impostor.hP, impostor.hP_["unidad"])
|
136
|
+
impostor.hP=hPC[0]
|
137
|
+
impostor.hP_["unidad"]=hPC[1]
|
138
|
+
wC=pdflatexUnit(impostor.w, impostor.w_["unidad"])
|
139
|
+
impostor.w=wC[0]
|
140
|
+
impostor.w_["unidad"]=wC[1]
|
141
|
+
hC=pdflatexUnit(impostor.h, impostor.h_["unidad"])
|
142
|
+
impostor.h=hC[0]
|
143
|
+
impostor.h_["unidad"]=hC[1]
|
144
|
+
|
145
|
+
#las paginas que no existen se dejan en blanco
|
146
|
+
cS=cutStack(impostor.nX,impostor.nY,impostor.nPaginas,impostor.nPliegos,impostor.w.to_f,impostor.h.to_f)
|
147
|
+
for i in 0...cS.size
|
148
|
+
if cS[i].to_i > impostor.nPaginasReal then
|
149
|
+
cS[i]="{}"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
cS=cS.join(",")
|
153
|
+
|
154
|
+
cutted=$dir+"/"+"cutStack.tex"
|
155
|
+
File.open(cutted, 'w') do |cutStack|
|
156
|
+
cutStack.puts "\\documentclass{report}"
|
157
|
+
cutStack.puts "\\usepackage{pdfpages}"
|
158
|
+
cutStack.puts "\\usepackage{geometry}"
|
159
|
+
cutStack.puts "\\geometry{"
|
160
|
+
cutStack.puts "papersize={#{impostor.wP}#{impostor.wP_["unidad"]},#{impostor.hP}#{impostor.hP_["unidad"]}},"
|
161
|
+
cutStack.puts "left=0mm,"#posibilidad de márgenes
|
162
|
+
cutStack.puts "right=0mm,"
|
163
|
+
cutStack.puts "top=0mm,"
|
164
|
+
cutStack.puts "bottom=0mm,"
|
165
|
+
cutStack.puts "ignoreall,"
|
166
|
+
cutStack.puts "headsep=0mm,"
|
167
|
+
cutStack.puts "headheight=0mm,"
|
168
|
+
cutStack.puts "foot=0mm,"
|
169
|
+
cutStack.puts "marginpar=0mm"
|
170
|
+
cutStack.puts "}"
|
171
|
+
cutStack.puts "\\begin{document}"
|
172
|
+
cutStack.puts "\\includepdf[pages={#{cS}},nup=#{impostor.nX}x#{impostor.nY},noautoscale, frame, width=#{impostor.w}#{impostor.w_["unidad"]}, height=#{impostor.h}#{impostor.h_["unidad"]}]{#{temp}}"
|
173
|
+
cutStack.puts "\\end{document}"
|
174
|
+
end
|
175
|
+
|
176
|
+
#LaTeX
|
177
|
+
Dir.chdir($dir)
|
178
|
+
tIni=Time.now
|
179
|
+
pdflatex=`#{$requerimientos["pdflatex"]} #{cutted}`
|
180
|
+
tFin=Time.now
|
181
|
+
t=tFin-tIni
|
182
|
+
Dir.chdir($codeDir)
|
183
|
+
|
184
|
+
#retorno
|
185
|
+
return Clases::MensajeTiempo.new(2,t)
|
186
|
+
end
|
187
|
+
|
188
|
+
#TODO 1 sola vez pdflatex?
|
189
|
+
|
190
|
+
def self.imponerBooklet(impostor, archivo)
|
191
|
+
#unidades latex
|
192
|
+
wC=pdflatexUnit(impostor.w_["numero"], impostor.w_["unidad"])
|
193
|
+
impostor.w=wC[0]
|
194
|
+
impostor.w_["unidad"]=wC[1]
|
195
|
+
hC=pdflatexUnit(impostor.h_["numero"], impostor.h_["unidad"])
|
196
|
+
impostor.h=hC[0]
|
197
|
+
impostor.h_["unidad"]=hC[1]
|
198
|
+
|
199
|
+
wDummy=impostor.w_["numero"].to_f#bug alchemist
|
200
|
+
pierpa=$dir+"/"+"booKlet.tex"
|
201
|
+
File.open(pierpa, 'w') do |booklet|
|
202
|
+
booklet.puts "\\documentclass{report}"
|
203
|
+
booklet.puts "\\usepackage{pdfpages}"
|
204
|
+
booklet.puts "\\usepackage{geometry}"
|
205
|
+
booklet.puts "\\geometry{"
|
206
|
+
booklet.puts "papersize={#{impostor.w_["numero"]}#{impostor.h_["unidad"]},#{impostor.h_["numero"]}#{impostor.h_["unidad"]}},"
|
207
|
+
booklet.puts "left=0mm,"#posibilidad de márgenes
|
208
|
+
booklet.puts "right=0mm,"
|
209
|
+
booklet.puts "top=0mm,"
|
210
|
+
booklet.puts "bottom=0mm,"
|
211
|
+
booklet.puts "ignoreall,"
|
212
|
+
booklet.puts "headsep=0mm,"
|
213
|
+
booklet.puts "headheight=0mm,"
|
214
|
+
booklet.puts "foot=0mm,"
|
215
|
+
booklet.puts "marginpar=0mm"
|
216
|
+
booklet.puts "}"
|
217
|
+
booklet.puts "\\begin{document}"
|
218
|
+
booklet.puts "\\includepdf[pages={#{impostor.bookletz.join(",")}},nup=2x1,noautoscale,width=#{wDummy/2}#{impostor.w_["unidad"]}, height=#{impostor.h_["numero"]}#{impostor.h_["unidad"]}]{#{archivo}}"
|
219
|
+
booklet.puts "\\end{document}"
|
220
|
+
end
|
221
|
+
#LaTeX
|
222
|
+
Dir.chdir($dir)
|
223
|
+
tIni=Time.now
|
224
|
+
pdflatex=`#{$requerimientos["pdflatex"]} #{pierpa}`
|
225
|
+
tFin=Time.now
|
226
|
+
t=tFin-tIni
|
227
|
+
Dir.chdir($codeDir)
|
228
|
+
#lo devuelvo
|
229
|
+
FileUtils.mv($dir+"/"+"booKlet.pdf", archivo)
|
230
|
+
#retorno
|
231
|
+
return Clases::MensajeTiempo.new(1,t)
|
232
|
+
end
|
233
|
+
|
234
|
+
def self.myPlacePDF(nX,nY,nPaginas,nPliegos)
|
235
|
+
myCounter=1 #numero de pagina
|
236
|
+
myPosition=0 #posicion en las coordenadas
|
237
|
+
@Transfer=0 #pliego
|
238
|
+
arreglo=[]
|
239
|
+
while (myCounter!=nPaginas+1) do
|
240
|
+
#USO
|
241
|
+
pos=Clases::Posicion.new(myCounter, myPosition, @Transfer)
|
242
|
+
arreglo.push(pos)
|
243
|
+
#NEXT
|
244
|
+
@Transfer+=1
|
245
|
+
if myCounter%2==0 then
|
246
|
+
myPosition-=2
|
247
|
+
end
|
248
|
+
myPosition+=1
|
249
|
+
if @Transfer==nPliegos then
|
250
|
+
@Transfer=0
|
251
|
+
myPosition+=2
|
252
|
+
end
|
253
|
+
myCounter+=1
|
254
|
+
end
|
255
|
+
return arreglo
|
256
|
+
end
|
257
|
+
|
258
|
+
#TODO podria eliminar w y h haciendo la comparacion en base a n y k?
|
259
|
+
def self.getCoordinates(nX,nY,w,h)
|
260
|
+
|
261
|
+
coordenadas=[]
|
262
|
+
#posibilidad de usar márgenes
|
263
|
+
x0=0
|
264
|
+
y0=0
|
265
|
+
xN=x0+w*(nX-1)
|
266
|
+
|
267
|
+
i=0
|
268
|
+
k=0#posicion en
|
269
|
+
n=0#fila
|
270
|
+
while(i<nX*nY) do
|
271
|
+
#USO
|
272
|
+
coordenadas.insert(2*i, Clases::Coordenada.new(x0+k*w,y0+n*h))
|
273
|
+
coordenadas.insert(2*i+1, Clases::Coordenada.new(xN-k*w,y0+n*h))
|
274
|
+
#NEXT
|
275
|
+
k+=1
|
276
|
+
if k==nX then
|
277
|
+
k=0
|
278
|
+
n+=1
|
279
|
+
end
|
280
|
+
i+=1
|
281
|
+
end
|
282
|
+
return coordenadas
|
283
|
+
end
|
284
|
+
|
285
|
+
def self.ordenar(mix)
|
286
|
+
for j in 0...mix.length
|
287
|
+
for k in 0...mix.length
|
288
|
+
if mix[j].t>mix[k].t and j<k then #si es de un pliego mayor
|
289
|
+
temp=mix[j]
|
290
|
+
mix[j]=mix[k]
|
291
|
+
mix[k]=temp
|
292
|
+
elsif mix[j].t==mix[k].t then #si es del mismo pliego
|
293
|
+
if mix[j].y>mix[k].y and j<k then#si es de una fila mayor
|
294
|
+
temp=mix[j]
|
295
|
+
mix[j]=mix[k]
|
296
|
+
mix[k]=temp
|
297
|
+
elsif mix[j].y==mix[k].y then #si es de la misma
|
298
|
+
if mix[j].x>mix[k].x and j<k then #si esta despues
|
299
|
+
temp=mix[j]
|
300
|
+
mix[j]=mix[k]
|
301
|
+
mix[k]=temp
|
302
|
+
end
|
303
|
+
end
|
304
|
+
end
|
305
|
+
end
|
306
|
+
end
|
307
|
+
return mix
|
308
|
+
end
|
309
|
+
|
310
|
+
def self.cutStack(nX,nY,nPaginas,nPliegos,w,h)
|
311
|
+
coordenadas=getCoordinates(nX,nY,w,h)
|
312
|
+
posiciones=myPlacePDF(nX,nY,nPaginas,nPliegos)
|
313
|
+
remix=[]
|
314
|
+
for i in 0...posiciones.size
|
315
|
+
mix=Clases::Mix.new(posiciones[i].mC, coordenadas[posiciones[i].mP].x, coordenadas[posiciones[i].mP].y, posiciones[i].t)
|
316
|
+
remix.insert(i, mix)
|
317
|
+
end
|
318
|
+
remix=ordenar(remix)
|
319
|
+
retorno=[]
|
320
|
+
#retorna solo el orden
|
321
|
+
for i in 0...remix.length
|
322
|
+
retorno << remix[i].n
|
323
|
+
end
|
324
|
+
return retorno
|
325
|
+
end
|
326
|
+
|
327
|
+
#conversion unidades alchemy 2 pdflatex
|
328
|
+
def self.pdflatexUnit(x, unidad)
|
329
|
+
if unidad=="point" then
|
330
|
+
return [x,"pt"]
|
331
|
+
elsif unidad=="printer_point" then
|
332
|
+
return [x,"bp"]
|
333
|
+
elsif unidad=="m" then
|
334
|
+
x=x.to.cm
|
335
|
+
return [x,"cm"]
|
336
|
+
elsif unidad=="inch" then
|
337
|
+
return [x, "in"]
|
338
|
+
#TODO elsif...
|
339
|
+
else
|
340
|
+
return [x,unidad]
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
#crea un cuadernillo
|
345
|
+
def self.unaDentroDeOtra(paginasReal, paginasEnCuadernillo, inicio, fin)
|
346
|
+
#llegan como float
|
347
|
+
inicio=inicio.to_i
|
348
|
+
fin=fin.to_i
|
349
|
+
|
350
|
+
arreglo=[]
|
351
|
+
for i in 0...paginasEnCuadernillo/2
|
352
|
+
if (i+1)%2!=0 then
|
353
|
+
arreglo.push(fin-i)
|
354
|
+
arreglo.push(i+inicio)
|
355
|
+
else
|
356
|
+
arreglo.push(i+inicio)
|
357
|
+
arreglo.push(fin-i)
|
358
|
+
end
|
359
|
+
end
|
360
|
+
for i in 0...arreglo.length #TODO vale la pena meterlo en el loop anterior o de todos modos el de cut&Stack la hace y lo elimino?
|
361
|
+
if arreglo[i]>paginasReal then
|
362
|
+
arreglo[i]="{}"
|
363
|
+
end
|
364
|
+
end
|
365
|
+
return arreglo
|
366
|
+
end
|
367
|
+
|
368
|
+
#TODO validar que unidad exista en alchemist
|
369
|
+
def self.input2alchemist(unidad)
|
370
|
+
if unidad=="pt" or unidad=="pts" then
|
371
|
+
return "point"
|
372
|
+
elsif unidad=="PT" or unidad=="bp" then
|
373
|
+
return "printer_point"
|
374
|
+
else
|
375
|
+
return unidad.downcase
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
def self.redondear(n)#por BUG de alchemist (ruby 1.9 tiene round(3))
|
380
|
+
(n*1000).round/1000
|
381
|
+
end
|
382
|
+
|
383
|
+
#agrupa en cuadernillos
|
384
|
+
def self.booklets(pagsEnCuadernillo, paginas, paginasReal, q)
|
385
|
+
arreglo=[]
|
386
|
+
van=0
|
387
|
+
for i in 0...(paginas.to_f/pagsEnCuadernillo).ceil
|
388
|
+
if i!=0 then
|
389
|
+
van+=pagsEnCuadernillo
|
390
|
+
end
|
391
|
+
inicio=van+1
|
392
|
+
fin=van+pagsEnCuadernillo
|
393
|
+
if fin>paginas and q!=nil then
|
394
|
+
pagsEnCuadernillo=q
|
395
|
+
fin=van+q
|
396
|
+
end
|
397
|
+
booklet=unaDentroDeOtra(paginasReal, pagsEnCuadernillo, inicio, fin)
|
398
|
+
arreglo.concat(booklet)
|
399
|
+
end
|
400
|
+
return arreglo
|
401
|
+
end
|
402
|
+
|
403
|
+
#multiplo de 4
|
404
|
+
def self.mult4(paginasEnPliego)
|
405
|
+
msg=nil
|
406
|
+
paginas=paginasEnPliego
|
407
|
+
if paginasEnPliego%4 != 0 then
|
408
|
+
paginas=((paginasEnPliego/4)+1)*4
|
409
|
+
msg=Clases::Mensaje.new(1,"se necesitaran #{paginas}p para imponer #{paginasEnPliego}p en #{paginas/4} cuadernillos plegables")
|
410
|
+
else
|
411
|
+
paginas=paginasEnPliego
|
412
|
+
end
|
413
|
+
return [paginas,msg]
|
414
|
+
end
|
415
|
+
|
416
|
+
def self.cortarCola(nPaginas, pagsEnCuadernillo, cuadernillosPorCostura)
|
417
|
+
max = (nPaginas/pagsEnCuadernillo).ceil
|
418
|
+
if max*pagsEnCuadernillo>nPaginas then
|
419
|
+
anterior=pagsEnCuadernillo*(max-1)
|
420
|
+
q=nPaginas-anterior
|
421
|
+
if q%4!=0 then
|
422
|
+
q=((q/4)+1)*4
|
423
|
+
end
|
424
|
+
if anterior+q < max*pagsEnCuadernillo then
|
425
|
+
return Clases::PreguntaReducir.new(cuadernillosPorCostura, max*pagsEnCuadernillo-nPaginas, q/4, (anterior+q)-nPaginas, q)
|
426
|
+
end
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
430
|
+
def self.validacion(impostor, preguntas)
|
431
|
+
mensajes=[]
|
432
|
+
if preguntas==nil then
|
433
|
+
preguntas=Hash.new
|
434
|
+
end
|
435
|
+
if impostor.cuadernillos then
|
436
|
+
if impostor.nX%2!=0 then
|
437
|
+
if preguntas["par"]==nil or !preguntas["par"].ok then
|
438
|
+
preguntas["par"]=Clases::PreguntaExigePar.new(impostor.nX)
|
439
|
+
return Clases::RespuestaImpostor.new(preguntas,mensajes)
|
440
|
+
else
|
441
|
+
impostor.nX=preguntas["par"].nX
|
442
|
+
end
|
443
|
+
end
|
444
|
+
if preguntas["cXC"]==nil or !preguntas["cXC"].ok then
|
445
|
+
preguntas["cXC"]=Clases::PreguntaCXC.new()
|
446
|
+
return Clases::RespuestaImpostor.new(preguntas,mensajes)
|
447
|
+
else
|
448
|
+
impostor.cuadernillosPorCostura=preguntas["cXC"].cXC
|
449
|
+
end
|
450
|
+
impostor.nX=impostor.nX/2
|
451
|
+
impostor.w=impostor.w*2
|
452
|
+
impostor.w_["numero"]=impostor.w
|
453
|
+
mensajes.push(Clases::Mensaje.new(1, "como imponemos en cuadernillos, tomamos la mitad de paginas horizontalmente y una pagina del doble de ancho"))
|
454
|
+
end
|
455
|
+
#HORIZONTALMENTE
|
456
|
+
if impostor.w!=0.point then
|
457
|
+
if impostor.wP!=0.point then
|
458
|
+
if impostor.nX==0 then
|
459
|
+
impostor.nX=(wP/w).floor
|
460
|
+
impostor.wP=impostor.wP_["numero"].send(impostor.wP_["unidad"])#operación alchemist cambia el operando
|
461
|
+
if impostor.nX==0 then
|
462
|
+
mensajes.push(Clases::MensajeDato.new(3, "horizontal", 5))#error
|
463
|
+
else
|
464
|
+
mensajes.push(Clases::MensajeDato.new(1, "horizontal", 1))#info
|
465
|
+
end
|
466
|
+
end
|
467
|
+
elsif impostor.nX!=0 then
|
468
|
+
if impostor.wP==0.point then
|
469
|
+
impostor.wP_["numero"]=impostor.nX*impostor.w.to_f#actualiza para no perderlo en operacion de medidas
|
470
|
+
impostor.wP=impostor.wP_["numero"].send(impostor.w_["unidad"])
|
471
|
+
impostor.wP_["unidad"]=impostor.w_["unidad"]
|
472
|
+
mensajes.push(Clases::MensajeDato.new(1, "horizontal", 2))#info
|
473
|
+
end
|
474
|
+
else
|
475
|
+
mensajes.push(Clases::MensajeDato.new(3, "horizontal", 1))#error
|
476
|
+
end
|
477
|
+
elsif impostor.wP!=0.point then
|
478
|
+
if impostor.nX!=0 then
|
479
|
+
if preguntas["escaladoH"]==nil or !preguntas["escaladoH"].ok then
|
480
|
+
preguntas["escaladoH"]=Clases::PreguntaEscalado.new("horizontalmente")
|
481
|
+
else
|
482
|
+
if preguntas["escaladoH"].yn then
|
483
|
+
impostor.w=(impostor.wP.to_f/impostor.nX).send(impostor.wP_["unidad"])
|
484
|
+
impostor.w_["numero"]=impostor.w
|
485
|
+
impostor.w_["unidad"]=impostor.wP_["unidad"]
|
486
|
+
mensajes.push(Clases::MensajeDato.new(1, "horizontal", 3))#info
|
487
|
+
else
|
488
|
+
impostor.w=impostor.wReal
|
489
|
+
if impostor.cuadernillos then
|
490
|
+
impostor.w=impostor.w*2
|
491
|
+
impostor.w_["numero"]=impostor.w
|
492
|
+
end
|
493
|
+
impostor.w_["unidad"]=impostor.size["unidad"]
|
494
|
+
mensajes.push(Clases::MensajeDato.new(1, "horizontal", 4))#info
|
495
|
+
end
|
496
|
+
end
|
497
|
+
else
|
498
|
+
impostor.w=impostor.wReal
|
499
|
+
if impostor.cuadernillos then
|
500
|
+
impostor.w=impostor.w*2
|
501
|
+
impostor.w_["numero"]=impostor.w
|
502
|
+
end
|
503
|
+
impostor.w_["unidad"]=impostor.size["unidad"]
|
504
|
+
mensajes.push(Clases::MensajeDato.new(1, "horizontal", 4))#info
|
505
|
+
impostor.nX=(impostor.wP/impostor.w).floor
|
506
|
+
impostor.wP=impostor.wP_["numero"].send(impostor.wP_["unidad"])
|
507
|
+
if impostor.nX==0 then
|
508
|
+
mensajes.push(Clases::MensajeDato.new(3, "horizontal", 5))#error
|
509
|
+
else
|
510
|
+
mensajes.push(Clases::MensajeDato.new(1, "horizontal", 1))#info
|
511
|
+
end
|
512
|
+
end
|
513
|
+
elsif impostor.nX!=0 then
|
514
|
+
impostor.w=impostor.wReal
|
515
|
+
if impostor.cuadernillos then
|
516
|
+
impostor.w=impostor.w*2
|
517
|
+
impostor.w_["numero"]=impostor.w
|
518
|
+
end
|
519
|
+
impostor.w_["unidad"]=impostor.size["unidad"]
|
520
|
+
mensajes.push(Clases::MensajeDato.new(1, "horizontal", 4))#info
|
521
|
+
impostor.wP_["numero"]=impostor.nX*impostor.w.to_f
|
522
|
+
impostor.wP=impostor.wP_["numero"].send(impostor.w_["unidad"])
|
523
|
+
impostor.wP_["unidad"]=impostor.w_["unidad"]
|
524
|
+
mensajes.push(Clases::MensajeDato.new(1, "horizontal", 2))#info
|
525
|
+
else
|
526
|
+
mensajes.push(Clases::MensajeDato.new(3, "horizontal", 4))#error
|
527
|
+
end
|
528
|
+
#VERTICALMENTE
|
529
|
+
if impostor.h!=0.point then
|
530
|
+
if impostor.hP!=0.point then
|
531
|
+
if impostor.nY==0 then
|
532
|
+
impostor.nY=(impostor.hP/impostor.h).floor
|
533
|
+
impostor.hP=impostor.hP_["numero"].send(impostor.hP_["unidad"])
|
534
|
+
if impostor.nY==0 then
|
535
|
+
mensajes.push(Clases::MensajeDato.new(3, "vertical", 5))#error
|
536
|
+
else
|
537
|
+
mensajes.push(Clases::MensajeDato.new(1, "vertical", 1))#info
|
538
|
+
end
|
539
|
+
end
|
540
|
+
elsif impostor.nY!=0 then
|
541
|
+
if impostor.hP==0.point then
|
542
|
+
impostor.hP_["numero"]=impostor.nY*impostor.h.to_f
|
543
|
+
impostor.hP=impostor.hP_["numero"].send(impostor.h_["unidad"])
|
544
|
+
impostor.hP_["unidad"]=impostor.h_["unidad"]
|
545
|
+
mensajes.push(Clases::MensajeDato.new(1, "vertical", 2))#info
|
546
|
+
end
|
547
|
+
else
|
548
|
+
mensajes.push(Clases::MensajeDato.new(3, "vertical", 1))#error
|
549
|
+
end
|
550
|
+
elsif impostor.hP!=0.point then
|
551
|
+
if impostor.nY!=0 then
|
552
|
+
if preguntas["escaladoV"]==nil or !preguntas["escaladoV"].ok then
|
553
|
+
preguntas["escaladoV"]=Clases::PreguntaEscalado.new("verticalmente")
|
554
|
+
else
|
555
|
+
if preguntas["escaladoV"].yn then
|
556
|
+
impostor.h=(impostor.hP.to_f/impostor.nY).send(impostor.hP_["unidad"])
|
557
|
+
impostor.h_["numero"]=impostor.h
|
558
|
+
impostor.h_["unidad"]=impostor.hP_["unidad"]
|
559
|
+
mensajes.push(Clases::MensajeDato.new(1, "vertical", 3))#info
|
560
|
+
else
|
561
|
+
impostor.h=impostor.hReal
|
562
|
+
impostor.h_["numero"]=impostor.h
|
563
|
+
impostor.h_["unidad"]=impostor.size["unidad"]
|
564
|
+
mensajes.push(Clases::MensajeDato.new(1, "vertical", 4))#info
|
565
|
+
end
|
566
|
+
end
|
567
|
+
else
|
568
|
+
#deducimos del pdf no mas
|
569
|
+
impostor.h=impostor.hReal
|
570
|
+
impostor.h_["numero"]=impostor.h
|
571
|
+
impostor.h_["unidad"]=impostor.size["unidad"]
|
572
|
+
mensajes.push(Clases::MensajeDato.new(1, "vertical", 4))#info
|
573
|
+
impostor.nY=(impostor.hP/impostor.h).floor
|
574
|
+
impostor.hP=impostor.hP_["numero"].send(impostor.hP_["unidad"])
|
575
|
+
if impostor.nY==0 then
|
576
|
+
mensajes.push(Clases::MensajeDato.new(3, "vertical", 5))#error
|
577
|
+
else
|
578
|
+
mensajes.push(Clases::MensajeDato.new(1, "vertical", 1))#info
|
579
|
+
end
|
580
|
+
end
|
581
|
+
elsif impostor.nY!=0 then
|
582
|
+
impostor.h=impostor.hReal
|
583
|
+
impostor.h_["numero"]=impostor.h
|
584
|
+
impostor.h_["unidad"]=impostor.size["unidad"]
|
585
|
+
mensajes.push(Clases::MensajeDato.new(1, "vertical", 4))#info
|
586
|
+
impostor.hP_["numero"]=impostor.nY*impostor.h.to_f
|
587
|
+
impostor.hP=impostor.hP_["numero"].send(impostor.h_["unidad"])
|
588
|
+
impostor.hP_["unidad"]=impostor.h_["unidad"]
|
589
|
+
mensajes.push(Clases::MensajeDato.new(1, "vertical", 2))#info
|
590
|
+
else
|
591
|
+
mensajes.push(Clases::MensajeDato.new(3, "vertical", 4))#error
|
592
|
+
end
|
593
|
+
#MEDIDAS
|
594
|
+
wPDummy=impostor.wP_["numero"].send(impostor.wP_["unidad"])#bug alchemist
|
595
|
+
hPDummy=impostor.hP_["numero"].send(impostor.hP_["unidad"])
|
596
|
+
if redondear(impostor.nX*impostor.w.to_f) > redondear(impostor.wP.to(impostor.w_["unidad"]).to_f) then
|
597
|
+
mensajes.push(Clases::MensajeMedida.new(3, "horizontal", [impostor.nX, impostor.w_, impostor.wP_]))#error
|
598
|
+
elsif impostor.nX>0 and wPDummy -(impostor.nX*impostor.w.to_f).send(impostor.w_["unidad"]) > 0.send(impostor.wP_["unidad"]) then
|
599
|
+
sobra=impostor.wP-(impostor.nX*impostor.w.to_f).send(impostor.w_["unidad"])
|
600
|
+
impostor.wP=impostor.wP_["numero"].send(impostor.wP_["unidad"])
|
601
|
+
mensajes.push(Clases::MensajeMedida.new(2, "horizontal", [sobra, impostor.wP_["unidad"]]))#warn
|
602
|
+
end
|
603
|
+
if redondear(impostor.nY*impostor.h.to_f) > redondear(impostor.hP.to(impostor.h_["unidad"]).to_f) then
|
604
|
+
mensajes.push(Clases::MensajeMedida.new(3, "vertical", [impostor.nY, impostor.h_, impostor.hP_]))#error
|
605
|
+
elsif impostor.nY>0 and hPDummy - (impostor.nY*impostor.h.to_f).send(impostor.h_["unidad"]) > 0.send(impostor.h_["unidad"]) then
|
606
|
+
sobra=impostor.hP-(impostor.nY*impostor.h.to_f).send(impostor.h_["unidad"])
|
607
|
+
impostor.hP=impostor.hP_["numero"].send(impostor.hP_["unidad"])
|
608
|
+
mensajes.push(Clases::MensajeMedida.new(2, "vertical", [sobra, impostor.hP_["unidad"]]))#warn
|
609
|
+
end
|
610
|
+
#PAGINAS
|
611
|
+
nXm=impostor.nX
|
612
|
+
if impostor.cuadernillos then
|
613
|
+
nXm*=2
|
614
|
+
end
|
615
|
+
if impostor.nPaginas==0 then
|
616
|
+
if impostor.nPliegos!=0 then
|
617
|
+
nCaben=impostor.nPliegos*nXm*impostor.nY
|
618
|
+
if preguntas["todasPag"]==nil or !preguntas["todasPag"].ok then
|
619
|
+
preguntas["todasPag"]=Clases::PreguntaTodasPag.new(impostor.nPliegos, nXm, impostor.nY, nCaben, impostor.nPaginasReal)
|
620
|
+
else
|
621
|
+
if !preguntas["todasPag"].yn then
|
622
|
+
impostor.nPaginas=nCaben
|
623
|
+
if nCaben <= impostor.nPaginas then
|
624
|
+
mensajes.push(Clases::MensajeDato.new(1, "paginas", 1))#info
|
625
|
+
else
|
626
|
+
mensajes.push(Clases::MensajeDato.new(3, "paginas", 1))#error
|
627
|
+
end
|
628
|
+
else
|
629
|
+
impostor.nPaginas=impostor.nPaginasReal
|
630
|
+
mensajes.push(Clases::MensajeDato.new(1, "paginas", 3))#info
|
631
|
+
end
|
632
|
+
end
|
633
|
+
else
|
634
|
+
impostor.nPaginas=impostor.nPaginasReal
|
635
|
+
mensajes.push(Clases::MensajeDato.new(1, "paginas", 3))#info
|
636
|
+
end
|
637
|
+
else
|
638
|
+
if impostor.nPaginas < impostor.nPaginasReal then
|
639
|
+
impostor.nPaginasReal=impostor.nPaginas
|
640
|
+
end
|
641
|
+
end
|
642
|
+
#no se cuantos pliegos
|
643
|
+
if impostor.nX!=0 and impostor.nY!=0 then
|
644
|
+
nPliegosCalc=(impostor.nPaginas.to_f/(nXm*impostor.nY)).ceil
|
645
|
+
if impostor.nPliegos==0 then
|
646
|
+
impostor.nPliegos=nPliegosCalc
|
647
|
+
if impostor.nPliegos%2!=0 then
|
648
|
+
mensajes.push(Clases::MensajeLadoLado.new(impostor.nPliegos))
|
649
|
+
impostor.nPliegos=(impostor.nPliegos.to_f/2).ceil*2
|
650
|
+
impostor.nPaginas=impostor.nPliegos*nXm*impostor.nY
|
651
|
+
end
|
652
|
+
mensajes.push(Clases::MensajeDato.new(1, "paginas", 2))#info
|
653
|
+
else
|
654
|
+
if impostor.nPliegos<nPliegosCalc then
|
655
|
+
faltan=nPliegosCalc-impostor.nPliegos
|
656
|
+
mensajes.push(Clases::MensajeDato.new(3, "pliegos", faltan))#error
|
657
|
+
elsif impostor.nPliegos>nPliegosCalc then
|
658
|
+
sobran=impostor.nPliegos-nPliegosCalc
|
659
|
+
mensajes.push(Clases::MensajeDato.new(2, "pliegos", sobran))#warn
|
660
|
+
end
|
661
|
+
end
|
662
|
+
end
|
663
|
+
if impostor.cuadernillos then
|
664
|
+
q=nil
|
665
|
+
m4=mult4(impostor.nPaginas)
|
666
|
+
impostor.nPaginas=m4.shift
|
667
|
+
msg=m4.shift
|
668
|
+
if msg!=nil then
|
669
|
+
mensajes.push(msg)
|
670
|
+
end
|
671
|
+
if impostor.cuadernillosPorCostura==0 then
|
672
|
+
pagsEnCuadernillo=impostor.nPaginas#todos unos dentro de otros
|
673
|
+
else
|
674
|
+
pagsEnCuadernillo=impostor.cuadernillosPorCostura*4
|
675
|
+
end
|
676
|
+
if preguntas["reducir"]==nil or !preguntas["reducir"].ok then
|
677
|
+
preguntas["reducir"]=cortarCola(impostor.nPaginas, pagsEnCuadernillo, impostor.cuadernillosPorCostura)
|
678
|
+
else
|
679
|
+
if preguntas["reducir"].yn then
|
680
|
+
q=preguntas["reducir"].q
|
681
|
+
end
|
682
|
+
end
|
683
|
+
impostor.bookletz=booklets(pagsEnCuadernillo, impostor.nPaginas, impostor.nPaginasReal, q)
|
684
|
+
impostor.nPaginas=impostor.bookletz.length/2
|
685
|
+
end
|
686
|
+
#nPaginas multiplo de nX*nY
|
687
|
+
if impostor.nX*impostor.nY!=0 and impostor.nPaginas%(impostor.nX*impostor.nY)!=0 then
|
688
|
+
impostor.nPaginas=(impostor.nPaginas/(impostor.nX*impostor.nY)+1)*(impostor.nX*impostor.nY)
|
689
|
+
mensajes.push(Clases::Mensaje.new(1, "El pdf tiene #{impostor.nPaginasReal} paginas, que impuestas en #{impostor.nX}x#{impostor.nY} son #{impostor.nPaginas} paginas"))
|
690
|
+
end
|
691
|
+
#TODO ¿ROTAR? si se gasta menos espacio por pliego o en total da menos pliegos
|
692
|
+
return Clases::RespuestaImpostor.new(preguntas,mensajes)
|
693
|
+
end
|
694
|
+
|
695
|
+
end
|
metadata
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: imposition
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 1345381509
|
5
|
+
prerelease: 6
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 8
|
9
|
+
- 8
|
10
|
+
- alpha
|
11
|
+
version: 0.8.8.alpha
|
12
|
+
platform: ruby
|
13
|
+
authors:
|
14
|
+
- Numerico
|
15
|
+
autorequire:
|
16
|
+
bindir: bin
|
17
|
+
cert_chain: []
|
18
|
+
|
19
|
+
date: 2012-08-16 00:00:00 Z
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: alchemist
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: uuidtools
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
47
|
+
type: :runtime
|
48
|
+
version_requirements: *id002
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: fileutils
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
hash: 3
|
58
|
+
segments:
|
59
|
+
- 0
|
60
|
+
version: "0"
|
61
|
+
type: :runtime
|
62
|
+
version_requirements: *id003
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: test/unit
|
65
|
+
prerelease: false
|
66
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
hash: 3
|
72
|
+
segments:
|
73
|
+
- 0
|
74
|
+
version: "0"
|
75
|
+
type: :development
|
76
|
+
version_requirements: *id004
|
77
|
+
description: nUp & booklets
|
78
|
+
email: webmaster@numerica.cl
|
79
|
+
executables:
|
80
|
+
- impostor
|
81
|
+
extensions: []
|
82
|
+
|
83
|
+
extra_rdoc_files: []
|
84
|
+
|
85
|
+
files:
|
86
|
+
- lib/imposition.rb
|
87
|
+
- lib/imposition/metodos.rb
|
88
|
+
- lib/imposition/clases.rb
|
89
|
+
- bin/impostor
|
90
|
+
homepage: https://github.com/Numerico/impostor
|
91
|
+
licenses: []
|
92
|
+
|
93
|
+
post_install_message:
|
94
|
+
rdoc_options: []
|
95
|
+
|
96
|
+
require_paths:
|
97
|
+
- lib
|
98
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
99
|
+
none: false
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
hash: 3
|
104
|
+
segments:
|
105
|
+
- 0
|
106
|
+
version: "0"
|
107
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
108
|
+
none: false
|
109
|
+
requirements:
|
110
|
+
- - ">"
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
hash: 25
|
113
|
+
segments:
|
114
|
+
- 1
|
115
|
+
- 3
|
116
|
+
- 1
|
117
|
+
version: 1.3.1
|
118
|
+
requirements: []
|
119
|
+
|
120
|
+
rubyforge_project:
|
121
|
+
rubygems_version: 1.8.24
|
122
|
+
signing_key:
|
123
|
+
specification_version: 3
|
124
|
+
summary: editorial imposition script
|
125
|
+
test_files: []
|
126
|
+
|