8

With the example command

man apropos > outputfile

a text file is generated which contains the formatted man page of apropos (with some little differences with respect to man apropos directly printed on screen, such as bold characters).

But I would like to manually set the maximum line width of the generated output file, so that all the paragraphs will be justified to that width.

man pages are created through groff: for example, I tried to put .ll 50 before a paragraph of the original .gz man source text file, but it is trivial if I need to work on several man pages. Moreover not all the characters are recognized:

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

So, I wonder if a more straightforward method exists. How to modify the maximum line width, during the creation of an outputfile? Is there some specific command?


Edit:

(All the following considerations are about Ubuntu 18.04: I can no more test them in previous versions, included the 14.04 of the above question.)

As regards a one-line temporary solution, if MANWIDTH has not been already exported with a custom value, there is no difference between

$ MANWIDTH=60 man apropos > outputfile

and

$ COLUMNS=60 man apropos > outputfile

The first one, using MANWIDTH, is however better in principle.


Edit 2 (not strictly related to the question):

To make instead a permanent width setting to be applied to any manpage printing, it is necessary to export the desired value of the variable. With:

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

man apropos will be printed with the same width regardless of any terminal window resizing. Instead,

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

will provide the same result as before only if the terminal window is not resized between export and man <page> > outputfile.

  • I can't reproduce your input code errors 195 168 could be è in UTF-8. Is the man page in English? What's your man implementation? What's your locale? – Stéphane Chazelas Aug 11 '15 at 14:04
  • the system is Ubuntu 14.04 (version from man man is 2.6.7.1). The man page is in Italian and it is UTF-8. What do you mean by locale? – BowPark Aug 11 '15 at 16:40
  • What's the output of locale? and locale charmap? – Stéphane Chazelas Aug 11 '15 at 16:57
  • locale output: LANG=it_IT.UTF-8 LANGUAGE= LC_CTYPE="it_IT.UTF-8" LC_NUMERIC="it_IT.UTF-8" locale charmap output: UTF-8 – BowPark Aug 11 '15 at 17:05
  • 1
    Yes the terminal not functional is from less because TERM is not set. I meant env -i LANG=it_IT.UTF-8 man apropos > output (or | head). – Stéphane Chazelas Aug 12 '15 at 8:33
14

Use the MANWIDTH environment variable:

MANWIDTH=60 man apropos > apropos.txt

The manpage for man 2.7.4 says:

If $MANWIDTH is set, its value is used as the line length for which manual pages should be formatted. If it is not set, manual pages will be formatted with a line length appropriate to the current terminal (using the value of $COLUMNS, an ioctl(2) if available, or falling back to 80 characters if neither is available).

That is, it overrides both COLUMNS and the ioctl value. I prefer to not rely on modifying COLUMNS (although it does work here) since its value is updated dynamically every time the window size changes.

Using MANWIDTH instead of COLUMNS also allows you to make the change permanent by adding a line such as export MANWIDTH=60 to your shell startup file.

  • Excellent job. I didn't want to change COLUMNS either, and MANWIDTH works a treat in RHEL5. Cheers. – Felipe Alvarez Apr 20 '16 at 0:35
  • 1
    A note to readers: you may need to use export MANWIDTH=60 if setting this in your ~/.bashrc. See stackoverflow.com/a/30173376/82216 . Also, consider wrapping man in a function to set MANWIDTH depending upon your terminal width, as suggested here on the Arch wiki. – sampablokuper Dec 17 '17 at 17:46
  • @Marcel M Thank you for your very precise answer. Can you please read the update in the question and edit your answer to include the fundamental suggestion about export MANWIDTH=60? – BowPark Oct 18 '18 at 8:07
  • @BowPark I wrote the answer without export because you asked about a temporary solution: "How to modify the maximum line width, during the creation of an outputfile?" (emphasis mine). You may even want to revert your edit as it doesn’t add to the question. (A comment is more appropriate.) – Marcel M Oct 18 '18 at 12:42
  • @MarcelM Actually you are right. I edited the question accordingly. I wrote a second edit with the export statements because in a comment it would be almost unreadable (not being possible to create newlines). – BowPark Oct 18 '18 at 14:03
10

Try setting the COLUMNS environment variable. Works for me with man from mandb 2.7.0.2 on Debian with groff 1.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 ...

With the version on Ubuntu 14.04, I need to write it:

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

There, man seems to disregard the COLUMNS environment variable if stdin is a terminal (it then queries the terminal device for the terminal width).

You can also try:

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

Which with zsh you can shorten to:

STTY='cols 60' man apropos | head

You could do it by invoking groff by hand as:

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

Your can't find character with input code errors were because you used -Tascii instead of -Tutf8 and didn't use -k to pre-process the files with preconv.

  • I tried the same command: COLUMNS=60 man apropos | head, but unfortunately the output width is all the screen width. Can I set the variable COLUMNS elsewhere or in other way? – BowPark Aug 11 '15 at 16:46
  • 2
    Try COLUMNS=60 < /dev/null man apropos | head. Looks like on Ubuntu 14.04, it doesn't trust COLUMNS if stdin is a terminal (and gets the width from the terminal device). – Stéphane Chazelas Aug 11 '15 at 16:53
  • Maybe it is like you supposed. And now it works, thank you! – BowPark Aug 11 '15 at 17:03
4

You can use the fmt command, which as far as I know is present in any Linux distribution.

man apropos | fmt -w 70 

will wrap up lines at 70 characters.

  • 1
    yes I have it, thank you, it works and it is pretty useful, but I need a justified text and it simply wrap up lines instead. – BowPark Aug 11 '15 at 16:42
  • Sorry, I must have missed up that part. – dr01 Aug 12 '15 at 8:10
2

You can use fold

man cp | fold -w 20

will fold after each 20 characters(!). Note that this will cut words in two as the only option is "fold every 20 characters"

taking care of this, you might use sed as follows (with dynamic line length)

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

will add a newline after 20 random characters followed by a space (i.e. new word). So lines might be longer than 20 characters (match is 20 characters then a space so a 26-character word would result in a 26-character line)

For omitting the last space in the sed command:

sed 's/\(.\{20\}\) /\1\n/g'
  • 1
    Thank you, I tried your examples and they work, but - as written in a comment to dr01 - I need a justified text. – BowPark Aug 11 '15 at 16:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.