#!/bin/bash # Generate the top-level Info node, given a directory of Info files # and (optionally) a skeleton file. The output will be suitable for a # top-level dir file. The skeleton file contains info topic names in the # order they should appear in the output. There are three special # lines that alter the behavior: a line consisting of just "--" causes # the next line to be echoed verbatim to the output. A line # containing just "%%" causes all the remaining filenames (wildcards # allowed) in the rest of the file to be ignored. A line containing # just "!!" exits the script when reached (unless preceded by a line # containing just "--"). Once the script reaches the end of the # skeleton file, it goes through the remaining files in the directory # in order, putting their entries at the end. The script will use the # ENTRY information in each info file if it exists. Otherwise it will # make a minimal entry. # sent by Jeffrey Osier , who thinks it came from # zoo@winternet.com (david d `zoo' zuhn) # modified 7 April 1995 by Joe Harrington to # take special flags # $Id$ INFODIR="$1" if [[ $# = 2 ]] then SKELETON="$2" else SKELETON="/dev/null" fi skip= if [[ $# -gt 2 ]] then echo "usage: $0 info-directory [ skeleton-file ]" 1>&2 exit 1 elif [[ -z ${INFODIR} ]] then INFODIR="%%DEFAULT_INFO_DIR%%" else true fi if [[ ! -d ${INFODIR} ]] then echo "$0: first argument must specify a directory" exit 1 fi # sanity checks for cmd in sed awk zcat ls grep egrep wc expr fgrep sort tr cut do if [[ -z $(type -P ${cmd}) ]] then echo "Command ${cmd} not found, not running $0" exit 1 fi done if [[ -x $(type -P date) ]] then _DATE="$(date)" else _DATE="unknown date" fi if [[ -x $(type -P whoami) ]] then _WHOAMI="$(whoami)" else if [[ -n ${USER} ]] then _WHOAMI="${USER}" else _WHOAMI="unknown user" fi fi if [[ -x $(type -P hostname) ]] then _HOSTNAME="$(hostname)" else if [[ -n ${HOSTNAME} ]] then _HOSTNAME="${HOSTNAME}" else _HOSTNAME="unknown hostname" fi fi if [[ -x $(type -P pwd) ]] then _PWD="$(cd ${INFODIR}; pwd)" else if [[ -n ${PWD} ]] then _PWD="$(cd ${INFODIR}; echo $PWD)" else _PWD="unknown directory" fi fi ### output the dir header echo "-*- Text -*-" echo "This file was generated automatically by $0." echo "This version was generated on ${_DATE}" echo "by ${_WHOAMI}@${_HOSTNAME} for ${_PWD}" cat << moobler This is the file .../info/dir, which contains the topmost node of the Info hierarchy. The first time you invoke Info you start off looking at that node, which is (dir)Top. File: dir Node: Top This is the top of the INFO tree This (the Directory node) gives a menu of major topics. Typing "q" exits, "?" lists all Info commands, "d" returns here, "h" gives a primer for first-timers, "mEmacs" visits the Emacs topic, etc. In Emacs, you can click mouse button 2 on a menu item or cross reference to select it. * Menu: The list of major topics begins on the next line. moobler ### go through the list of files in the skeleton. If an info file ### exists, grab the ENTRY information from it. If an entry exists ### use it, otherwise create a minimal dir entry. ### ### Then remove that file from the list of existing files. If any ### additional files remain (ones that don't have a skeleton entry), ### then generate entries for those in the same way, putting the info for ### those at the end.... infofiles=$(cd ${INFODIR}; /bin/ls | grep -v '\-[0-9]*\.gz$' | grep -v '\-[0-9]*$' | egrep -v '^dir$|^dir\.info$|^dir\.orig$') # echoing gets clobbered by backquotes; we do it the hard way... lines=$(wc ${SKELETON} | awk '{print $1}') line=1 while [ ${lines} -ge ${line} ] do # Read one line from the file. This is so that we can echo lines with # whitespace and quoted characters in them. fileline=$(awk NR==${line} ${SKELETON}) # flag fancy features if [[ ! -z ${echoline} ]] then # echo line echo "${fileline}" fileline= echoline= elif [ "${fileline}" = "--" ] then # should we echo the next line? echoline=1 elif [ "${fileline}" = "%%" ] then # eliminate remaining files from dir? skip=1 elif [ "${fileline}" = "!!" ] then # quit now exit 0 fi # handle files if they exist for file in ${fileline}"" do # expand wildcards ("" handles blank lines) fname= if [[ -z ${echoline} ]] && [[ -n ${file} ]] then # Find the file to operate upon. Check both possible names. infoname=$(echo ${file} | sed 's/\.gz$//') infoname=$(echo ${infoname} | sed 's/\.info$//') noext= ext= if [ -f ${INFODIR}/${infoname} ] then noext="${infoname}" fi if [ -f ${INFODIR}/${infoname}.info ] then ext="${infoname}.info" fi if [ -f ${INFODIR}/${infoname}.info.gz ] then ext="${infoname}.info.gz" fi # If it exists with both names take what was said in the file. if [[ -n ${ext} ]] && [[ -n ${noext} ]] then fname="${file}" warn="### Warning: $ext and $noext both exist! Using ${file}. ###" elif [ ! \( -z "$ext" -a -z "$noext" \) ] then # just take the name if it exists only once fname=${noext}${ext} fi # if we found something and aren't skipping, do the entry if [[ -n ${fname} ]] then if [[ -z ${skip} ]] then if [ -n ${warn} ]] then # issue any warning echo "${warn}" warn= fi if [[ ${fname##*.} = gz ]] then entry=$(zcat ${INFODIR}/${fname} | sed -e '1,/START-INFO-DIR-ENTRY/d' -e '/END-INFO-DIR-ENTRY/,$d') else entry=$(sed -e '1,/START-INFO-DIR-ENTRY/d' -e '/END-INFO-DIR-ENTRY/,$d' ${INFODIR}/${fname}) fi if [[ -n ${entry} ]] then echo "${entry}" else echo "* ${infoname}: (${infoname})." fi fi # remove the name from the directory listing infofiles=$(echo "" ${infofiles} "" | sed -e "s/ ${fname} / /" -e "s/ / /g") fi fi done line=$(expr $line + 1) done if [[ -z ${infofiles} ]] then exit 0 elif [[ ${lines} -gt 0 ]] then echo fi # Sort remaining files by INFO-DIR-SECTION. prevsect= filesectdata=$(cd ${INFODIR}; fgrep INFO-DIR-SECTION /dev/null ${infofiles} | fgrep -v 'INFO-DIR-SECTION Miscellaneous' | sort -t: -k2 -k1 | tr ' ' '_') for sectdata in ${filesectdata} do file=$(echo ${sectdata} | cut -d: -f1) section=$(sed -n -e 's/^INFO-DIR-SECTION //p' ${INFODIR}/${file}) infofiles=$(echo "" ${infofiles} "" | sed -e "s/ ${file} / /" -e "s/ / /g") if [[ ${prevsect} != ${section} ]] then if [[ -n ${prevsect} ]] then echo "" fi echo "${section}" prevsect="${section}" fi infoname=$(echo ${file} | sed 's/\.gz$//') infoname=$(echo ${infoname} | sed 's/\.info$//') if [[ ${file##*.} = gz ]] then entry=$(zcat ${INFODIR}/${file} | sed -e '1,/START-INFO-DIR-ENTRY/d' -e '/END-INFO-DIR-ENTRY/,$d') else entry=$(sed -e '1,/START-INFO-DIR-ENTRY/d' -e '/END-INFO-DIR-ENTRY/,$d' ${INFODIR}/${file}) fi if [[ -n ${entry} ]] then echo "${entry}" elif [[ ! -d ${INFODIR}/${file} ]] then echo "* ${infoname}: (${infoname})." fi done # Process miscellaneous files. for file in ${infofiles} do if [[ -n ${prevsect} ]] then echo "" echo "Miscellaneous" prevsect="" fi infoname=$(echo ${file} | sed 's/\.gz$//') infoname=$(echo ${infoname} | sed 's/\.info$//') if [[ ${file##*.} = gz ]] then entry=$(zcat ${INFODIR}/${file} | sed -e '1,/START-INFO-DIR-ENTRY/d' -e '/END-INFO-DIR-ENTRY/,$d') else entry=$(sed -e '1,/START-INFO-DIR-ENTRY/d' -e '/END-INFO-DIR-ENTRY/,$d' ${INFODIR}/${file}) fi if [[ -n ${entry} ]] then echo "${entry}" elif [[ ! -d ${INFODIR}/${file} ]] then echo "* ${infoname}: (${infoname})." fi done