Imprimer des pages de manuel à largeur fixe

11

Avec l'exemple de commande

man apropos > outputfile

un fichier texte est généré qui contient la manpage formatée de apropos(avec quelques petites différences par rapport à l' man aproposimpression directe à l'écran, comme les caractères gras).

Mais je voudrais définir manuellement la largeur de ligne maximale du fichier de sortie généré, afin que tous les paragraphes soient justifiés à cette largeur.

manles pages sont créées via groff: par exemple, j'ai essayé de mettre .ll 50avant un paragraphe du .gz manfichier texte source d' origine , mais c'est trivial si j'ai besoin de travailler sur plusieurs manpages. De plus tous les personnages ne sont pas reconnus:

apropos.1:45: warning: can't find character with input code 195
apropos.1:45: warning: can't find character with input code 168
apropos.1:47: warning: can't find character with input code 178
apropos.1:131: warning: can't find character with input code 169

Je me demande donc s'il existe une méthode plus simple. Comment modifier la largeur maximale de ligne, lors de la création d'un outputfile? Existe-t-il une commande spécifique?


Modifier :

(Toutes les considérations suivantes concernent Ubuntu 18.04: je ne peux plus les tester dans les versions précédentes, y compris le 14.04 de la question ci-dessus.)

En ce qui concerne une solution temporaire d'une ligne, si elle MANWIDTHn'a pas déjà été exportée avec une valeur personnalisée, il n'y a pas de différence entre

$ MANWIDTH=60 man apropos > outputfile

et

$ COLUMNS=60 man apropos > outputfile

La première, en utilisant MANWIDTH, est cependant meilleure en principe.


Edit 2 (pas strictement lié à la question):

Pour définir à la place un paramètre de largeur permanent à appliquer à toute impression de page de manuel, il est nécessaire d' exporter la valeur souhaitée de la variable. Avec:

$ export MANWIDTH=60
# zero or more additional lines
$ man apropos > outputfile

man apropossera imprimé avec la même largeur quel que soit le redimensionnement de la fenêtre du terminal. Au lieu,

$ export COLUMNS=60
# zero or more additional lines
$ man apropos > outputfile

fournira le même résultat qu'auparavant uniquement si la fenêtre du terminal n'est pas redimensionnée entre exportet man <page> > outputfile.

BowPark
la source
Je ne peux pas reproduire vos input codeerreurs 195 168 pourraient être è en UTF-8. La page de manuel est-elle en anglais? Quelle est votre implémentation homme? Quelle est votre localisation?
Stéphane Chazelas
le système est Ubuntu 14.04 (la version man manest 2.6.7.1). La page de manuel est en italien et elle est UTF-8. Qu'entendez-vous par locale?
BowPark
Quelle est la sortie de locale? et locale charmap?
Stéphane Chazelas
localesortie: LANG=it_IT.UTF-8 LANGUAGE= LC_CTYPE="it_IT.UTF-8" LC_NUMERIC="it_IT.UTF-8" locale charmapsortie:UTF-8
BowPark
1
Oui le terminal non fonctionnel vient de lesscar TERMn'est pas paramétré. Je voulais dire env -i LANG=it_IT.UTF-8 man apropos > output(ou | head).
Stéphane Chazelas

Réponses:

19

Utilisez la MANWIDTHvariable d'environnement:

MANWIDTH=60 man apropos > apropos.txt

La page de manuel de man 2.7.4 indique:

Si $ MANWIDTH est défini, sa valeur est utilisée comme longueur de ligne pour laquelle les pages de manuel doivent être formatées. S'il n'est pas défini, les pages de manuel seront formatées avec une longueur de ligne appropriée au terminal actuel (en utilisant la valeur de $ COLUMNS, un ioctl (2) si disponible, ou retomber à 80 caractères si aucun n'est disponible).

Autrement dit, il remplace à la fois COLUMNSet la ioctlvaleur. Je préfère ne pas compter sur la modification COLUMNS(bien que cela fonctionne ici) car sa valeur est mise à jour dynamiquement à chaque fois que la taille de la fenêtre change.

L'utilisation de MANWIDTHau lieu de COLUMNSvous permet également de rendre la modification permanente en ajoutant une ligne telle que export MANWIDTH=60votre fichier de démarrage du shell.

Marcel M
la source
Excellent travail. Je ne voulais pas non plus changer les COLONNES, et MANWIDTH fonctionne comme un régal dans RHEL5. À votre santé.
Felipe Alvarez
1
Note aux lecteurs: vous pouvez avoir besoin d'utiliser export MANWIDTH=60si le réglage dans votre ~/.bashrc. Voir stackoverflow.com/a/30173376/82216 . En outre, envisager l' emballage mandans une fonction pour définir MANWIDTH en fonction de votre largeur du terminal, comme le suggère ici sur le wiki Arch.
sampablokuper
@Marcel M Merci pour votre réponse très précise. Pouvez-vous s'il vous plaît lire la mise à jour dans la question et modifier votre réponse pour inclure la suggestion fondamentale à propos de export MANWIDTH=60?
BowPark
@BowPark J'ai écrit la réponse sans exportcar vous avez demandé une solution temporaire: "Comment modifier la largeur de ligne maximale, lors de la création d'un fichier de sortie? " (C'est moi qui souligne). Vous pouvez même annuler votre modification car elle n'ajoute rien à la question. (Un commentaire est plus approprié.)
Marcel M
@MarcelM En fait, vous avez raison. J'ai modifié la question en conséquence. J'ai écrit un deuxième montage avec les exportdéclarations car dans un commentaire ce serait presque illisible (impossible de créer des nouvelles lignes).
BowPark
10

Essayez de définir la COLUMNSvariable d'environnement. Fonctionne pour moi avec mande mandb2.7.0.2 sur Debian avec groff1.22.3.

$ COLUMNS=60 man apropos | head
APROPOS(1)          Manual pager utils          APROPOS(1)



NAME
       apropos - search the manual page names and descrip
       tions

SYNOPSIS
       apropos [-dalv?V] [-e|-w|-r]  [-s  list]  [-m  sys

$ COLUMNS=70 man apropos | head
APROPOS(1)               Manual pager utils               APROPOS(1)



NAME
       apropos - search the manual page names and descriptions

SYNOPSIS
       apropos  [-dalv?V] [-e|-w|-r] [-s list] [-m system[,...]] [-M
       path] [-L locale] [-C file] keyword ...

Avec la version sur Ubuntu 14.04, je dois l'écrire:

COLUMNS=60 < /dev/null man apropos | head

Là, mansemble ignorer la COLUMNSvariable d'environnement si stdin est un terminal (il interroge ensuite le terminal pour la largeur du terminal).

Vous pouvez également essayer:

s=$(stty -g); stty cols 60; man apropos | head; stty "$s"

Qui avec zshvous peut raccourcir en:

STTY='cols 60' man apropos | head

Vous pouvez le faire en invoquant groffà la main:

gzip -dcf "$(man -w apropos)" |
  groff -ekpstR -mtty-char -mandoc -Tutf8 -rLL=60n |
  col -bpx

Votre ne peut pas trouver caractère avec le code d' entrée erreurs étaient parce que vous avez utilisé au -Tasciilieu de -Tutf8et ne pas utiliser -kde pré-traiter les fichiers avec preconv.

Stéphane Chazelas
la source
J'ai essayé la même commande COLUMNS=60 man apropos | head:, mais malheureusement, la largeur de sortie est toute la largeur de l'écran. Puis-je définir la variable COLUMNSailleurs ou d'une autre manière?
BowPark
2
Essayez COLUMNS=60 < /dev/null man apropos | head. On dirait que sur Ubuntu 14.04, il ne fait pas confiance COLUMNSsi stdin est un terminal (et obtient la largeur du périphérique terminal).
Stéphane Chazelas
C'est peut-être comme vous le supposiez. Et maintenant ça marche, merci!
BowPark
4

Vous pouvez utiliser la fmtcommande, qui pour autant que je sache, est présente dans n'importe quelle distribution Linux.

man apropos | fmt -w 70 

terminera les lignes à 70 caractères.

dr_
la source
1
oui je l'ai, merci, cela fonctionne et c'est assez utile, mais j'ai besoin d'un texte justifié et il suffit de conclure les lignes à la place.
BowPark
Désolé, j'ai dû manquer cette partie.
dr_
2

Vous pouvez utiliser fold

man cp | fold -w 20

se pliera après chaque 20 caractères (!). Notez que cela coupera les mots en deux car la seule option est "plier tous les 20 caractères"

en prenant soin de cela, vous pouvez utiliser sedcomme suit (avec une longueur de ligne dynamique)

man cp | sed 's/.\{20\} /&\n/g'

ajoutera une nouvelle ligne après 20 caractères aléatoires suivis d'un espace (c'est-à-dire un nouveau mot). Ainsi, les lignes peuvent dépasser 20 caractères (la correspondance est de 20 caractères, puis un espace pour qu'un mot de 26 caractères donne une ligne de 26 caractères)

Pour avoir omis le dernier espace de la sedcommande:

sed 's/\(.\{20\}\) /\1\n/g'
Fiximan
la source
1
Merci, j'ai essayé vos exemples et ils fonctionnent, mais - comme écrit dans un commentaire à dr01 - j'ai besoin d'un texte justifié.
BowPark