What a great macro! The first time I ran it, it popped up a window with a whole bunch of font names in it - I suspect it was just pstopdf building some sort of font cache. It never displayed anything after that.
Thanks !
I hadn’t seen that font cache event - I wonder if there’s a simple way of trapping it …
UPDATE:
I’ve added an -l
switch to pstopdf
to the macro in the post above – I think that should redirect any messages about font initialisation to a log file …
CMD="$KMVAR_Shell_command";
man -t "$CMD" | pstopdf -l -i -o $HOME/Desktop/$CMD.pdf;
open -a Preview $HOME/Desktop/$CMD.pdf
FWIW a version which lists 1000+ commands and lets you select which ones you want to see PDF man pages for:
Browse Bash command man page(s).kmmacros (2.9 KB)
osascript -l JavaScript <<JXA_END 2>/dev/null
function run() {
function d(a) {
return a = ['man -t "', '" | pstopdf -l -i -o $HOME/Desktop/', ".pdf; open -a Preview $HOME/Desktop/", ".pdf"].join(a);
}
var c = Application.currentApplication(), b = Application("System Events");
c.includeStandardAdditions = !0;
b.includeStandardAdditions = !0;
b.activate();
var a = c.doShellScript('man -k . | grep "(1)" | cut -d "(" -f 1 | sort -f | uniq -u').split("\r"), a = b.chooseFromList(a, {withTitle:"BASH man pages", withPrompt:"Choose 1 or more from " + a.length.toString() + " commands :", okButtonName:"Read", multipleSelectionsAllowed:!0}), a = a instanceof Array ? a : [];
lstNoEntry = [];
a.forEach(function(a) {
try {
return c.doShellScript(d(a));
} catch (b) {
lstNoEntry.push("no manual entry for: " + a);
}
});
lstNoEntry.length && (b.activate(), b.displayAlert(lstNoEntry.join("\n"), {message:"no manual entry found"}));
return !0;
}
JXA_END
Extended version of the first macro above (enter shell command name to view man page PDF), which simply:
- Keeps the generated PDFs in a folder (prompts you on first use to choose or make a folder),
- checks, when you ask for a man page, whether the corresponding PDF already exists, and either opens the existing one or creates a new one, and
- remembers the last command that you asked for.
Shell manual page for command (as PDF) copy.kmmacros (9.5 KB)
And an updated version of the second macro above (browse and select from 1000+ commands to read PDF man pages) which:
- Uses the same PDF folder as the other script, and
- opens any existing PDF for a given command, rather than creating a new copy,
- remembers the previous selection(s) from either script.
Browse Bash command man page(s).kmmacros (10.0 KB)
This version currently does not allow asking for the man page of things like “5 vpnd”
Subtly adjusting the quoting resolves the problem:
CMD="$KMVAR_Shell_command";
man -t $CMD | pstopdf -l -i -o "$HOME/Desktop/$CMD.pdf"
open -a Preview "$HOME/Desktop/$CMD.pdf"
By removing the quoting around the $CMD in the man, you can have the two parameters, and by quoting the $CMD in the path and the open, the file name can have a space in it.
Speaking of which, technically $HOME can have a space in it too, so it should always be quoted - this lead to a significant data loss bug in an iTunes update for folks with this issue.
UPDATE - the version I am using now, which aims to include those quote adjustments:
Shell manual page for command (as PDF) copy.kmmacros (32.1 KB)
Hello, I have downloaded your last version of "Browse Bash command man page(s).kmmacros", but after setting a folder as asked, the macro does not create nor show a pdf of a man command. To understand what happens, I have changed the last Execute Shell script of the macro from "ignore result" to "display results in a window".
Here is the error output:
/var/folders/tq/242wr3411rl03x6czq91h4b00000gn/T/Keyboard-Maestro-Script-391AA1A3-86CF-4179-86EB-721EF954B392: eval: line 5: syntax error near unexpected token `('
/var/folders/tq/242wr3411rl03x6czq91h4b00000gn/T/Keyboard-Maestro-Script-391AA1A3-86CF-4179-86EB-721EF954B392: eval: line 5: `echo /Users/(myName)/Documents/Man page PDFs (via Keyboard Maestro)'
pstopdf failed on PS read from stdin with error code 30
See log file "ls.pdf.log" for messages
The file /ls.pdf does not exist.
The folder "/Users/(myName)/Documents/Man page PDFs (via Keyboard Maestro)" is empty.
Can you help, please? (by the way, the second macro " Shell manual page for command (as PDF) copy.kmmacros" doesn't work neither, nothing is displayed).
The second version is working here under Catalina.
Which macOS version are you using there?
The trick would probably be to get something working on the command line in Terminal.app, and then gradually re-wrap a macro around it.
For example, can you at least get something in Terminal.app
by requesting the pstopdf
command line options – entering this incantation:
pstopdf --help
and a view of the man page with:
man pstopdf
If those both fire OK, then try writing a man page PDF to the Desktop with something like:
man -t tr | pstopdf -l -o "$HOME/Desktop/tr.pdf"
and if that seems to work OK then
open "$HOME/Desktop/tr.pdf"
If all of those things have functioned OK, then perhaps the issue is with the destination folder ?
Let me know where you get to ...
One thing that might be worth experimenting with in the last Shell script action of the macro:
IFS=' '; read -a CMDSET <<< "$KMVAR_Shell_command";
for CMD in "${CMDSET[@]}"; do
MANPDF="$CMD.pdf"
# Allow for expansion of $HOME etc in path string
cd "$(eval echo $KMVAR_man_page_PDF_folder)";
if [ ! -e $MANPDF ]; then
man -t $CMD | pstopdf -l -i -o $MANPDF
fi
open -a Preview "$MANPDF"
done
is to eliminate the -i
flag from the main line, editing it to:
man -t $CMD | pstopdf -l -o $MANPDF
Here's my current version (working on Catalina), with the -i
flag suppressed:
Thanks for your answer. I'm under Big Sur (11.2.1).
pstopdf --help
gave:
pstopdf: illegal option -- -
Usage: pstopdf [inputfile] [-o outname] [-l] [-p]
Try: man pstopdf
The next:
man pstopdf
is OK. Then with:
man -t tr | pstopdf -l -o "$HOME/Desktop/tr.pdf"
I obtain 2 files, the expected tr.pdf and a tr.pdf.log (it contain a list of fonts). The next command:
open "$HOME/Desktop/tr.pdf"
is also OK. The pdf is opened in Preview.app.
Your new version of "Shell manual page for command (as PDF).kmmacros" don't work neither.
So, I go to the Keyboard Maestro preferences to delete the "man page PDF folder", and retry with your new version, and set the destination folder to ~/Documents/man-page-PDF
, and it works.
My previous destination folder was ~/Documents/Man page PDFs (via Keyboard Maestro)
.
Doesn't your macro support path with spaces in it?
But, the second macro "Browse Bash command man page(s).kmmacros" don't work (nothing displayed). To try understand why it don't work, I modified the last "Execute shell script" to change form "ignore results" to "display results in a window". But no window is displayed. In last resort, I add an "Alert" action before the last "Execute shell script" and the alert is displayed as expected. So what can I do with the Javascript code to test what is wrong?
I don't think the macro contains any JavaScript – the shell script issues are a bit hard to test when we are using different OS versions (and possibly different shells ?)
Did I understand from your narrative above:
So, I go to the Keyboard Maestro preferences to delete the "man page PDF folder", and retry with your new version, and set the destination folder to
~/Documents/man-page-PDF
, and it works.
That you have managed to find a working permutation of the options ?
In "Browse Bash command man page(s).kmmacros", aren't in the code:
osascript -l JavaScript <<JXA_END 2>/dev/null
(function(strFolderVar) {
function l(a, b) {
b = b || strFolderVar;
a JavaScript code?
The macro "Shell manual page for command (as PDF).kmmacros" run yet perfectly by changing the destination folder from ~/Documents/Man page PDFs (via Keyboard Maestro)
to ~/Documents/man-page-PDF
. So I think there was a problem because my first destination folder contained spaces in the name.
I have never used the Script Editor.app with the Javascript language. What must I paste to the Script Editor.app (with JavaScript instead AppleScript setting in the window) to test the code? I tried with all the code in the "Execute shell script" action, except the first and the last line (so no osascript -l JavaScript <<JXA_END 2>/dev/null
nor JXA_END
) and the script compile, and display a window with a big list of 245 commands.
So why doesn't run it in the macro?
(text edited: previously, when pasted in the Script Editor.app, I forgot a (
at the beginning).
Got it. There is indeed a JS fragment in there, but it's still part of a Shell script.
(a literal string argument to the shell osascript
command)
I could take a look later in the week at allowing for paths with space. Many thanks for pointing it out.
(Incidentally, if you ever do want to experiment with some JS code in Script Editor, the trick is to choose JavaScript from the language selector at top left)
Yes, it's exactly what I have do (but as my language is not English in my country, I badly explain it).
As the (JavaScript) code run (*) in Script Editor.app, the problem is in the first line:
osascript -l JavaScript <<JXA_END 2>/dev/null
or in the last line:
JXA_END
(*) in the Script Editor.app, the code display a window with 245 commands (but not the ls
command!). If I select the "openssl" in the list, I obtain a window titled: "no manual entry for: openssl".
Same error for "ps2pdf".
But theses error are perhaps I run the code in the Script Editor.app and not in the macro via the shell.
Yes – as I was trying, probably not very clearly, to explain - that isn't JavaScript – that's a shell command.
No more time today, alas, but I will take a look at all this in the week : - )
After checking with @ComplexPoint, the solution was found. I don't know why, but in the System Preferences, on "Security and confidentiality", at "Automatisation", for Keyboard Maestro.app, "System Events.app" wasn't checked. After checking it, all run good.
Sorry for this.
I'm using this for the man pages, but how can I adapt it to accept other Terminal output, such as "transcode-video --help"? Thanks!
The PDF is derived, in that macro, from the Postscript output which man
can generate if we choose its -t
option.
You would only be able to pull off a similar trick with other shell commands which can generate a formatted version in Postscript – you won't be able to do it with plain text output streams.
(I had to correct this a couple of times, kindly look at the final version, please.)
Thanks!
Enscript (installed using HomeBrew) is a possibility, if "enscript.cfg" is modified so that the line
DefaultOutputMethod: printer
is changed to
DefaultOutputMethod: stdout
In that case, a pipe such as
enscript --filter="transcode-video --help" | pstopdf -l -o ~/desktop/onefile.pdf
is successful.
However, substituting
enscript --filter=$CMD | pstopdf -l -o $MANPDF
for
man -t $CMD | pstopdf -l -o $MANPDF
in the macro didn't work, apparently because "transcode-video --help" when entered into the dialog, is interpreted as two separate commands.
So that's one issue to be solved (my proficiency is mainly limited to AppleScript), and the second is to fork between the two command versions based on a conditional (should be easy to trap an error when either executable doesn't receive correct input).
I still used to get better results with "open -f -a /Applications/Preview.app" (before prepending the app path with "/System" was required).
"| open -f -a /Applications/Safari.app" is still beneficial to some extent, however.