%!
%# ginyB42 v.0.1 Beta és un aplicatiu d'anàlisi i composició pels caràcters de la Bíblia
%# de 42 línies de Gutenberg, escrit per a intèrprets Ghostscript, PHP i servidors Apache.
%# El componen els fitxers que segueixen sota llicència GPL:
%# Interfície web: index.php, executal.php, nohihacami.php i llistaB42.html.
%# Componedor en línia al servidor: ginyB42.ps
%# Analitzador i generador per línia de comanda de caràcters .B42: ventaQVdat_011.ps
%# Catàleg digital de tipus: tots els fitxers amb l'extensió .DAT .DAT.B42 .PNG
%# Copyright (c) 2004-2010
%# Concepte: Luz Ma. Rangel Alanís <quadrati@luzrangel.com>
%# Codi: Marc Antoni Malagarriga i Picas <marcantoni.malagarriga.picas@ub.edu>
%# Projecte de Programari Lliure: http://sourceforge.net/projects/gutenberginy/
%# Repositori: http://gutenberginy.svn.sourceforge.net/viewvc/gutenberginy/
%# Aquest programa és programari lliure: podeu redistribuir-lo i/o modificar-lo
%# sota els termes de la Llicència Pública General de GNU publicada per la Free
%# Software Foundation, ja sigui la versió 3 de la Llicència, o (a la seva elecció)
%# qualsevol versió posterior.
%#
%# Aquest programa es distribueix amb l'esperança que sigui útil, però SENSE CAP GARANTIA;
%# ni tan sols la garantia implícita MERCANTIL o d'APTITUD PER A UN OBJECTIU PARTICULAR.
%# Consulteu els detalls de la Llicència Pública General de GNU per a més informació.
%#
%# Haurieu de rebre una còpia de la Llicència Pública General de GNU junt amb aquest
%# programa. En cas contrari, consulteu <http://www.gnu.org/licenses/>
%# Multiplataforma: Linux | Unix | Windows | MacOSX
%# Per a intèrprets PS: Ghostscript 8/9 AdobeAcrobatDistiller 4 i +
%# execució amb GS per línia de comandes:
%# gs -q -dNOSAFER -o aviam.pdf -sDEVICE=pdfwrite -c .setpdfwrite -f ginyB42.ps
%% ginyB42 v.0.1 Beta compon, un a un cada vegada, rengs de la Bíblia de 42 línies
%% segons uns criteris d'espaiat i llargària de línia establerts per la frase mestra:
%% (\210iudas a\257ut #g\133\242u\210it #phar\133s e\075 zar\046 de#)
%% que fa de mida real 86 mm (la de la pàgina de la Bíblia original)
%% on l'espai normal (32) equival a 1 SubMòdul i el # (35) equival a la meitat d'un SubMòdul
%% Les combinacions d'espais permeses son ...
%% 1 ample (32), 1 prim (35), 1 ample+1 prim (32+35), 2 amples (32+32)
%% al final de línia només hi pot anar 1 prim (si és que hi va) i mai espais a l'inici
%% Ara podem treballar amb diacrítics (els anomenem signes paràsits) que es componen centrats
%% horitzontalment per l'ample del caràcter principal (el paràsit sempre s'escriu primer)
%# Raonaments mètrics fonamentals en relació a les diverses variables utilitzades en el codi:
%# 1. El valor d'1 Mòdul m equival a l'anomenada altura x del tipus
%# 2. El Mòdul m és format per 25 unitats unitats matriu d'ample i alt (25x25)
%# cadascuna d'elles, equival al valor de les variables /1QuintuM o /Modul:5 (la unitat matriu)
%# expressades sempre en punts tipogràfics
%# 3. La cinquena part del Mòdul m l'anomenem SubMòdul
%# 4. Si restem les variables: UliniaAscendent - UliniaDbase ... ens hauria de donar sempre 25
%# que és la quantitat d'unitats matriu que equivalen al Mòdul m
%# 5. Les variables UliniaAscendent i UliniaDbase acoten l'alçada x del caràcter, per dalt
%# i per baix, la línia de base respectivament
%# 6. El valor del Quadratí (/nQ /AltCaixa), és equivalent al valor d'altura del Mòdul Tipogràfic
%# 7. El concepte de prosa només es aplicable a l'espaiat entre lletres (mai entre paraules!)
%% cal fer
%% implementar l'execucio diferida per email
(\n\n ... ginyB42.ps t r e b a l l a ...) print flush
%# 0 %% execució del fitxer de capçalera de dades al servidor quan l'aplicatiu es crida via web
%# si aquesta línia és activa llavors les dades de %# 1 %# 2 i %# 3 s'anul·len
%% (capGinyB42.dat) (r) file 1024 string readstring pop cvx exec
%# 1 %% quina mena de composició triem? (anul·lar el valor quan %# 0 és actiu!)
%# 0=semMESTRE 1=semUNA 2=semFIXA
%% ara no són rellevants per l'aplicaitu web: 3=semTOTES 4=semTOTEStotes
0
/QCT exch def %% index que activara la composicio
%# 2 %% text a compondre (anul·lar el valor quan %# 0 és actiu!)
%%(genuit roboam:roboam aut genuit)
%%(iudas aut #genuit #phares et zara de#)
%%(zas.asz saz #asz azs#)
%%(\056\101\105\174\117\165)
%%(t\051a\051at\051)
%%(\141)
%%(\076a)
%% frase mestra inicial a l'aplicatiu web
%%(\210iudas a\257ut #g\133\242u\210it #phar\133s e\075 zar\046 de#)
%% p q PETA?
(\106a)
%% altres frases d'anàlisi
%% (\111ac\260b #a\257ut g\133\242u\210it #\210iud\257a#e\075#f\207\046t\207\133s e\210\223\360:)
%% (t\135amar#. Phares a\257ut g\133\242u\210it e\076r\260m:)
%% (e\076r\260m #a\257ut#g\133\242u\210it ar\046m . #Aram a\257ut)
%% prosa fixa de mitjana
%%23.99 26.79 20.92 27.14 add add add 4 div ==
%%27.14 20.92 add 2 div ==
%% càlcul de l'escala aproximada de reducció en la que estem treballant en la relació ginyB42/línia real
%% 86 2.835 mul %% valor en punts d'una línia real
%% 8845.2 div %% dividim per la llargària en punts de la línia a 13 quadratins d'escala de treball ps
%% adreça a disc del localhost
%% /Users/femfum/Sites/www2.ub.edu/cursusductus/hagaselaluz/B42
/liniaB42 exch def
%# 3 %% nombre de quadratins de la Línia Mestre (anul·lar el valor quan %# 0 és actiu!)
%% el valor de la Línia Mestre de la B42 és 13
%% podem donem preferència a aquest valor abans que llegir el fitxer iudasautgenuitpharesetzarade
6
/nQ exch def
%# 4 %% treballem amb percentatges (true) o amb unitats matriu (false) ?
false
/PoM exch def
%# 5 %% valor del llindar de tolerancia d'error segons unitats triades a %# 4 %%
0 %% ara li donem valor zero doncs la tolerància ens despistaria visualment
%# fi de capçalera de dades
%% cal mirar-se bé el tema de la precisió en el sistema de resolucions a Ghostscript
%% /HWResolution [721 721] put % (per GS treballant a 721 equival a un 100% d'escala)
PoM
{ %% deduïm el llindar per percentatges
/PRCNTTGtlrnc exch def %% actua si %# 4 és a true
}
{ %% deduïm el llindar per unitats matriu
/llM exch def % actua si %# 4 és a false
}ifelse
%# només una opció de %# a, %# b, %# c, %% d, %% e, pot estar activa
%# per l'aplicatiu web, només %# a, %# b, %# c, són possibles
%# a %% Compon amb prosa relativa als quadratins d'amplada de la Línia Mestre
%% abans fèiem: componem 1 vegada i establim l'amplada de línia com a Mestre? (índex 0)
false
/semMESTRE exch def
%# b %% Compon sense prosa
%% abans fèiem: componem 1 vegada? (índex 1)
false
/semUNA exch def
%# c %% Compon amb prosa fixa [24 punts] i estableix l'ample de Línia Mestre (índex 2)
false
/semFIXA exch def
%% d %% componem amb totes les combinacions d'espais possibles segons l'amplada de Línia Mestre? (índex 3)
false
/semTOTES exch def
%% e %% componem amb totes les combinacions d'espais i versions de caràcters possibles segons l'amplada de Línia Mestre? (índex 4)
false
/semTOTEStotes exch def
%% activem a true l'opció triada
[
/semMESTRE %% 0 Compon amb prosa relativa als quadratins d'amplada de la Línia Mestre
/semUNA %% 1 Compon sense prosa
/semFIXA %% 2 Compon amb prosa fixa [24 punts] i estableix l'ample de Línia Mestre
/semTOTES %% implementades però sense aplicació actual a l'entorn web
/semTOTEStotes %% implementades però sense aplicació actual a l'entorn web
]
QCT get true def
%% no corregim tret que PRCNTTGtlrnc o llM siguin negatives
PoM
{
PRCNTTGtlrnc 0 lt
{ %% llavors li donem un valor zero de percentatge per que no peti l'algorisme
0 /PRCNTTGtlrnc exch def
}if
}
{
llM 0 lt
{ %% llavors li donem un valor zero del llindar per que no peti l'algorisme
0 /llM exch def
}if
}ifelse
%# Detecta intèrprets Distiller i Ghostscript (o desconeguts) i n'avalua la versió
/Ghost false def %% gatell per detectar Ghostscript (true) o Distiller (false)
/soRTim false def %% gatell de sortida per errors
/vldrs true def %% podem treballar amb transparències?
systemdict /product known
{ %% és Ghostscript?
systemdict /product get (Ghostscript) search
{ %% si, és GS
pop pop pop
%% és 8.54 o + per treballar amb transparències?
systemdict /revision get cvi 854 ge
{
/Ghost true def
}
{
(\n\n >>> ginyB42 necessita Ghostscript 8.54 o + per treballar amb transparencies <<<\n ... el dial del llindar quedara perfilat ...) print flush
%% /soRTim true def
/vldrs false def
}ifelse
}
{ %% no es pas GS
systemdict /product get (Distiller) search
{ %% si, és Distiller
pop pop pop
%% avalua si és 6000 (6.0) o superior per poder activar les transparències
/currentdistillerparams where
{ %% és Distiller
pop currentdistillerparams /CoreDistVersion get 6000 lt %% és 6.0 o + ?
{
(\n\n >>> ginyB42 necessita Distiller 6.0 o + per treballar amb transparencies <<<\n ... el dial del llindar quedara perfilat ...) print flush
%% /soRTim true def
/vldrs false def
}if
}
{ %% seria estrany que no tingués currentdistillerparams ...
%% intèrpret desconegut
(\n >>> INTERPRET desconegut <<<\n ... PLEGUEM!\n\n) print flush /soRTim true def
} ifelse
}
{ %% és una altra cosa (p.e. Apple pstopdf) ...
systemdict /product get (\n\n) print flush print flush
( ... interpret NO implementat per aquest programari <<<\n ... PLEGUEM!\n\n) print flush /soRTim true def
}ifelse
}ifelse
}
{
(\n >>> INTERPRET desconegut <<<\n ... PLEGUEM!\n\n) print flush /soRTim true def
}ifelse
soRTim {quit}if %% és millor treballar amb stop que amb quit? (Ghostscript desapareix!)
%% gruix de línia general
.5 dup setlinewidth 2 mul /gDlg exch def
%% missatge d'anàlisi dels caràcters
(\n\n ... analitzant els caracters disponibles ...\n\n) print flush
%% llistem tots els .B42 i muntem el paquet de xifrat dels caràcters amb les seves variants
0 /iB42 exch def %% i els comptem
/OtotOre true def %% gatell inicial per saber si som els primers
/xifratB42 256 array def %% la taula de caràcters a 1 octet (byte)
%% aquí podem modificar l'adreça (path) de captura dels caràcters, però perilla que el directori
%% ens faci allargar exessivament el path i ens peti el llistat tabulat
%% donem per fet que els .B42 sempre seran allà on hi hagi ginyB42.ps
(*.B42)
{ %% filenameforall
{ %% stopped
dup dup length /xTab exch def %% la llargada del nom del fitxer ens servirà per ponderar el nombre de tabuladors a posar per tal que la llista surti correctament arrenglerada
print flush %% llistem el nom del .DAT.B42
(r) file dup cvx exec
dup /Caracter get
%% llistem el codi octal i el nom del caràcter de cada B42 que tenim disponible ponderant la separació per tabuladors
dup dup [()(\t\t\t\t)(\t\t\t)(\t\t)(\t)] xTab 8 div floor cvi get print flush 0 get
%% aquí és on tractem el codi del glif en base vuit
%% 0 get 8 3 string cvrs
%% no necessitem transforma-lo a base 8 doncs ara ja el podem llistar directament en aquesta base
print flush
(\t) print flush 1 get print flush (\n) print flush
0 get
%% convertim la cadena en base 8 a decimal per incrustar-la a l'Encoding
1 3 getinterval (8# ) dup 3 -1 roll 2 exch putinterval cvx exec
%% 0 get
exch dup /Caixa get 1 get dup
%% aquest valor ha de ser (en teoria) idèntic per a tots els caràcters
%% ho comprovarem també quan deduïm el format de pàgina
OtotOre
{
%% /OtotOre false def
/AltCaixa exch def %% desem l'alçada de la caixa del caràcter
%% equivalent al valor del Mòdul Tipogràfic i equivalent al valor del Quadratí
/suaraAltCaixa exch def
}
{
suaraAltCaixa ne
{
(\n\n >>> ATENCIO! ... hi ha el caracter octal ... ) print flush
2 index 8 3 string cvrs print flush
( ... amb una altura de Caixa DIFERENT!\n) print flush
}if
dup /AltCaixa exch def %% desem l'alçada de la caixa del caràcter
%% equivalent al valor del Mòdul Tipogràfic i equivalent al valor del Quadratí
/suaraAltCaixa exch def
}ifelse
dup /Modul:5 get dup
%# desem el valor de la unitat matriu que ha de ser (en teoria) idèntica a tots els caràcters
%% ho comprovarem també quan deduïm el format de pàgina
OtotOre
{
/OtotOre false def
/1QuintuM exch def %% la unitat matriu
/suara1QuintuM exch def
}
{
suara1QuintuM ne
{
(\n\n >>> ATENCIO! ... hi ha el caracter octal ... ) print flush
2 index 8 3 string cvrs print flush
( ... amb un valor d'Unitat Matriu DIFERENT!\n) print flush
}if
dup /1QuintuM exch def %% la unitat matriu
/suara1QuintuM exch def
}ifelse
exch
%% primer mirem si aquesta posició és buida (null) o ja hi ha una array
dup xifratB42 exch get type /nulltype eq
{ %% és buida i per tant muntem una nova array
xifratB42 3 1 roll exch 1 array astore put %% incrustem el diccionari dins l'array a la posició ascii que li toca
}
{ %% ja hi ha un array i per tant l'ampliem
dup xifratB42 exch get %% posem l'array a l'stack per ampliar-la
dup length dup /dNou exch def 1 add array dup 3 -1 roll 0 exch putinterval
dup 4 -1 roll dNou exch put %% incrustem el diccionari a la darrera posició de l'array ampliada
xifratB42 3 1 roll put %% reincrustem l'array ampliada de les variants del caràcter a l'ascii que li toca
}ifelse
closefile
iB42 1 add /iB42 exch def
}stopped
{
pop (<<<< aquest .B42 es erroni!)
dup [()(\t\t\t\t)(\t\t\t)(\t\t)(\t)] xTab 8 div floor cvi get print flush
print flush (\n) print flush
}if
} 256 string filenameforall
%% xifratB42 (:-D)pstack quit
%# missatge del nombre de caràcters disponibles
(\n ... hi ha ... ) print flush
iB42 3 string cvs print flush
( ... caracters disponibles\n) print flush
iB42 0 eq
{ %% en cas de .B42 erronis aquí necessitem treballar amb quit si volem que stopped treballi fi
( ... NO hi ha cap caracter del cataleg .B42 disponible <<<\n ... PLEGUEM!\n\n) print flush quit
}if
%# aquí generem dinàmicament l'html dels ascii/octal/png/nom dels caràcters pel PopUp del web ...
%% hauríem de fer un algorisme paral·lel per general el fitxer en PDF
(llistaB42.html) (w) file /glifHtml exch def
%% escrivim la capçalera de l'html
glifHtml
(<html><head><title> caràcters disponibles a ginyB42 </title></head><body bgcolor="#ffffff"><font face='Monaco, Lucida Console, Andale Mono, Courier New' size=1 color='#66aaaa'>ASCII OCTAL GLIF NOM INTERN<br><font color='#000000'>) writestring
%% escrivim els dos valors de l'espai en blanc
glifHtml
(<br> <font size=4> </font> \\040 <img src="espai040.png" align="center" title="per escriure aquest caràcter pots copiar i enganxar qualsevol dels 2 codis de l'esquerra (Octal o Ascii) dins del camp per compondre el text"> SubModul<br><br> <font size=4>#</font> \\043 <img src="espai043.png" align="center" title="per escriure aquest caràcter pots copiar i enganxar qualsevol dels 2 codis de l'esquerra (Octal o Ascii) dins del camp per compondre el text"> UnitatMatriu<br>) writestring
xifratB42
{
dup null eq
{
pop
}
{
0 get /Caracter get dup
%% esrivim el codi ascii
glifHtml ( <font size=4>) writestring
0 get
dup length string copy 1 3 getinterval (8#000) dup 2 4 -1 roll putinterval
cvx exec dup %% fem que l'string en base vuit s'activi com a tal
3 string cvs glifHtml exch writestring
glifHtml (;</font>) writestring
glifHtml ( <font color='#ff0000'>) writestring %% tabulem
8 3 string cvrs dup length 3 exch sub 1 add (\\000) dup 3 -1 roll 4 -1 roll putinterval
dup glifHtml exch writestring %% escrivim el codi octal
glifHtml (</font><img src=") writestring
1 3 getinterval glifHtml exch writestring glifHtml dup (.png) writestring (" align="center" title="per escriure aquest caràcter pots copiar i enganxar qualsevol dels 2 codis de l'esquerra (Octal o Ascii) dins del camp per compondre el text">) writestring %% escrivim el .png
1 get glifHtml exch writestring %% escrivim el nom del caràcter
glifHtml (<br>) writestring %% escrivim el salt de línia
}ifelse
}forall
%% escrivim la cua de l'html i tanquem
glifHtml dup (<br><br></font></font></body></html>) writestring closefile
%% incrustem a la taula de caràcters l'array amb diccionari pels 2 espais entre paraules ...
xifratB42 32 %% per l'ascii 32
[
<<
/Modul:5 1QuintuM
/Caracter [(\040) (SubModul) ]
/Caixa [ 1QuintuM 5 mul AltCaixa ] %% l'espai es un SubMòdul (5 unitats matriu)
/Color (1 0 1) %% magenta
>> %% espai d'ample d'1 SubMòdul
] put
xifratB42 35 %% per l'ascii 35
[
<<
/Modul:5 1QuintuM
/Caracter [(\043) (UnitatMatriu) ]
/Caixa [ 1QuintuM 2.5 mul AltCaixa ] %% la destralada es mig SubMòdul (2.5 unitats matriu)
/Color (0 1 1) %% cian
>> %% espai d'ample 1/2 SubMòdul
] put
%# diccionari de caràcters paràsits
<< %% el valor el desem com a nombre radial en base 8 i la clau com a decimal
/175 /8#257 %% (MACRON)
/136 /8#210 %% (TILDE I \(breve invertido\))
%% /96 /8#140 %% (PUNTO ARRIBA) %% segurament es podrà eliminar definitivament
/168 /8#250 %% (DOS PUNTOS ARRIBA)
/183 /8#205 %% (PUNTO VOLADO)
%% /62 /8#076 % (LETRA MINUSCULA M VOLADA) %% segurament es podrà eliminar definitivament
/186 /8#272 %% (LETRA MINUSCULA O VOLADA)
/223 /8#337 %% (LETRA MINUSCULA Z VOLADA)
%% /46 /8#056 % x provar (el punt)
%% /115 /8#163 % x provar (la s)
%% /124 /testaI % x provar
>>
/prstsB42 exch def
%% podem transformar el radial a decimal fàcilment
%% dup /8#257 get == (mmmmmmmm) == /8#257 5 string cvs cvx exec == quit
%# aquí desem el diccionari de caràcters amb versions
%% la clau és el valor decimal del caràcter i el valor un array amb els valors decimals de les altres versions
<<
/97 [38] %% LETRA MINUSCULA A 8#141
/38 [97] %% LETRA MINUSCULA A 8#046
/98 [43] %% LETRA MINUSCULA B 8#142
/43 [98] %% LETRA MINUSCULA B 8#053
/99 [123] %% LETRA MINUSCULA C 8#143
/123 [99] %% LETRA MINUSCULA C 8#173
/100 [125] %% LETRA MINUSCULA D 8#144
/125 [100] %% LETRA MINUSCULA D 8#175
/101 [91] %% LETRA MINUSCULA E 8#145
/91 [101] %% LETRA MINUSCULA E 8#133
/104 [93] %% LETRA MINUSCULA H 8#150
/93 [104] %% LETRA MINUSCULA H 8#135
/105 [147 124] %% LETRA MINUSCULA I 8#151
/147 [105 124] %% LETRA MINUSCULA I 8#223
/124 [147 105] %% LETRA MINUSCULA I LARGA 8#174
/109 [231] %% LETRA MINUSCULA M 8#155
/231 [109] %% LETRA MINUSCULA M 8#347
/110 [162] %% LETRA MINUSCULA N 8#156
/162 [110] %% LETRA MINUSCULA N 8#242
/111 [176] %% LETRA MINUSCULA O 8#157
/176 [111] %% LETRA MINUSCULA O 8#260
/112 [44] %% LETRA MINUSCULA P 8#160
/44 [112] %% LETRA MINUSCULA P 8#054
/113 [169] %% LETRA MINUSCULA Q 8#161
/169 [113] %% LETRA MINUSCULA Q 8#251
/114 [135 60] %% LETRA MINUSCULA R 8#162
/135 [114 60] %% LETRA MINUSCULA R 8#207
/60 [114 135] %% LETRA MINUSCULA R ROTUNDA 8#074
/41 [115 40] % LETRA MINUSCULA S CON DESCENDENTE 8#051
/62 [40 115] %% LETRA MINUSCULA S LARGA 8#076
/40 [62 115] %% LETRA MINUSCULA S LARGA 8#050
/115 [40 62] %% LETRA MINUSCULA S 8#163
/116 [61] %% LETRA MINUSCULA T 8#164
/61 [116] %% LETRA MINUSCULA T 8#075
/117 [33] %% LETRA MINUSCULA U 8#165
/33 [117] %% LETRA MINUSCULA U 8#041
/120 [161] %% LETRA MINUSCULA X 8#170
/161 [120] %% LETRA MINUSCULA X CON DESCENDENTE 8#241
>>
/vrsnsB42 exch def %% ara no s'utilitza enlloc
%% marges de pàgina que apliquem als 4 costats
100 /mArgEs exch def
%% missatge d'exploració
(\n ... explorant la metrica i els mots ...) print flush
%# deduïm el format de pàgina
%# filtrem si hi ha incongruències en els valors de la Unitat Matriu i el Mòdul Tipogràfic (l'alçada de la caixa del caràcter)
%% deduïm el nombre de tipus d'espais en blanc que hi ha
0 /liniaFA exch def %% valor inicial de l'ample de la línia a compondre
0 /hiHa32 exch def %% nombre d'espais en blanc d'ample d'1 SubMòdul
0 /hiHa35 exch def %% nombre d'espais en blanc d'ample mig SubMòdul
liniaB42
{ %% forall
dup 32 eq
{
hiHa32 1 add /hiHa32 exch def %% controlem el nombre d'espais en blanc d'ample d'1 SubMòdul
}if
dup 35 eq
{
hiHa35 1 add /hiHa35 exch def %% controlem el nombre d'espais en blanc d'ample mig SubMòdul
}if
dup xifratB42 exch get
dup null eq
{
pop 1 string dup 3 -1 roll 0 exch put
(\n\n) print flush
== ( ... caracter NO disponible ...\n\n) print flush quit
}
{
%% mirem si l'ascii del caràcter es al diccionari de caràcters paràsits
1 index prstsB42 exch 3 string cvs known
{ %% si hi és, no sumem res ...
pop pop %% ... i eliminem l'array de diccionaris i l'ascii
}
{ %% si NO hi és, ens comportem com sempre ...
0 get %# de moment sempre treballarem amb la primera versió (aquí és on s'hi hauria de posar el controlador de variacions)
dup /Caixa get dup 0 get %% pesquem l'ample del Mòdul Tipogràfic
%% comprovem l'altura del Mòdul Tipogràfic (alt de caixa) i el valor de la Unitat de Mòdul, per a cada caràcter, i detectar possibles diferències (que no hi haurien de ser?)
exch 1 get AltCaixa ne
{
(\n\n >>> ATENCIO! ... hi ha el caracter octal ... ) print flush
2 index 8 3 string cvrs print flush
( ... amb una altura de Caixa DIFERENT!\n) print flush
}if
exch /Modul:5 get 1QuintuM ne
{
(\n\n >>> ATENCIO! ... hi ha el caracter ... ) print flush
1 index 8 3 string cvrs print flush
( ... amb un valor d'Unitat Matriu DIFERENT!\n) print flush
}if
liniaFA add /liniaFA exch def %% sumem al total
pop %% eliminem l'ascii sobrer
}ifelse
}ifelse
}forall
%# desem els mots diferents que componen la frase, per ordre i en una array motsB42 (amb el seu valor ascii)
true /AraEscriuElMot exch def %% valor inicial del gatell per saber si cal escriure el mot o no
mark
liniaB42
{ %% forall
dup dup 32 eq exch 35 eq or
{
pop %% l'eliminem doncs pertany a un espai
AraEscriuElMot {counttomark array astore exch pop mark}if
false /AraEscriuElMot exch def
}
{ %% si no es un espai el deixem a l'stack
true /AraEscriuElMot exch def
}ifelse
}forall
AraEscriuElMot
{ %% la frase acaba sense cap espai al final
counttomark array astore exch pop count array astore /motsB42 exch def %% desem la frase amb els mots empaquetats
}
{ %% la frase acaba amb un espai al final
pop count array astore /motsB42 exch def %% desem la frase amb els mots empaquetats
}ifelse
%% comprovant que motsB42 ha treballat B
%% motsB42
%% {
%% dup length string/elMot exch def elMot/NullEncode filter/elMotF exch def
%% {
%% elMotF exch write
%% }forall
%% elMotF closefile elMot ==
%% }forall
%% (:::::::) pstack quit
%# comptador del nombre de caràcters (descomptant els paràsits i els espais!) que formen la frase
%# per poder controlar després la prosa que cal ajustar entre ells
/nombreDcaracters 0 def
%araOb42 mArgEs sub %% amplada actual de la línia
gsave
false
{
liniaB42
{ %% forall
dup dup 32 eq exch 35 eq or
{ %% això és un espai
%%(ESPAI)pstack quit
pop
}
{
dup prstsB42 exch 3 string cvs known
{ %% això és un paràsit
%%(PARASIT)pstack quit
pop
}
{ %% això és un caràcter de veritat
%%(CARACTER)pstack quit
pop
/nombreDcaracters nombreDcaracters 1 add def %% comptador
}ifelse
}ifelse
}forall
}if
%% gallet de detecció del codi del paràsit
/Cprst null def
%% componem la línia
mArgEs /araOb42 exch def %% valor inicial del punt actual d'origen X del caràcter
liniaB42
{ %% forall
dup xifratB42 exch get
0 get begin %% ara entrem de forma fixa la primera versió del caràcter
%% gsave
%% %% situem l'inici de la caixa del caràcter
%% araOb42 mArgEs translate
dup dup 32 eq exch 35 eq or
{ %% això és un espai
pop
%% %% pintem la caixa de l'espai
%% gsave
%% Color cvx exec setrgbcolor 0 0 Caixa aload pop
%% %% 4 -1 roll gDlg add 4 1 roll exch gDlg sub exch % rectifiquem xq no s'aixafi?
%% %% rectstroke
%% rectfill
%% grestore
Caixa 0 get end %% sortim del diccionari del B42 abans no desem el nou X
araOb42 add /araOb42 exch def %% actualitzem i desem pel proper origen
}
{
dup prstsB42 exch 3 string cvs known
%% false
{ %% això és un paràsit
%% (**!**) pstack quit
end
/Cprst exch def
}
{ %% això és un caràcter de veritat
pop
%% %% pintem la caixa del caràcter
%% gsave 0 0 1 setrgbcolor 0 0 Caixa aload pop
%% 4 copy rectstroke grestore
%% %% fem el vincle virtual per que aparegui el nom del .DAT associat al passar el cursor per sobre
%% 4 array astore
%% [
%% exch /Rect exch
%% /Subtype /Widget
%% /Ff 65536
%% %% generem un nom únic per mitjà de la posició X
%% /T araOb42 36 string cvs
%% %% l'etiqueta la forma el mateix DAT + el nom del caràcter
%% /TU DAT dup length 3 add dup /eldarrer exch def Caracter 1 get dup length 3 -1 roll add string dup 4 -1 roll
%% 0 exch putinterval dup eldarrer 3 sub ( : ) putinterval dup 3 -1 roll eldarrer exch putinterval
%% /FT /Btn
%% /H /N
%% %% en cas que féssim vincles ...
%% %% /AA <</D << /S /Launch /F << /Type /Filespec /F pdfNEXT >> >> >>
%% /ANN
%% pdfmark
%% gsave
%% %% situem la línia de base del caràcter (nou punt 0,0)
%% 0 UliniaDbase Modul:5 mul translate
%% gsave
%% %% situem l'origen del caràcter al punt 0,0 actual
%% Origen aload pop translate
%% :-/ aquí es on ajustem l'origen del caràcter (tret q sigui zero)?
%% Oglif 0 get 0 translate
%% %% capturem l'array del glif i ressucitem els operadors (suara literals)
%% glif {cvx exec}forall
%% %% pintem el caràcter?
%% gsave
%% .75 .75 .75 setrgbcolor eofill grestore .5 0 .5 setrgbcolor stroke
%% grestore
%% grestore
%% %% pintem la línia d'ascendent
%% 1 0 0 setrgbcolor
%% 0 UliniaAscendent Modul:5 mul moveto
Caixa 0 get
dup
%% dup
%% UliniaAscendent Modul:5 mul lineto stroke
%% %% ara de forma fixa a 8 unitats matriu, doncs UliniaDbase canvia segons els caràcters!
%% %% pintem la línia de base
%% 1 0 0 setrgbcolor
%% 0 8 Modul:5 mul moveto Caixa 0 get 8 Modul:5 mul lineto stroke
%% :-/ aquí es on ajustem l'origen pel caràcter següent (tret que sigui zero)
dup OglifS 0 get sub sub %% restem del valor de l'ample de la Caixa del caràcter
end %% sortim del diccionari del B42 abans no desem el nou X
araOb42 add /araOb42 exch def %% actualitzem i desem pel proper origen
/darrerAmple exch def
%% %% si no es un null pintem el caràcter paràsit
%% Cprst null ne
%% false
%% {
%% save
%% xifratB42 Cprst get 0 get begin %% ara entrem de forma fixa la primera versió del caràcter
%% gsave
%% %% situem l'origen del caràcter al punt 0,0 actual
%% Origen aload pop
%% %% aquí cal centrar el paràsit en relació a l'ample del caràcter que el conté
%% darrerAmple Caixa 0 get sub 2 div 3 -1 roll
%% add exch
%% (***!!***) pstack quit
%% UliniaDbase Modul:5 mul add
%% translate
%% %% capturem l'array del glif i ressucitem els operadors (suara literals)
%% glif {cvx exec}forall
%% %% pintem el caràcter?
%% gsave
%% .75 .75 .75 setrgbcolor eofill grestore .5 0 .5 setrgbcolor stroke
%% grestore
%% grestore
%% end
%% restore
%% null /Cprst exch def
%% }if
/nombreDcaracters nombreDcaracters 1 add def %% comptador
}ifelse
}ifelse
%% grestore
}forall
grestore
%% fi del comptador de caràcters
%# calculem el valor de l'espaiat extra entre caràcters (prosa) o no?
%% per que quadri amb el valor Mestre del nombre de quadratins de la llargària de línia, o no?
%% com treballem el valor del nombre de quadratins en funció del tipus d'execució?
semUNA
{
%% el nombre de quadratins considerat Mestre per una línia de la Bíblia (13) es manté fix
%% de forma que condiciona el format de pàgina, tret que se superi per excés i llavors
%% el dial ens donaria la referència d'on hi ha aquest valor dins la pàgina
nQ %% valor del nombre de quadratins de la variable de capçalera
}
{ %% seria semMESTRE o semFIXA
semFIXA
{
%% llegim el valor en punts de la Línia Mestre del fitxer a disc
(iudasautgenuitpharesetzarade) (r) file 64 string readline pop
cvx exec %% capturem l'ample establert en nombre de quadratins dins la casella d'index.php i que a l'executar s'ha desat en punts
AltCaixa div %% i en recalculem el seu valor en quadratins
}if
nQ %% valor del nombre de quadratins de la variable de capçalera
}ifelse
/nQ exch def %% redefinim
%% nQ AltCaixa mul
%% anem a comprovar la relació del valor de l'ample de línia amb el valor dels 13 teòrics quadratins de l'ample original d'una línia de la Bíblia de Gutenberg
%% 13 'quadratins' = 13 AltCaixa (alçada de la caixa del caràcter) mul
%% el valor del quadratí és el que es desa a l'índex 1 de l'array de la clau /Caixa de cada .B42
%% o sigui l'altura del Mòdul Tipogràfic
(\n\n)print flush
%% per cert ... quants quadratins són 5 metres? (5 metres és el màxim format teòric d'impressió)
%% 8235 %% 1 metre
%% 5 mul AltCaixa div
%% (:-O)pstack quit
AltCaixa nQ mul %% valor de la Línia Mestre on haurà de quadrar la línia si fem semMESTRE
araOb42 mArgEs sub %% amplada actual de la línia sense prosa
sub %% valor total en punts que hem d'ajustar ...
%# el nombre d'espais entre caràcters a recalcular és: nombreDcaracters motsB42 length sub
%# doncs ignorem els espaiats entre paraules
nombreDcaracters motsB42 length sub
dup /ndecar exch def %% per a semFIXA
dup 64 string cvs print flush
semUNA
{ %% aquí no recalcularem res
( ... nombre d'espais entre caracters\n)print flush
}
{
( ... nombre d'espais entre caracters a recalcular\n)print flush
}ifelse
%% dividim el nombre d'espais pel que manca per quadrar amb la Línia Mestre
dup 0 eq
{
pop pop 0
}
{
div
}ifelse %% valor en punts de prosa per a cada espai
semFIXA
{
pop 24
dup 64 string cvs print flush ( ... valor FIX en punts de prosa\n)print flush
}
{ %% semMESTRE o semUNA
semUNA
{ %% no donem aquesta informació per la pantalleta doncs és innecessària
}
{
dup 64 string cvs print flush ( ... valor en punts de prosa\n)print flush
}ifelse
}ifelse
/PRoSa exch def %% valor extra a afegir a cadascun dels espais entre lletres vàlids
nombreDcaracters 64 string cvs print flush ( ... nombre de caracters de la frase\n)print flush
AltCaixa nQ mul %% el valor Mestre hauría de ser de nQ (13?) quadratins
dup 64 string cvs print flush ( ... valor d'amplada en punts dels )print flush
nQ 64 string cvs print flush
( quadratins d'amplada de la Linia Mestre\n)print flush
araOb42 mArgEs sub %% amplada actual de la línia sense prosa
dup 64 string cvs print flush ( ... amplada actual de la linia sense prosa\n)print flush
semFIXA
{
/aaDLLaP exch def %% amplada actual de la linia sense prosa
pop %%(:-V)pstack quit
ndecar 24 mul %% calculem quants punts totals hem d'afegir (+)
%% per establir el nou valor de la Línia Mestre!
dup aaDLLaP add dup /aaDLLaP exch def %% amplada actual de la linia AMB prosa
/liniaFA exch def %% valor idèntic que necessitem pel format de pàgina
dup 64 string cvs print flush ( ... valor total, en punts, de prosa per afegir\n)print flush
}
{ %% semMESTRE o semUNA
dup /liniaFA exch def %% valor que necessitem pel format de pàgina
sub %% calculem quants punts totals hem o hauríem d'afegir (+) o restar (-)
semUNA
{ %% no donem aquesta informació per la pantalleta doncs és innecessària
}
{
dup 64 string cvs print flush ( ... valor total, en punts, de prosa per ajustar\n)print flush
}ifelse
}ifelse
%% 21 div %% frase del iudas ...
%% 24 div %% frase del Jacob
%% 23 div %% frase thamar
%% 19 div %% frase esrom
%% fi del càlcul del valor de l'espaiat
%% ventall de composicions possibles ...
semMESTRE %% compon amb prosa relativa als quadratins d'amplada de la Línia Mestre
semFIXA %% compon amb prosa fixa [24 punts] i estableix l'ample de la Línia Mestre
or
{
semMESTRE
{ %% semMESTRE
%% missatge de composició
(\n\n ... compon amb prosa relativa als quadratins d'amplada de la Linia Mestre ...) print flush
<<
/PageSize
%% liniaFA mArgEs 2 mul add
AltCaixa nQ mul %% el valor Mestre de nQ quadratins passats a punts
mArgEs 2 mul add %% + el marges = X de la pàgina
AltCaixa mArgEs 2 mul add %% Y de la pàgina
2 array astore
>> setpagedevice
}
{ %% semFIXA
%% missatge de composició
(\n\n ... compon amb prosa fixa [24 punts] i estableix l'ample de Linia Mestre ...) print flush
%% el mateix format de plana que l'ample del text compost + els marges
%% prosa: correcció del format de pàgina pel nou comportament de la prosa
<</PageSize liniaFA mArgEs 2 mul add AltCaixa mArgEs 2 mul add 2 array astore >>setpagedevice
}ifelse
%% gallet de detecció del codi del paràsit
/Cprst null def
%% prosa: gallet de detecció de quan cal afegir la prosa
/faPRoSa false def
%# componem la línia
mArgEs /araOb42 exch def %% valor inicial del punt actual d'origen X del caràcter
liniaB42
{ %% forall
dup xifratB42 exch get
0 get begin %% ara entrem de forma fixa la primera versió del caràcter
gsave
%% situem l'inici de la caixa del caràcter
araOb42 mArgEs translate
dup dup 32 eq exch 35 eq or
{ %% això és un espai
%% prosa: aquí ajustem la prosa per als nQ (13?) quadratins
userdict /faPRoSa get
{
PRoSa neg 0 translate
}if
pop
%% pintem la caixa de l'espai
gsave
Color cvx exec setrgbcolor 0 0 Caixa aload pop
%% 4 -1 roll gDlg add 4 1 roll exch gDlg sub exch % rectifiquem xq no s'aixafi?
%% rectstroke
rectfill
grestore
Caixa 0 get end %% sortim del diccionari del B42 abans no desem el nou X
%% prosa: aquí ajustem la prosa per als nQ (13?) quadratins
userdict /faPRoSa get
{
PRoSa sub
%% prosa: inicialitzem el gatell de detecció dels espais vàlids per corregir la prosa
userdict /faPRoSa false put
}if
araOb42 add /araOb42 exch def %% actualitzem i desem pel proper origen
}
{
dup prstsB42 exch 3 string cvs known
%% false
{ %% això és un paràsit
%% (**!**) pstack quit
end
/Cprst exch def
}
{ %% això és un caràcter de veritat
pop
%% pintem la caixa del caràcter
gsave 0 0 1 setrgbcolor 0 0 Caixa aload pop
4 copy rectstroke grestore
%% fem el vincle virtual per que aparegui el nom del .DAT associat al passar el cursor per sobre
4 array astore
[
exch /Rect exch
/Subtype /Widget
/Ff 65536
%% generem un nom únic per mitjà de la posició X
/T araOb42 36 string cvs
%% l'etiqueta la forma el mateix DAT + el nom del caràcter
/TU DAT dup length 3 add dup /eldarrer exch def Caracter 1 get dup length 3 -1 roll add string dup 4 -1 roll
0 exch putinterval dup eldarrer 3 sub ( : ) putinterval dup 3 -1 roll eldarrer exch putinterval
/FT /Btn
/H /N
%% en cas que féssim vincles ...
%% /AA <</D << /S /Launch /F << /Type /Filespec /F pdfNEXT >> >> >>
/ANN
pdfmark
gsave
%% situem la línia de base del caràcter (nou punt 0,0)
0 UliniaDbase Modul:5 mul translate
gsave
%% situem l'origen del caràcter al punt 0,0 actual
Origen aload pop translate
%% :-/ aquí es on ajustem l'origen del caràcter (tret q sigui zero)?
%% Oglif 0 get 0 translate
%% capturem l'array del glif i ressucitem els operadors (suara literals)
glif {cvx exec}forall
%% pintem el caràcter?
gsave
.75 .75 .75 setrgbcolor eofill grestore .5 0 .5 setrgbcolor stroke
grestore
grestore
%% pintem la línia d'ascendent
1 0 0 setrgbcolor
0 UliniaAscendent Modul:5 mul moveto
Caixa 0 get
dup dup UliniaAscendent Modul:5 mul lineto stroke
%% ara de forma fixa a 8 unitats matriu, doncs UliniaDbase canvia segons els caràcters!
%% pintem la línia de base
1 0 0 setrgbcolor
0 8 Modul:5 mul moveto Caixa 0 get 8 Modul:5 mul lineto stroke
%% :-/ aquí es on ajustem l'origen pel caràcter següent (tret que sigui zero)
dup OglifS 0 get sub sub %% restem del valor de l'ample de la Caixa del caràcter
%% prosa: aquí ajustem la prosa per als nQ (13?) quadratins
userdict /faPRoSa get
{
PRoSa add
}
{
PRoSa add
userdict /faPRoSa true put
}ifelse
end %% sortim del diccionari del B42 abans no desem el nou X
araOb42 add /araOb42 exch def %% actualitzem i desem pel proper origen
/darrerAmple exch def
%% si no es un null pintem el caràcter paràsit
Cprst null ne
%% false
{
save
xifratB42 Cprst get 0 get begin %% ara entrem de forma fixa la primera versió del caràcter
gsave
%% situem l'origen del caràcter al punt 0,0 actual
Origen aload pop
%% aquí cal centrar el paràsit en relació a l'ample del caràcter que el conté
darrerAmple Caixa 0 get sub 2 div 3 -1 roll
add exch
%% (***!!***) pstack quit
UliniaDbase Modul:5 mul add
translate
%% capturem l'array del glif i ressucitem els operadors (suara literals)
glif {cvx exec}forall
%% pintem el caràcter?
gsave
.75 .75 .75 setrgbcolor eofill grestore .5 0 .5 setrgbcolor stroke
grestore
grestore
end
restore
null /Cprst exch def
}if
}ifelse
}ifelse
grestore
}forall
%% llistem l'ample de la línia?
(\n\n >>> l'ample de Linia Mestre fixat es de ... ) print flush
%% araOb42 mArgEs sub 32 string cvs %% amplada actual de la línia sense prosa (forçar espaiats)
liniaFA dup 32 string cvs
%% aquí hem de discriminar si és semFIXA doncs llavors establim el nou valor de la Línia Mestre
%% en funció de la llargària real de línia del text compost amb prosa
semFIXA
{
dup
%% establim la llargària Mestre
(iudasautgenuitpharesetzarade) (w) file dup 3 -1 roll writestring closefile
}if
%% si no, no fixem res!
%% {
%% AltCaixa nQ mul %% nombre de quadratins pel seu valor en punts
%% dup 32 string cvs dup
%% %% establim la llargària Mestre
%% (iudasautgenuitpharesetzarade) (w) file dup 3 -1 roll writestring closefile
%% }ifelse
print flush ( ... punts | ) print flush
%% araOb42 mArgEs sub 1QuintuM div %% calculem el valor en SubMòduls o en unitats matriu?
%% araOb42 mArgEs sub AltCaixa div %% calculem el valor en quadratins?
AltCaixa div %% nombre de quadratins
32 string cvs print flush
%% ( ... unitats mariu <<<\n) print flush
( ... quadratins <<<\n) print flush
semFIXA
{ %% rellegim de nou el valor Mestre que hem establert al fitxer a disc
(iudasautgenuitpharesetzarade) (r) file 64 string readline pop cvx exec %% capturem l'ample de Línia Mestre
/aMestre exch def %% el desem
}
{ %% semMESTRE
%% el valor Mestre és el que ve de capçalera (camp de l'ample de Línia Mestre al web)
AltCaixa nQ mul %% nombre de quadratins pel seu valor en punts
/aMestre exch def %% el desem
}ifelse
%% en funció del % de tolerància d'error admesa calculem els llindars per sobre i per sota ...
PoM
{ %% deduïm el llindar per percentatges
PRCNTTGtlrnc aMestre mul 100 div
}
{ %% deduïm el llindar per unitats modulars
llM 1QuintuM mul
}ifelse
/ERRORtlrnc exch def %% valor en punts del llindar
aMestre ERRORtlrnc sub
10 mul truncate 10 div %% tallem només a 1 decimal
/llindarJUSSA exch def %% el llindar per sota
aMestre
10 mul truncate 10 div %% tallem només a 1 decimal
/llindarSOBIRA exch def %% el llindar per sobre (no hi ha llindar + enllà de l'ample Mestre)
%% posem el dial de l'ample Mestre de línia amb les toleràncies x transparència (o no)
%% hi ha un detector Dist/Ghost per saber si hem de generar la transparència per pdfmark o .setblendmode o res degut a GS anteriors al 8.54
gsave %% pintem l'àrea de tolerància del marge d'error (compresa entre el valor JUSSÀ i SOBIRÀ)
/DeviceCMYK setcolorspace
Ghost
{ %% Ghostscript
vldrs
{ %% treballem amb transparències
/Multiply .setblendmode .5 .setopacityalpha %% treballant amb Ghostscript 8.54 (mínim)
0 0 1 0 setcolor
mArgEs llindarJUSSA add 0 ERRORtlrnc AltCaixa mArgEs 2 mul add rectfill %% omplim el llindar
grestore
gsave 0 0 0 setrgbcolor 0 setlinewidth %% color i ample del dial (0 assegura visibilitat òptima i prima)
mArgEs llindarJUSSA add ERRORtlrnc add dup 0 moveto %% X del dial de l'ample Mestre
AltCaixa mArgEs 2 mul add lineto %% Y del dial de l'ample Mestre
stroke grestore %% tracem
}
{ %% treballem SENSE transparències
0 0 0 1 setcolor 0 setlinewidth %% color i ample del llindar (0 assegura visibilitat òptima i prima)
mArgEs llindarJUSSA add 0 ERRORtlrnc AltCaixa mArgEs 2 mul add rectstroke %% tracem el llindar
grestore
gsave 0 0 0 setrgbcolor .0 setlinewidth %% color i ample del dial (0 assegura visibilitat òptima i prima)
mArgEs llindarJUSSA add ERRORtlrnc add dup 0 moveto %% X del dial de l'ample Mestre
AltCaixa mArgEs 2 mul add lineto %% Y del dial de l'ample Mestre
stroke grestore %% tracem
}ifelse
}
{ %% Distiller
vldrs
{ %% treballem amb transparències
[ /ca .5 /CA .5 /BM /Multiply /SetTransparency pdfmark %% treballant amb Distiller 6.0 (mínim)
0 0 1 0 setcolor
mArgEs llindarJUSSA add 0 ERRORtlrnc AltCaixa mArgEs 2 mul add rectfill %% omplim el llindar
grestore
gsave 0 0 0 setrgbcolor .2 setlinewidth %% color i ample del dial
mArgEs llindarJUSSA add ERRORtlrnc add dup 0 moveto %% X del dial de l'ample Mestre
AltCaixa mArgEs 2 mul add lineto %% Y del dial de l'ample Mestre
stroke grestore %% tracem
}
{ %% treballem SENSE transparències
0 0 0 1 setcolor .2 setlinewidth %% ample del llindar
mArgEs llindarJUSSA add 0 ERRORtlrnc AltCaixa mArgEs 2 mul add rectstroke %% tracem el llindar
grestore
gsave 0 0 0 setrgbcolor .2 setlinewidth %% color i ample del dial
mArgEs llindarJUSSA add ERRORtlrnc add dup 0 moveto %% X del dial de l'ample Mestre
AltCaixa mArgEs 2 mul add lineto %% Y del dial de l'ample Mestre
stroke grestore %% tracem
}ifelse
}ifelse
%% currentdict {== ==}forall (xxxxxxx) == quit
showpage
}if %% semMESTRE: compon amb prosa relativa als quadratins d'amplada de la Línia Mestre?
%% semFIXA: compon amb prosa fixa [24 punts] i estableix l'ample de Línia Mestre?
semUNA %% Compon sense prosa
{
%% missatge de composició
(\n\n ... compon sense prosa ...) print flush
%% desactivem llegir a fitxer!
%% (iudasautgenuitpharesetzarade) (r) file 64 string readline pop cvx exec %% capturem l'ample de Línia Mestre
%% el valor Mestre és el que ve de capçalera (camp de l'ample de Línia Mestre al web)
AltCaixa nQ mul %% nombre de quadratins pel seu valor en punts
/aMestre exch def %% el desem
%% gallet de detecció del codi del paràsit
/Cprst null def
%% el mateix format de plana que l'ample del text compost (o el aMestre) + els marges + el llindar
<<
/PageSize
liniaFA aMestre %% ERRORtlrnc add
gt
{ %% si l'ample de la línia és + gran que l'ample Mestre, doncs preval
liniaFA mArgEs 2 mul add
}
{ %% si no, deixem l'ample Mestre (+ els marges) com a format de pàgina
aMestre mArgEs 2 mul add
}ifelse
AltCaixa mArgEs 2 mul add 2 array astore
>>setpagedevice
%# componem la línia
mArgEs /araOb42 exch def %% valor inicial del punt actual d'origen X del caràcter
liniaB42
{ %% forall
dup xifratB42 exch get
0 get begin %% ara entrem de forma fixa la primera versió del caràcter
gsave
%% situem l'inici de la caixa del caràcter
araOb42 mArgEs translate
dup
dup 32 eq exch 35 eq or
{
pop
%% pintem la caixa de l'espai
gsave
Color cvx exec setrgbcolor 0 0 Caixa aload pop
%% 4 -1 roll gDlg add 4 1 roll exch gDlg sub exch %% rectifiquem per que no s'aixafi?
%% rectstroke
rectfill
grestore
Caixa 0 get end %% sortim del diccionari del B42 abans no desem el nou X
araOb42 add /araOb42 exch def %% actualitzem i desem pel proper origen
}
{
dup prstsB42 exch 3 string cvs known
%% false
{
%% (**!**) pstack quit
end
/Cprst exch def
}
{
pop
%% pintem la caixa del caràcter
gsave 0 0 1 setrgbcolor 0 0 Caixa aload pop
4 copy rectstroke grestore
%% fem el vincle virtual per que aparegui el nom del .DAT associat al passar el cursor per sobre
4 array astore
[
exch /Rect exch
/Subtype /Widget
/Ff 65536
%% generem un nom únic per mitjà de la posició X
/T araOb42 36 string cvs
%% l'etiqueta la forma el mateix DAT + el nom del caràcter
/TU DAT dup length 3 add dup /eldarrer exch def Caracter 1 get dup length 3 -1 roll add string dup 4 -1 roll
0 exch putinterval dup eldarrer 3 sub ( : ) putinterval dup 3 -1 roll eldarrer exch putinterval
/FT /Btn
/H /N
%% en cas que féssim vincles ...
%% /AA <</D << /S /Launch /F << /Type /Filespec /F pdfNEXT >> >> >>
/ANN
pdfmark
gsave
%% situem la línia de base del caràcter (nou punt 0,0)
0 UliniaDbase Modul:5 mul translate
gsave
%% situem l'origen del caràcter al punt 0,0 actual
Origen aload pop translate
%% capturem l'array del glif i ressucitem els operadors (suara literals)
glif {cvx exec}forall
%% pintem el caracter?
gsave
.75 .75 .75 setrgbcolor eofill grestore .5 0 .5 setrgbcolor stroke
grestore
grestore
%% pintem la línia d'ascendent
1 0 0 setrgbcolor
0 UliniaAscendent Modul:5 mul moveto
Caixa 0 get
dup
dup
UliniaAscendent Modul:5 mul lineto stroke
%% ara de forma fixa a 8 unitats matriu, doncs UliniaDbase canvia segons els caràcters!
%% pintem la línia de base
1 0 0 setrgbcolor
0 8 Modul:5 mul moveto Caixa 0 get 8 Modul:5 mul lineto stroke
%% :-/ aquí és on ajustem l'origen pel caràcter següent (tret que sigui zero)
dup OglifS 0 get sub sub %% restem del valor de l'ample de la Caixa del caràcter
end %% sortim del diccionari del B42 abans no desem el nou X
araOb42 add /araOb42 exch def %% actualitzem i desem pel proper origen
/darrerAmple exch def
%% si no és un null pintem el caràcter paràsit
Cprst null ne
%% false
{
save
xifratB42 Cprst get 0 get begin %% ara entrem de forma fixa la primera versió del caràcter
gsave
%% situem l'origen del caràcter al punt 0,0 actual
Origen aload pop
%% aquí cal centrar el paràsit en relació a l'ample del caràcter que el conté
darrerAmple Caixa 0 get sub 2 div 3 -1 roll
add exch
%% (***!!***) pstack quit
UliniaDbase Modul:5 mul add
translate
%% capturem l'array del glif i ressucitem els operadors (suara literals)
glif {cvx exec}forall
%% pintem el caràcter?
gsave
.75 .75 .75 setrgbcolor eofill grestore .5 0 .5 setrgbcolor stroke
grestore
grestore
end
restore
null /Cprst exch def
}if
}ifelse
}ifelse
grestore
}forall
%% en funció del % de tolerància d'error admesa calculem els llindars per sobre i per sota ...
PoM
{ %% deduïm el llindar per percentatges
PRCNTTGtlrnc aMestre mul 100 div
}
{ %% deduïm el llindar per unitats modulars
llM 1QuintuM mul
}ifelse
/ERRORtlrnc exch def %% valor en punts del llindar
aMestre ERRORtlrnc sub
10 mul truncate 10 div %% tallem només a 1 decimal
/llindarJUSSA exch def %% el llindar per sota
aMestre
10 mul truncate 10 div %% tallem només a 1 decimal
/llindarSOBIRA exch def %% el llindar per sobre (no hi ha llindar + enllà de l'ample Mestre)
%% posem el dial de l'ample Mestre de línia amb les toleràncies x transparència (o no)
%% hi ha un detector Dist/Ghost per saber si hem de generar la transparència per pdfmark o .setblendmode o res degut a GS anteriors al 8.54
gsave %% pintem l'àrea de tolerància del marge d'error (compresa entre el valor JUSSÀ i SOBIRÀ)
/DeviceCMYK setcolorspace
Ghost
{ %% Ghostscript
vldrs
{ %% treballem amb transparències
/Multiply .setblendmode .5 .setopacityalpha %% treballant amb Ghostscript 8.54 (mínim)
0 0 1 0 setcolor
mArgEs llindarJUSSA add 0 ERRORtlrnc AltCaixa mArgEs 2 mul add rectfill %% omplim el llindar
grestore
gsave 0 0 0 setrgbcolor 0 setlinewidth %% color i ample del dial (0 assegura visibilitat òptima i prima)
mArgEs llindarJUSSA add ERRORtlrnc add dup 0 moveto %% X del dial de l'ample Mestre
AltCaixa mArgEs 2 mul add lineto %% Y del dial de l'ample Mestre
stroke grestore %% tracem
}
{ %% treballem SENSE transparències
0 0 0 1 setcolor 0 setlinewidth %% color i ample del llindar (0 assegura visibilitat òptima i prima)
mArgEs llindarJUSSA add 0 ERRORtlrnc AltCaixa mArgEs 2 mul add rectstroke %% tracem el llindar
grestore
gsave 0 0 0 setrgbcolor .0 setlinewidth %% color i ample del dial (0 assegura visibilitat òptima i prima)
mArgEs llindarJUSSA add ERRORtlrnc add dup 0 moveto %% X del dial de l'ample Mestre
AltCaixa mArgEs 2 mul add lineto %% Y del dial de l'ample Mestre
stroke grestore %% tracem
}ifelse
}
{ %% Distiller
vldrs
{ %% treballem amb transparències
[ /ca .5 /CA .5 /BM /Multiply /SetTransparency pdfmark %% treballant amb Distiller 6.0 (mínim)
0 0 1 0 setcolor
mArgEs llindarJUSSA add 0 ERRORtlrnc AltCaixa mArgEs 2 mul add rectfill %% omplim el llindar
grestore
gsave 0 0 0 setrgbcolor .2 setlinewidth %% color i ample del dial
mArgEs llindarJUSSA add ERRORtlrnc add dup 0 moveto %% X del dial de l'ample Mestre
AltCaixa mArgEs 2 mul add lineto %% Y del dial de l'ample Mestre
stroke grestore %% tracem
}
{ %% treballem SENSE transparències
0 0 0 1 setcolor .2 setlinewidth %% ample del llindar
mArgEs llindarJUSSA add 0 ERRORtlrnc AltCaixa mArgEs 2 mul add rectstroke %% tracem el llindar
grestore
gsave 0 0 0 setrgbcolor .2 setlinewidth %% color i ample del dial
mArgEs llindarJUSSA add ERRORtlrnc add dup 0 moveto %% X del dial de l'ample Mestre
AltCaixa mArgEs 2 mul add lineto %% Y del dial de l'ample Mestre
stroke grestore %% tracem
}ifelse
}ifelse
showpage
%% llistem l'ample de la línia?
(\n\n >>> l'ample de linia es ... ) print flush
araOb42 mArgEs sub 32 string cvs print flush
( ... punts | ) print flush
%% araOb42 mArgEs sub 1QuintuM div %% calculem el valor en SubMòduls o en unitats matriu?
araOb42 mArgEs sub AltCaixa div %% calculem el valor en quadratins
32 string cvs print flush
%% ( ... unitats matriu <<<\n) print flush
( ... quadratins <<<\n) print flush
}if %% Compon sense prosa?
semTOTES %% componem amb totes les combinacions d'espais possibles segons l'amplada de Línia Mestre
{
%% missatge de composició
(\n\n ... component la linia amb TOTES les combinacions d'espaiat possibles ...) print flush
(iudasautgenuitpharesetzarade) (r) file 64 string readline pop cvx exec %% capturem l'ample de Línia Mestre
/aMestre exch def %% el desem
%% en funció del % de tolerància d'error admesa calculem els llindars per sobre i per sota ...
PoM
{ %% deduïm el llindar per percentatges
PRCNTTGtlrnc aMestre mul 100 div
}
{ %% deduïm el llindar per unitats modulars
llM 1QuintuM mul
}ifelse
/ERRORtlrnc exch def %% valor en punts del llindar
aMestre ERRORtlrnc sub
10 mul truncate 10 div %% tallem només a 1 decimal
/llindarJUSSA exch def %% el llindar x sota
aMestre
10 mul truncate 10 div %% tallem només a 1 decimal
/llindarSOBIRA exch def %% el llindar per sobre (no hi ha llindar + enllà de l'ample Mestre)
%% primer mirem si amb els màxims espais possibles a combinar assolim el llindarJUSSA (detectarem línies excessivament curtes)
0 /MassaCurta exch def %% ample total de la línia
motsB42 %% array amb els mots empaquetats
{ %% forall x cada mot
{ %% forall x cada caràcter del mot
xifratB42 exch get
0 get begin %% ara entrem de forma fixa la primera versió del caràcter
Caixa 0 get end %% sortim del dic del B42 i sumem l'ample (X)
MassaCurta add /MassaCurta exch def
}forall
xifratB42 32 get 0 get begin %% ara entrem de forma fixa la primera versió del caràcter
Caixa 0 get end %% sortim del diccionari del B42 i sumem l'ample (X)
2 mul %% calculem el doble espai ample
dup /darrerEspai exch def
MassaCurta add /MassaCurta exch def
}forall
%% restem el darrer espai que no existeix
MassaCurta darrerEspai sub /MassaCurta exch def
xifratB42 35 get 0 get begin %% ara entrem de forma fixa la primera versió del caràcter d'espai ample
Caixa 0 get end %% sortim del diccionari del B42 i sumem l'ample (X)
MassaCurta add /MassaCurta exch def %% sumem el darrer espai fi, possible al final de la línia
MassaCurta llindarJUSSA ge %% amb els màxims espais en blanc assolim el valor mínim de tolerància de llindarJUSSA?
{ %% si
false /esMassaCurta exch def
}
{ %% detectem línies massa curtes
true /esMassaCurta exch def
(\n\n >>> Ep! linia M A S S A C U R T A <<<\n ... la componem nomes UNA vegada ...\n) print flush
}ifelse
%% segon mirem si amb els mínims espais possibles a combinar superem el llindarSOBIRA (detectarem línies excessivament llargues)
0 /MassaLlarga exch def %% ample total de la línia
motsB42 %% array amb els mots empaquetats
{ %% forall per cada mot
{ %% forall per cada caràcter del mot
xifratB42 exch get
0 get begin %% ara entrem de forma fixa la primera versió del caràcter
Caixa 0 get end %% sortim del dic del B42 i sumem l'ample (X)
MassaLlarga add /MassaLlarga exch def
}forall
xifratB42 35 get 0 get begin %% ara entrem de forma fixa la primera versió del caràcter d'espai fi
Caixa 0 get end %% sortim del dic del B42 i sumem l'ample (X)
dup /darrerEspai exch def
MassaLlarga add /MassaLlarga exch def
}forall
%% restem el darrer espai que no existeix
MassaLlarga darrerEspai sub /MassaLlarga exch def
MassaLlarga llindarSOBIRA gt %% amb els mínims espais en blanc superem el valor màxim de tolerància de llindarSOBIRA?
{ %% detectem línies massa llargues
true /esMassaLlarga exch def
(\n\n >>> Ep! linia M A S S A L L A R G A <<<\n ... la componem nomes UNA vegada ...\n) print flush
}
{ %% no
false /esMassaLlarga exch def
}ifelse
%% MassaLlarga llindarSOBIRA (;;;;;;;) pstack quit
%% tercer i final, la componem només 1 vegada o componem amb totes les possibilitats amb el joc d'espais a combinar
esMassaLlarga esMassaCurta or %% si una de les dues és vertadera ...
{ %% componem només 1 vegada
esMassaLlarga %% per exemplificar millor l'error ...
{ %% el mateix format de plana que l'ample del text compost + els marges
<</PageSize liniaFA mArgEs 2 mul add AltCaixa mArgEs 2 mul add 2 array astore >>setpagedevice
}
{ %% el mateix format de plana que l'ample del text MESTRE + els marges
<</PageSize aMestre mArgEs 2 mul add AltCaixa mArgEs 2 mul add 2 array astore >>setpagedevice
}ifelse
%% componem la línia
mArgEs /araOb42 exch def %% valor inicial del punt actual d'origen X del caràcter
liniaB42
{ %% forall
dup xifratB42 exch get
0 get begin %% ara entrem de forma fixa la primera versió del caràcter
gsave
% situem l'inici de la caixa del caràcter
araOb42 mArgEs translate
dup 32 eq exch 35 eq or
{
%% pintem la caixa de l'espai
gsave
Color cvx exec setrgbcolor 0 0 Caixa aload pop
%% 4 -1 roll gDlg add 4 1 roll exch gDlg sub exch %% rectifiquem per que no s'aixafi?
%% rectstroke
rectfill
grestore
Caixa 0 get end %% sortim del diccionari del B42 abans no desem el nou X
araOb42 add /araOb42 exch def %% actualitzem i desem pel proper origen
}
{
%% pintem la caixa del caràcter
gsave 0 0 1 setrgbcolor 0 0 Caixa aload pop
4 copy rectstroke grestore
%% fem el vincle virtual per que aparegui el nom del .DAT associat al passar el cursor per sobre
4 array astore
[
exch /Rect exch
/Subtype /Widget
/Ff 65536
%% generem un nom únic per mitjà de la posicio X
/T araOb42 36 string cvs
%% l'etiqueta la forma el mateix DAT + el nom del caràcter
/TU DAT dup length 3 add dup /eldarrer exch def Caracter 1 get dup length 3 -1 roll add string dup 4 -1 roll
0 exch putinterval dup eldarrer 3 sub ( : ) putinterval dup 3 -1 roll eldarrer exch putinterval
/FT /Btn
/H /N
%% en cas que féssim vincles ...
%% /AA <</D << /S /Launch /F << /Type /Filespec /F pdfNEXT >> >> >>
/ANN
pdfmark
gsave
%% situem la línia de base del caràcter (nou punt 0,0)
0 UliniaDbase Modul:5 mul translate
gsave
%% situem l'origen del caràcter al punt 0,0 actual
Origen aload pop translate
%% capturem l'array del glif i ressucitem els operadors (suara literals)
glif {cvx exec}forall
%% pintem el caràcter?
gsave
.75 .75 .75 setrgbcolor eofill grestore .5 0 .5 setrgbcolor stroke
grestore
grestore
%% pintem la línia d'ascendent
1 0 0 setrgbcolor
0 UliniaAscendent Modul:5 mul moveto
Caixa 0 get
dup
UliniaAscendent Modul:5 mul lineto stroke
%% ara de forma fixa a 8 unitats matriu, doncs UliniaDbase canvia segons els caràcters!
%% pintem la línia de base
1 0 0 setrgbcolor
0 8 Modul:5 mul moveto Caixa 0 get 8 Modul:5 mul lineto stroke
%% :-/ aquí es on ajustem l'origen pel caràcter següent (tret que sigui zero)
dup OglifS 0 get sub sub %% restem del valor de l'ample de la Caixa del caràcter
end %% sortim del dic del B42 abans no desem el nou X
araOb42 add /araOb42 exch def %% actualitzem i desem pel proper origen
}ifelse
grestore
}forall
%% posem el dial de l'ample Mestre de línia amb les toleràncies x transparència (o no)
%% hi ha un detector Dist/Ghost per saber si em de generar la transparència per pdfmark o .setblendmode o res degut a GS anteriors al 8.54
gsave %% pintem l'àrea de tolerància del marge d'error (compresa entre el valor JUSSÀ i SOBIRÀ)
/DeviceCMYK setcolorspace
Ghost
{ %% Ghostscript
vldrs
{ %% treballem amb transparències
/Multiply .setblendmode .5 .setopacityalpha %% treballant amb Ghostscript 8.54 (mínim)
0 0 1 0 setcolor
mArgEs llindarJUSSA add 0 ERRORtlrnc AltCaixa mArgEs 2 mul add rectfill %% omplim el llindar
grestore
gsave 0 0 0 setrgbcolor .2 setlinewidth %% color i ample del dial
mArgEs llindarJUSSA add ERRORtlrnc add dup 0 moveto %% X del dial de l'ample Mestre
AltCaixa mArgEs 2 mul add lineto %% Y del dial de l'ample Mestre
stroke grestore %% tracem
}
{ %% treballem SENSE transparències
0 0 0 1 setcolor .2 setlinewidth %% ample del llindar
mArgEs llindarJUSSA add 0 ERRORtlrnc AltCaixa mArgEs 2 mul add rectstroke %% tracem el llindar
grestore
gsave 0 0 0 setrgbcolor .2 setlinewidth %% color i ample del dial
mArgEs llindarJUSSA add ERRORtlrnc add dup 0 moveto %% X del dial de l'ample Mestre
AltCaixa mArgEs 2 mul add lineto %% Y del dial de l'ample Mestre
stroke grestore %% tracem
}ifelse
}
{ %% Distiller
vldrs
{ %% treballem amb transparències
[ /ca .5 /CA .5 /BM /Multiply /SetTransparency pdfmark %% treballant amb Distiller 6.0 (mínim)
0 0 1 0 setcolor
mArgEs llindarJUSSA add 0 ERRORtlrnc AltCaixa mArgEs 2 mul add rectfill %% omplim el llindar
grestore
gsave 0 0 0 setrgbcolor .2 setlinewidth %% color i ample del dial
mArgEs llindarJUSSA add ERRORtlrnc add dup 0 moveto %% X del dial de l'ample Mestre
AltCaixa mArgEs 2 mul add lineto %% Y del dial de l'ample Mestre
stroke grestore %% tracem
}
{ %% treballem SENSE transparències
0 0 0 1 setcolor .2 setlinewidth %% ample del llindar
mArgEs llindarJUSSA add 0 ERRORtlrnc AltCaixa mArgEs 2 mul add rectstroke %% tracem el llindar
grestore
gsave 0 0 0 setrgbcolor .2 setlinewidth %% color i ample del dial
mArgEs llindarJUSSA add ERRORtlrnc add dup 0 moveto %% X del dial de l'ample Mestre
AltCaixa mArgEs 2 mul add lineto %% Y del dial de l'ample Mestre
stroke grestore %% tracem
}ifelse
}ifelse
showpage
%% llistem l'ample de la línia?
(\n >>> la linia a compondre fa ... ) print flush
araOb42 mArgEs sub 32 string cvs print flush
( ... punts | ) print flush
araOb42 mArgEs sub 1QuintuM div %% calculem el valor en SubMòduls o en unitats matriu?
32 string cvs print flush
( ... unitats matriu <<<\n\n >>> l'ample de Linia Mestre es de ... ) print flush
aMestre 32 string cvs print flush
( ... punts | ) print flush
aMestre 1QuintuM div %% calculem el valor en SubMòduls o en unitats matriu?
32 string cvs print flush
( ... unitats matriu) print flush
(\n >>> el llindar de tolerancia Mestre es de ... ) print flush
PoM
{ %% deduïm el llindar per percentatges
PRCNTTGtlrnc 32 string cvs print flush
( % ...\n) print flush
}
{ %% deduïm el llindar per unitats modulars
llM 32 string cvs print flush
( unitats matriu ...\n) print flush
}ifelse
( ... el que suposa un valor de ... ) print flush
ERRORtlrnc 32 string cvs print flush
( ... punts | ) print flush
ERRORtlrnc 1QuintuM div %% calculem el valor en SubMòduls o en unitats matriu?
32 string cvs print flush
( ... unitats matriu\n\n) print flush
}
{ %% totes les combinacions possibles jugant amb les 4 menes d'espais
[ %% paquet amb les quatre menes d'espais a jugar indexats entre 1 i 4
null %% índex 0
[35] %% índex 1 : 1 prim (35)
[32] %% índex 2 : 1 ample (32)
[32 35] %% índex 3 : 1 ample+1 prim (32+35)
[32 32] %% índex 4 : 2 amples (32+32)
] /els4espais exch def
/rEbUIg 0 def %% comptador de línies que no encaixen dins el llindar Mestre
/ReBuTJaDeS (ReBuTJaDeS.txt) (w) file def %% fitxer on escriurem (ascii) totes les línies rebutjades
/eNFiLa %% aquest procediment assaja primer la validesa de la llargada de línia en funció del llindar Mestre i si s'escau la compon
{
%% muntem la línia amb la combinatòria d'espais corresponent dins una cadena
%% primer cerquem la llargada de la cadena
0 /stringFA exch def
eMPRoVeM {els4espais exch get length stringFA add /stringFA exch def} forall %% els espais
motsB42 {length stringFA add /stringFA exch def} forall %% els mots
stringFA string /LAfila exch def %% la cadena que fa de buffer
LAfila /NullEncode filter /LAfilaF exch def %% el fitxer d'escriptura del buffer
motsB42 0 get {LAfilaF exch write}forall %% escrivim el primer mot (índex zero)
1 1 motsB42 length 1 sub
{ %% per tot l'array dels mots empaquetats començant per l'índex 1
dup 1 sub eMPRoVeM exch get els4espais exch get {LAfilaF exch write}forall %% escrivim l'espai
motsB42 exch get {LAfilaF exch write}forall %% escrivim el mot
}for
LAfilaF closefile
LAfila %% la fila amb la combinatòria d'espais interiors
dup length dup 1 add string dup dup 5 -1 roll 0 exch putinterval
3 -1 roll 35 put %% construïm la fila amb la combinatòria idem d'abans però amb l'espai prim # afegit al final
/LAfila# exch def %% desem la fila amb l'espai prim al final
%% componem la línia amb la combinatòria d'espais interiors que toqui
%% assaig per compondre la línia per saber si entra dins el llindar
0 /araOb42 exch def %% valor inicial del punt actual d'origen X del caràcter
LAfila
{ %% forall
xifratB42 exch get
0 get begin %% ara entrem de forma fixa la primera versió del caràcter
Caixa 0 get end %% sortim del dic del B42 abans no desem el nou X
araOb42 add /araOb42 exch def %% actualitzem i desem pel proper origen
}forall
%% fi d'assaig per compondre la línia
%% la llargada de línia, per ser vàlida, ha d'encaixar entre llindarJUSSA i llindarSOBIRA
araOb42 10 mul truncate 10 div %% tallem només a 1 decimal
dup llindarJUSSA ge
exch llindarSOBIRA le and %% només si ambdues són bones ...
{ %% línia vàlida per compondre
%% componem la línia de debò
%% el mateix format de plana que l'ample del text MESTRE + els marges
<</PageSize aMestre mArgEs 2 mul add AltCaixa mArgEs 2 mul add 2 array astore >>setpagedevice
mArgEs /araOb42 exch def %% valor inicial del punt actual d'origen X del caràcter
LAfila
{ %% forall
dup xifratB42 exch get
0 get begin %% ara entrem de forma fixa la primera versió del caracter
gsave
%% situem l'inici de la caixa del caràcter
araOb42 mArgEs translate
dup 32 eq exch 35 eq or
{
%% pintem la caixa de l'espai
gsave
Color cvx exec setrgbcolor 0 0 Caixa aload pop
%% 4 -1 roll gDlg add 4 1 roll exch gDlg sub exch %% rectifiquem per que no s'aixafi?
%% rectstroke
rectfill
grestore
Caixa 0 get end %% sortim del diccionari del B42 abans no desem el nou X
araOb42 add /araOb42 exch def %% actualitzem i desem pel proper origen
}
{
%% pintem la caixa del caràcter
gsave 0 0 1 setrgbcolor 0 0 Caixa aload pop
%% 4 copy DESACTIVEM LES ANOTACIONS DONCS INFLEN EXTRAORDINARIAMENT EL FITXER AMB MOLTES PLANES!
rectstroke grestore
%% fem el vincle virtual xq aparegui el nom del .DAT associat al passar el cursor per sobre
%% 4 array astore
%% [
%% exch /Rect exch
%% /Subtype /Widget
%% /Ff 65536
%% %% generem un nom unic per mitja de la posicio X
%% /T araOb42 36 string cvs
%% %% l'etiqueta la forma el mateix DAT + el nom del caracter
%% /TU DAT dup length 3 add dup /eldarrer exch def Caracter 1 get dup length 3 -1 roll add string dup 4 -1 roll
%% 0 exch putinterval dup eldarrer 3 sub ( : ) putinterval dup 3 -1 roll eldarrer exch putinterval
%% /FT /Btn
%% /H /N
%% %% en cas que fessim vincles ...
%% %/AA <</D << /S /Launch /F << /Type /Filespec /F pdfNEXT >> >> >>
%% /ANN
%% pdfmark
gsave
%% situem la línia de base del caràcter (nou punt 0,0)
0 UliniaDbase Modul:5 mul translate
gsave
%% situem l'origen del caràcter al punt 0,0 actual
Origen aload pop translate
%% capturem l'array del glif i ressucitem els operadors (suara literals)
glif {cvx exec}forall
%% pintem el caràcter?
gsave
.75 .75 .75 setrgbcolor eofill grestore .5 0 .5 setrgbcolor stroke
grestore
grestore
%% pintem la línia d'ascendent
1 0 0 setrgbcolor
0 UliniaAscendent Modul:5 mul moveto
Caixa 0 get
dup
UliniaAscendent Modul:5 mul lineto stroke
%% ara de forma fixa a 8 unitats matriu, doncs UliniaDbase canvia segons els caràcters!
%% pintem la línia de base
1 0 0 setrgbcolor
0 8 Modul:5 mul moveto Caixa 0 get 8 Modul:5 mul lineto stroke
%% :-/ aquí és on ajustem l'origen pel caràcter següent (tret que sigui zero)
dup OglifS 0 get sub sub %% restem del valor de l'ample de la Caixa del caràcter
end %% sortim del diccionari del B42 abans no desem el nou X
araOb42 add /araOb42 exch def %% actualitzem i desem pel proper origen
} ifelse
grestore
}forall
%% posem el dial de l'ample Mestre de línia amb les toleràncies x transparència (o no)
%% hi ha un detector Dist/Ghost per saber si em de generar la transparència per pdfmark o .setblendmode o res degut a GS anteriors al 8.54
gsave %% pintem l'àrea de tolerància del marge d'error (compresa entre el valor JUSSÀ i SOBIRÀ)
/DeviceCMYK setcolorspace
Ghost
{ %% Ghostscript
vldrs
{ %% treballem amb transparències
/Multiply .setblendmode .5 .setopacityalpha %% treballant amb Ghostscript 8.54 (mínim)
0 0 1 0 setcolor
mArgEs llindarJUSSA add 0 ERRORtlrnc AltCaixa mArgEs 2 mul add rectfill %% omplim el llindar
grestore
gsave 0 0 0 setrgbcolor .2 setlinewidth %% color i ample del dial
mArgEs llindarJUSSA add ERRORtlrnc add dup 0 moveto %% X del dial de l'ample Mestre
AltCaixa mArgEs 2 mul add lineto %% Y del dial de l'ample Mestre
stroke grestore %% tracem
}
{ %% treballem SENSE transparències
0 0 0 1 setcolor .2 setlinewidth %% ample del llindar
mArgEs llindarJUSSA add 0 ERRORtlrnc AltCaixa mArgEs 2 mul add rectstroke %% tracem el llindar
grestore
gsave 0 0 0 setrgbcolor .2 setlinewidth %% color i ample del dial
mArgEs llindarJUSSA add ERRORtlrnc add dup 0 moveto %% X del dial de l'ample Mestre
AltCaixa mArgEs 2 mul add lineto %% Y del dial de l'ample Mestre
stroke grestore %% tracem
}ifelse
}
{ %% Distiller
vldrs
{ %% treballem amb transparències
[ /ca .5 /CA .5 /BM /Multiply /SetTransparency pdfmark %% treballant amb Distiller 6.0 (mínim)
0 0 1 0 setcolor
mArgEs llindarJUSSA add 0 ERRORtlrnc AltCaixa mArgEs 2 mul add rectfill %% omplim el llindar
grestore
gsave 0 0 0 setrgbcolor .2 setlinewidth %% color i ample del dial
mArgEs llindarJUSSA add ERRORtlrnc add dup 0 moveto %% X del dial de l'ample Mestre
AltCaixa mArgEs 2 mul add lineto %% Y del dial de l'ample Mestre
stroke grestore %% tracem
}
{ %% treballem SENSE transparències
0 0 0 1 setcolor .2 setlinewidth %% ample del llindar
mArgEs llindarJUSSA add 0 ERRORtlrnc AltCaixa mArgEs 2 mul add rectstroke %% tracem el llindar
grestore
gsave 0 0 0 setrgbcolor .2 setlinewidth %% color i ample del dial
mArgEs llindarJUSSA add ERRORtlrnc add dup 0 moveto %% X del dial de l'ample Mestre
AltCaixa mArgEs 2 mul add lineto %% Y del dial de l'ample Mestre
stroke grestore %% tracem
}ifelse
}ifelse
showpage
%% ( ... LINIA VALIDA PER COMPONDRE ... ) pstack quit
}
{ %% línia rebutjada
rEbUIg 1 add /rEbUIg exch def %% comptador de línies que no encaixen dins el llindar Mestre
ReBuTJaDeS dup LAfila writestring (\015\012) writestring %% escrivim la línia rebutjada amb retorn dur
%% ( ... LINIA REBUTJADA ... ) pstack quit
}ifelse
%% componem la mateixa fila amb l'espai prim # al final
%% assaig de composició de línia per saber si entra dins el llindar per ser composta
0 /araOb42 exch def %% valor inicial del punt actual d'origen X del caràcter
LAfila#
{ %% forall
xifratB42 exch get
0 get begin %% ara entrem de forma fixa la primera versió del caràcter
Caixa 0 get end %% sortim del diccionari del B42 abans no desem el nou X
araOb42 add /araOb42 exch def %% actualitzem i desem pel proper origen
}forall
%% fi d'assaig per compondre la línia
%% la llargada de línia, per ser vàlida, ha d'encaixar entre llindarJUSSA i llindarSOBIRA
araOb42 10 mul truncate 10 div %% tallem només a 1 decimals
dup llindarJUSSA ge
exch llindarSOBIRA le and %% només si ambdues són bones ...
{ %% línia vàlida per compondre
%% componem la línia de debò
%% el mateix format de plana que l'ample del text MESTRE + els marges
<</PageSize aMestre mArgEs 2 mul add AltCaixa mArgEs 2 mul add 2 array astore >>setpagedevice
mArgEs /araOb42 exch def %% valor inicial del punt actual d'origen X del caràcter
LAfila#
{ %% forall
dup xifratB42 exch get
0 get begin %% ara entrem de forma fixa la primera versió del caràcter
gsave
%% situem l'inici de la caixa del caràcter
araOb42 mArgEs translate
dup 32 eq exch 35 eq or
{
%% pintem la caixa de l'espai
gsave
Color cvx exec setrgbcolor 0 0 Caixa aload pop
%% 4 -1 roll gDlg add 4 1 roll exch gDlg sub exch % rectifiquem per que no s'aixafi?
%% rectstroke
rectfill
grestore
Caixa 0 get end %% sortim del diccionari del B42 abans no desem el nou X
araOb42 add /araOb42 exch def %% actualitzem i desem pel proper origen
}
{
%% pintem la caixa del caràcter
gsave 0 0 1 setrgbcolor 0 0 Caixa aload pop
%% 4 copy DESACTIVEM LES ANOTACIONS DONC INFLEN EXTRAORDINARIAMENT EL FITXER AMB MOLTES PLANES!
rectstroke grestore
%% fem el vincle virtual xq aparegui el nom del .DAT associat al passar el cursor per sobre
%% 4 array astore
%% [
%% exch /Rect exch
%% /Subtype /Widget
%% /Ff 65536
%% %% generem un nom unic per mitja de la posicio X
%% /T araOb42 36 string cvs
%% %% l'etiqueta la forma el mateix DAT + el nom del caracter
%% /TU DAT dup length 3 add dup /eldarrer exch def Caracter 1 get dup length 3 -1 roll add string dup 4 -1 roll
%% 0 exch putinterval dup eldarrer 3 sub ( : ) putinterval dup 3 -1 roll eldarrer exch putinterval
%% /FT /Btn
%% /H /N
%% %% en cas que fessim vincles ...
%% %/AA <</D << /S /Launch /F << /Type /Filespec /F pdfNEXT >> >> >>
%% /ANN
%% pdfmark
gsave
%% situem la línia de base del caràcter (nou punt 0,0)
0 UliniaDbase Modul:5 mul translate
gsave
%% situem l'origen del caràcter al punt 0,0 actual
Origen aload pop translate
%% capturem l'array del glif i ressucitem els operadors (suara literals)
glif {cvx exec}forall
%% pintem el caràcter?
gsave
.75 .75 .75 setrgbcolor eofill grestore .5 0 .5 setrgbcolor stroke
grestore
grestore
%% pintem la línia d'ascendent
1 0 0 setrgbcolor
0 UliniaAscendent Modul:5 mul moveto
Caixa 0 get
dup
UliniaAscendent Modul:5 mul lineto stroke
%% ara de forma fixa a 8 unitats matriu, doncs UliniaDbase canvia segons els caràcters!
%% pintem la línia de base
1 0 0 setrgbcolor
0 8 Modul:5 mul moveto Caixa 0 get 8 Modul:5 mul lineto stroke
%% :-/ aquí és on ajustem l'origen pel caràcter següent (tret que sigui zero)
dup OglifS 0 get sub sub %% restem del valor de l'ample de la Caixa del caràcter
end %% sortim del diccionari del B42 abans no desem el nou X
araOb42 add /araOb42 exch def %% actualitzem i desem pel proper origen
} ifelse
grestore
}forall
%% posem el dial de l'ample Mestre de línia amb les toleràncies x transparència (o no)
%% hi ha un detector Dist/Ghost per saber si hem de generar la transparència per pdfmark o .setblendmode o res degut a GS anteriors al 8.54
gsave %% pintem l'àrea de tolerància del marge d'error (compresa entre el valor JUSSÀ i SOBIRÀ)
/DeviceCMYK setcolorspace
Ghost
{ %% Ghostscript
vldrs
{ %% treballem amb transparències
/Multiply .setblendmode .5 .setopacityalpha %% treballant amb Ghostscript 8.54 (mínim)
0 0 1 0 setcolor
mArgEs llindarJUSSA add 0 ERRORtlrnc AltCaixa mArgEs 2 mul add rectfill %% omplim el llindar
grestore
gsave 0 0 0 setrgbcolor .2 setlinewidth %% color i ample del dial
mArgEs llindarJUSSA add ERRORtlrnc add dup 0 moveto %% X del dial de l'ample Mestre
AltCaixa mArgEs 2 mul add lineto %% Y del dial de l'ample Mestre
stroke grestore %% tracem
}
{ %% treballem SENSE transparències
0 0 0 1 setcolor
mArgEs llindarJUSSA add 0 ERRORtlrnc AltCaixa mArgEs 2 mul add rectstroke %% tracem el llindar
grestore
gsave 0 0 0 setrgbcolor .2 setlinewidth %% color i ample del dial
mArgEs llindarJUSSA add ERRORtlrnc add dup 0 moveto %% X del dial de l'ample Mestre
AltCaixa mArgEs 2 mul add lineto %% Y del dial de l'ample Mestre
stroke grestore %% tracem
}ifelse
}
{ %% Distiller
vldrs
{ %% treballem amb transparències
[ /ca .5 /CA .5 /BM /Multiply /SetTransparency pdfmark %% treballant amb Distiller 6.0 (mínim)
0 0 1 0 setcolor
mArgEs llindarJUSSA add 0 ERRORtlrnc AltCaixa mArgEs 2 mul add rectfill %% omplim el llindar
grestore
gsave 0 0 0 setrgbcolor .2 setlinewidth %% color i ample del dial
mArgEs llindarJUSSA add ERRORtlrnc add dup 0 moveto %% X del dial de l'ample Mestre
AltCaixa mArgEs 2 mul add lineto %% Y del dial de l'ample Mestre
stroke grestore %% tracem
}
{ %% treballem SENSE transparències
0 0 0 1 setcolor .2 setlinewidth %% ample del llindar
mArgEs llindarJUSSA add 0 ERRORtlrnc AltCaixa mArgEs 2 mul add rectstroke %% tracem el llindar
grestore
gsave 0 0 0 setrgbcolor .2 setlinewidth %% color i ample del dial
mArgEs llindarJUSSA add ERRORtlrnc add dup 0 moveto %% X del dial de l'ample Mestre
AltCaixa mArgEs 2 mul add lineto %% Y del dial de l'ample Mestre
stroke grestore %% tracem
}ifelse
}ifelse
showpage
%% ( ... LINIA VALIDA PER COMPONDRE ... ) pstack quit
}
{ %% línia rebutjada
rEbUIg 1 add /rEbUIg exch def %% comptador de línies que no encaixen dins el llindar Mestre
ReBuTJaDeS dup LAfila# writestring (\015\012) writestring %% escrivim la línia rebutjada amb retorn dur
%% ( ... LINIA REBUTJADA ... ) pstack quit
}ifelse
}bind def
%% engeguem la combinatòria de selespensatotes3
%% aquest algorisme permet fer totes les combinacions possibles d'un joc d'elements (elsQjuguen)
%% envers un altre (llocsONcombinen), d'una forma universal i per qualsevol cosa (les treu per la pantalleta)
%% l'algorisme manega un sistema d'índex que genera estrictament les combinacions vàlides dins un paquet
%% sense necessitat de descartar-ne cap per redundàncies o superació de límits
%% Ho aplicarem d'entrada al componedor de línies de la Biblia 42L de Gutenberg (tesi de Luz Ma. Rangel)
%% tipus d'espais a combinar
%% en donem el valor per ordre (i no per índex) per facilitar-ne la gestió
/elsQjuguen [1 2 3 4] def %% hauríem de posar un filtre si aquest array podés tenir 1 sol element
%% el nombre d'espais entre paraules de la frase a generar la combinatòria
motsB42 length 1 sub %% un menys que els mots que juguen
/llocsONcombinen exch def %% hauríem de posar un filtre si aquest valor podés valer zero
elsQjuguen 0 get llocsONcombinen 1 sub {dup}repeat llocsONcombinen array astore
/BiNaCio exch def %% valor inicial de la combinatòria d'espais
BiNaCio dup length array copy /eMPRoVeM exch def %% == treiem per la pantalleta la combinació inicial
%% valor de l'índex d'unitats
llocsONcombinen 1 sub /iU exch def
%% valor màxim d'un sumador
elsQjuguen dup length 1 sub get /maxSum exch def
%% valor mínim d'un sumador
elsQjuguen 0 get /minSum exch def
%% valor inicial de l'índex sumador que no és d'unitats
iU 1 sub /iNOu exch def
elsQjuguen length llocsONcombinen exp cvi
dup (\n ... amb ... ) print flush llocsONcombinen 32 string cvs print flush
( ... espais, podriem compondre ... ) print flush 2 mul 32 string cvs print flush
( ... linies diferents!\n) print flush
(\n ... el llindar de tolerancia Mestre es de ... ) print flush
PoM
{ %% deduïm el llindar per percentatges
PRCNTTGtlrnc 32 string cvs print flush
( % ...\n) print flush
}
{ %% deduïm el llindar per unitats modulars
llM 32 string cvs print flush
( unitats matriu ...\n) print flush
}ifelse
( ... el que suposa un valor de ... ) print flush
ERRORtlrnc 32 string cvs print flush
( ... punts | ) print flush
ERRORtlrnc 1QuintuM div %% calculem el valor en SubMòduls o en unitats matriu?
32 string cvs print flush
( ... unitats matriu\n\n) print flush
eNFiLa %% analitzem i componem la doble possibilitat de combinatòria
%% (COMBINATORIA x FER) pstack quit
%% array /tOtEs exch def % l'array tOtEs és el magatzem que contindria totes les combinacions diferents possibles
%% valor de sortida del loop general de combinacions (totes -1 que és el valor inical de BiNaCio)
1 sub /Kampora exch def
%% índex inicial on escriure la combinatòria al magatzem tOtEs (si s'escau)
0 /COMBi exch def
{ %% loop generador de combinacions
BiNaCio iU get maxSum eq %% el sumador d'unitats ha arribat al seu valor màxim?
{
%% inicialitzem BiNaCio per les unitats a minSum
BiNaCio iU minSum put
%% tret que el valor situat a iNOu hagi arribat al màxim
BiNaCio iNOu get maxSum eq
{
%% endarrerim d'1 iNOu i sumem 1 al seu valor ...
%% tret que hi hagi algun minSum entremig de iNOu i iU
false /hiHA1Entremig exch def
iNOu 1 add 1 iU 1 sub
{ %% si n'hi ha algun el detectarem en aquest for
dup BiNaCio exch get minSum eq
{
true /hiHA1Entremig exch def /iNOu exch def %% és el nou iNOu !
}
{
pop
}ifelse
}for
hiHA1Entremig
{ %% doncs llavors afegim 1 al valor del darrer l'iNOu d'entremig
BiNaCio iNOu get 1 add BiNaCio exch iNOu exch put
BiNaCio dup length array copy /eMPRoVeM exch def % == treiem x la pantalleta la combinacio inicial
eNFiLa %% analitzem i componem la doble possibilitat de combinatòria
%% (<<<1>>>) ==
COMBi 1 add /COMBi exch def %% fem còrrer l'índex del magatzem
}
{
iNOu 1 sub /iNOu exch def
%% aquí hi ha d'anar un loop per detectar que anant enrere no hi hagi un iNOu igual a maxSum
{
BiNaCio iNOu get maxSum eq
{
iNOu 1 sub /iNOu exch def
}
{
exit
}ifelse
}loop
BiNaCio iNOu get 1 add BiNaCio exch iNOu exch put
%% ... i inicialitzem a minSum els valors que vagin de iNOu+1 fins iU
iNOu 1 add 1 iU {BiNaCio exch minSum put}for
BiNaCio dup length array copy /eMPRoVeM exch def % == treiem x la pantalleta la combinacio inicial
eNFiLa %% analitzem i componem la doble possibilitat de combinatòria
%% (<<<2>>>) ==
COMBi 1 add /COMBi exch def %% fem córrer l'índex del magatzem
}ifelse
}
{
%% afegim 1 al valor de iNOu tret que hi hagi algun minSum entremig de iNOu i iU
iNOu 1 add 1 iU 1 sub
{ %% si n'hi ha algun el detectarem en aquest for
dup BiNaCio exch get minSum eq
{
/iNOu exch def % nou iNOu !
}
{
pop
}ifelse
}for
BiNaCio iNOu get 1 add BiNaCio exch iNOu exch put
BiNaCio dup length array copy /eMPRoVeM exch def %% == treiem per la pantalleta la combinació inicial
eNFiLa %% analitzem i componem la doble possibilitat de combinatòria
%% (<<<3>>>) ==
COMBi 1 add /COMBi exch def %% fem córrer l'índex del magatzem
}ifelse
}
{
{ %% loop sumador d'unitats
BiNaCio iU get 1 add BiNaCio exch iU exch put
BiNaCio dup length array copy /eMPRoVeM exch def %% == treiem per la pantalleta la combinació inicial
eNFiLa %% analitzem i componem la doble possibilitat de combinatòria
%% (<<<4>>>) ==
COMBi 1 add /COMBi exch def %% fem córrer l'índex del magatzem
BiNaCio iU get maxSum eq {exit}if
}loop
}ifelse
Kampora COMBi eq {exit}if
}loop %% generador de combinacions
ReBuTJaDeS closefile %% tanquem el fitxer de línies rebutjades
( >>> han estat compostes ... ) print flush Kampora 1 add 2 mul rEbUIg sub 32 string cvs print flush
( ... linies, i ... ) print flush rEbUIg 32 string cvs print flush
( ... han estat rebutjades\n) print flush
}ifelse
}if %% componem amb totes les combinacions d'espais possibles segons l'amplada de Línia Mestre?
semTOTEStotes %% componem amb totes les combinacions d'espais i versions de caràcters possibles segons l'amplada de Línia Mestre
{
(\n >>> algorisme x implementar encara ... PLEGUEM!\n\n) print flush quit
}if %% componem amb totes les combinacions d'espais i versions de caràcters possibles segons l'amplada de Línia Mestre?
%% fi del ventall de composicions possibles
%% muntem el fitxer que servirà de gatell per executal.php per saber que tot ha anat bé i pot vincular el PDF generat
(dIspOnIblEs.flag) (w) file closefile
%% /DSPNBLS exch def
%% xifratB42
%% {
%% dup null eq
%% {
%% pop
%% }
%% {
%% 0 get /Caracter get 0 get 0 get DSPNBLS exch write DSPNBLS 32 write
%% %1 get (\n) print flush print flush
%% }ifelse
%% }forall
%% DSPNBLS closefile
%% definició dels camps públics del PDF
[
/Title liniaB42
/Keywords (\(Johannes\) Fust, \(Johannes\) Gutenberg, \(Peter\) Schöffer, Acuñación, Ascendentes, Average linkage, B-42, Biblia, Calígrafo, caligrafía, caligráfico, Carácter, Casa de moneda, Ceca, Cluster analysis \(análisis de conglomerados\), Clustering \(agrupación\), Clustering jerárquico aglomerativo, Clustering óptimo, Código fuente, Composición, Conservador, Contorno exterior, Contornos globales, Coordenadas, Cuerpo, DAT.B42, Dendrograma, Descendentes, Diferencia estructural, Diseño, Disimilaridad, Distancia, Escritura, Evangelio de Mateo, Fondo Antiguo, Fondo Tipográfico, FormPak, Fundición, Fundición Bauer-Neufville, Gensfleich, Ghostscript, Gótica textur, Grupo de control, Industria gráfica, Letras, Línea maestra, Matriz, matrices, Mayúsculas, MDS, Minúsculas, Mitutoyo, Modelo, Modulación, Módulo 'm', Molde, Muestra, Multidimensional Scaling, Nuevo Testamento, Pauta, Póliza francesa, Póliza múltiple, Pseudoformato tipográfico, Punzón, punzones, QVision, QVPak, lenguaje R, Rialera, Software libre, Tallador, Terminal, Test de Dixon, Test estadístico para la detección de outliers, Tipo, tipografía, tipográfica, tipográfico, Tipos móviles, Universidad de Sevilla, VentaQVdat, Aglomerative hierarchical, Ascending, Bible, Body, Calligrapher, calligraphy, calligraphic, Capitalized, Carver, Character, Cluster analysis, Clustering optimal, Codes, Coin, coined, Composition, Conservative, Contour, Control group, Coordinates, Dendrogram, Descending, Dissimilarity, dissimilarities, Distance, Dixon's Test, Font, Foundry, French policy, Gauge, Gospel of Matthew, Gothic textura, Ingot molds, Lowercase, Master line, Matrix, matrices, Mint, Model, Modulation, Module 'm', Mold, Movable type, multiple typographic bill, New Testament, Outline, Pseudoformat, punch, punches, R laguage \(data processing\), Sample, Scripture, Statistical, Terminal, Test for detecting outlier, Textur, Type, typography, typographic, typographical, Encunyació, Ascendents, Bíblia, Cal·lígraf, cal·ligrafia, cal·Ligràfic, Caràcter, Seca, anàlisi de conglomerats, Clustering jeràrquic aglomeratiu, Clustering òptim, Codi font, Composició, Contorn exterior, Contorns globals, Coordenades, Cos, Descendents, Diferència estructural, Disseny, Dissimilaritat, Distància, Escriptura, Evangeli de Mateu, Fons Antic, Fons Tipogràfic, Gòtica textur, Grup de control, Indústria gràfica, Lletres, Línia mestra, Matriu, matrius, Majúscules, Minúscules, Model, Modulació, Mòdul 'm', Motlle, Mostra, Nou Testament, Pòlissa francesa, Pòlissa múltiple, Pseudoformat tipogràfic, Punxó, punxons, llenguatge R \(tractament de dadesi\), Programari lliure, Tallador, Test estadístic per a la detecció de outliers, Tipus, tipografia, tipogràfica, tipogràfic, Tipus mòbils, femfum, open source software, postscript, universitat de barcelona, tesi doctoral, PhD Thesis)
/Author (Luz Ma. Rangel Alanís & Marc Antoni Malagarriga i Picas)
/Subject (Componedor de la Bíblia de 42 línies)
/Creator (GNU ginyB42.ps Applet)
/DOCINFO
pdfmark
%% missatge de final
(\n\n ... F E T A !\n\n\n) print flush