How to include a file when writing a custom man page?
Currently I just copy the source file for my custom man page into place like this:
SOURCE=man/myManPage.1
DEST_DIR=/usr/local/share/man/man.1
sudo install -g 0 -o 0 -m 0644 "$SOURCE" "$DEST_DIR/"
yes | sudo gzip "$DEST_DIR/myManPage.1"Works fine.
Now I want to be able to include a file containing a footer. Looks like using the .so macro in my man page source file might be one way forward:
.so footer.tmacThe .mso macro might be another option:
.mso footer.tmacThe problem with both of those approaches is that I am not actually running groff when moving the man page into place, I just copy the source into a .gz file and the include file is not around on the user machine so the footer does not display.
Perhaps I need to preprocess the man source somehow so a complete file is generated?
2 Answers
There is a soelim command provided with groff to do exactly this.
1soelim reads files and replaces lines of the form
.so fileby the contents of file.
Here is my solution, using soelim as suggested by @meuh:
#!/bin/bash
# Publishes man.1 files in ~/myman/
# Preprocesses .so statements by including the specified files
INCLUDED=included
function publish { SOURCE="~/myman/$INCLUDED/$1" if [[ ! -f "$SOURCE" ]]; then echo "Fatal: '$SOURCE' does not exist" exit 2 fi I="${1##*.}" DEST_DIR=/usr/local/share/man/man${I} sudo mkdir -p ${DEST_DIR} sudo rm -f "$DEST_DIR/$1.gz" sudo install -g 0 -o 0 -m 0644 "$SOURCE" "$DEST_DIR/" echo "Creating $DEST_DIR/$1.gz" yes | sudo gzip "$DEST_DIR/$1"
}
cd "~/myman"
mkdir -p ${INCLUDED}
for CMD in *.1; do soelim -I ./ $CMD > $INCLUDED/$CMD pushd ${INCLUDED} > /dev/null publish "${CMD}" popd > /dev/null
done
sudo mandbHere is a man source file with two .so include directives:
.TH man-course 1 "03 May 2019" "1.0" "cad-course man page"
.SH NAME
cad-course \- Cadenza Client command for authoring course content
.SH SYNOPSIS
cad course id aa | audioFromTitles | dw | fetch [-r] | gitNewRepo | publish | pp | status
.SH DESCRIPTION
\fBcad-course\fR is a Cadenza Client curriculum management command for authoring course-level content.
.so cad-description.tmac
.SH OPTIONS
The cad-course command takes sub-commands and options.
.SH EXAMPLES cad course 40 dw # Launch DreamWeaver on content for course #40 (Intro to Scala)
.PP cad course 40 dw # Launch DreamWeaver on content for course #40
.PP cad course 40 audioFromTitles # Build a new Adobe Audition audio project from course #40 transcript titles
.PP cad course 40 gitNewRepo # Wipe out any existing GitHub project for course #40 and make a new one,
check in current stuff. Use regular git commands as content is authored.
.PP cad course 40 fetch # (Re)download all of the content for course #40's courses from the active database and the active S3 buckets.
If uncommitted changes to course's git repo, ask user if the changes should
be committed before fetching. If no git repo, makes one.
.PP cad course -r 40 fetch # Also recurses by fetching sections & their lectures.
.so cad-footer.tmacHere is cad-description.tmac:
The complete list of curriculum management commands is: cad-site, cad-group, cad-course, cad-section and cad-lecture.Here is cad-footer.tmac:
.SH SEE ALSO cad-course(1),cad-group(1),cad-install(1),cad-lecture(1),cad-publish(1),cad-section(1),cad-site(1),cad-status(1),cad-status(1),bash(8)
.SH BUGS
No known bugs.
.SH AUTHOR
Michael Slinn ()This is the output from man cad:
man(1) cad man page man(1)
NAME cad - Cadenza Client command-line interface
SYNOPSIS cad install status # TODO What other options might apply?
DESCRIPTION cad is a command-line interface for cadenzaClient
OPTIONS The cad command takes sub-commands and options.
EXAMPLES cad -h
SEE ALSO cad-course(1),cad-group(1),cad-install(1),cad-lecture(1),cad-publish(1),cad-section(1),cad-site(1),cad-status(1),cad-status(1),bash(8)
BUGS No known bugs.
AUTHOR Michael Slinn ()
1.0 03 May 2019 man(1)