Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MANPAGER won't work on Mandoc's man implementation #1145

Closed
Bumbadawg opened this issue Aug 19, 2020 · 15 comments
Closed

MANPAGER won't work on Mandoc's man implementation #1145

Bumbadawg opened this issue Aug 19, 2020 · 15 comments

Comments

@Bumbadawg
Copy link

What version of bat are you using?
0.15.4

Describe the bug you encountered:
Using export MANPAGER="sh -c 'col -bx | bat -l man -p'"
results in -bx: 1: Syntax error: Unterminated quoted string

Describe what you expected to happen?
paging with bat

How did you install bat?
Void Linux package manager

** The bug **
It was already reported here for Termux, and it coudl well be the case for Alpine and other Mandoc's man implementations cases.
See termux/termux-packages#4781 (comment)

** Lazy solution **
Instead of recompiling man from GNU (https://www.nongnu.org/man-db/development.html)
one can be using export MANPAGER='nvim +Man!'

@Bumbadawg Bumbadawg added the bug Something isn't working label Aug 19, 2020
@sharkdp sharkdp added documentation and removed bug Something isn't working labels Sep 7, 2020
@sharkdp
Copy link
Owner

sharkdp commented Sep 7, 2020

Thank you for reporting this.

This is not a bug in bat. This implementation of man is currently not supported. This should probably be documented.

sharkdp added a commit that referenced this issue Oct 1, 2020
@sharkdp sharkdp closed this as completed in 4bd1b15 Oct 2, 2020
@lahwaacz
Copy link

It does not work because mandoc does not do shell tokenization of the $MANPAGER string, it just splits it into a list of words and passes them to execvp. So the error comes from sh which complains about an unterminated quoted string from the word 'col.

bat itself does not have any problems displaying the output of mandoc's man command, you just have to configure the pager appropriately. This can be done by putting the following in a wrapper script and then export MANPAGER="your_wrapper":

#!/bin/sh
cat "$1" | col -bx | bat --language man --style plain

@eth-p
Copy link
Collaborator

eth-p commented Dec 2, 2020

#!/bin/sh
cat "$1" | col -bx | bat --language man --style plain

Not that performance matters much for a shell script like this, but you can even cut out the cat invocation:

col -bx < "$1" | bat --language man -p

@WhyNotHugo
Copy link

If you don't have col installed, it's shipped as part of heirloom-doctools.

8dcc added a commit to 8dcc/linux-dotfiles that referenced this issue Apr 16, 2023
@ju1ius
Copy link

ju1ius commented Jul 5, 2023

col -bx < "$1" | bat --language man -p

Or:

#!/bin/sh
exec col -bx | bat -pl man

@lahwaacz
Copy link

lahwaacz commented Oct 2, 2023

col -bx < "$1" | bat --language man -p

Or:

#!/bin/sh
exec col -bx | bat -pl man

These two commands are not equivalent - the former reads from a file denoted by $1 and the latter reads from stdin. The former is required for mandoc, the latter may be required for other things that use $MANPAGER (e.g. using the help function in an ipython shell). The following can be used as a universal solution (note that cat here is not as useless as in #1145 (comment)):

#!/bin/sh

# mandoc passes a file name, other tools write to stdout
# using `cat "$@"` we take care of both reading from file and stdin
exec cat "$@" | col -bx | bat --language man --style plain --pager "$PAGER"

@WhyNotHugo
Copy link

@lahwaacz Thanks, this solution works wonderfully!

@eth-p
Copy link
Collaborator

eth-p commented Feb 12, 2024

As part of my investigation into other man-related issues, I figured out why the mandoc implementation doesn't work:

It does extremely simple shell splitting for the MANPAGER variable, which makes it impossible to escape spaces.

image

@lahwaacz's approach of putting it in a separate script is the only solution to having this work with mandoc.

@Mark-Joy
Copy link

Mark-Joy commented Jul 22, 2024

exec cat "$@" | col -bx | bat --language man --style plain --pager "$PAGER"

Or this for better performance:

#!/bin/sh
if [ -f "$1" ]; then
  col -bx < "$1" | bat --language man --plain
else
  col -bx | bat --language man --plain
fi

@lahwaacz
Copy link

Or this for better performance:

Did you actually measure it?

In any case, [ -f "$1" ] seems like a wrong condition: if there is no file but stdin, there is no $1 itself.

@Mark-Joy
Copy link

In any case, [ -f "$1" ] seems like a wrong condition: if there is no file but stdin, there is no $1 itself.

what else is the else clause for?
The code means: if the input is a file then take the file, otherwise take the stdin

Did you actually measure it?

Do I have to? One must be processed through cat and then col, while the other just goes through col

@lahwaacz
Copy link

In any case, [ -f "$1" ] seems like a wrong condition: if there is no file but stdin, there is no $1 itself.

what else is the else clause for? The code means: if the input is a file then take the file, otherwise take the stdin

You should not check if $1 is a file, but if there is actually any input. Find out what $# is... 😉

Did you actually measure it?

Do I have to? One must be processed through cat and then col, while the other just goes through col

And you have added one shell condition instead. What do you think is faster: cat or [ -f "$1" ]?

@Mark-Joy
Copy link

Mark-Joy commented Jul 22, 2024

Hey, so you have so much free time in your life huh?

It just bothered me when you don't understand the code and saying it's wrong. It's not wrong. See, after you figure out what my code means, you already improve it. Good learning for you, right? 😉
I'll take your offer then

#!/bin/sh
if [ $# -eq 0 ]; then
  col -bx | "$BAT_BIN" --language man --plain
else
  col -bx < "$1" | "$BAT_BIN" --language man --plain
fi

And you have added one shell condition instead. What do you think is faster: cat or [ -f "$1" ]?

Isn't it obvious? But sure, have it your way.. I don't have much time and energy for something like this

For others: In ubuntu, bat is actually batcat, so set BAT_BIN to bat or batcat depends on your environment.

@lahwaacz
Copy link

I don't have much time and energy for something like this

Yeah it is much easier to claim something without actually verifying that it is true. I can as easily claim that there is no actual benefit in terms of performance.

@Mark-Joy
Copy link

You are all the way right 😉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants