#! /bin/sh ## mdoc2man.sh -- script to convert mdoc-isms to man-isms ## ## Time-stamp: "2012-04-15 07:38:27 bkorb" ## ## This file is part of AutoOpts, a companion to AutoGen. ## AutoOpts is free software. ## AutoOpts is Copyright (c) 1992-2012 Bruce Korb - all rights reserved ## ## AutoOpts is available under any one of two licenses. The license ## in use must be one of these two and the choice is under the control ## of the user of the license. ## ## The GNU Lesser General Public License, version 3 or later ## See the files "COPYING.lgplv3" and "COPYING.gplv3" ## ## The Modified Berkeley Software Distribution License ## See the file "COPYING.mbsd" ## ## These files have the following md5sums: ## ## 43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3 ## 06a1a2e4760c90ea5e1dad8dfaac4d39 COPYING.lgplv3 ## 66a5cedaf62c4b2637025f049f9b826f COPYING.mbsd ## This "library" converts mdoc-isms into man-isms. It gets included ## by the man page template at the point where mdoc-isms might start appearing ## and then "emit-man-text" is invoked when all the text has been assembled. ## ## Display the command line prototype, ## based only on the argument processing type. ## ## And run the entire output through "sed" to convert mdoc-isms # /bin/sh on Solaris is too horrible for words # case "$0" in /bin/sh ) test -x /usr/xpg4/bin/sh && exec /usr/xpg4/bin/sh ${1+"$@"} ;; esac parent_pid=$$ prog=`basename $0 .sh` NmName= die() { echo "$prog error: $*" >&2 ps -p ${AG_pid:-999999999} >/dev/null 2>&1 && \ kill -TERM ${AG_pid} kill -TERM $parent_pid sleep 1 kill -9 $parent_pid sleep 1 exit 1 } had_no_arg() { die "'$1' command had no argument: <$line>" } # One function for each mdoc structure. # do_nest_enum() { do_enum } do_enum() { echo '.in +4' local ix=1 while IFS='' read -r line do case "${line}" in .It* ) printf '.ti -4\n%d\n\t' $ix ix=`expr $ix + 1` ;; .Bl' '*enum* ) do_nest_enum ;; .Bl' '*tag* ) do_nest_tag ;; .Bl' '*bullet* ) do_nest_bullet ;; .Bd' '* ) do_nest_block ;; .Op' '* ) do_nest_optional ;; .Fl' '* ) do_nest_flag ;; .Ar' '* ) do_nest_arg ;; .El* ) echo '.in -4' return 0 ;; * ) echo "$line" ;; esac done die "EOF reached processing '.Bl -enum'" } do_nest_tag() { echo '.in +4' while IFS='' read -r line do case "${line}" in .It* ) printf '.ti -4\n.IR ' echo ${line#.It} ;; .Bl' '*enum* ) do_nest_enum ;; .Bl' '*tag* ) do_nest_tag ;; .Bl' '*bullet* ) do_nest_bullet ;; .Bd' '* ) do_nest_block ;; .Op' '* ) do_nest_optional ;; .Fl' '* ) do_nest_flag ;; .Ar' '* ) do_nest_arg ;; .El* ) echo '.in -4' return 0 ;; * ) echo "$line" ;; esac done die "EOF reached processing '.Bl -tag'" } do_tag() { while IFS='' read -r line do case "${line}" in .It* ) printf '.TP\n.BR ' echo ${line#.It} ;; .Bl' '*enum* ) do_nest_enum ;; .Bl' '*tag* ) do_nest_tag ;; .Bl' '*bullet* ) do_nest_bullet ;; .Bd' '* ) do_nest_block ;; .Op' '* ) do_nest_optional ;; .Fl' '* ) do_nest_flag ;; .Ar' '* ) do_nest_arg ;; .El* ) return 0 ;; * ) echo "$line" ;; esac done die "EOF reached processing '.Bl -tag'" } do_nest_bullet() { do_bullet } do_bullet() { echo '.in +4' while IFS='' read -r line do case "${line}" in .It* ) printf '.ti -4\n\\fB*\\fP\n' echo ${line#.It} ;; .Bl' '*enum* ) do_nest_enum ;; .Bl' '*tag* ) do_nest_tag ;; .Bl' '*bullet* ) do_nest_bullet ;; .Bd' '* ) do_nest_block ;; .Op' '* ) do_nest_optional ;; .Fl' '* ) do_nest_flag ;; .Ar' '* ) do_nest_arg ;; .El* ) echo '.in -4' return 0 ;; * ) echo "$line" ;; esac done die "EOF reached processing '.Bl -bullet'" } do_nest_block() { do_block } do_block() { printf '.br\n.in +4\n.nf\n' while IFS='' read -r line do case "${line}" in .B* ) die ".Bx command nested within .Bd" ;; .Ed* ) echo .in -4 echo .fi return 0 ;; * ) echo "$line" ;; esac done die "EOF reached processing '.Bd'" } do_nest_optional() { do_optional } do_optional() { set -- $line shift local text='[' while test $# -gt 0 do m1="$1" case "X$1" in 'X...' | 'X\*' ) text=${text}' "\fI'${1}'\fR"' shift ;; XAr | XCm ) text=${text}' "\fI'${2}'\fR"' shift 2 || had_no_arg "$m1" ;; XFl ) text=${text}' \fB-'${2}'\fR' shift 2 || had_no_arg "$m1" ;; * ) text="${text} \"$2\"" m1="$1" shift 2 || had_no_arg "$m1" ;; esac done echo "${text} ]" } do_nest_flag() { do_flag } do_flag() { echo ${line#.Fl} } do_nest_arg() { do_arg } do_arg() { line=`echo ${line#.Ar}` echo "\\fI${line}\\fR" } do_NmName() { # do we want to downcase the line first? Yes... set -- `echo ${line#.Nm} | \ sed -e 's/-/\\-/g' \ -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` NmNameSfx= if test $# -gt 0 then case "$1" in [A-Za-z]* ) NmName=$1 shift ;; esac test $# -gt 0 && NmNameSfx=" $*" fi echo ".B $NmName$NmNameSfx" } do_line() { case "${line}" in .Bl' '*enum* ) do_enum ;; .Bl' '*tag* ) do_tag ;; .Bl' '*bullet* ) do_bullet ;; .Bd' '* ) do_block ;; .Op' '* ) do_optional ;; .Fl' '* ) do_flag ;; .Ar' '* ) do_arg ;; .Nm' '* ) do_NmName ;; .Nm ) do_NmName ;; * ) echo "$line" ;; esac return 0 } easy_fixes=' s/^\.Sh/.SH/ s/^\.Ss/.SS/ s/^\.Em/.I/ s/^\.Pp/.PP/ s/^.in *\\-/.in -/ ' readonly easy_fixes set -f { while IFS='' read -r line do do_line done } | sed "${easy_fixes}" exit 0