 |
Korn shell script function to generate a calendar for a month and/or
year. This script is an emulation of the Unix "cal" command.
################################################################
function usagemsg_cal_k93 {
print "
Program: cal_k93
Generate a monthly or yearly calendar
Usage: ${1##*/} [-?vV] [[month] year]
Where:
-v = Verbose mode - displays cal_k93 function info
-V = Very Verbose Mode - debug output displayed
Author: Dana French (dfrench@mtxia.com)
Copyright 2006, All Rights Reserved
\"AutoContent\" enabled
"
}
################################################################
####
#### Description:
####
#### Function to generate a monthly or yearly calendar.
#### Emulation of the Unix "cal" command.
####
#### Assumptions:
####
#### If specified, the year number is assumed to be greater
#### than 0. If specified, the month number is assumed to be
#### between 1 and 12, 1=Jan 2=Feb 3=Mar...
####
#### Dependencies:
####
#### This function is dependent upon several other K93_Unix
#### functions to provide needed information, therefore these
#### functions must exist in a directory referenceced by the
#### FPATH variable.
####
#### Unfortunately, Korn shell does not provide a mechanism
#### to determine the current month and year. So if no
#### command line arguments are provided to this function,
#### specifying the year and or month, the external Unix
#### command "date" is used to generate the current month and
#### year number. If needed, the directory containing the
#### "date" command is assumed to be in the PATH.
####
#### Products:
####
#### This function can generate a monthly or yearly calendar
#### for any year greater than year number 0.
####
#### Configured Usage:
####
#### This function can be called from the command line or
#### from within other functions, and it can be called with
#### or without command line arguments. If specified, the
#### command line arguments identify the year and month for
#### which to display a calendar. See the usage message for
#### syntax.
####
#### Details:
####
################################################################
function cal_k93 {
typeset VERSION="1.0"
typeset TRUE="1"
typeset FALSE="0"
typeset VERBOSE="${FALSE}"
typeset VERYVERB="${FALSE}"
typeset FULLYEAR="${FALSE}"
typeset YEAR=$( date +"%Y" )
typeset MONTH=$( date +"%m" )
typeset SPACE=" "
typeset WID="21"
DOW2=( Su Mo Tu We Th Fr Sa )
DOW3=( Sun Mon Tue Wed Thu Fri Sat )
DOWFULL=( Sunday Monday Tuesday Wednesday Thursday Friday Saturday )
MNAME=( NUL January February March April May June July August September October November December )
DIM=( 0 31 28 31 30 31 30 31 31 30 31 30 31 )
####
#### Process the command line options and arguments, saving
#### the values as appropriate.
####
while getopts ":vV" OPTION
do
case "${OPTION}" in
'v') VERBOSE="${TRUE}";;
'V') VERYVERB="${TRUE}";;
[?:#]) usagemsg_cal_k93 "${0}" && return 1 ;;
esac
done
shift $(( ${OPTIND} - 1 ))
trap "usagemsg_cal_k93 ${0}" EXIT
#### VIOLATION of the underlying principle behind the purpose
#### of K93_Unix. Since Korn shell does not have a built-in
#### mechanism to determine the current month or the current
#### year, the external program "date" is used to determine
#### these values.
(( ${#} == 1 )) && typeset YEAR="${1}" FULLYEAR="${TRUE}"
(( ${#} == 2 )) && typeset YEAR="${2}" MONTH="${1}"
#### If more than two command line parameters remain, this is
#### an error. Display an error message and return from the
#### function with a non-zero (2) exit code.
if (( ${#} > 2 ))
then
print -u 2 -- "# Error: Invalid number of command line parameters"
return 2
fi
trap "-" EXIT
####
#### Display some program info and the command line arguments specified
#### if "VERBOSE" mode was specified.
####
(( VERYVERB == TRUE )) && set -x
(( VERBOSE == TRUE )) && print -u 2 -- "# Entering Function: ${0}"
(( VERBOSE == TRUE )) && print -u 2 -- "# Version..........: ${VERSION}"
(( VERBOSE == TRUE )) && print -u 2 -- "# Month Specified..: ${MONTH:-}"
(( VERBOSE == TRUE )) && print -u 2 -- "# Year Specified...: ${YEAR:-}"
################################################################
################################################################
#### If the year is a leap year, add 1 to the number of
#### days in the month of february.
if leapyear_k93 -y ${YEAR}
then
DIM[2]="29"
fi
#### If single month, set the beginning and ending values for the
#### loop to be the numeric value of that month.
(( FULLYEAR == FALSE )) && BEG=${MONTH} END=${MONTH}
#### If full year calendar is to be displayed, set the
#### beginning and ending values for the loop to be 1 and 12.
if (( FULLYEAR == TRUE ))
then
(( VERBOSE == TRUE )) && print -u 2 -- "# Generating calender for entire year of \"${YEAR}\""
BEG="1"
END="12"
fi
#### Generate a calendar for the the month or year specified,
#### using a loop.
for (( MON=${BEG}; MON<=${END}; ++MON ))
do
unset ROW1 ROW2 ROW3 ROW4 ROW5 ROW6
typeset -R2 ROW1 ROW2 ROW3 ROW4 ROW5 ROW6
#### Initialize each position of each row of the calendar,
#### since each row represents a week, each row will have 7
#### non-null elements although they may not begin at index
#### position 0. Initialize each array element for each
#### calendar row with two blank characters, since each
#### position may contain a double digit number.
for (( i=0; i<=6; ++i ))
do
ROW1[i]=" "
ROW2[i+7]=" "
ROW3[i+14]=" "
ROW4[i+21]=" "
ROW5[i+28]=" "
ROW6[i+35]=" "
done
#### Determine on which day of the week the first day of the
#### month occurs using the "dow_k93" function. If "VERBOSE"
#### mode was specified on the command line of this function
#### using a "-v" option, pass it along to the "dow_k93"
#### function.
DOWOPT="-y ${YEAR} -m ${MON} -d 1"
(( VERBOSE == TRUE )) && DOWOPT="${DOWOPT} -v"
FIRSTDAY="$( dow_k93 ${DOWOPT} )"
(( VERBOSE == TRUE )) && print -u 2 -- "# ${MNAME[MON]} 1, ${YEAR}...: ${DOWFULL[FIRSTDAY]}"
#### Assign day numbers to each day of the month, beginning
#### on the day of the week the month starts. Assign the
#### day numbers sequentially for each row of the calendar.
#### Some row positions may not have a number assigned.
#### Account for the Gregorian Reformation from Sep 2-14,
#### 1752, by skipping Sep 3-13.
for (( i=${FIRSTDAY}; i<=(${DIM[${MON}]}+${FIRSTDAY}-1); ++i ))
do
if (( YEAR == 1752 )) &&
(( MON == 9 )) &&
(( ( i - FIRSTDAY + 1 ) > 2 ))
then
(( i >= 0 && i <= 6 )) && ROW1[i]=$(( i - FIRSTDAY + 12 ))
(( i >= 7 && i <= 13 )) && ROW2[i]=$(( i - FIRSTDAY + 12 ))
(( i >= 14 && i <= 20 )) && ROW3[i]=$(( i - FIRSTDAY + 12 ))
else
(( i >= 0 && i <= 6 )) && ROW1[i]=$(( i - FIRSTDAY + 1 ))
(( i >= 7 && i <= 13 )) && ROW2[i]=$(( i - FIRSTDAY + 1 ))
(( i >= 14 && i <= 20 )) && ROW3[i]=$(( i - FIRSTDAY + 1 ))
(( i >= 21 && i <= 27 )) && ROW4[i]=$(( i - FIRSTDAY + 1 ))
(( i >= 28 && i <= 34 )) && ROW5[i]=$(( i - FIRSTDAY + 1 ))
(( i >= 35 && i <= 41 )) && ROW6[i]=$(( i - FIRSTDAY + 1 ))
fi
done
#### Determine the length of the string containing the full
#### month name followed by the 4 digit year. Then center
#### this string over a calendar by subtracting the length
#### from the width of a calendar and divide the result by 2.
#### This is the number of spaces that should be inserted
#### before the "month year" string and after the string as
#### well.
TLEN=$(( ${#MNAME[${MON}]} + ${#YEAR} + 1 ))
SPCS=$(( ( WID - TLEN ) / 2 ))
SUFFIX="${SPCS}"
IFS=$' \t\n'
#### Store all elements of each row of the calendar in an
#### array to be displayed after all calendars have been
#### generated (if a full year calendar is being generated)
(( VERBOSE == TRUE )) && print -u 2 -- "# Generating calendar for ${MNAME[MON]}, ${YEAR}"
CAL1[MON]="${SPACE:0:SPCS}${MNAME[${MON}]} ${YEAR}${SPACE:0:SUFFIX}"
CAL2[MON]="${DOW2[*]}"
CAL3[MON]="${ROW1[*]}"
CAL4[MON]="${ROW2[*]}"
CAL5[MON]="${ROW3[*]}"
CAL6[MON]="${ROW4[*]}"
CAL7[MON]="${ROW5[*]}"
CAL8[MON]="${ROW6[*]}"
done
#### If a full year calendar is to be displayed, display the
#### first three months of the year, then the second three
#### months, and so on. For the three months being displayed
#### at a time, display the first row of each calendar, one
#### after the other all on the same line, then the second
#### line, and so on. Continue for each calendar row, then
#### display the next three months, and so on until all
#### months for the year are displayed.
if (( FULLYEAR == TRUE ))
then
print
for (( i=1; i<=8; ++i ))
do
eval print -- "\"\${CAL${i}[1]} \${CAL${i}[2]} \${CAL${i}[3]}\""
done
for (( i=1; i<=8; ++i ))
do
eval print -- "\"\${CAL${i}[4]} \${CAL${i}[5]} \${CAL${i}[6]}\""
done
for (( i=1; i<=8; ++i ))
do
eval print -- "\"\${CAL${i}[7]} \${CAL${i}[8]} \${CAL${i}[9]}\""
done
for (( i=1; i<=8; ++i ))
do
eval print -- "\"\${CAL${i}[10]} \${CAL${i}[11]} \${CAL${i}[12]}\""
done
print
else
#### If a single month is to be displayed, display each
#### stored row of the calendar for the month, in sequential
#### order one row after the other.
for (( i=1; i<=8; ++i ))
do
eval print -- "\"\${CAL${i}[${MONTH}]}\""
done
fi
(( VERBOSE == TRUE )) && print -u 2 -- "# Exiting Function.: ${0}"
return 0
}
################################################################
|
 |