.\" Copyright (c) 2002 Eivind Eklund
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\"    notice, this list of conditions and the following disclaimer
.\"    in this position and unchanged.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\"    notice, this list of conditions and the following disclaimer in the
.\"    documentation and/or other materials provided with the distribution.
.\" 3. The name of the author may not be used to endorse or promote products
.\"    derived from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\"	$FreeBSD$
.\"
.Dd February 28, 2002
.Dt GENERICVIEW.CONF 5
.Sh NAME
.Nm genericview.conf
.Nd configuration file for
.Xr genericview 1
.Sh SYNOPSIS
.Nm 
.Sh DESCRIPTION
.Xr genericview 1
is a smart selector for external helper applications.
It parses the configuration format described here, and use the data therein to
start other viewers for various file types.
The term "viewers" is somewhat loose;
.Xr genericview 1
is also capable of e.g. playing an audio file.
.Pp
The basic format of the file is
.Pp
<type>
.Op Aq type ... :
.Aq viewer
.Op Aq "viewer options"
.Op Aq viewer Op Aq "viewer options" ...
.Pp
This is parsed
.Em after
comments have been removed and line continuations have been resolved.
Comments are done from hash (#) to the end of line.
However, hashes inside 
.Aq viewer
and 
.Aq type
is excempted, so be certain to place whitespace between
.Aq viewer
and any comment.
Line continuations are done by placing a backslash at the end of a line.
This will result in the line being joined with the next non-comment line, and
the results being parsed as a single line.
.Pp
.Aq type
is a string naming a single type of file to be viewed (e.g, pdf) with
the specified viewers.
The string can only contain the characters A to Z in upper and lower case, the
numbers from 0 to 9, underscore (_), and period (.).
.Pp
The viewers specified the first time one specific
.Aq type
string is mentioned gets used.
Viewers mentioned at later occurances of that specific
.Aq type
string are ignored.
.Pp
.Aq viewer
is a string describing a single command that can display this type of file.
It is just the command name and any options.
To embed spaces, either enclose the the command in double quotes ("") or use
backslash to escape the whitespace.
The first word (after any introducing parentheses) of
.Aq viewer
is assumed to
be the command that actually does the display.
This viewer will be eligible for use if there exists an executable that match
that first word.
The first eligible viewer will be used unless
.Fl page
is specified on the command line of
.Xr genericview 1 .
If
.Fl page
is specified, the first eligible viewer that wants
.Xr genericview 1
to run a pager for it will be used.
If there is no eligible viewer that wants
.Xr genericview 1
to run a pager, a message saying that the information is available elsewhere
will be printed on standard out, and the first eligible viewer will be used.
.Pp
If no eligible viewer is available, a message informing about this and what
viewers has been looked for will be displayed.
.Pp
.Aq viewer options
are modifiers on the previous viewer.
These modify the behaviour
.Nm genericview
expects from the viewer, and allows
.Nm genericview
to provide services for the viewer.
The parameters available are
.Bl -tag -width notfiles
.It Fl page
The viewer will do output on stdout, and wants this output to be run in a
pager (something like
.Xr more 1
or
.Xr less 1 ).
.Nm genericview
will either use the pager of the program that called for the viewer, start the
pager indicated by the
.Ev X11PAGER
environment variable, or run an X terminal with a normal text mode pager in.
.It Fl xterm
Start the viewer in a separate X terminal.
The terminal will quit when the program exists.
.It Fl multi
Inform that the program accepts multiple filenames.
If
.Nm genericview
is called with multiple file arguments, it will only execute viewers that have
the
.Fl multi
flag.
.It Fl requires
By default,
.Nm genericview
will detect whether a viewer is usable or not by checking if the first word of
the viewer specification is available for execution in the user's
.Ev PATH .
If any
.Fl requires
flags are given for the viewer,
.Nm genericview
will instead check whether the parameters given for the
.Fl requires
flags are available.
There may be several
.Fl requires
flags, and all will be checked.
Each instance of
.Fl requires
only takes a single argument, and it has to be all word characters (no
whitespace or escaping is processed.)
.El
.Sh EXAMPLES
.Bd -literal
#
# The simplest example possible.
# The part on the left of the colon - "mod" - is the type of file to be
# viewed.  In this case, it is a mod audio file that will be replayed.
# The word to the left of the parameter is the viewer, xmp, a replay program.
# It just replays the mod, using the default audio device.
#
# If genericview finds xmp in the command path ($PATH), it will call xmp with
# the name of the mod file, as in this example:
#	genericview mod memory.mod
#		->
#	xmp memory.mod
# If genericview does not find xmp, it will exit with an error message telling
# this.
#
mod:		xmp

#
# A slightly more complex example.  Here, pdf files can be handled by a host
# of different programs.  They are listed here in order of preference; ie,
# acrobat will be taken if available, and gv will only be used if nothing else
# was available.
#
pdf:		acrobat acroread4 xpdf ghostview gv

#
# Some file types may all be handled by the same program - in the below case,
# all of jpg, gif, and generic image is displayed by xv.
#
jpg gif image:	xv

#
# As you can see, it is possible to pass parameters (beyond the filename) to a
# program by enclosing the entire expression in quotes.
#
mp3:		gqmpeg x11amp "mpg123 -b 2048"

#
# It is possible to do the same by escaping the spaces in an expression.
#
video:		xanim mpeg_play\\ -quiet\\ -dither\\ color

#
# In cases where the filename needs to be inside the command, it can be added
# by ${FILENAME}.  Also note that you can use redirections inside the
# expression; this is because it is interpreted by /bin/sh.
#
ulaw:		"cat ${FILENAME} > /dev/audio"

#
# Some helpers just dump ascii data, and would like to have something page it
# for them.  genericview takes care of that.  If -page is given as parameter
# for a viewer (as opposed to as a command line parameter to genericview),
# genericview will make sure that the output is displayed in a pager:
#	- If -canpage was given as a command line parameter to genericview, it
#	  will pass the output to the caller's internal pager by printing it
#	  on standard out.
#	- If -page was given as a commandline parameter to genericview, it
#	  will not only pass the output to the pager of the calling program,
#	  it will even prefer viewers that want to have paged output.
#	- If neither -canpage nor -page is passed on the command line, but
#	  the environment variable $X11PAGER is set, it will pass the output to
#	  the program $X11PAGER points at.
#	- If neither -canpage nor -page is passed on the command line, but the
#	  environment variable PAGER is set, it will start an xterm with the
#	  output of the viewer piped to the program $PAGER points at.
#	- If $PAGER is not set, it will start an xterm as above, but use less
#	  as PAGER.
#
tar_Z tar_gz:	"tar ztvf" -page

#
# First, notice the use of line continuation by \\ in the below example.
#
# Second, notice that we use escaped double quotes (\\") instead of single quotes
# in the expression below.  This is because $FILENAME is pre-escaped for the
# shell.  Anything that includes ${FILENAME} needs to be interpreted by the
# shell.  Single quotes (') inhibit this interpretation.  Another impact of
# this is that you do not need to quote a filename in order to handle spaces
# in it.
#
# Third, notice that we pass ${FILENAME} remotely (to an already running
# mozilla/netscape) which may have a different working directory than we do.
# This is OK because ${FILENAME} is always expanded to an absolute filename -
# ie, one starting with "/", like "/etc/passwd".
#
html:		"mozilla -remote \\"openURL(file://${FILENAME})\\"" \\
		"netscape -remote \\"openURL(file://${FILENAME})\\"" \\
		"lynx -dump" -page cat -page


#
# If you need to get just the filename, use a recursive shell escape to call
# basename, like this (notice that line continuations work inside the shell
# strings, and that comments are stripped before line continuations are
# evaluated):
#
compile_c:	"gcc -O -Wall -g -o \\
	# We need to call dirname from gcc in order to make sure that we get
	# genericview to check that gcc exists, rather than cd, as cd is a
	# shell built-in and which returns error for that.
	# Also notice that it is perfectly OK the ${FILENAME} several times.
	$(dirname ${FILENAME})/$(basename ${FILENAME} .c} ${FILENAME}" \\
	-page

#
# It is possible to just run the shell and terminal. This is useful e.g. for
# editors.
# -multi tells that the command accepts multiple files
#
edit:	emacs -multi xemacs -multi vim -xterm -multi ee -xterm -multi \\
	vi -xterm -multi

#
# A rather complex example utilizing the underlying shell.
# It does not introduce any new elements, though.
#
rpm:		"(rpm -q -is -p ${FILENAME} && \\
		echo -n 'Requires: ' && rpm -q -R -p ${FILENAME} && \\
		echo -n 'Provides: ' && rpm -q --provides -p ${FILENAME})" \\
		-page

#
# The xterm entry is special - it is used internally to determine which
# terminal for X to show.  The programs listed here accept the -T, -n, and -e
# arguments with the same meaning as xterm has.  (I am not sure all the below
# does...)
#
xterm:	xterm aterm eterm rxvt

#
# Term is the entry for outside callers that want to start a terminal.
# Here shown with the same programs as for the xterm entry.
#
term:	xterm aterm eterm rxvt

#
# A really complex example of what can be achieved with a little bit of
# creativity.  This small piece use ps2pdf or pdftops and xpdf to display
# postscript files when ghostview and gv are not available.
# Notice the use of -requires to show what executables this entry needs to
# work.  This inhibits the checking of the first word of the viewer itself.
# The parameters to -requires has to be continous non-whitespace characters,
# with no escapes possible.
# This is somewhat clumsy and does not catch kill signals to the
# shell for cleanup, and also creates the pdf file in the same spot as the
# postscript file, which may not be writeable.
#
# Notice:
# 1. The use of an intermediate assignment to PDFFILE.  This is because
#    ${FILENAME} cannot have modifiers (like %.ps, which strips .ps from the
#    end of the string), due to being expanded prior to the shell starting to
#    execute.
# 2. The use of double quotes around PDFFILE later in the expression.  This is
#    because PDFFILE is a true shell variable, and thus able to have problems
#    with spaces.
# 3. That the expression is divided in two branches, depending on whether the
#    pdf in question exists from before or not.  This is to avoid awkward
#    scenes where the .ps a user double clicks on is converted from a PDF.
#    If a pdf exists, it is assumed to be correct.
#
# BUGS:
#	This really should generate the pdf in a temporary directory, so it
#	would be possible to be SURE that we are showing something that match
#	the postscript file.
#
ps:	ghostview gv \\
	"(PDFFILE=${FILENAME}; PDFFILE="${PDFFILE%.ps}.pdf"; \\
		![ -e "$PDFFILE" ] && (ps2pdf ${FILENAME} && xpdf "$PDFFILE"; \\
			rm -f "$PDFFILE"; true) || xpdf "$PDFFILE")" \\
		-requires ps2pdf -requires xpdf


ps:		ghostview gv
sid:		sidplay
deb:		"dpkg-deb -c" -page
bz2:		bzcat -page
gz Z:		zcat -page
rfc howto:	cat -page
tar:		"tar tvf" -page
tar_bz2:	"tar --use-compress-prog=bunzip2 -tvf" -page
tar_Z tar_gz:	"tar ztvf" -page
zip:		"unzip -v" -page
man:		"nroff -mandoc" -page
.Ed
.Sh AUTHORS
.An "Eivind Eklund" Aq eivind@FreeBSD.org
.Sh SEE ALSO
.Xr genericview 1
