URL: https://linuxfr.org/users/gilcot/journaux/retrospective-sur-la-mise-en-page-en-console Title: rétrospective sur la mise en page en console Authors: Gil Cot ✔ Date: 2022年02月05日T12:15:49+01:00 Tags: philosophie_unix, documentation, ligne_de_commande, nostalgie, bsd, linux et unix Score: 51 'jour 'nal. Dans [une enfilage sur le clavier](https://linuxfr.org/users/elessar/journaux/des-concepteurs-qui-ont-eteint-trop-tot-leur-cerveau#comment-1874132), j'avais avoué ma passion pour l'histoire des systèmes et matériels informatiques ; et dans diverses autres discussion, ici et ailleurs, j'ai souvent évoqué l'influence des [télescripteurs](https://fr.wikipedia.org/wiki/T%C3%A9l%C3%A9scripteur) (en tant que [périphériques d'entrée-sortie](https://fr.wikipedia.org/wiki/P%C3%A9riph%C3%A9rique_informatique#Types_de_p%C3%A9riph%C3%A9riques)) sur le [système Unix](https://fr.wikipedia.org/wiki/UNIX_System_V), un [processeur de textes commandé textuellement](https://linuxfr.org/users/mrspackman/journaux/l-esprit-unix-une-culture-des-mots)... C'est cet aspect que j'aimerais rappeler à travers quelques commandes oubliées. # 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](https://consomatique.fr/saisie-de-texte-au-kilometre-quest-ce-que-cest/)) d'une part, et la mise en forme d'autre part. Un éditeur comme _Vi_ permet d'observer cette règle facilement : on est en mode insertion 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 Entrée)](https://www.memoclic.com/448-word/18940-saisie-au-kilometre.html). Dans un [éditeur de texte](https://fr.wikipedia.org/wiki/%C3%89diteur_de_texte), que ce soit pour avec un [balisage](https://fr.wikipedia.org/wiki/Langage_de_balisage_l%C3%A9ger) ou directement pour l'imprimante comme dans le cas présent, c'est plus simple : la touche Entrée 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](https://fr.wikipedia.org/wiki/Terminal_%28informatique%29)...) Les systèmes _Unix_ offrent quelques outils pour cela. # replis sur bord de lignes Le premier, peu connu, est [le filtre POSIX "`fold`"](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/fold.html#top), apparu dans [1BSD](https://en.wikipedia.org/wiki/Berkeley_Software_Distribution) en 1977 (sortie officielle de la distribution en mars 1978). 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 : ```console $ 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 ! ```console $ 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. ``` J'utilise cette commande dans mes scripts pour des traitements caractère par caractère : ```sh # 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` : ```sh # from variable for char in $(echo "$var" | grep -os '.'); do stuff; done # from file for char in $(grep -os '.' "$filepath"); do stuff; done ``` # ajustement des paragraphes à une largeur Il existe un autre filtre, apparu dans [2BSD](https://en.wikipedia.org/wiki/History_of_the_Berkeley_Software_Distribution#2BSD_%28PDP-11%29) 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](https://fr.wikipedia.org/wiki/FMT) comme en [anglais](https://en.wikipedia.org/wiki/FMT) 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.](http://fmtlib.net/latest/index.html), cousin de "`printf`"/"`sprintf`" anciennement connu sous le nom de "[`cppformat`](https://isocpp.org/blog/2016/05/cppformat-3.0.0-and-becomes-fmt-victor-zverovich)" et est utilisé par exemple dans [Go](https://golang.org/pkg/fmt/) et dans [Java EE en tant que JSTL](http://www.codejava.net/java-ee/jstl/jstl-format-tag-formatnumber) etc.) On lui indique aussi la largeur voulue avec l'option "`-w`" (qui est de 75 caractères par défaut ...parce que conçu avec la [nétiquette](https://fr.wikipedia.org/wiki/N%C3%A9tiquette) et [les RFC du courriel](https://stackoverflow.com/a/23928579/1699311) en tête) ```console $ 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 `vi` hé hé). Du coup, il peut [appliquer un retrait à la première ligne du paragraphe](https://french.stackexchange.com/questions/10958/utilisation-des-retraits-au-d%C3%A9but-des-paragraphes) (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](https://support.office.com/fr-fr/article/Cr%C3%A9er-un-retrait-de-premi%C3%A8re-ligne-5788cf53-3ce9-4381-bd3a-2819c538ecd9) et [là](http://www.commentcamarche.net/contents/1651-word-regler-le-retrait-des-paragraphe) ou [là](http://coursvallee.purebackend.com/word/ateliers_word/atelier_9_word/atelier_9_word.htm) 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 `vi` hé hé) et peuvent alors appliquer la règle typographique anglophone d'espacement (datant de l'époque des machines à écrire et devant faciliter la lecture) : un seul 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](https://man.openbsd.org/fmt)/[FreeBSD](https://www.freebsd.org/cgi/man.cgi?query=fmt&sektion=1&apropos=0&manpath=FreeBSD+6.2-RELEASE) | [GNU/Linux](https://linux.die.net/man/1/fmt) | [Sun Solaris](https://docs.oracle.com/cd/E23823_01/html/816-5165/fmt-1.html#scrolltoc) | [Plan 9](http://plan9.bell-labs.com/magic/man2html/1/fmt) | [IBM AIX](http://publib16.boulder.ibm.com/doc_link/en_US/a_doc_lib/cmds/aixcmds2/fmt.htm) | | |--------|--------|-------|--------|--------|------| | `-w I` | `-w I` | `-w I`| `-w I` | `-w I` | use `I` width output (default goal is around 93% of width) | | `-I` | `-I` | `-I` | `-l I` | `-I` | use `I` width output | | `I` | `-g I` | | | | goal is `I` (and max width is `I+10` unless specified) | | `I L` | `-g I -w L` | | | | goal is `I` and max width is `L` | | `-c` | | | | | Center | | `-d X` | | | | | sentence ending Delimiters are `X` | | `-l I` | | | | | replace `I` 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 I` | | | | | replace Tabs with `I` spaces instead of 1 | | | `-p X` | | | | reformat only lines beginning with `X` Prefix | | | `-c` | `-c` | | | preserve indentation of first two lines = Crown margin | | | `-s` | `-s` | `-j` | | Split/fold only long lines but do not refill (i.e. Join short lines) | | | | | `-i I` | | Indent each line with `I` spaces | 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](https://stackoverflow.com/a/17225565/1699311) 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...](https://inconsolation.wordpress.com/2013/11/07/fmt-and-the-difference-is/) # 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 _`](http://www.opengroup.org/onlinepubs/9699919799/utilities/expand.html#top) | | `-l _` | [`unexpand -t _`](http://www.opengroup.org/onlinepubs/9699919799/utilities/unexpand.html#top) | Les filtres dédiés permettent d'ailleurs de faire beaucoup plus... ```console $ 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`](https://man.openbsd.org/expand.1) est apparue avec 1BSD en mars 1978, et [`tabs`](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/tabs.html) est apparu dans [PWB/UNIX](https://fr.wikipedia.org/wiki/PWB/UNIX) publié en juillet 1977.) Encore une fois, pas eu besoin d'attendre la machinerie moderne (voir [ici](http://www.commentcamarche.net/contents/1709-word-tabulations) et [là](https://www.votreassistante.net/creer-taquets-de-tabulations-word/) ou [là](http://questionbureautique.over-blog.com/article-tabulations-sous-word-120104572.html) par exemple.) ```console $ # 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`](https://www.netadmintools.com/art327.html#wbounce-modal) du projet [_HTML Tidy_](http://tidy.sourceforge.net) et qui a la particularité de combiner l'équivalent de `expand` (une seule largeur de tabulation) avec l'équivalent de [`dos2unix` ou `fromdos`](https://opensharing.fr/commandes-linux-dos2unix). C'est présent dans _Mac OS X_ et [Solaris](https://docs.oracle.com/cd/E88353_01/html/E37839/tab2space-1.html) entre autres. - la commande [`retab` dans _Vim_](https://vim.fandom.com/wiki/Super_retab) et peut être [vite implémenté dans Emacs](https://gist.github.com/snim2/223491) et dans [VSC](https://github.com/liuqx0717/tabs-to-spaces/blob/master/tab2space.sln) - 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](http://www.nicemice.net/amc/) à produire "[`par`](http://www.nicemice.net/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](http://www.nicemice.net/par/par-doc.var) ; 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é 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`" et "`h`" et "`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`... ```console $ # 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
let non-trailing body chars in B as is =/+/- prefix, non-leading in suffix replace/augment/diminish c count all words as capitalized body chars by d
use indentation as a delimiter P ditto for protective chars E send messages to stderr Q ditto for quote chars e discard superfious lines -------- Integer parameters: -------- f narrow paragraph for best fit h skip IP's 1st lines g preserve wide sentence breaks in scan for common affixes i hide lines inserted by p prefix length j justify paragraphs r if not 0, force bodiless l treat last lines like others lines to length q supply vacant lines between s suffix length different quote nesting levels T tab stops every cols R print error for too-long words w max output line length t 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. ```console $ # comme "fmt" mais les tabulations deviennent un 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](http://www.nicemice.net/par/build-hints.var). À surveiller. # balle au centre et égalisation Pour le centrage, il faut hélas recourir à "[`printf`](https://stackoverflow.com/a/12477090/1699311)" (ou "[`perl`](https://stackoverflow.com/a/12472021/1699311)" ou "[`sed`](https://www.unix.com/302288634-post3.html)" ou autre) puis [boucler sur toutes les lignes](https://superuser.com/a/829870/161454) (ce qui peut se faire avec "[`awk`](https://superuser.com/a/915899/161454)" qui est [mon filtre favori dans ce cas ci](https://unix.stackexchange.com/a/96115/23889)...) Nota : [_Vim_ a la commande "`:center`" qui fait bien cela](https://unix.stackexchange.com/a/94758/23889) ; 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_](https://superuser.com/a/171624/161454) et [_Nano_](https://superuser.com/a/637512/161454) ; et sinon ça [se scripte dans un langage un peu avancé](https://superuser.com/a/171642/161454).) 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...](https://en.wikipedia.org/wiki/Typographic_alignment#Problems_with_justification) 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](https://fr.wikipedia.org/wiki/C%C3%A9sure_%28typographie%29) (ou « [hyphenation](https://en.wikipedia.org/wiki/Hyphen#Justification_and_line-wrapping) » en anglais, qui se fait avec le [trait d'union](https://fr.wikipedia.org/wiki/Trait_d%27union#Codage_informatique)...) 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](http://www.dpbsmith.com/tj2.html), pour la machine [PDP-1](https://en.wikipedia.org/wiki/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 _Dorsey_) et non logiciel (comme _Vydec_)... # impressions standards Voyons maintenant une dernière commande, apparue avec la première version officielle distribuée aux universités vers 1971 mais déjà utilisé au Bell Labs (en fait [il nait en août 1969](https://framablog.org/2009/08/10/unix-40-ans/) mais [son état civile est enregistré pour le 1er janvier de 1970](http://www.commentcamarche.net/contents/1147-introduction-aux-systemes-unix) 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. Tout comme l'écran du terminal ou de la console a un certain nombre de lignes ×ばつ colonnes (par exemple ×ばつ80) la page aussi. Ces dimensions (longueur ×ばつ largeur de papier, par défaut ×ばつ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](https://techlib.fr/definition/margin.html) » (nulle par défaut, et à ne pas confondre avec la [marge technique](https://forum.ubuntu-fr.org/viewtopic.php?id=1105761) ou le [débord](https://www.coollibri.com/blog/utilite-dune-impression-sans-marge-sous-word/) qui s'ajoute), qui est retiré de la largeur, avec l'option "`-o`" (pour « line Offset ») ![](https://www.coollibri.com/blog/wp-content/uploads/2018/12/imprimer-chez-un-professionnel-marges-et-fonds-perdus-1024x731.jpg) Comme il s'agit de document à imprimer, "`pr`" rajoute un [en-tête](https://www.linternaute.fr/dictionnaire/fr/definition/en-tete/) 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](https://www.linternaute.fr/dictionnaire/fr/definition/pied-de-page/)... Ce n'est certainement pas parfait, mais [moins prise de tête àmha.](https://www.developpez.net/forums/d2060606/logiciels/microsoft-office/word/ajouter-marges-lorsqu-y-entete-pied-page/) ```console $ # 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 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](http://dircomleblog.canalblog.com/archives/2009/11/27/15907065.html) qui sont [plus ou moins obligatoires](https://www.entreprises.cci-paris-idf.fr/web/reglementation/developpement-entreprise/droit-affaires/quelles-sont-mentions-obligatoires-documents-commerciaux) dans cette zone... On en rencontre qui utilisent l'en-tête du document pour des informations autre que leur logo et leur nom. 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 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.) ```console $ # 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 text $ 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.) ```console $ # 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 `(10+1+5)+1+N+1+(4+1+1) = 17+N+7` avec : - champ de gauche : `10+1+5` est le nombre de caractères pour la date (`10`) et l'horaire (`5`) conformément aux [normes](http://www.btb.termiumplus.gc.ca/tpv2guides/guides/clefsfp/index-fra.html?lang=fra&lettr=indx_catlog_d&page=9lcOojjUrxt8.html#date-chif) - champ de droite : `4+1+1` est le nombre de caractères pour le numéro de page (`<10` sinon augmenter en conséquence) - champ du milieu : `N` 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. 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`](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/nl.html)" 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. ```console $ # 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.) ```console $ # 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 en rang et/ou partielles 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`](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/paste.html)" ou "[`rs`](https://manpagez.com/man/1/rs/)" par exemple.) Le séparateur entre colonnes est l'espace, 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. ```console $ # 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 le 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 : ```console $ # 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 -n 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 -n 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 -n 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. 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 une s'arrêter à une page donnée... Avec cette option, l'implémentation GNU propose une option "`-N`" pour réinitialiser le compteur quand on utilise l'option "`-n`" et c'est pas mal. ```console $ # par défaut, toutes les 4 pages $ # (de la première à la dernière donc) $ pr -w 30 -l 15 -f formated0 | cat -n 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 -n 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 -n 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 -n 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 -n 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](http://www.encyclopedia-bureautique.com/dictionnaire/les-veuves-orphelines) (lignes creuses/isolées/désolidarisées.) # impressions 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... ```console $ # 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 -n 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 -n 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 -n ``` 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. ```console $ # 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 -n 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`](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/diff.html)"... 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`". # chasse fixe L'utilitaire "`pr`" permet diverses mises en pages plus ou moins avancées pour une [impression brute/directe](https://advancedweb.fr/impression-brute-directement-sur-une-imprimante-usb-sans-passer-par-le-spouleur-windows/) (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 qu'on utilise. | [OpenBSD](https://man.openbsd.org/pr.1)/[FreeBSD](https://www.freebsd.org/cgi/man.cgi?query=pr&sektion=1) | [GNU](https://linux.die.net/man/1/pr) | [AIX](https://www.ibm.com/support/knowledgecenter/en/ssw_aix_71/com.ibm.aix.cmds4/pr.htm) | [POSIX](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/pr.html) | | |--------|--------|--------|--------|---| | `+I` | `+I` | `+I` | `+I` | begin output at page number `I` | | | `+I:L` | | | output pages from number `I` to `L` | | `-I` | `-I` | `-I` | `-I` | produce `I` 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 X` | | | use `X` as header Date format | | `-eCI` | `-eCI` | `-eCI` | `-eCI` | Expand each input `C` (default tab) to `n×ばつI+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 X` | `-h X` | `-h X` | use `X` instead of filename as centered Header | | `-iCI` | `-iCI` | `-iCI` | `-iCI` | replace multiple blanks by `C` char. (default tab) at `n×ばつI+1` (default 8) in output | | | `-J` | | | Join lines, i.e. merge full lines and turn off `-W` truncation | | `-l I` | `-l I` | `-l I` | `-l I` | set page Length to `I` lines | | `-m` | `-m` | `-m` | `-m` | Merge contents of multiple files (lines side by side) | | `-nCI` | `-nCI` | `-nCI` | `-nCI` | print line Number separated by `C` char. (default tab) using `I` width column (default 5) | | | `-N I` | | | first line Number printed with `+I` | | `-o I` | `-o I` | `-o I` | `-o I` | precede each line of output with `I` space as Offset | | | | `-p` | `-p` | Pause before each page on TTY | | `-r` | `-r` | `-r` | `-r` | no diagnostic Reports on file open failure | | `-sC` | `-sC` | `-sC` | `-sC` | Separate text columns with `C` char. (default tab) instead of spaces, turn off truncation when no `-s` | | | `-SC` | | | Separate text columns with `C` 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 I` | `-w I` | `-w I` | `-w I` | set the Width of the line to `I` instead of 72 (when not `-s`) or 512 (when `-s`) | | | `-W I` | | | set page Width to `I` instead of 72, truncate except `-J` but no interference with `-s` or `-S` | Avant de finir, revenons sur les largeurs par défaut : - 80 fold - 75 fmt - 72 par - 72 pr Cela va faire bizarre aujourd'hui à ceux qui n'ont pas connu les « polices à [chasse](https://fr.wikipedia.org/wiki/Chasse_%28typographie%29) fixe » —[comme Consolas, Courier New, DejaVu Sans Mono, Droid Sans Mono, Inconsolata, Menlo, Lucida Console, Monaco, Terminal, etc.](https://en.wikipedia.org/wiki/List_of_monospaced_typefaces)— et les [fontes](https://coreight.com/content/guide-polices-typographie) qui caractérisent les [imprimantes à impacts](https://web.archive.org/web/20160915231846/https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/3/html/Introduction_to_System_Administration/s1-printers-types-impact.html) : - les imprimantes dérivées des téléscripteurs (en fait toute machine à écrire électrique pilotable par ordinateur), initialement, comme les [Friden Flexowriter](https://en.wikipedia.org/wiki/Friden_Flexowriter) et les [IBM Selectric](https://fr.wikipedia.org/wiki/Technique_IBM_%C3%A0_boule) - les [imprimantes à marguerites](http://www.dicofr.com/cgi-bin/n.pl/dicofr/definition/20011012123643) (similaires à des machines à écrire) ou [à tulipe](https://fr.wikipedia.org/wiki/Imprimante_%C3%A0_marguerite) (qui permet d'avoir deux ou trois fontes au lieu d'une seule), - les [imprimantes à marteau ou à chaîne](https://en.wikipedia.org/wiki/Line_printer) qu'on trouvait souvent couplés aux [mainframes](https://fr.wikipedia.org/wiki/Ordinateur_central), - les [imprimantes matricielles](http://imprimantesthermique.free.fr/les-imprimantes-matricielles.htm) maintenant (et qui ont [toujours la côte](http://www.ordinateur.cc/Mat%C3%A9riel/Imprimantes/26180.html) malgré leurs [défauts](http://www.ocominc.com/fr/news/Advantages-and-disadvantages-of-dot-matrix-printer.html), un marché où [Epson](https://www.epson.fr/products/printers/dot-matrix-printers) 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](https://en.wikipedia.org/wiki/Line_matrix_printer) qui sont à mi-chemin entre les imprimantes à ligne et les imprimantes matricielles, comme les Printronix P7000. - les [tables traçantes](https://fr.wikipedia.org/wiki/Traceur_%28informatique%29) (qui sont [encore d'usage](https://www.azero.fr/comment-choisir-son-traceur/) 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](https://en.wikipedia.org/wiki/IBM_3270#Models) (80 caractères) ainsi que les [téléscripteurs](https://en.wikipedia.org/wiki/Teleprinter) (72 caractères) même s'il y a eu rapidement [des équipements pouvant atteindre 132 caractères](https://en.wikipedia.org/wiki/Line_printer)... Il se trouve, que pour pour une petite fonte lisible (soit une taille de caractère standard de 10 [pitch](https://en.wikipedia.org/wiki/Pitch_%28typewriter%29) ou ~20 CPI —environ 1⁄6e pouce ou un [pica](https://en.wikipedia.org/wiki/Pica_%28typography%29)—) on a bien 72 [CPL](https://en.wikipedia.org/wiki/Characters_per_line#History) ...qui correspond au [format standard de papier américain](http://www.papersizes.org/us-paper-sizes.htm) « [_letter_ de ×ばつ11 pouces](https://en.wikipedia.org/wiki/Letter_%28paper_size%29) ». Cependant, [certains suggèrent de faire moins (entre 50 et 70 CPL)](https://baymard.com/blog/line-length-readability), ce qu'on obtient avec une plus grande fonte (soit une taille de caractère standard de 12 [pitch](https://en.wikipedia.org/wiki/Pitch_%28typewriter%29) ou ~17 CPI —alias un elite pour les [IBM Selectric](https://en.wikipedia.org/wiki/IBM_Selectric_typewriter)—). ![Selectric iii balls](https://upload.wikimedia.org/wikipedia/commons/thumb/d/dc/Selectric-iii-balls.jpg/775px-Selectric-iii-balls.jpg) Les journaux ne s'y sont pas trompé en privilégiant le multi colonage (avec un [optimum entre 40 et 50 par colonne](http://mikeyanderson.com/optimal_characters_per_line)...) ! Alors, à l'heure des polices proportionnelles (qui posent [des soucis très différents](https://web.archive.org/web/20180102085458/http://coin.des.experts.pagesperso-orange.fr/reponses/faq9_33.html) 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](https://www.retif.eu/encaissement-et-securite/encaissement/caisses-enregistreuses-magasin.html)... ![Twitter receipt printer](https://upload.wikimedia.org/wikipedia/commons/thumb/5/54/Twitter_receipt_printer.jpg/440px-Twitter_receipt_printer.jpg) (Parmi les principaux fabricants, on trouve [Sharp](https://sharp.com.sg/web/products/ProdList.asp?Catid=39), [Casio](http://casio-caisses-enregistreuses.fr/casio-gamme-standard/), et bien [d'autres](https://www.bureau-vallee.fr/informatique/materiel-bureautique/calculatrices/calculatrices-imprimante-et-caisse.html). Ceci dit, comme toujours, il n'est pas obligatoire [que l'imprimante et le clavier et le logiciel ne fassent qu'un](https://www.cdiscount.com/arts-loisirs/r-imprimante+ticket+de+caisse.html#_his_) —les uns et les autres aiment vendre [des solutions tout-en-un](http://www.ultratactile.fr/10-imprimantes-pour-caisse-enregistreuse) mais dont on se retrouve prisonnier...) Ces dernières sont souvent des imprimantes thermiques (nombreux [direct](http://www.clemsys.com/40-imprimante-de-caisse-imprimante-etiquette-code-barre) ou à [transfert](https://www.timcod.fr/produits/imprimantes/bureautiques-thermiques/) et quelques uns [à sublimation](https://imprimante.ooreka.fr/comprendre/thermique)) ou [à diodes](https://fr.wikipedia.org/wiki/Imprimante_LED), connectable par USB ou sans fil, fonctionnant sur secteur, etc. J'ai eu pendant quelques temps la [_HP 82240B_](https://commerce.hpcalc.org/82240b.php) qui est une [imprimante de poche connectée par IR](https://www.cnet.com/products/hp-infrared-printer/specs/) que je n'ai pu utiliser (en dehors de ma calculatrice) qu'avec _Linux_ ! Comme le rappelle [Sylvain cote sur HPMuseum](http://www.hpmuseum.org/forum/archive/index.php?thread-6275.html), 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](https://www.calculatorsource.com/m-mcp8850b.html) ! Mis à part le packaging vraiment bien fichu et l'électronique très bien maîtrisé par l'équipe de [Corvallis](https://fr.wikipedia.org/wiki/Corvallis_%28Oregon%29), on peut faire la même chose avec d'autres composants ou en faire d'autres usages ([suffit d'avoir un adaptateur IR](https://hackaday.io/project/25616-hp-82240b-ir-receiver-and-printer-interface)...) ![hp-82240b](http://commerce.hpcalc.org/images/82240b-angle-medium.jpg) 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é ou paru peu clair, n'hésite pas : ça se passe en commentaires.

AltStyle によって変換されたページ (->オリジナル) /