Skip to content

Instantly share code, notes, and snippets.

@jdbrice
Last active December 31, 2022 17:14
Show Gist options
  • Star 15 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save jdbrice/3b7395d7f1ff724a744a26ab9bfd078b to your computer and use it in GitHub Desktop.
Save jdbrice/3b7395d7f1ff724a744a26ab9bfd078b to your computer and use it in GitHub Desktop.
Generate markdown table calendar. Use wiki links to individual days
# Author: Daniel Brandenburg
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
#
# Original: https://gist.github.com/jdbrice/3b7395d7f1ff724a744a26ab9bfd078b
######################################################################
# OPTIONS
#relative or full path to output file
outputFile="calendar.md"
# Date range to generate
startDate=2020-07-01
endDate=2020-07-31
# use `date` on linus, for OSX set this to `gdate` you may need to install it (brew install coreutils)
date_cmd="gdate"
# controls the link format for each day:
# [[ $linkFormat | $displayFormat ]]
# Note: you can include `XX` immediately after the day number to get the ordinal suffix
linkFormat="%Y-%b-%dXX-%a"
displayFormat="%e"
# marker for empty days in calendar view
emptydays="--"
monthHeadingLvl="# " # the heading used for the months
monthHeadingFormat="%B, %Y"
# table headers
hWeek="Week"
hMon="Mon"
hTue="Tue"
hWed="Wed"
hThu="Thu"
hFri="Fri"
hSat="Sat"
hSun="Sun"
#####################################
# should we check for file existance?
# if false the following options wont work
# checking all the files is a little slow,
# so you can turn it off if you want
checkFileExists=true
#no trailing slash please
dailyNotePath="<path_to_obsidian_vault_daily_notes>"
# Should non-existing notes get linked?
linkNonExisting=true
#highlight the link for (non)existing
# link is wrapped with this e.g. ** [[ link | display ]] **
hle="**" #exsting or used for all if checkFileExists=false
hlne="" # not existing
hlt="==" #highlight for today's date (in addition to others)
# END OPTIONS
######################################################################
# Count the number of daily notes that you have
# TODO:
# - breakdown by day / week / month
# - consider metrics on files themselves (word count etc.)
countExistingNotes=0
countNonExistingNotes=0
# initialize the output file
echo "" > "$outputFile"
curr="$startDate"
DaySuffix() {
case `$date_cmd +%-d --date "$curr"` in
1|21|31) echo "st";;
2|22) echo "nd";;
3|23) echo "rd";;
*) echo "th";;
esac
}
function print_day_wiki_link {
if [ "$checkFileExists" != true ]; then
printf "| $hle[[ %s \| %s ]]$hle " "`$date_cmd +$linkFormat --date "$curr"`" "`$date_cmd +$displayFormat --date "$curr"`" >> "$outputFile"
return
fi
day_suffix=$(DaySuffix)
# replace the string 'XX' with the day suffix if it is found within the linkFormat string
linkTemplate=${linkFormat/XX/$day_suffix}
# Main link output
testFile="$dailyNotePath/`$date_cmd +$linkTemplate --date "$curr"`.md"
hil="" #no highlight by default
if [ `$date_cmd +%Y-%m-%d --date "$curr"` == `$date_cmd +%Y-%m-%d` ]; then
hil="$hlt"
fi
if [ -e "$testFile" ]; then # Daily note file exists
printf "| $hil$hle[[ %s \| %s ]]$hle$hil " "`$date_cmd +$linkTemplate --date "$curr"`" "`$date_cmd +$displayFormat --date "$curr"`" >> "$outputFile"
countExistingNotes=$((countExistingNotes+1))
elif [ "$linkNonExisting" == true ]; then # Daily note file does not exists, but still make a link
printf "| $hil$hlne[[ %s \| %s ]]$hlne$hil " "`$date_cmd +$linkTemplate --date "$curr"`" "`$date_cmd +$displayFormat --date "$curr"`" >> "$outputFile"
countNonExistingNotes=$((countNonExistingNotes+1))
elif [ "$linkNonExisting" == false ]; then # Daily note DNE and also do not link
printf "| $hil$hlne%s$hlne$hil " "`$date_cmd +$displayFormat --date "$curr"`" >> "$outputFile"
countNonExistingNotes=$((countNonExistingNotes+1))
fi
}
while true; do
# echo "$curr"
[ "$curr" \< "$endDate" ] || break
# Print the table header on the first day of the month
if [ `$date_cmd +%d --date "$curr"` == "01" ]; then
# pad the end of the last month
if [ `$date_cmd +%a --date "$curr -1 day"` != "Sun" ] && [ $curr != $startDate ]; then
# day in the week
ndays=`$date_cmd +%u --date "$curr"`
# loop from last day to the end of the week
for i in $(seq $ndays 7); do
printf "|$emptydays" >> "$outputFile"
done
# close the last column
printf "|" >> "$outputFile"
fi
# start a new month
printf " \n" >> "$outputFile"
printf " \n" >> "$outputFile"
printf "$monthHeadingLvl %s\n" "`$date_cmd +"$monthHeadingFormat" --date "$curr"`" >> "$outputFile"
printf "| $hWeek | $hMon | $hTue | $hWed | $hThu| $hFri | $hSat | $hSun |\n" >> "$outputFile"
printf "|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|\n" >> "$outputFile"
# If the months first week doesnt start on Monday, pad it
# and print the week number
if [ `$date_cmd +%a --date "$curr"` != "Mon" ]; then
# print the week number
printf "|%s" "`$date_cmd +%W --date "$curr"`" >> "$outputFile"
# day in the week
ndays=`$date_cmd +%u --date "$curr"`
# minus one for padding
ndays=`echo "$ndays-1" | bc`
# loop from Monday to the first day of the month
for i in $(seq 1 $ndays); do
printf "|$emptydays" >> "$outputFile"
done
fi
fi
# start the week row with the week number
if [ `$date_cmd +%a --date "$curr"` == "Mon" ]; then
printf "|%s" "`$date_cmd +%W --date "$curr"`" >> "$outputFile"
fi
# Main link output - no arguments, only uses global vars
print_day_wiki_link
# End the row on Sunday
if [ `$date_cmd +%a --date "$curr"` == "Sun" ]; then
printf "|\n" >> "$outputFile"
fi
# increment the date by one day
curr=$( $date_cmd +%Y-%m-%d --date "$curr +1 day" )
done
# print the last day and finish the month off
print_day_wiki_link
# pad the end of the last month
if [ `$date_cmd +%a --date "$curr"` != "Sun" ] ; then
# day in the week
ndays=`$date_cmd +%u --date "$curr"`
# loop from last day to the end of the week
for i in $(seq $ndays 7); do
printf "|$emptydays" >> "$outputFile"
done
# close the last column
printf "|" >> "$outputFile"
fi
echo "You have $countExistingNotes daily notes"
@argenos
Copy link

argenos commented Sep 11, 2020

I'm getting an error on this line:

./calendar.sh: 96: ./calendar.sh: function: not found
./calendar.sh: 105: ./calendar.sh: Bad substitution

I'm using Ubuntu 18.04

@kstephens
Copy link

Insert this as the first line: #!/usr/bin/env bash.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment