Bernard Delechamp le 9 novembre 2000 Pour mon job, j'ai eu besoin de générer une page de garde de fax pour HylaFAX, personnalisable et utilisable par le programme client whfc (http://www.transcom.de/whfc/) sous Windows95/98. Après avoir suivi la FAQ de HylaFAX (http://www.hylafax.org/HylaFAQ/Q202.html) quant à la génération de page de garde, je n'y suis pas parvenu, ni avec tgif (http://bourbon.cs.umd.edu:8001/tgif/), ni avec killustrator, couplés avec le script sed make_faxcover (file://sgi.com/sgi/fax/contrib/covers/make_faxcover.tar.Z). Ces tentatives m'ont permis de travailler avec tgif, superbe logiciel qui gagnerait à être plus connu et que je vous engage à découvrir si ce n'est déjà fait ;-) Fermons de ce pas la parenthèse. J'ai suivi à la lettre les explications, mais les variables refusent de s'imprimer. Ne connaissant pas suffisamment le langage postscript, j'ai essayé de voir si StarOffice ne permettrait pas de réaliser ce travail. Je me suis rendu compte que le postscript généré par StarOffice sous GNU/Linux était radicalement différent de ce que les autres logiciels produisent. En effet, chaque caractère fait l'objet d'une ligne de la forme : yy xx C Ce qui fait que l'impression d'une chaîne de 3 caractères va en générer une bonne cinquantaine dans le fichier postscript. Les champs de chaque ligne sont les suivants : hh : Code hexadécimal du caractère à générer. xx : Abscisse sur la page. yy : Ordonnée sur la page. C : Appel de la macro-instruction 'C' qui va se positionner dans la page et imprimer le caractère voulu. Remarque : le postscript créé par MS-Word sous Windows reprend le même principe, mais avec quelques variantes. Tout ceci sortant du débat, nous n'en parlerons pas plus longtemps ;-) I Création de la page de garde sous StarOffice ---------------------------------------------- Il s'agira d'un document texte des plus classiques, dans lequel on va positionner des caractères spéciaux aux emplacements où l'on désire faire apparaître des champs HylaFAX. Je n'ai pas pu utiliser la méthode préconisée pour make_faxcover, à savoir : faire précéder chaque nom de champ HylaFAX de la chaîne de caractères 'XXXX-' car cela aurait entraîné l'obligation de traiter de 7 à 22 lignes avant de connaître le paramètre souhaité. Aux emplacements prévus pour les variables, on mettra les codes de champs suivants (voir la page de man de faxcover pour les descriptions plus complètes) : Champ SO Champ HylaFAX ?A to ?B to-company ?C to-location ?D to-voice-number ?E to-fax-number ?F comments ?G regarding ?H pageWidth ?I pageLength ?J from ?K from-company ?L from-location ?M from-voice-number ?N from-fax-number ?O page-count ?P todays-date ?a à ?t comments1 à comments20 J'ai choisi le caractère '?' pour annoncer les champs, car, si la syntaxe française est respectée, il ne peut être suivi ni d'un chiffre, ni d'une lettre. De plus, il est sans doute moins fréquent que d'autres signes de ponctuation. Il faut veiller à laisser, après chaque champ, un espace suffisant pour éviter les sur-impressions. Un bon conseil peut être de ne mettre qu'un champ par ligne. II Génération du fichier postscript ----------------------------------- Dans le menu fichier de StarOffice, choisir Imprimer, choisir une imprimante postscript (une laser quelconque avec le pilote «Generic Printer» devrait faire l'affaire), sélectionner «Imprimer dans un fichier», indiquer un nom de fichier, valider, et c'est tout, en principe. Par exemple, pour écrire «À l'attention de ?A», vous devez obtenir quelque chose qui ressemble à ça (j'ai ajouté les caractères écrits entre parenthèses) : 252.96 102.72 C (À) <20> 263.04 102.72 C ( ) <6c> 266.64 102.72 C (l) <27> 270.48 102.72 C (') <61> 275.04 102.72 C (a) <74> 282.0 102.72 C (t) <74> 286.56 102.72 C (t) <65> 291.12 102.72 C (e) <6e> 297.36 102.72 C (n) <74> 305.04 102.72 C (t) <69> 309.6 102.72 C (i) <6f> 313.44 102.72 C (o) <6e> 320.4 102.72 C (n) <20> 328.08 102.72 C ( ) <64> 331.68 102.72 C (d) <65> 339.36 102.72 C (e) <20> 345.6 102.72 C ( ) <3a> 349.2 102.72 C (:) <3f> 252.96 118.8 C (?) <41> 263.04 118.8 C (A) Les deux dernières lignes ci-dessus doivent être remplacées par : 252.96 118.8 M /to IS puisque <3f><41> correspond à ?A qui a été affecté au champ /to, si vous avez suivi jusque là ;-) III Principes du script ----------------------- Il y a en fait deux choses à faire : 1) Insérer en début de fichier les quelques macros nécessaires. Là, je ne me suis pas cassé, j'ai repris ce qui est indiqué dans la HylaFAQ, merci au(x) mainteneur(s). 2) Repérer chaque ligne qui demande à imprimer un '?', et qui doit donc comporter : <3f> abscisse ordonnée C On doit alors mémoriser les coordonnées, et voir ce que contient la ligne suivante. Si elle contient une lettre attendue selon la table de correspondance ci-dessus (vous suivez ?), on remplace les deux lignes par une seule telle que : abscisse ordonnée M /macro IS Dans le cas contraire, c'est que la page devait comporter un caractère '?', donc il faut générer les deux lignes originelles sans les modifier. IV Le script «make_pgard» ------------------------- Le script proposé est écrit en bash. Il fonctionne, j'ai essayé de l'optimiser au maximum, mais il gagnerait sans doute à l'être encore, voire à être réécrit dans un langage plus puissant, perl, C, python, COBOL, ALGOL, PL/1, BASIC, etc. (Pour les 4 derniers, je déc...ne) N'hésitez pas à me tenir au courant des tests que vous pourrez avoir faits, des bugs rencontrés, et des améliorations apportées. Que tous les contributeurs en soient remerciés par avance. #!/bin/bash # # Script permettant de transformer un fichier postscript créé avec # StarOffice en une page de garde utilisable par HylaFAX # if [ $# -eq 0 ] ; then echo "usage $0 fichier.entrée.ps [> fichier.sortie.ps]" exit 1 fi IFS=$(echo -ne "\n\r") for LIGNE in $(cat $1) ; do # Récupérer le 1er champ de la ligne PREM_MOT="${LIGNE%% *}" if [ "${ENCOURS}" ] ; then # Paramètre en cours de traitement ENCOURS="" # Ne garder que les chiffres du champ. # Je ne sais pas si c'est une bonne idée d'éliminer les # caractères < et >. On verra à l'usage... PREM_MOT=${PREM_MOT%>} ; PREM_MOT=${PREM_MOT#<} # Recherche de la lettre identifiant la macro case "${PREM_MOT}" in 41) MACRO=to ;; 42) MACRO=to-company ;; 43) MACRO=to-location ;; 44) MACRO=to-voice-number ;; 45) MACRO=to-fax-number ;; 46) MACRO=comments ;; 47) MACRO=regarding ;; 48) MACRO=pageWidth ;; 49) MACRO=pageLength ;; 4a) MACRO=from ;; 4b) MACRO=from-company ;; 4c) MACRO=from-location ;; 4d) MACRO=from-voice-number ;; 4e) MACRO=from-fax-number ;; 4f) MACRO=page-count ;; 50) MACRO=todays-date ;; 61) MACRO=comments1 ;; 62) MACRO=comments2 ;; 63) MACRO=comments3 ;; 64) MACRO=comments4 ;; 65) MACRO=comments5 ;; 66) MACRO=comments6 ;; 67) MACRO=comments7 ;; 68) MACRO=comments8 ;; 69) MACRO=comments9 ;; 6a) MACRO=comments10 ;; 6b) MACRO=comments11 ;; 6c) MACRO=comments12 ;; 6d) MACRO=comments13 ;; 6e) MACRO=comments14 ;; 6f) MACRO=comments15 ;; 70) MACRO=comments16 ;; 71) MACRO=comments17 ;; 72) MACRO=comments18 ;; 73) MACRO=comments19 ;; 74) MACRO=comments20 ;; *) # ? n'était pas suivi de A à P ni # de a à p : générer la ligne # précédente telle quelle echo "${LIGNE_PREC}" MACRO="" ;; esac if [ "${MACRO}" ] ; then # Il y avait une macro, la générer echo "${ADRESSE% *} M /${MACRO} IS" continue fi fi if [ "${PREM_MOT}" = "<3f>" ] ; then # On trouve le signe '?'. # Attendre de décoder la ligne suivante # Conserver les coordonnées ADRESSE=${LIGNE#* } # Une macro est en cours de traitement, # voir la ligne suivante du fichier. ENCOURS=OUI else # Ligne normale (sic) echo "${LIGNE}" # Insérer, éventuellement, les macros complémentaires [ "${LIGNE}" = "%%BeginProlog" ] && echo "%% %% Lignes ajoutées par make_pgard, définition des macros complémentaires %% 1 setlinejoin /nullstring () def /IS { dup where { pop load dup nullstring ne {S} {pop} ifelse } {pop} ifelse } bind def /M { moveto } bind def /S { show } bind def %% Fin de l'ajout de make_pgard " fi LIGNE_PREC=${LIGNE} done # Si la dernière ligne comportait "<3f>...", la générer telle que [ "${ENCOURS}" ] && echo "${LIGNE_PREC}" ############################################ C'est fini V Mode d'emploi --------------- Faire un copier-coller du script dans un répertoire figurant dans votre path, /usr/local/bin est peut-être un bon choix, sous le nom «make_pgard» par exemple. Exécuter le script par : make_pgard fichier_ps_généré_par_SO >votre_page_de_garde Testez le fichier généré en construisant une page de garde à l'aide de faxcover : faxcover -f nom -n num -C votre_page_de_garde >essai Regardez le man de faxcover pour les autres options possibles, modifiez éventuellement le fichier obtenu (essai). Aux environs de la ligne n° 50, vous devriez trouver des lignes qui ressemblent à ceci (définitions des macros) : /to (Nom du destinataire) def /to-company (Société destinataire) def /to-location (Lieu destinataire) def /to-voice-number (04 xxxxxx) def /to-fax-number (04 xxxxxx) def /pageWidth 209.97 def /pageLength 296.97 def /from (votre nom) def /from-fax-number (04 xxxxxx) def /from-voice-number (04 xxxxxx) def /from-company (Votre société) def /from-location (Ici) def /page-count () def /todays-date (Thu Nov 09 2000, 10:48 CET) def /regarding (Objet) def /comments (Commentaires) Vous modifiez comme bon vous semble, et vous faites un essai d'impression. Attention, ça peut demander pas mal de temps, entre le transfert vers l'imprimante et l'exécution du postscript, soit par l'imprimante, soit par votre filtre, il peut s'écouler de longues secondes. Si ça marche, il suffit alors de copier le fichier généré par make_pgard à la place de la page de garde par défaut de HylaFAX, chez moi «/home/local/lib/fax/faxcover.ps». Évidemment, sauvegardez le fichier original auparavant. Enfin, c'est vous qui voyez. Si vous utilisez le programme client whfc sous Windows (http://www.transcom.de/whfc/), copiez également le même fichier sur chaque machine du réseau, et configurez chaque whfc pour qu'il aille chercher sa (ou ses) page(s) de garde au bon endroit. VI Oufffffffff -------------- That's all folk.