From 4d1342782d64d5a0566ecea92ae50fa0aa95a92b Mon Sep 17 00:00:00 2001 From: Rushmore75 Date: Thu, 22 Jan 2026 16:59:07 -0700 Subject: [PATCH 1/2] testing --- end.mm | 11 +++++++++++ gen.sh | 49 +++++++++++++++++++++++++++++++++++++------------ hours.tbl | 14 ++++++++++++++ item.tbl | 15 +++++++++++++++ start.mm | 22 ++++++++++++++++++++++ 5 files changed, 99 insertions(+), 12 deletions(-) create mode 100644 end.mm create mode 100644 hours.tbl create mode 100644 item.tbl create mode 100644 start.mm diff --git a/end.mm b/end.mm new file mode 100644 index 0000000..be12111 --- /dev/null +++ b/end.mm @@ -0,0 +1,11 @@ +.1C 1 +.DS C +.PP +.B +Total: $${TOTAL} +.R +.DE +.PP +Hours were charged at $${RATE}/hr. If you have any questions please reach out at any of the provided contacts above. +Thank you for your business! + diff --git a/gen.sh b/gen.sh index dbb96e5..4b505c8 100755 --- a/gen.sh +++ b/gen.sh @@ -4,7 +4,7 @@ RATE=50 short_help() { - echo "$0 [output file]" + echo "$0 [output file]" echo "--help for help" } long_help() { @@ -30,12 +30,20 @@ else CSV=$1 fi -COMPANY="" +CSV2="" if [[ -z $2 ]]; then short_help exit else - COMPANY=$2 + CSV2=$2 +fi + +COMPANY="" +if [[ -z $3 ]]; then + short_help + exit +else + COMPANY=$3 fi # Increment a global invoice number @@ -50,21 +58,38 @@ echo $INV_NUM > $INV_FILE # 3rd argument is output location (optional) OUTPUT="invoice-${INV_NUM}.pdf" -if [[ ! -z $3 ]]; then - OUTPUT=$3 +if [[ ! -z $4 ]]; then + OUTPUT=$4 fi # Parse the CSV into: Label;Hrs;Cost -TMP=$(mktemp) -cat $CSV | RATE=$RATE awk -F, '{ sum += $2 }; { print $1 ";" $2 ";" $2 * ENVIRON["RATE"] } END { print "Total" ";" sum ";" sum * ENVIRON["RATE"]}' > $TMP +HRS_TMP=$(mktemp) +cat $CSV | RATE=$RATE awk -F, '{ sum += $2 }; { print $1 ";" $2 ";" $2 * ENVIRON["RATE"] } END { print "Sub-Total" ";" sum ";" sum * ENVIRON["RATE"]}' > $HRS_TMP + +CONSUME_TMP=$(mktemp) +cat $CSV2 | awk -F, '{ sum += $2 }; { print $1 ";" $2 } END { print "Sub-Total" ";" sum }' > $CONSUME_TMP + +HRS_COST=$(cat $HRS_TMP | tail -n 1 | awk -F";" '{ print $3 }') +CONSUME_COST=$(cat $CONSUME_TMP | tail -n 1 | awk -F";" '{ print $2 }') + +TOTAL_COST=$(A=$HRS_COST B=$CONSUME_COST awk 'BEGIN{ print ENVIRON["A"] + ENVIRON["B"] }') # TOTAL = Last line # BODY = Everything but the last line -TOTAL=$(cat $TMP | tail -n 1) \ - BODY=$(cat $TMP | head -n -1) \ - COMPANY=$COMPANY \ +COMPANY=$COMPANY \ INVOICE_NUM=$INV_NUM \ + envsubst < start.mm > 1.tmp +HRS_TOTAL=$(cat $HRS_TMP | tail -n 1) \ + HRS_BODY=$(cat $HRS_TMP | head -n -1) \ + envsubst < hours.tbl > 2.tmp +ITEM_TOTAL=$(cat $CONSUME_TMP | tail -n 1) \ + ITEM_BODY=$(cat $CONSUME_TMP | head -n -1) \ + envsubst < item.tbl > 3.tmp +TOTAL=$TOTAL_COST \ RATE=$RATE \ - envsubst < template.mm | groff -t -mm -T pdf > $OUTPUT + envsubst < end.mm > 4.tmp -rm $TMP +cat 1.tmp 2.tmp 3.tmp 4.tmp | groff -t -mm -T pdf > $OUTPUT + +rm $HRS_TMP +rm $CONSUME_TMP diff --git a/hours.tbl b/hours.tbl new file mode 100644 index 0000000..c389e88 --- /dev/null +++ b/hours.tbl @@ -0,0 +1,14 @@ +.TS +nospaces center tab(;); +CbSS +CiCi|Ci +RN|N. +Work Performed +Job;Hours;Cost +_ +${HRS_BODY} +_ +.T& +RiNi|Ni. +${HRS_TOTAL} +.TE diff --git a/item.tbl b/item.tbl new file mode 100644 index 0000000..1359c5a --- /dev/null +++ b/item.tbl @@ -0,0 +1,15 @@ +.NCOL +.TS +nospaces center tab(;); +CbS +Ci|Ci +R|N. +Other +Item;Cost +_ +${ITEM_BODY} +_ +.T& +Ri|Ni. +${ITEM_TOTAL} +.TE diff --git a/start.mm b/start.mm new file mode 100644 index 0000000..f94a073 --- /dev/null +++ b/start.mm @@ -0,0 +1,22 @@ +\# Make headers bold +.ds HF 3 3 +\# Make lvl 1 headers 20pt, lvl 2 18pt +.ds HP 20 18 +.S 12 +\# Disable page header +.PH '''' +\# Centered block +.DS C +.HU "${COMPANY}'s Bill" +.DE +\# Contact info +.TS +nospaces center tab(;); +LR. +Cooies Unlimited;(123) 456-7890 +123 Sesame St.;cookie@example.com +Dumpster 1;\*[DT] +Nicevile FL;Invoice ID #${INVOICE_NUM} +.TE + +.2C From 23d8ce39105d949958ca0430060fcad6c8e22115 Mon Sep 17 00:00:00 2001 From: Oliver Date: Thu, 22 Jan 2026 18:18:08 -0700 Subject: [PATCH 2/2] 1 and 2 column pdfs work --- template.mm => 1col.template.mm | 21 ++--- 2col.template.mm | 62 ++++++++++++++ end.mm | 11 --- gen.sh | 147 ++++++++++++++------------------ hours.tbl | 14 --- work.csv => hrs.csv | 0 item.tbl | 15 ---- items.csv | 4 + start.mm | 22 ----- 9 files changed, 141 insertions(+), 155 deletions(-) rename template.mm => 1col.template.mm (69%) create mode 100644 2col.template.mm delete mode 100644 end.mm delete mode 100644 hours.tbl rename work.csv => hrs.csv (100%) delete mode 100644 item.tbl create mode 100644 items.csv delete mode 100644 start.mm diff --git a/template.mm b/1col.template.mm similarity index 69% rename from template.mm rename to 1col.template.mm index fd6e752..2da5b28 100644 --- a/template.mm +++ b/1col.template.mm @@ -7,34 +7,35 @@ .PH '''' \# Centered block .DS C -.HU "Your Bill" +.HU "${COMPANY}'s Bill" .DE \# Contact info .TS nospaces center tab(;); LR. -Cooies Unlimited;(123) 456-7890 -123 Sesame St.;cookie@example.com -Dumpster 1;\*[DT] -Nicevile FL;Invoice ID #${INVOICE_NUM} +${COMPANY_NAME};$PHONE +${ADDR_LN_1};${EMAIL} +${ADDR_LN_2};\*[DT] +${ADDR_LN_3};Invoice ID #${INVOICE_NUM} .TE -\# Billing info .TS nospaces center tab(;); CbSS CiCi|Ci RN|N. -${COMPANY} +Work Performed Job;Hours;Cost _ -${BODY} +${HRS_BODY} _ .T& RbN|Nb. -${TOTAL} +Total;${HRS_TOTAL} .TE - +.DS C +.R +.DE .PP Hours were charged at $${RATE}/hr. If you have any questions please reach out at any of the provided contacts above. Thank you for your business! diff --git a/2col.template.mm b/2col.template.mm new file mode 100644 index 0000000..00e1be8 --- /dev/null +++ b/2col.template.mm @@ -0,0 +1,62 @@ +\# Make headers bold +.ds HF 3 3 +\# Make lvl 1 headers 20pt, lvl 2 18pt +.ds HP 20 18 +.S 12 +\# Disable page header +.PH '''' +\# Centered block +.DS C +.HU "${COMPANY}'s Bill" +.DE +\# Contact info +.TS +nospaces center tab(;); +LR. +${COMPANY_NAME};$PHONE +${ADDR_LN_1};${EMAIL} +${ADDR_LN_2};\*[DT] +${ADDR_LN_3};Invoice ID #${INVOICE_NUM} +.TE + +.2C +.TS +nospaces center tab(;); +CbSS +CiCi|Ci +RN|N. +Work Performed +Job;Hours;Cost +_ +${HRS_BODY} +_ +.T& +RiNi|Ni. +Sub-Total;${HRS_TOTAL} +.TE +.NCOL +.TS +nospaces center tab(;); +CbS +Ci|Ci +R|N. +Other +Item;Cost +_ +${ITEM_BODY} +_ +.T& +Ri|Ni. +Sub-Total;${ITEM_TOTAL} +.TE +.1C 1 +.DS C +.PP +.B +Total: $${TOTAL} +.R +.DE +.PP +Hours were charged at $${RATE}/hr. If you have any questions please reach out at any of the provided contacts above. +Thank you for your business! + diff --git a/end.mm b/end.mm deleted file mode 100644 index be12111..0000000 --- a/end.mm +++ /dev/null @@ -1,11 +0,0 @@ -.1C 1 -.DS C -.PP -.B -Total: $${TOTAL} -.R -.DE -.PP -Hours were charged at $${RATE}/hr. If you have any questions please reach out at any of the provided contacts above. -Thank you for your business! - diff --git a/gen.sh b/gen.sh index 4b505c8..dfcd918 100755 --- a/gen.sh +++ b/gen.sh @@ -1,95 +1,76 @@ #!/bin/bash - # What you charge an hour -RATE=50 +export RATE=50 +export COMPANY_NAME="Cookies Unlimited, LLC" +export ADDR_LN_1="123 Sesasme St" +export ADDR_LN_2="Dumpster 1" +export ADDR_LN_3="12345, Nicevile, FL" +export PHONE="(123) 456-7890" +export EMAIL="cookie@exapmle.com" -short_help() { - echo "$0 [output file]" - echo "--help for help" -} -long_help() { - short_help +print_help() { + echo "$0 -1 [output file]" + echo "$0 -2 [output file]" echo "" - echo "The csv file should be setup as:" - echo "" - echo "Job , Hours " - echo "" - echo "With no empty line at the end." + echo "CSV files should be ,." + echo "CSV files should have no empty line at the end." echo "Paying company name is any string" echo "The output argument is optional and will by default output to invoice-.pdf" } +get_invoice_num() { + # Increment a global invoice number + INV_FILE="last_invoice_number" + INV_NUM=0 + if [[ -f $INV_FILE ]]; then + INV_NUM=$(expr $(cat $INV_FILE) + 1) + else + INV_NUM=1 + fi + echo $INV_NUM > $INV_FILE + echo $INV_NUM +} +read_hrs_csv() { + TMP=$(mktemp) + # Parse the CSV into: Label;Hrs;Cost + cat $1 | RATE=$RATE awk -F, '{ sum += $2 }; { print $1 ";" $2 ";" $2 * ENVIRON["RATE"] } END { print sum ";" sum * ENVIRON["RATE"] }' > $TMP + echo $TMP +} +read_items_csv() { + TMP=$(mktemp) + cat $1 | awk -F, '{ sum += $2 }; { print $1 ";" $2 } END { print sum }' > $TMP + echo $TMP +} -CSV="" if [[ -z $1 ]]; then - short_help - exit -elif [[ $1 = "--help" ]]; then - long_help + print_help exit +fi + +export INVOICE_NUM=$(get_invoice_num) +OUTPUT="invoice-${INVOICE_NUM}.pdf" + +HRS_TMP=$(read_hrs_csv $2) +export HRS_TOTAL=$(cat $HRS_TMP | tail -n 1) +export HRS_BODY=$(cat $HRS_TMP | head -n -1) + +if [[ $1 = "-1" ]]; then + if [[ ! -z $4 ]]; then + OUTPUT=$4 + fi + export COMPANY=$3 + envsubst < 1col.template.mm | groff -t -mm -T pdf > $OUTPUT +elif [[ $1 = "-2" ]]; then + if [[ ! -z $5 ]]; then + OUTPUT=$5 + fi + HRS_COST=$(cat $HRS_TMP | tail -n 1 | awk -F";" '{ print $2 }') + CONSUME_TMP=$(read_items_csv $3) + CONSUME_COST=$(cat $CONSUME_TMP | tail -n 1 | awk -F";" '{ print $2 }') + export ITEM_TOTAL=$(cat $CONSUME_TMP | tail -n 1) + export ITEM_BODY=$(cat $CONSUME_TMP | head -n -1) + export TOTAL=$(A=$HRS_COST B=$ITEM_TOTAL awk 'BEGIN{ print ENVIRON["A"] + ENVIRON["B"] }') + export COMPANY=$4 + envsubst < 2col.template.mm | groff -t -mm -T pdf > $OUTPUT else - CSV=$1 + echo First arg should be either -1 or -2 fi - -CSV2="" -if [[ -z $2 ]]; then - short_help - exit -else - CSV2=$2 -fi - -COMPANY="" -if [[ -z $3 ]]; then - short_help - exit -else - COMPANY=$3 -fi - -# Increment a global invoice number -INV_FILE="last_invoice_number" -INV_NUM=0 -if [[ -f $INV_FILE ]]; then - INV_NUM=$(expr $(cat $INV_FILE) + 1) -else - INV_NUM=1 -fi -echo $INV_NUM > $INV_FILE - -# 3rd argument is output location (optional) -OUTPUT="invoice-${INV_NUM}.pdf" -if [[ ! -z $4 ]]; then - OUTPUT=$4 -fi - -# Parse the CSV into: Label;Hrs;Cost -HRS_TMP=$(mktemp) -cat $CSV | RATE=$RATE awk -F, '{ sum += $2 }; { print $1 ";" $2 ";" $2 * ENVIRON["RATE"] } END { print "Sub-Total" ";" sum ";" sum * ENVIRON["RATE"]}' > $HRS_TMP - -CONSUME_TMP=$(mktemp) -cat $CSV2 | awk -F, '{ sum += $2 }; { print $1 ";" $2 } END { print "Sub-Total" ";" sum }' > $CONSUME_TMP - -HRS_COST=$(cat $HRS_TMP | tail -n 1 | awk -F";" '{ print $3 }') -CONSUME_COST=$(cat $CONSUME_TMP | tail -n 1 | awk -F";" '{ print $2 }') - -TOTAL_COST=$(A=$HRS_COST B=$CONSUME_COST awk 'BEGIN{ print ENVIRON["A"] + ENVIRON["B"] }') - -# TOTAL = Last line -# BODY = Everything but the last line -COMPANY=$COMPANY \ - INVOICE_NUM=$INV_NUM \ - envsubst < start.mm > 1.tmp -HRS_TOTAL=$(cat $HRS_TMP | tail -n 1) \ - HRS_BODY=$(cat $HRS_TMP | head -n -1) \ - envsubst < hours.tbl > 2.tmp -ITEM_TOTAL=$(cat $CONSUME_TMP | tail -n 1) \ - ITEM_BODY=$(cat $CONSUME_TMP | head -n -1) \ - envsubst < item.tbl > 3.tmp -TOTAL=$TOTAL_COST \ - RATE=$RATE \ - envsubst < end.mm > 4.tmp - -cat 1.tmp 2.tmp 3.tmp 4.tmp | groff -t -mm -T pdf > $OUTPUT - -rm $HRS_TMP -rm $CONSUME_TMP diff --git a/hours.tbl b/hours.tbl deleted file mode 100644 index c389e88..0000000 --- a/hours.tbl +++ /dev/null @@ -1,14 +0,0 @@ -.TS -nospaces center tab(;); -CbSS -CiCi|Ci -RN|N. -Work Performed -Job;Hours;Cost -_ -${HRS_BODY} -_ -.T& -RiNi|Ni. -${HRS_TOTAL} -.TE diff --git a/work.csv b/hrs.csv similarity index 100% rename from work.csv rename to hrs.csv diff --git a/item.tbl b/item.tbl deleted file mode 100644 index 1359c5a..0000000 --- a/item.tbl +++ /dev/null @@ -1,15 +0,0 @@ -.NCOL -.TS -nospaces center tab(;); -CbS -Ci|Ci -R|N. -Other -Item;Cost -_ -${ITEM_BODY} -_ -.T& -Ri|Ni. -${ITEM_TOTAL} -.TE diff --git a/items.csv b/items.csv new file mode 100644 index 0000000..f39d388 --- /dev/null +++ b/items.csv @@ -0,0 +1,4 @@ +Prep,2 +Cooking,1.25 +Event,10 +Cleanup,2.5 diff --git a/start.mm b/start.mm deleted file mode 100644 index f94a073..0000000 --- a/start.mm +++ /dev/null @@ -1,22 +0,0 @@ -\# Make headers bold -.ds HF 3 3 -\# Make lvl 1 headers 20pt, lvl 2 18pt -.ds HP 20 18 -.S 12 -\# Disable page header -.PH '''' -\# Centered block -.DS C -.HU "${COMPANY}'s Bill" -.DE -\# Contact info -.TS -nospaces center tab(;); -LR. -Cooies Unlimited;(123) 456-7890 -123 Sesame St.;cookie@example.com -Dumpster 1;\*[DT] -Nicevile FL;Invoice ID #${INVOICE_NUM} -.TE - -.2C