Salut les agrumes.
Dans une enfilage sur le clavier, j’avais avoué ma passion pour l’histoire des systèmes et matériels informatiques ; et dans diverses autres discussion, j’ai souvent évoqué l’influence des téléscripteurs (en tant que périphériques d’entrée-sortie) sur le système Unix, un processeur de textes commandé textuellement… C’est cet aspect que j’aimerais rappeler à travers quelques commandes oubliées.
- intro au kilomètre
- replis sur bord de lignes
- paragraphes ajustées à une largeur
- expansion au taquet
- paragraphes au large
- balle au centre et égalisation
- impressions standards
- impressions avancées
- impression en chasse fixe
intro au kilomètre
J’ai souvenir qu’on enseignait à une certaine époque (j’ai l’impression que ce n’est plus vrai quand je regarde autour de moi) que dans la création de documents textes (lettre, rédaction, roman, etc.) il y a deux étapes distinctes : la saisie (dite au kilomètre) d’une part, et la mise en forme d’autre part. Un éditeur modal, comme vi
, permet d’observer cette règle facilement : on est en mode saisie (insertion ou ajout) pour la partie de saisie, et en mode commandes pour la partie édition avant mise en forme…
Lors de cette phase de saisie brute, les traitements de texte moderne nécessitent de distinguer le simple saut de ligne du changement de paragraphe (qui est associé à la touche ⏎). Dans un éditeur de texte, que ce soit pour avec un balisage ou directement pour l’imprimante comme dans le cas présent, c’est plus simple : la touche ⏎ permet de juste passer à la ligne (ce qui est rarement nécessaire), et il faut sauter au moins une ligne pour indiquer un nouveau paragraphe.
Une fois son texte saisi (input mode) et corrigé (command mode), il faut le mettre en forme pour l’impression (ou l’affichage sur le terminal…) Les systèmes Unix offrent quelques outils pour cela.
replis sur bord de lignes
Le premier, peu connu, est le filtre POSIX « fold
» (qui signifie plier/replier), apparu dans 1BSD en 1977 (sortie officielle de la distribution en mars 1978).
utilisation simple
On lui indique la largeur voulue avec l’option « -w
» (par défaut c’est du 80
caractères…) Il va être utile pour adapter la largeur du texte, en particulier lorsqu’on l’envoie vers une imprimante (sans retour de ligne, les lignes trop longues sont juste tronquées…) On peut l’utiliser aussi pour voir le résultat du même texte avec une largeur d’écran différente. Exemple :
$ echo "The _fold_ utility is a filter that shall fold lines from its\
input files, but breaking the lines to have a maximum of _width_\
column position (or bytes, if the *-b* option is specified)." | fold
The _fold_ utility is a filter that shall fold lines from its input files, but b
reaking the lines to have a maximum of _width_ column position (or bytes, if the
*-b* option is specified).
$ echo "The _fold_ utility is a filter that shall fold lines from its\
input files, but breaking the lines to have a maximum of _width_\
column position (or bytes, if the *-b* option is specified)." | fold -w 75
The _fold_ utility is a filter that shall fold lines from its input files,
but breaking the lines to have a maximum of _width_ column position (or byt
es, if the *-b* option is specified).
$ echo "The _fold_ utility is a filter that shall fold lines from its\
input files, but breaking the lines to have a maximum of _width_\
column position (or bytes, if the *-b* option is specified)." | fold -w 60
The _fold_ utility is a filter that shall fold lines from it
s input files, but breaking the lines to have a maximum of _
width_ column position (or bytes, if the *-b* option is spec
ified).
Le fonctionnement est un peu simplet : noter la coupe abrupt des mots …sauf si on utilise l’option « -s
» qui demande de couper aux espaces !
$ echo "The _fold_ utility is a filter that shall fold lines from its\
input files, but breaking the lines to have a maximum of _width_\
column position (or bytes, if the *-b* option is specified)." > wrap.txt
$ fold wrap.txt | tr ' ' '~'
The~_fold_~utility~is~a~filter~that~shall~fold~lines~from~its~input~files,~but~b
reaking~the~lines~to~have~a~maximum~of~_width_~column~position~(or~bytes,~if~the
~*-b*~option~is~specified).
Use~*-s*~option~to~split~at~latest~space~before~maximum~_width_.
The~_fmt_~utility~is~a~filter~that~shall~reformat~each~paragraph~from~its~input~
files,~but~break~the~lines~to~have~a~maximum~of~_width_~column~position.
$ fold -s wrap.txt | tr ' ' '~'
The~_fold_~utility~is~a~filter~that~shall~fold~lines~from~its~input~files,~but~
breaking~the~lines~to~have~a~maximum~of~_width_~column~position~(or~bytes,~if~
the~*-b*~option~is~specified).
Use~*-s*~option~to~split~at~latest~space~before~maximum~_width_.
The~_fmt_~utility~is~a~filter~that~shall~reformat~each~paragraph~from~its~input~
files,~but~break~the~lines~to~have~a~maximum~of~_width_~column~position.
$ fold -s -w 75 wrap.txt | tr ' ' '~'
The~_fold_~utility~is~a~filter~that~shall~fold~lines~from~its~input~files,~
but~breaking~the~lines~to~have~a~maximum~of~_width_~column~position~(or~
bytes,~if~the~*-b*~option~is~specified).
Use~*-s*~option~to~split~at~latest~space~before~maximum~_width_.
The~_fmt_~utility~is~a~filter~that~shall~reformat~each~paragraph~from~its~
input~~files,~but~break~the~lines~to~have~a~maximum~of~_width_~column~
position.
$ fold -w 60 -s wrap.txt | tr ' ' '~'
The~_fold_~utility~is~a~filter~that~shall~fold~lines~from~
its~input~files,~but~breaking~the~lines~to~have~a~maximum~
of~_width_~column~position~(or~bytes,~if~the~*-b*~option~is~
specified).
Use~*-s*~option~to~split~at~latest~space~before~maximum~
_width_.
The~_fmt_~utility~is~a~filter~that~shall~reformat~each~
paragraph~from~its~input~files,~but~break~the~lines~to~have~
a~maximum~of~_width_~column~position.
usage détourné
J’utilise cette commande dans mes scripts pour des traitements caractère par caractère, de petites chaînes :
# from variable
for char in $(echo "$var" | fold -w 1); do stuff; done
# from file
for char in $(fold -w 1 "$filepath"); do stuff; done
…chose qu’on peut faire aussi à l’aide de grep
:
# from variable
for char in $(echo "$var" | grep -os '.'); do stuff; done
# from file
for char in $(grep -os '.' "$filepath"); do stuff; done
Mais préférez plutôt (plus robuste et accepte de longues chaînes de caractères) :
# from variable
echo "$var" | fold -w 1 | {
while read char; do stuff; done
}
# from file
fold -w 1 "$filepath" | {
while read char; do stuff; done
}
et faites gaffe à IFS
…
paragraphes ajustées à une largeur
Il existe un autre filtre, apparu dans 2BSD en 1978 et vite adopté par d’autres distributions. Il porte le nom de « fmt
» pour « ForMat Text »… (En dehors du système, c’est un sigle qui peut avoir plusieurs sens en français comme en anglais et ailleurs. Dans de nombreux langages de programmation, c’est souvent le nom de la bibliothèque pour faire du formatage de données —textes/nombres/etc., cousin de « printf
» et « sprintf
» anciennement connu sous le nom de « cppformat
» et qui est utilisé par exemple dans Go et dans Java EE en tant que JSTL etc.)
utilisation et options
On lui indique aussi la largeur voulue avec l’option « -w
» (cf. encadré d’information plus bas pour la valeur par défaut.)
$ fmt wrap.txt | tr ' ' '~'
The~_fold_~utility~is~a~filter~that~shall~fold~lines~from~its~input~files,
but~breaking~the~lines~to~have~a~maximum~of~_width_~column~position~
(or~bytes,~if~the~*-b*~option~is~specified).~~Use~*-s*~option~to~split
at~latest~space~before~maximum~_width_.
The~_fmt_~utility~is~a~filter~that~shall~reformat~each~paragraph~from
its~input~ files,~but~break~the~lines~to~have~a~maximum~of~_width_
column~position.
$ fmt -w 80 wrap.txt | tr ' ' '~'
The~_fold_~utility~is~a~filter~that~shall~fold~lines~from~its~input~files,
but~breaking~the~lines~to~have~a~maximum~of~_width_~column~position~(or~bytes,
if~the~*-b*~option~is~specified).~~Use~*-s*~option~to~split~at~latest~space
before~maximum~_width_.
The~_fmt_~utility~is~a~filter~that~shall~reformat~each~paragraph~from~its
input~files,~but~break~the~lines~to~have~a~maximum~of~_width_~column~position.
$ fmt -w 60 wrap.txt | tr ' ' '~'
The~_fold_~utility~is~a~filter~that~shall~fold~lines~from
its~input~files,~but~breaking~the~lines~to~have~a~maximum
of~_width_~column~position~(or~bytes,~if~the~*-b*~option
is~specified).~~Use~*-s*~option~to~split~at~latest~space
before~maximum~_width_.
The~_fmt_~utility~is~a~filter~that~shall~reformat~each
paragraph~from~its~input~files,~but~break~the~lines~to
have~a~maximum~of~_width_~column~position.
Il met en œuvre la notion de mots comme suite de caractères séparés par des blancs, et reconnait la notion de paragraphe comme étant séparés par une ou plusieurs lignes vides (comme « ex
/vi
» hé hé.) Du coup, il peut appliquer un retrait à la première ligne du paragraphe (option « -p
» de l’implémentation BSD) …ou carrément l’inverse (option « -t
» de l’implémentation GNU.) Eh oui, la typographie n’a pas attendu les traitements de texte… (voir ci et là ou là par exemple.)
On notera qu’il connait aussi la notion de phrase comme étant terminées par une ponctuation de fin (point… final, d’interrogation, d’exclamation, en fait comme dans « ex
/vi
» hé hé) et peut alors appliquer la règle typographique anglophone d’espacement (datant de l’époque des machines à écrire et devant faciliter la lecture) : une seule espace entre les mots et deux espaces entre les phrases. (BSD « -s
» ou GNU « -u
») Noter que la commande « J
» de « ed
/ex
/vi
» procède normalement ainsi…
D’autres implémentations peuvent offrir de centrer le texte sur la ligne ou d’autres options sympathiques, comme de conserver les lignes dans les paragraphes (GNU « -s
»)
OpenBSD/FreeBSD | GNU/Linux | Sun Solaris | Plan 9 | IBM AIX | Minix | |
---|---|---|---|---|---|---|
-w Ⅰ |
-w Ⅰ |
-w Ⅰ |
-w Ⅰ |
-w Ⅰ |
-w Ⅰ |
use Ⅰ Width output (default goal is around 93% of width) |
-Ⅰ |
-Ⅰ |
-Ⅰ |
-l Ⅰ |
-Ⅰ |
-Ⅰ |
use Ⅰ width output |
Ⅰ |
-g Ⅰ |
goal is Ⅰ (and max width is Ⅰ+10 unless specified) |
||||
Ⅰ Ⅱ |
-g Ⅰ -w Ⅱ |
goal is Ⅰ and max width is Ⅱ |
||||
-c |
Center | |||||
-d Ⅹ |
sentence ending Delimiters are Ⅹ |
|||||
-l Ⅰ |
replace Ⅰ spaces with tabs at beginning of line |
|||||
-m |
try to format Mail headers too | |||||
-n |
disable Nroff compatibility so not skip lines starting with '.' | |||||
-p |
indent Paragraph first line | |||||
-t |
Tagged paragraph (indent lines but first) | |||||
-s |
-u |
Uniformize white spaces by Single one/two between words/sentences | ||||
-t Ⅰ |
replace Tabs with Ⅰ spaces instead of 1 |
|||||
-p Ⅹ |
reformat only lines beginning with Ⅹ Prefix |
|||||
-c |
-c |
-c |
preserve indentation of first two lines = try to be smarter about Crown margin | |||
-s |
-s |
-j |
-s |
Split/fold only long lines but do not refill (i.e. Join short lines) | ||
-i Ⅰ |
Indent each line with Ⅰ spaces |
|||||
-i Ⅹ |
allow the Indentation text to include any character from Ⅹ (quote the chars list to protect it from the shell), in addition to spaces and tabs |
|||||
-C |
is short for -c -i'/*' and is useful for reformatting C/C++ Comments |
|||||
-M |
is short for -c -i'>' and is useful for reformatting eMail Messages |
Ceci dit, il ne faut se limiter qu’à une option, « -w
… » (voire même juste « -
… » puisque d’anciennes implémentation AIX ne connaissent que ce dernier mais que cette dernière forme n’est pas reconnue sur Plan 9…)
Pour le travail de base, « fmt
» est quasiment équivalent à « fold -s
». Ainsi, « fold
» reste intéressant quand il faut respecter les sauts de lignes, tandis que « fmt
» va formater un paragraphe en essayant d’avoir un texte homogène…
La largeur par défaut n’est pas la même selon les implémentations (et ce n’est pas une commande POSIX), mais est toujours en accord avec la nétiquette et les RFC du courriel…
75
pour BSDwith lines as close to the goal length as possible without exceeding the maximum. The goal length defaults to 65 and the maximum to 10 more than the goal length.
75
pour GNUmaximum line width (default of 75 columns)
72
pour AIX et MinixSpecifies the line length. The default value for Width is 72 characters.
70
pour Plan9Output line length is n, including indent (default 70).
les bornes limites
Il y a, dans les implémentations BSD et GNU, deux limites…
- le maximum est le mur infranchissable… (dans l’analogie de la gestion des quotas c’est l’équivalent du « hard limit ».)
- le goal (but ou objectif en français) est la limite désirée, désirable mais légèrement dépassable… (donc l’équivalent du « soft limit » dans l’analogie avec la gestion des quotas.)
Dans ces implémentations, trois cas peuvent donc se produire :
- Quand on indique max seul, avec «
-w
», le programme doit en déduire le goal- semble que BSD utilise la même valeur,
- tandis que GNU calcule que ça fait 93%.
- Quand on indique goal seul, le programme doit en déduire le max
- BSD fait plus dix caractères, et
- GNU fait plus 7% (sept pour cent.)
- Quand on spécifie les deux, le programme va essayer de couper un peu après (ou juste à) goal et toujours avant max !
$ # ceci est une implémentation BSD
$ fmt -v
fmt: illegal option -- v
usage: fmt [-cmps] [-d chars] [-l num] [-t num]
[-w width | -width | goal [maximum]] [file ...]
Options: -c center each line instead of formatting
-d <chars> double-space after <chars> at line end
-l <n> turn each <n> spaces at start of line into a tab
-m try to make sure mail header lines stay separate
-n format lines beginning with a dot
-p allow indented paragraphs
-s coalesce whitespace inside lines
-t <n> have tabs every <n> columns
-w <n> set maximum width to <n>
goal set target width to goal
$ # mon fichier de test
$ wc lorem
1 69 446 lorem
$ ## soft 52 (soit max vers 62?)
$ # BSD: fmt 52 lorem
$ # GNU: fmt -g 52 lorem
$ # 1 2 3 4 5 G 6 m
$ #456789012345678901234567890123456789012345678901234567890123456789
$ fmt 52 lorem
Lorem ipsum dolor sit amet, consectetur adipiscing
elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis
nostrud exercitation ullamco laboris nisi ut aliquip
ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore
eu fugiat nulla pariatur. Excepteur sint occaecat
cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.
$ ## soft 47 (soit max vers 57?)
$ # 1 2 3 4 G 5 m 6
$ #456789012345678901234567890123456789012345678901234567890123456789
$ fmt 47 lorem
Lorem ipsum dolor sit amet, consectetur adipiscing
elit, sed do eiusmod tempor incididunt ut labore
et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi
ut aliquip ex ea commodo consequat. Duis aute
irure dolor in reprehenderit in voluptate velit
esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim
id est laborum.
$ ## hard 65 (soit but vers 55?)
$ # BSD: fmt -w 65 lorem
$ # GNU: fmt -w 65 lorem
4 # 1 2 3 4 5 g 6 M
$ #456789012345678901234567890123456789012345678901234567890123456789
$ fmt -w 65 lorem
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat
nulla pariatur. Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
$ ## hard 57 (soit but vers 47?)
$ # 1 2 3 4 g 5 M 6
$ #456789012345678901234567890123456789012345678901234567890123456789
$ fmt -w 57 lorem
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore
magna aliqua. Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea
commodo consequat. Duis aute irure dolor in reprehenderit
in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est
laborum.
$ ## intervalle 48--52
$ # BSD: fmt 48 52 lorem
$ # GNU: fmt -w 52 -g 48 lorem
$ # GNU: fmt -g 48 -w 52 lorem
$ # 1 2 3 4 G 5 M 6
$ #456789012345678901234567890123456789012345678901234567890123456789
$ fmt 48 52 lorem
Lorem ipsum dolor sit amet, consectetur adipiscing
elit, sed do eiusmod tempor incididunt ut labore
et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat. Duis aute irure
dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur
sint occaecat cupidatat non proident, sunt in culpa
qui officia deserunt mollit anim id est laborum.
$ ## intervalle 47--54
$ # 1 2 3 4 G 5 M 6
$ #456789012345678901234567890123456789012345678901234567890123456789
$ fmt 47 54 lorem
Lorem ipsum dolor sit amet, consectetur adipiscing
elit, sed do eiusmod tempor incididunt ut labore
et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi
ut aliquip ex ea commodo consequat. Duis aute
irure dolor in reprehenderit in voluptate velit
esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim
id est laborum.
expansion au taquet
Pour les tabulations, il existe des filtres POSIX qu’il vaut mieux utiliser en amont ; ça rend les scripts plus portables.
BSD fmt |
alternative POSIX |
---|---|
-t Ⅰ |
expand -t Ⅰ |
-l Ⅰ |
unexpand -t Ⅰ |
Les filtres dédiés permettent d’ailleurs de faire beaucoup plus…
$ cat -t taquets.txt
Fournitures^IQuantité^IPrix
Crayons^I12^I15,76
Feuilles A4^I1000^I137,5
Correcteurs^I10^I18
$ # par défaut on positionne en colonne modulo 8...
$ echo "1------.-1-------.-2-------.-3" ; cat taquets.txt
1------.-1-------.-2-------.-3-------.-
Fournitures Quantité Prix
Crayons 12 15,76
Feuilles A4 1000 137,5
Correcteurs 10 18
$ echo "1------.-1-------.-2-------.-3" ; cut -f 1-3 taquets.txt
1------.-1-------.-2-------.-3-------.-
Fournitures Quantité Prix
Crayons 12 15,76
Feuilles A4 1000 137,5
Correcteurs 10 18
$ # cas par défaut de la commande qui remplace TAB par 8
$ echo "1------.-1-------.-2-------.-3" ; expand taquets.txt
1------.-1-------.-2-------.-3-------.-
Fournitures Quantité Prix
Crayons 12 15,76
Feuilles A4 1000 137,5
Correcteurs 10 18
$ # mais on peut spécifier une autre largeur de TAB comme 7
$ echo "1------.-1-------.-2-------.-3" ; expand -t 7 taquets.txt
1------.-1-------.-2-------.-3-------.-
Fournitures Quantité Prix
Crayons 12 15,76
Feuilles A4 1000 137,5
Correcteurs 10 18
$ # On peut mettre des Taquets par exemple en colonnes 17 et 33
$ echo "1------.-1-------.-2-------.-3" ; expand -t 17,33 taquets.txt
1------.-1-------.-2-------.-3-------.-
Fournitures Quantité Prix
Crayons 12 15,76
Feuilles A4 1000 137,5
Correcteurs 10 18
$ # On peut mettre des Taquets par exemple en colonnes 13 et 23
$ echo "1------.-1-------.-2-------.-3" ; expand -t 13,23 taquets.txt
1------.-1-------.-2-------.-3-------.-
Fournitures Quantité Prix
Crayons 12 15,76
Feuilles A4 1000 137,5
Correcteurs 10 18
$ # On peut redefinir les taquets pour le terminal
$ # (profite à tous les programmes)
$ tabs 13,23 ; echo "1------.-1-------.-2-------.-3" ; cat taquets.txt ; tabs -8
1------.-1-------.-2-------.-3-------.-
Fournitures Quantité Prix
Crayons 12 15,76
Feuilles A4 1000 137,5
Correcteurs 10 18
On savait déjà faire tout cela en ligne de commande dans ces années là (pour la petite histoire, « expand
» est apparue avec 1BSD en mars 1978, et « tabs
» est apparu dans PWB/UNIX publié en juillet 1977.) Encore une fois, pas eu besoin d’attendre la machinerie moderne (voir ici et là ou là par exemple.)
$ # attention a bien les enchaîner....
$ fold -w 60 taquets.txt
Fournitures Quantité Prix
Crayons 12 15,76
Feuilles A4 1000 137,5
Correcteurs 10 18
$ fmt -w60 taquets.txt
Fournitures Quantité Prix Crayons 12 15,76
Feuilles A4 1000 137,5 Correcteurs 10 18
$ fmt -s -w 60 taquets.txt
Fournitures Quantité Prix
Crayons 12 15,76
Feuilles A4 1000 137,5
Correcteurs 10 18
$ expand -t 13,23 taquets.txt | fmt -s -w 60
Fournitures Quantité Prix
Crayons 12 15,76
Feuilles A4 1000 137,5
Correcteurs 10 18
Pour la route, si on n’est pas préoccupé par la portabilité, il y a d’autres alternatives à « expand
» :
- «
tab2space
» du projet HTML Tidy et qui a la particularité de combiner l’équivalent de «expand
» (une seule largeur de tabulation) avec l’équivalent de «dos2unix
» ou «fromdos
». C’est présent dans MacOS X et Solaris entre autres. - la commande «
:retab
» dans «vim
», qui peut être vite implémenté dans «emacs
» et dans « VScode
» - etc.
paragraphes au large
Il semble qu’il y a matière à améliorations, surtout dans le cadre du courriel, ce qui a conduit Adam M. Costello à produire « par
» en 1993 (juste l’abréviation de « PARagraph » je crois, mais c’aurait pu être le sigle de « Paragraphs Alternative Reformater » aussi.) Je ne maitrise pas sa syntaxe peu évidente ; mais il sait traiter :
- les mails (option «
q
» ajustable avec «Q
… » et combinable avec «i
» et «e
») - les marges (options «
p
» et «s
» pouvant être combinées avec «t
» ou «f
») - les imbrications de commentaires et messages cités (options «
d
») - la préservation des espaces initiaux (option «
r
») - les justification (option «
j
») et la dernière ligne (option «l
») - le remplissage quasi complet (option «
f
») sans justification - l’expansion de la tabulation (option «
T
… ») - et le retrait des lignes superflues (option «
e
») - et d’autres choses (options «
c
», «h
», «g
», par exemple)
…le tout en gérant l’Unicode (en UTF-8) ! La largeur est aussi indiquée avec « -w
… » (on peut utiliser juste « w
… » ou « … ») et est par défaut 72
…
$ # attention par n'opère que comme filtre...
$ par -w 60 wrap.txt
par error:
bad argument: wrap.txt
options for par:
help print option summary ---------- Boolean parameters. ---------
version print version number b<body> let non-trailing body chars in
B<op><set> as <op> is =/+/- prefix, non-leading in suffix
replace/augment/diminish c<cap> count all words as capitalized
body chars by <set> d<div> use indentation as a delimiter
P<op><set> ditto for protective chars E<Err> send messages to stderr
Q<op><set> ditto for quote chars e<expel> discard superfious lines
-------- Integer parameters: -------- f<fit> narrow paragraph for best fit
h<hang> skip IP's 1st <hang> lines g<guess> preserve wide sentence breaks
in scan for common affixes i<invis> hide lines inserted by <quote>
p<prefix> prefix length j<just> justify paragraphs
r<repeat> if not 0, force bodiless l<last> treat last lines like others
lines to length <width> q<quote> supply vacant lines between
s<suffix> suffix length different quote nesting levels
T<tab> tab stops every <tab> cols R<report> print error for too-long words
w<width> max output line length t<touch> move suffixes left
See par.doc or par.1 (the man page) for more information.
$ # ...il lit l'entrée standard et écrit sur la sortie standard
$ echo "_par_ is a filter which reformates each paragraph from its input
to its output" | par
_par_ is a which reformates each paragraph from its input to its
output
$ # donc envoyer d'abord le fichier sur l'entrée standard...
$ cat wrap.txt | par -w 60 | tr ' ' '~'
The~_fold_~utility~is~a~filter~that~shall~fold~lines~from~~.
its~input~files,~but~breaking~the~lines~to~have~a~maximum~~.
of~_width_~column~position~(or~bytes,~if~the~*-b*~option~is.
specified)~Use~*-s*~option~to~split~at~latest~space~before~.
maximum~_width_~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.
The~_fmt_~utility~is~a~filter~that~shall~reformat~each
paragraph~from~its~input~files,~but~break~the~lines~to~have
a~maximum~of~_width_~column~position.
$ # les points systématiques à la fin de ligne sont reproduits
$ # ...donc lui signaler qu'il n'y a pas de délimiteur de fin
$ cat wrap.txt | par -w 60 -s 0 | tr ' ' '~'
The~_fold_~utility~is~a~filter~that~shall~fold~lines~from
its~input~files,~but~breaking~the~lines~to~have~a~maximum
of~_width_~column~position~(or~bytes,~if~the~*-b*~option~is
specified)~Use~*-s*~option~to~split~at~latest~space~before
maximum~_width_.
The~_fmt_~utility~is~a~filter~that~shall~reformat~each
paragraph~from~its~input~files,~but~break~the~lines~to~have
a~maximum~of~_width_~column~position.
$ # ...ou ajouter le point dans la liste des caractères normaux
$ cat wrap.txt | par -w 60 -B+. | tr ' ' '~'
The~_fold_~utility~is~a~filter~that~shall~fold~lines~from
its~input~files,~but~breaking~the~lines~to~have~a~maximum
of~_width_~column~position~(or~bytes,~if~the~*-b*~option~is
specified)~Use~*-s*~option~to~split~at~latest~space~before
maximum~_width_.
The~_fmt_~utility~is~a~filter~that~shall~reformat~each
paragraph~from~its~input~files,~but~break~the~lines~to~have
a~maximum~of~_width_~column~position.
$ # essayons d'avoir des lignes plus équilibrées, comme fmt...
$ cat wrap.txt | par -w60fs0 | tr ' ' '~'
The~_fold_~utility~is~a~filter~that~shall~fold~lines~from
its~input~files,~but~breaking~the~lines~to~have~a~maximum
of~_width_~column~position~(or~bytes,~if~the~*-b*~option~is
specified)~Use~*-s*~option~to~split~at~latest~space~before
maximum~_width_.
The~_fmt_~utility~is~a~filter~that~shall~reformat~each
paragraph~from~its~input~files,~but~break~the~lines~to
have~a~maximum~of~_width_~column~position.
$ # on peut carrément vouloir justifier les lignes...
$ cat wrap.txt | par -w60j | tr ' ' '~'
The~_fold_~utility~~is~a~filter~that~shall~~fold~lines~from.
its~input~files,~~but~breaking~the~lines~to~~have~a~maximum.
of~_width_~column~position~(or~bytes,~if~the~*-b*~option~is.
specified)~Use~*-s*~option~to~~split~at~latest~space~before.
maximum~_width_~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.
The~~_fmt_~utility~~is~~a~filter~~that~~shall~reformat~~each
paragraph~from~its~input~files,~~but~break~the~lines~to have
a~maximum~of~_width_~column~position.
$ # ...sans oublier de combiner le reste...
$ cat wrap.txt | par 60js0 | tr ' ' '~'
The~_fold_~utility~~is~a~filter~~that~shall~~fold~lines~from
its~input~files,~but~breaking~the~lines~to~have~a~maximum~of
_width_~column~~position~(or~~bytes,~if~the~~*-b*~~option~is
specified).~Use~*-s*~option~to~~split~at~latest~space~before
maximum~_width_.
The~~_fmt_~utility~~is~~a~filter~~that~~shall~reformat~~each
paragraph~from~its~input~files,~~but~break~the~lines~to have
a~maximum~of~_width_~column~position.
par
est aussi bien pour reformater des mails (format texte) ! Mais dans beaucoup de cas, il est assez compliqué à mon avis… À réserver donc aux rares cas où les autres ne satisfont pas.
$ # comme "fmt" mais les tabulations deviennent une espace...
$ cat taquets.txt | par -w 60
Fournitures Quantité Prix Crayons 12 15,76 Feuilles A4 1000
137,5 Correcteurs 10 18
$ # je ne suis pas parvenu à utiliser cette option
$ cat taquets.txt | par -w 60 -T 8
Fournitures Quantité Prix 12 5,76 A4 137,5 urs 10 8
$ # on peut au moins arriver à préserver les sauts de ligne...
$ par -w 60 -d < taquets.txt
Fournitures Quantité Prix
Crayons 12 15,76
Feuilles A4 1000 137,5
Correcteurs 10 18
$ # on peut demander de préserver les 23 premiers caractères...
$ expand -t 13,23 taquets.txt | par w60p23
Fournitures Quantité Prix
Crayons 12 15,76
Feuilles A4 1000 137,5
Correcteurs 10 18
Il a le mérite d’exister et d’être présent dans de plus en plus de distributions, sinon se porte facilement. À surveiller.
balle au centre et égalisation
Pour le centrage, il faut hélas recourir à « printf
» (ou « perl
» ou « sed
» ou autre) puis boucler sur toutes les lignes (ce qui peut se faire avec « awk
» qui est mon filtre favori dans ce cas ci…)
Nota : « vim
» a la commande « :center
» qui fait bien cela ; ainsi que « :right
» et « :left
», et tous les trois peuvent s’abréger à 2 caractères et on peut indiquer ensuite la largeur voulue (80
sinon).
Concernant la pleine justification, c’est un processus plus couteux qui se fait en répartissant astucieusement des espaces entre les mots (chose que savent faire « emacs
» et « nano
» ; et sinon ça se scripte dans un langage un peu avancé.) Ce procédé est bien connu, mais le résultat n’est pas toujours des plus heureux et se retrouve facilement avec des fleuves qui sillonnent le texte…
Idéalement, pour faire de la justification, il faut certes ajouter des blancs ci et là, mais arriver à limiter le nombre de ceux-ci et jouer également avec la césure des mots (ou « hyphenation » en anglais, qui se fait avec le trait d’union…) dont les règles varient selon les langues. On peut par exemple s’appuyer sur un « dictionnaire » dédié. C’est d’ailleurs l’approche des logiciels pionniers : « Justify », puis « TJ-1 » et enfin « TJ-2 » en 1963, pour la machine PDP-1, ne traitent que l’anglais en utilisant un dictionnaire de césures… On le considère parfois comme le premier « processeur de texte » (ou « traitement de texte », buzzword du NY Times en 1971) en tant que machine dédiée (comme les « AES-90 et Micom-2000 de Stephen B. Dorsey » et la « série Vydec de Exxon ») et non logiciel (comme les « MultiMate, Electric Pencil, WordStar, Scripsit, etc. »)…
impressions standards
Voyons maintenant une dernière commande, apparue avec la première version officiellent distribuée aux universités vers 1971 mais déjà utilisé au Bell Labs (en fait il nait en août 1969 mais son état civile est enregistré pour le 1er janvier de 1970 ha-ha …et dès le début le système est utilisé en interne entre par les secrétaires.) Du nom de « pr
», elle prépare la « mise en page » pour l’impression papier… (est-ce que son nom est l’abréviation de « print » ou le sigle de « print request » est une des questions qui me turlupinent…)
Cette mise en page va consister surtout en la « pagination » (i.e. le découpage en « page ») comme le font les éditeurs plein écran (« vi
/emacs
/nano
/etc. ») et visualiseurs de texte (« pager
/pg
/more
/less
/most
/etc. ») Sauf qu’eux raisonnent par rapport à l’écran tandis que « pr
» raisonne par rapport à la page papier.
réglages de papier
Tout comme l’écran du terminal ou de la console a un certain nombre de lignes × colonnes (par exemple 25×80) la page aussi. Ces dimensions (longueur × largeur de papier, par défaut 66
×72
) peuvent être spécifiées respectivement avec les options « -l
» (pour « page length ») et « -w
» (pour « page Width »).
Mais pour le papier, il y aussi la notion de « marge interne » (nulle par défaut, et à ne pas confondre avec la marge technique ou le débord qui s’ajoute), qui est retiré de la largeur, avec l’option « -o
» (pour « line Offset »)
page de base
Comme il s’agit de document à imprimer, « pr
» rajoute un en-tête de 5
lignes (prises dans la longueur totale…) et y place au milieu (troisième ligne) : la date de génération (à gauche), le numéro de page (à droite), et le nom du fichier (au milieu) ou titre du document… Il prend également 5
lignes pour le pied de page…
Ce n’est certainement pas parfait, mais moins prise de tête àmha.
$ # noter la belle entête faite toute seule
$ expand -t 13,23 taquets.txt | pr -w 50 | head
2017-10-30 13:27 Page 1
Fournitures Quantité Prix
Crayons 12 15,76
Feuilles A4 1000 137,5
Correcteurs 10 18
$ # ajouter un décalage de 2 espaces à gauche
$ expand -t 13,23 taquets.txt | pr -o 2 -w 50 | head
2017-10-30 13:33 Page 1
Fournitures Quantité Prix
Crayons 12 15,76
Feuilles A4 1000 137,5
Correcteurs 10 18
$ # pr mange 5 lignes en haut et autant en bas
$ expand -t 13,23 taquets.txt | pr -l 12 -w 50 | cat -n
1
2
3 2017-10-30 13:43 Page 1
4
5
6 Fournitures Quantité Prix
7 Crayons 12 15,76
8 Feuilles A4 1000 137,5
9
10
11
12
13
14
15
15
16 2017-10-30 13:43 Page 2
17
18
19 Correcteurs 10 18
20
21
22
23
24
$ # pr mange 10 lignes et pagine automatiquement
$ expand -t 13,23 taquets.txt | pr -l 13 -w 50 | cat -n
1
2
3 2017-10-30 13:43 Page 1
4
5
6 Fournitures Quantité Prix
7 Crayons 12 15,76
8 Feuilles A4 1000 137,5
9
10
11
12
13
14
15
15
16 2017-10-30 13:43 Page 2
17
18
19 Correcteurs 10 18
20
21
22
23
24
25
26
Le pied de page n’est pas utilisé et je trouve que c’est un gâchis de ces cinq lignes. Mais c’est très utile pour les sociétés, qui impriment sur du papier avec un certain nombre de mentions qui sont plus ou moins obligatoires dans cette zone… On en rencontre qui utilisent l’en-tête du document pour des informations autre que leur logo et leur nom.
paramétrages de page
L’option « -t
» permet de désactiver les en-têtes et pieds de page ajoutés automatiquement, comme souvent requis sur les sorties papier. Noter que ceux-ci sont automatiquement désactivés quand le nombre de lignes n’est pas supérieur à dix !
Question : Est-ce que les commandes déjà évoquées sont utiles ici ?
Réponse : Oui, « -w
» positionne le numéro de page sans adapter le texte, et la largeur minimale utilisée est de 24
(en dessous ce n’est pas pris en compte.)
L’implémentation GNU offre en plus l’option « -W
» qui permet d’appliquer un effet « truncate »… Cette implémentation offre également l’option « -T
» qui fait comme « -t
» mais envoie le code de saut saut de page au lieu de plusieurs saut de ligne : c’est normalement plus rapide car l’imprimante éjecte la page au lieu de la dérouler ligne par ligne. Il est à noter que la norme propose « -F
» et « -f
» pour ce faire (donc « -T
» a pour forme portable « -tF
» simplement.)
$ # plus d'entête et pied de page avec "`-t`"
$ expand -t 13,23 taquets.txt | pr -t | head
Fournitures Quantité Prix
Crayons 12 15,76
Feuilles A4 1000 137,5
Correcteurs 10 18
$ # plus d'entête et pied de page quand l<=10
$ expand -t 13,23 taquets.txt | pr -l 5
Fournitures Quantité Prix
Crayons 12 15,76
Feuilles A4 1000 137,5
Correcteurs 10 18
$ # "-w" ne tronque pas (utile ici)
$ expand -t 13,23 taquets.txt | pr -w 26 | head
2017-10-30 13:27 Page 1
Fournitures Quantité Prix
Crayons 12 15,76
Feuilles A4 1000 137,5
Correcteurs 10 18
$ # "-w" ne s'applique pas au texte
$ echo "ceci est une ligne de 30 car." | pr -l 2 -w 20
ceci est une ligne de 30 car.
$ echo "ceci est une ligne de 30 car." | pr -l 2 -W 20
ceci est une ligne d
$ echo "ceci est une ligne de 30 car." | fold -s -w 20 | pr -l 2 -w 20
ceci est une ligne
de 30 car.
$ # "-w" utilise une valeur minimale de 24...
$ # (juste ce qu'il faut pour l'horodatage et la pagination)
$ expand -t 13,23 taquets.txt | pr -w 10 | head
2017-10-30 13:27 Page 1
Fournitures Quantité Prix
Crayons 12 15,76
Feuilles A4 1000 137,5
Correcteurs 10 18
$ # "-F" si on ne veut pas enregistrer dans un fichier
$ # mais envoyer directement à l'imprimante
$ expand -t 13,23 taquets.txt | pr -w 10 | wc
66 17 196
$ expand -t 13,23 taquets.txt | pr -w 10 -F | wc
9 17 140
On ne le voit pas dans les précédents exemples, mais dans l’entête il y a le nom du fichier centré. Du moins, par défaut, car on peut mettre un texte personnalisé en utilisant l’option « -h
» (pour « personalized Header ».)
L’implémentation GNU propose en plus l’option « -D
» pour personnaliser le champ de date par son propre texte… (on peut bien entendu utiliser « $(date +...)
» pour changer le format de la date si on le désire.)
$ # préparons notre fichier...
$ expand -t 13,23 taquet.txt > formated1
$ # faisons notre impression
$ pr -w 40 -l 15 formated1 | head | cat -n
1
2
3 2017-10-30 13:45 formated1 Page 1
4
5
6 Fournitures Quantité Prix
7 Crayons 12 15,76
8 Feuilles A4 1000 137,5
9 Correcteurs 10 18
10
$ # changeons le titre tant qu'à faire
$ pr -w 40 -l 15 -h "liste d'achats" formated1 | head | cat -n
1
2
3 2017-10-30 13:47 liste d'achats Page 1
4
5
6 Fournitures Quantité Prix
7 Crayons 12 15,76
8 Feuilles A4 1000 137,5
9 Correcteurs 10 18
10
$ # vérifions pour la largeur minimale...
$ pr -w 30 -l 15 -h "liste d'achats" formated1 | head | cat -n
1
2
3 2017-10-30 13:47 liste d'achats Page 1
4
5
6 Fournitures Quantité Prix
7 Crayons 12 15,76
8 Feuilles A4 1000 137,5
9 Correcteurs 10 18
10
$ # changeons le champ de date aussi...
$ pr -w 20 -l 15 -h "liste d'achats" -D "now" formated1 | head | cat -n
1
2
3 now liste d'achats Page 1
4
5
6 Fournitures Quantité Prix
7 Crayons 12 15,76
8 Feuilles A4 1000 137,5
9 Correcteurs 10 18
10
$ # gardons juste la date
$ # (obligatoire sinon utiliser cat au lieu de pr)
$ pr -w 20 -l 15 -h "" -D "" formated1 | head | cat -n
1
2
3 Page 1
4
5
6 Fournitures Quantité Prix
7 Crayons 12 15,76
8 Feuilles A4 1000 137,5
9 Correcteurs 10 18
10
On voit au passage, que la largeur minimale n’est pas 24
mais avec :
- champ de gauche : est le nombre de caractères pour la date (
10
) et l’horaire (5
) conformément aux normes - champ de droite : est le nombre de caractères pour le numéro de page (
<10
sinon augmenter en conséquence) - champ du milieu : est le nombre de caractères composant le titre
On n’a certes pas le choix pour l’emplacement des différents éléments, mais cela correspond bien aux pratiques en vigueur que l’on bafoue avec les traitement de texte en s’improvisant typographe.
autres paramétrages
C’est beau n’est-ce pas ? Mais cette commande peut faire plus !
Dans notre exemple, il peut être intéressant de numéroter les lignes du tableau, et il sait le faire avec l’option « -n
» ; pas besoin de passer par « nl
» au préalable (mais ce filtre a ses petits plus…)
Par défaut, elle utilise une colonne de 5 caractères, mais on peut ajuster cela en accolant un entier à l’option.
Le contenu est séparé du numéro par une tabulation, ce qui le fait commencer en huitième colonne. On peut aussi changer ce caractère par un autre accolé à l’option.
On peut combiner les deux mais dans un ordre précis !
$ # numéroter les lignes du tableau
$ pr -n -l 5 formated1
1 Fournitures Quantité Prix
2 Crayons 12 15,76
3 Feuilles A4 1000 137,5
4 Correcteurs 10 18
$ # numéroter sur 3 colonnes
$ pr -n3 -l 5 formated1
1 Fournitures Quantité Prix
2 Crayons 12 15,76
3 Feuilles A4 1000 137,5
4 Correcteurs 10 18
$ # il faut acoller l'argument...
$ pr -n 3 -l 5 formated1
pr: 3: No such file or directory
1 Fournitures Quantité Prix
2 Crayons 12 15,76
3 Feuilles A4 1000 137,5
4 Correcteurs 10 18
$ # utiliser le point au lieu de la tabulation
$ pr -n. -l 5 formated1
1.Fournitures Quantité Prix
2.Crayons 12 15,76
3.Feuilles A4 1000 137,5
4.Correcteurs 10 18
$ # utiliser l'espace au lieu de la tabulation
$ pr -n\ -l 5 formated1
1 Fournitures Quantité Prix
2 Crayons 12 15,76
3 Feuilles A4 1000 137,5
4 Correcteurs 10 18
$ # toujours le point et sur deux colonnes
$ pr -n.2 -t -l 5 formated1
1.Fournitures Quantité Prix
2.Crayons 12 15,76
3.Feuilles A4 1000 137,5
4.Correcteurs 10 18
$ # l'ordre importe ici...
$ pr -n3. -t -l 5 formated1
pr: `-n' extra characters or invalid number in argument: `3.'
Try `pr --help' for more information
Il peut, de la même façon convertir des espaces successifs en un seul caractère (par défaut la tabulation, comme « unexpand
»), avec l’option « -i
» et son corolaire avec (par défaut la tabulation en espaces, comme « expand
») avec l’option « -e
». Ces deux options s’utilisent comme « -n
» : il y a des paramètres par défaut (espace/tabulation et huit) mais on peut indiquer son caractère et son nombre (de blanc ou espacement des taquets.)
$ # quand il y a plus de 2 espaces remplacer par 1 tab
$ # taquet en position muliple de 8 (8, 16, 24, 32, etc.)
$ echo "Quatre Trois Deux Un Zero" | pr -l 1 -i | cat -t
Quatre^I Trois^I Deux^IUn Zero
$ # quand il y a plus de 2 espaces remplacer par 1 tab
$ # taquet en position muliple de 2 (2, 4, 6, 8, 10, 12, etc.)
$ echo "Quatre Trois Deux Un Zero" | pr -l 1 -i2 | cat -t
Quatre^I^ITrois^I^IDeux^IUn Zero
$ # quand il y a plus de 2 espaces remplacer par 1 tab
$ # taquet en position muliple de 12 (12, 24, 32, 64, etc.)
$ echo "Quatre Trois Deux Un Zero" | pr -l 1 -i2 | cat -t
Quatre Trois Deux^IUn Zero
$ # quand il y a plus de 2 espaces remplacer par 1 point
$ # taquet en position muliple de 8 (8, 16, 24, 32, etc.)
$ echo "Quatre Trois Deux Un Zero" | pr -l 1 -i. | cat -t
Quatre. Trois. Deux.Un Zero
$ # quand il y a plus de 2 espaces remplacer par 1 point
$ # taquet en position muliple de 6 (6, 12, 18, 24, etc.)
$ echo "Quatre Trois Deux Un Zero" | pr -l 1 -i.6 | cat -t
Quatre Trois.Deux.Un Zero
$ # chez moi, Ctrl+V puis Tab, sinon utiliser un fichier
$ echo "tab tabtab stop" | cat -t
tab^Itabtab^I^Istop
$ # remplacer les tabulations par 4 espaces
$ # en fait on positionne aux taquets multiples de 8...
$ echo "tab tabtab stop" | pr -l 1 -e | tr ' ' '~'
tab~~~~~tabtab~~~~~~~~stop
$ # remplacer les tabulations par 3 espaces
$ # en fait on positionne aux taquets multiples de 3...
$ echo "tab tabtab stop" | pr -l 1 -e3 | tr ' ' '~'
tab~~~tabtab~~~~~~stop
$ # remplacer les underscores par 3 espaces
$ # en fait on positionne aux taquets multiples de 3...
$ echo "tab_tabtab__stop" | pr -l 1 -e_3 | tr ' ' '~'
tab~~~tabtab~~~~~~stop
$ # remplacer les underscores par 4 espaces
$ # en fait on positionne aux taquets multiples de 8...
$ echo "tab_tabtab__stop" | pr -l 1 -e_ | tr ' ' '~'
tab~~~~~tabtab~~~~~~~~stop
Il y a peu de cas où cela sert vraiment, d’après mon expérience, mais la possibilité existe ; et je n’ai pas pu retrouver la cause historique.
impressions avancées
répartition en colonnes
Une des possibilités incontournables est le multi colonage ! Les lignes du texte qui est passé à la commande, sont divisées en autant de colonnes que demandées par l’option numérique (qui est donc « -1
» par défaut, et on utilisera « -2
» pour faire une double colonne et « -3
» pour une triple, etc.), puis ces colonnes sont juxtaposées horizontalement (comme avec « paste
» ou « rs
» par exemple.)
Le séparateur entre colonnes est l’espace, chose que l’on peut changer avec l’option « -s
» auquel on accole le caractère voulu (mais contrairement au « -d
» de « paste
», on ne peut pas alterner plusieurs séparateurs.)
L’implémentation GNU propose l’option « -S
» qui ici ne change rien… (tout comme « -W
» ne change rien dans le cas présent) on y reviendra.
$ # GNU/Linux: quelle est la plus longue ligne?
$ # et on voit qu'une largeur de 30 convient
$ wc -L formated1
28 formated1
$ # cat formated1
$ pr -l 4 -w 30 formated1
Fournitures Quantité Prix
Crayons 12 15,76
Feuilles A4 1000 137,5
Correcteurs 10 18
$ # sur 2 colonnes de 30/2
$ # lignes "Fourn..." et "Crayo..." d'une part
$ # lignes "Feuil..." et "Corre..." d'autre part
$ pr -2 -l 4 -w 30 formated1
Fournitures Q Feuilles A4 1
Crayons 1 Correcteurs 1
$ # sur 2 colonnes de 60/2
$ # lignes "Fourn..." et "Crayo..." d'une part
$ # lignes "Feuil..." et "Corre..." d'autre part
$ pr -l 4 -w 60 -2 formated1
Fournitures Quantité Prix Feuilles A4 1000 137,5
Crayons 12 5,76 Correcteurs 10 18
$ # sur 2 colonnes de 60/2
$ # avec le point au lieu d'espace
$ pr -l 4 -2 -w 60 -s. formated1
Fournitures Quantité Prix .Feuilles A4 1000 137,5
Crayons 12 5,76 .Correcteurs 10 18
$ # attention à bien le coller...
$ pr -l 4 -2 -w 60 -s . formated1
pr: .: Is a directory
$ # sur 2 colonnes de 30/2
$ # avec rien au lieu d'espace
$ pr -l 4 -2 -w 30 -s formated1
Fournitures QuFeuilles A4 1
Crayons 12Correcteurs 1
$ # sur 2 colonnes de 30/2
$ # avec point au lieu d'espace
$ # et en numérotant (on voit la répartition des lignes)
$ pr -l 4 -2 -w 30 -s. -n formated1
1 Fourni. 3 Feuill
2 Crayon. 4 12Corr
J’avoue que cet exemple n’est pas ce qu’il y a de mieux, mais ça montre toute la difficulté de la chose et la nécessité d’avoir une commande dédiée pour « mettre en page » avant d’imprimer. Prenons un autre exemple, qui va nous permettre de mettre en évidence l’option « -a
» (change le sens de colonage) qui peut être utile dans certains rares cas :
$ # préparons notre fichier...
$ # pour être à 28 comme formated1
$ fold -s -w 28 wrap.txt > formated0
$ # imprimons en 2 colonnes de 60/2
$ # remplissage normal, en N par page: P1C1, P1C2, P2C1, P2C2
$ pr -2 -w 60 -l 15 -f formated0 | cat -nt
1
2
3 2017-11-01 13:05 formated0 Page 1
4
5
6 The _fold_ utility is a column position (or bytes.
7 filter that shall fold if the *-b* option is
8 lines from its input files, espicified).
9 but breaking the lines to Use *-* option to split at
10 have a maximum of _width_ latest space before maximum
11 ^L
12
13 2017-11-01 13:05 formated0 Page 2
14
15
16 _width_. input files, but break the
17 lines to have a maximum of
18 The _fmt_ utility is a _width_ column position.
19 filter that shall reformat
20 each paragraph from its
21 ^L
$ # imprimons en 2 colonnes de 60/2
$ # remplissage alternatif, en Z par lignes successives...
$ pr -2 -w 60 -l 15 -f formated0 | cat -nt
1
2
3 2017-11-01 13:05 formated0 Page 1
4
5
6 The _fold_ utility is a filter that shall fold
7 lines from its input files, but breaking the lines to
8 have a maximum of _width_ column position (or bytes,
9 if the *-b* option is specified).
10 Use *-s* option to split at latest space before maximum
11 ^L
12
13 2017-11-01 13:05 formated0 Page 2
14
15
16 _width_.
17 The _fmt_ utility is a filter that shall reformat
18 each paragraph from its input files, but break the
29 lines to have a maximum of _width_ column position.
20
21 ^L
$ # imprimons en 2 colonnes de 60/2
$ # remplissage alternatif, en Z par lignes successives...
$ pr -2 -w 60 -l 12 -f formated1 | cat -nt
1
2
3 2017-11-01 13:09 formated1 Page 1
4
5
6 Fournitures Quantité Prix Crayons 12 15,75
7 Feuilles A4 10000 137,5 Correcteurs 10 18
8 ^L
Je n’ai eu à utiliser ce truc qu’une seule fois, pour imprimer un index de noms (à raison d’un par ligne dans le fichier) triés (par « sort
».)
Il y a aussi l’option « -d
», sans paramètre, que j’invite à tester.
sélection de pages
Il y une autre option un peu étrange qu’il peut être utile de connaître : « +
» qui permet de commencer à partir d’une page donnée… L’implémentation GNU permet permet en plus d’indiquer de s’arrêter à une page donnée…
En plus de cela, cette implémentation propose une option « -N
» pour réinitialiser le compteur quand on utilise l’option « -n
» et c’est pas mal.
$ # par défaut, toutes les 4 pages
$ # (de la première à la dernière donc)
$ pr -w 30 -l 15 -f formated0 | cat -nt
1
2
3 2017-10-30 13:54 formated0 Page 1
4
5
6 The _fold_ utility is a
7 filter that shall fold
8 lines from its input files,
9 but breaking the lines to
10 have a maximum of _width_
11 ^L
12
13 2017-10-30 13:54 formated0 Page 2
14
15
16 column position (or bytes,
17 if the *-b* option is
18 specified).
19 Use *-s* option to split at
20 latest space before maximum
21 ^L
22
23 2017-10-30 13:54 formated0 Page 3
24
25
26 _width_.
27
28 The _fmt_ utility is a
29 filter that shall reformat
30 each paragraph from its
31 ^L
32
33 2017-10-30 13:54 formated0 Page 4
34
35
36 input files, but break the
37 lines to have a maximum of
38 _width column position.
39
40
41 ^L
$ # possible seulement à partir de la 3ème...
$ # (de la 3ème à la dernière page donc)
$ pr -w 30 -l 15 -f +3 formated0 | cat -nt
1
2
3 2017-10-30 13:54 formated0 Page 3
4
5
6 _width_.
7
8 The _fmt_ utility is a
9 filter that shall reformat
10 each paragraph from its
11 ^L
12
13 2017-10-30 13:54 formated0 Page 4
14
15
16 input files, but break the
17 lines to have a maximum of
18 _width column position.
19
20
21 ^L
$ # il n'y a pas de 5ème page...!
$ # (j'utilise l'astuce avec 999
$ # pour avoir le nombre de pages)
$ pr -w 40 -l 17 +5 formated0
pr: starting page number 5 exceeds page count 4
$ # GNU pr permet de la 2ème à la 3ème...
$ pr -w 30 -l 15 -f +2:3 formated0 | cat -n
1
2
3 2017-10-30 13:54 formated0 Page 2
4
5
6 column position (or bytes,
7 if the *-b* option is
8 specified).
9 Use *-s* option to split at
10 latest space before maximum
11 ^L
12
13 2017-10-30 13:54 formated0 Page 3
14
15
16 _width_.
17
18 The _fmt_ utility is a
19 filter that shall reformat
20 each paragraph from its
21 ^L
$ # GNU pr permet juste la 3ème...
$ pr -w 30 -l 15 -f +3:3 formated0 | cat -nt
1
2
3 2017-10-30 13:54 formated0 Page 3
4
5
6 _width_.
7
8 The _fmt_ utility is a
9 filter that shall reformat
10 each paragraph from its
11 ^L
$ # pour juste les 2 premières bien indiquer 1:2
$ pr -w 30 -l 15 -f +:2 formated0
pr: invalid + argument `:2'
$ # quand on numérote la page 4
$ pr -w 30 -l 15 -f +4 -n formated0 | cat -nt
1
2
3 2017-10-30 13:54 formated0 Page 4
4
5
6 16 input files, but break the
7 17 lines to have a maximum of
8 18 _width column position.
9 19
10 20
11 ^L
$ # GNU nous permet de dire qu'on commence
$ # à la 4ème ligne (du second paragraphe)
$ pr -w 30 -l 15 -f +4 -n -N 4 formated0 | cat -nt
1
2
3 2017-10-30 13:54 formated0 Page 4
4
5
6 4 input files, but break the
7 5 lines to have a maximum of
8 6 _width column position.
9 7
10 8
11 ^L
On remarque au passage (première ligne du texte ou sixième imprimée, à la troisième page) que « pr
» ne connait pas la notion de paragraphes, ou en tout cas ne gère pas le difficile problème de veuvage et d’orphelinage des lignes (lignes creuses/isolées/désolidarisées.)
impression de livrets
Tout comme « fold
» et « fmt
», « pr
» peut prendre plusieurs fichiers en entrée. Sans l’utilisation de l’option « -h
», chaque fichier se voit indiqué car les fichiers sont parcourus « séquentiellement » de sorte que chacun commence sur une nouvelle page. Mieux, les fichiers suivants commencent toujours sur une page impaire (c’est pratique quand chaque fichier représente un chapitre de votre manuscrit par exemple) ce qui est « top » ! Par contre, il recommence la pagination (ce qui est pratique si on imprime des documents séparés mais pas génial si on imprime un livre éclaté en plusieurs fichiers) et peut produire des pages vides (l’algorithme est relativement simple et correspond à la plupart des cas courants.) En tout cas, tout cela est fait automatiquement…
$ # préparons notre fichier...
$ fold -w 40 -s wrap.txt > formated2
$ # faisons notre impression 1 colonne
$ # c'est séquentiel, normal.
$ pr -w 40 -l 17 formated2 formated1 | cat -nt
1
2
3 2017-10-30 13:45 formated2 Page 1
4
5
6 The _fold_ utility is a filter that
7 shall fold lines from its input files,
8 but breaking the lines to have a
9 maximum of~ width ~column position (or
10 bytes, if the *-b* option is specified)
11 Use *-s* option to split at latest
12 space before maximum _width_.
13
14
15
16
17
18
19
20 2017-10-30 13:45 formated2 Page 2
21
22
23
24 The _fmt_ utility is a filter that
25 shall reformat each paragraph from its
26 input files, but break the lines to
27 have a maximum of _width_ column
28 position.
29
30
31
32
33
34
35
36
37 2017-10-30 13:45 formated2 Page 3
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 2017-10-30 13:45 formated1 Page 1
55
56
57 Fournitures Quantité Prix
58 Crayons 12 15,76
59 Feuilles A4 1000 137,5
60 Correcteurs 10 18
61
62
63
64
65
66
$ pr -w 40 -l 17 -f formated2 formated1 | cat -nt
1
2
3 2017-10-30 13:47 formated2 Page 1
4
5
6 The _fold_ utility is a filter that
7 shall fold lines from its input files,
8 but breaking the lines to have a
9 maximum of~ width ~column position (or
10 bytes, if the *-b* option is specified)
11 Use *-s* option to split at latest
12 space before maximum _width_.
13 ^L
14
15 2017-10-30 13:47 formated2 Page 2
16
17
18
19 The _fmt_ utility is a filter that
20 shall reformat each paragraph from its
21 input files, but break the lines to
22 have a maximum of _width_ column
23 position.
24
25 ^L
26
27 2017-10-30 13:47 formated2 Page 3
28
29
30
31 ^L
32
33 2017-10-30 13:47 formated1 Page 1
34
35
36 Fournitures Quantité Prix
37 Crayons 12 15,76
38 Feuilles A4 1000 137,5
39 Correcteurs 10 18
40 ^L
$ # il n'y a pas de 4ème page...
$ pr -w 40 -l 17 +4 formated1 formated2
pr: starting page number 4 exceeds page count 1
pr: starting page number 4 exceeds page count 3
$ # faisons notre impression 2 colonnes
$ # c'est toujours séquentiel.
$ pr -w 60 -l 17 -2 formated0 formated1 | cat -nt
Il y a cependant une option sympathique quand on imprime plusieurs fichiers : « -m
» qui va faire autant de colonnes que de fichiers, et c’est incompatible avec l’option de colonage.
$ # mettre côte à côte les 2 fichiers
$ pr -w 60 -l 15 -f -m formated0 formated1 | head
1
2
3 2017-10-30 13:54 Page 1
4
5
6 The _fold_ utility is a Fournitures Quantité Prix
7 filter that shall fold Crayons 12 15,76
8 lines from its input files, Feuilles A4 10000 137,5
9 but breaking the lines to Correcteurs 10 18
10 have a maximum of _width_
$ # mettre côte à côte les 2 fichiers
$ pr -w 60 -l 15 -f -m formated0 formated2 | cat -nt
1
2
3 2017-10-30 13:55 Page 1
4
5
6 The _fold_ utility is a The _fold_ utility is a filte
7 filter that shall fold shall fold lines from its inp
8 lines from its input files, but breaking the lines to hav
9 but breaking the lines to maximum of _width_ column pos
10 have a maximum of _width_ bytes, if the *-b* option is
11 ^L
12
13 2017-10-30 13:55 Page 2
14
15
16 column position (or bytes, Use *-s* option to split at l
17 if the *-b* option is space before maximum _width_.
18 specified).
19 Use *-s* option to split at The _fmt_ utility is a filter
20 latest space before maximum shall reformat each paragraph
21 ^L
22
23 2017-10-30 13:55 Page 3
24
25
26 _width_. input files, but break the li
27 have a maximum of _width_ col
28 The _fmt_ utility is a position.
29 filter that shall reformat
30 each paragraph from its
31 ^L
32
33 2017-10-30 13:55 Page 4
34
35
36 input files, but break the
37 lines to have a maximum of
38 _width column position.
39
40
41 ^L
$ # mettre côte à côte les 3 fichiers
$ pr -w 70 -l 15 -m formated0 formated1 formated2 | head
1
2
3 2017-10-30 13:54 Page 1
4
5
6 The _fold_ utility is Fournitures Quantité P The _fold_ utility is
7 filter that shall fold Crayons 12 shall fold lines from
8 lines from its input f Feuilles A4 10000 but breaking the lines
9 but breaking the lines Correcteurs 10 maximum of _width_ col
10 have a maximum of _wid bytes, if the *-b* opt
$ # ce n'est pas compatible avec le colonnage forcé...
$ pr -w 70 -l 15 -m -4 formated0 formated1 formated2
pr: cannot specify number of columns when printing in parallel
$ # ...pareil pour le format alternatif (Z au lieu de W)...
$ pr -w 70 -l 15 -m -a formated0 formated1 formated2
pr: cannot specify printing accross and printing in parallel
$ # ...mais le changement de séparateur fonctionne
$ pr -w 70 -l 15 -m -s\| formated? | head
1
2
3 2017-10-30 13:56 Page 1
4
5
6 The _fold_ utility is |Fournitures Quantité P |The _fold_ utility is
7 filter that shall fold|Crayons 12 |shall fold lines from
8 lines from its input f|Feuilles A4 10000 |but breaking the lines
9 but breaking the lines|Correcteurs 10 |maximum of _width_ col
10 have a maximum of _wid| |bytes, if the *-b* opt
C’est une variante intéressante de « diff -y
»…
Noter qu’aucun nom de fichier n’est privilégié et qu’il n’y a pas de « mix » particulier. Mais on peut utiliser « -h
» pour ajouter son propre titre.
L’implémentation GNU propose aussi une option « -J
» qui avec annule la troncature des lignes qui dépassent la largeur spécifiée par « -w
».
impression en chasse fixe
L’utilitaire « pr
» permet diverses mises en pages plus ou moins avancées pour une impression brute/directe (i.e. sans passer par un pilote, l’imprimante pouvant gérer du pur texte et étant dans le mode qui va bien, on y reviendra.) Elle a pléthore d’options pour satisfaire la plupart des caprices. Elles n’ont pas toutes été évoquées ici, et j’invite à parcourir le « man page » associé dans la distribution que l’on utilise.
OpenBSD/FreeBSD | GNU | AIX | POSIX | |
---|---|---|---|---|
+Ⅰ |
+Ⅰ |
+Ⅰ |
+Ⅰ |
begin output at page number Ⅰ |
+Ⅰ:Ⅱ |
output pages from number Ⅰ to Ⅱ |
|||
-Ⅰ |
-Ⅰ |
-Ⅰ |
-Ⅰ |
produce Ⅰ columns wide |
-a |
-a |
-a |
-a |
fill columns Across the page in a round robin order |
-c |
show Control chars | |||
-d |
-d |
-d |
-d |
produce Double spaced output |
-D Ⅹ |
use Ⅹ as header Date format |
|||
-eⅭⅠ |
-eⅭⅠ |
-eⅭⅠ |
-eⅭⅠ |
Expand each input Ⅽ (default tab) to n×Ⅰ+1 (default 8) |
-F |
-F |
-F |
-F |
use Form feed char. for new pages, not multiple newline |
-f |
-f |
-f |
-f |
same as -F plus pause on stdout |
-h Ⅹ |
-h Ⅹ |
-h Ⅹ |
-h Ⅹ |
use Ⅹ instead of filename as centered Header |
-iⅭⅠ |
-iⅭⅠ |
-iⅭⅠ |
-iⅭⅠ |
replace multiple blanks by Ⅽ char. (default tab) at n×Ⅰ+1 (default 8) in output |
-J |
Join lines, i.e. merge full lines and turn off -W truncation |
|||
-l Ⅰ |
-l Ⅰ |
-l Ⅰ |
-l Ⅰ |
set page Length to Ⅰ lines |
-m |
-m |
-m |
-m |
Merge contents of multiple files (lines side by side) |
-nⅭⅠ |
-nⅭⅠ |
-nⅭⅠ |
-nⅭⅠ |
print line Number separated by Ⅽ char. (default tab) using Ⅰ width column (default 5) |
-N Ⅰ |
first line Number printed with +Ⅰ |
|||
-o Ⅰ |
-o Ⅰ |
-o Ⅰ |
-o Ⅰ |
precede each line of output with Ⅰ space as Offset |
-p |
-p |
Pause before each page on TTY | ||
-r |
-r |
-r |
-r |
no diagnostic Reports on file open failure |
-sⅭ |
-sⅭ |
-sⅭ |
-sⅭ |
Separate text columns with Ⅽ char. (default tab) instead of spaces, turn off truncation when no -s |
-SⅭ |
Separate text columns with Ⅽ char, (default space with -J or tab), but no effect on columns |
|||
-t |
-t |
-t |
-t |
omit five+five lines of header+Trailers on each page |
-T |
omit headers+Trailers and pagination by form feed in input | |||
-w Ⅰ |
-w Ⅰ |
-w Ⅰ |
-w Ⅰ |
set the Width of the line to Ⅰ instead of 72 (when not -s ) or 512 (when -s ) |
-W Ⅰ |
set page Width to Ⅰ instead of 72, truncate except -J but no interference with -s or -S |
Avant de finir, revenons sur les largeurs par défaut :
Cela va faire bizarre aujourd’hui à ceux et celles qui n’ont pas connu les « polices à chasse fixe » — comme Consolas, Courier New, DejaVu Sans Mono, Droid Sans Mono, Inconsolata, Menlo, Lucida Console, Monaco, Terminal, etc.— et les fontes qui caractérisent les imprimantes à impacts :
- les imprimantes dérivées des téléscripteurs (en fait toute machine à écrire électrique pilotable par ordinateur), initialement, comme les Friden Flexowriter et les IBM Selectric
- les imprimantes à marguerites (similaires à des machines à écrire) ou à tulipe (qui permet d’avoir deux ou trois fontes au lieu d’une seule),
- les imprimantes à marteau ou à chaîne qu’on trouvait souvent couplés aux mainframes,
- les imprimantes matricielles maintenant (et qui ont toujours la côte malgré leurs défauts, un marché où Epson s’en est bien tiré avec son modèle MX-80 —j’en ai eu un) ainsi que Star avec son LC-10,
- les imprimantes à peigne, ou ligne matricielle qui sont à mi-chemin entre les imprimantes à ligne et les imprimantes matricielles, comme les Printronix P7000.
- les tables traçantes (qui sont encore d’usage malgré les technologies d’impression récentes),
Les limites (entre 70
et 80
caractères) sont historiques, adaptées aux consoles (plus exactement les moniteurs) standards comme le IBM 3270 et ses variantes et compatibles (80
caractères) ainsi que les téléscripteurs (72
caractères) même s’il y a eu rapidement des équipements pouvant atteindre 132
caractères… Il se trouve, que pour pour une petite fonte lisible (soit une taille de caractère standard de 10 pitch ou ~20
CPI —environ ⅙ pouce ou un pica—) on a bien 72
CPL …qui correspond au format standard de papier américain « letter de 8½×11 pouces ».
Cependant, certains suggèrent de faire moins (entre 50
et 70
CPL), ce qu’on obtient avec une plus grande fonte (soit une taille de caractère standard de 12 pitch ou ~17
CPI —alias un elite pour les IBM Selectric—).
Les journaux ne s’y sont pas trompé en privilégiant le multi colonage (avec un optimum entre 40
et 50
par colonne…) !
Alors, à l’heure des polices proportionnelles (qui posent des soucis très différents et où il faut raisonner en « pixels » et non plus en caractères), est-ce que tout ceci est dépassé ? Pas vraiment. D’une part la chasses fixe peut s’utiliser avec le matériel récent réglé comme il se doit, d’autre part il y a encore pas mal de machines pro qui sont matricielles dont beaucoup utilisent de très petites largeurs de papier…
(Parmi les principaux fabricants, on trouve Sharp, Casio, et bien d’autres. Ceci dit, comme toujours, il n’est pas obligatoire que l’imprimante et le clavier et le logiciel ne fassent qu’un —les uns et les autres aiment vendre des solutions tout-en-un mais dont on se retrouve prisonnier…) Ces dernières sont souvent des imprimantes thermiques (nombreux direct ou à transfert et quelques uns à sublimation) ou à diodes, connectable par USB ou sans fil, fonctionnant sur secteur, etc.
J’ai eu pendant quelques temps la HP 82240B qui est une imprimante de poche connectée par IR que je n’ai pu utiliser (en dehors de ma calculatrice) qu’avec Linux ! Comme le rappelle Sylvain cote sur HPMuseum, elle a 2 jeux de caractères et 3 fontes (6
et 7
points de haut ainsi qu’une moins connue de 5
points) permettant d’avoir 24
et 32
CPL ainsi que 48
!
Mis à part le packaging vraiment bien fichu et l’électronique très bien maîtrisée par l’équipe de Corvallis, on peut faire la même chose avec d’autres composants ou en faire d’autres usages (suffit d’avoir un adaptateur IR…)
Sur cette note de nostalgie, j’arrête ce qui n’est plus loin de devenir un roman. À bientôt peut-être pour la suite de cette exploration ; et si des points t’ont interpelé-e ou parus peu clairs, n’hésite pas : ça se passe en commentaires.