################################################################ 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 } ################################################################