I have a scheduled.txt file like this:
# Scheduled tasks for todo.txt # Format: # # a dow, Mon,Tue,Wed,... # b moy, Jan,Feb,Mar,... # d dom, 01..31 # D m/d/y 12/30/12 # F Y-m-d 2012-12-30 # j doy 001..366 # V woy 01..53 # # %2 = Division by 2 is possible # %N2= Devision by 2 is not possible # # Empy lines are ignored #===Planned===# V=%2 a=Sun ~Clean bed sheets # Every odd day j=%N2 ~Check wait # Every 3 days j=%3 ~Get finance up to date # First of the month d=01 ~Urenlijsten
This file is parsed by this script:
#!/bin/bash
# 2 modes: debug || commit
if [[ "x$1" = "xdebug" ]]; then
COMMIT=false
say(){ echo $*; }
elif [[ "x$1" = "xcommit" ]]; then
COMMIT=true
say(){ return; }
else
echo 'debug or commit?'
exit 1
fi
SCHEDFILE=$HOME/todo/repeatedtasks.txt
TODOFILE=$HOME/todo/todo.txt
TEMPTODOFILE=`mktemp`
# We work in a temporary file. Copying back happens at the end.
[ $COMMIT = 'true' ] && cp $TODOFILE $TEMPTODOFILE
addtask(){
TASK=$*
say "ADDING $TASK"
# Add if commit is true:
if [ $COMMIT = 'true' ] ; then
# We don't add tasks multiple times. If it's already there, append !
if grep -q "^$TASK" $TEMPTODOFILE ; then
# There already, append !
sed -i "/$TASK/ s/$/\!/" $TEMPTODOFILE
else
# Not there already
echo $TASK >> $TEMPTODOFILE
fi
fi
}
# Process each line in todo.txt
egrep "^[a-zA-Z]+" $SCHEDFILE | while read SCHED ; do
say
say "==== Parsing $SCHED ===="
TASK=$(echo $SCHED | cut -d\~ -f2 )
# We can have multiple date parts. They must all be true before a task is added.
DATEPARTS=$(echo $SCHED | cut -d\~ -f1 | sed 's/ *$//g')
say "The dateparts are [$DATEPARTS]"
ADDME=no
for DATEPART in $DATEPARTS; do
# Parse this part
# The parts of the line
DATESTR=$(echo $DATEPART | cut -d= -f1 )
DATEVAL=$(echo $DATEPART | cut -d= -f2 )
say "Part $DATESTR = $DATEVAL"
# Find the current date value for DATESTR
DATESTR_FORMATTED=''
for str in $DATESTR; do DATESTR_FORMATTED+="$str"; done
CURDATEVAL=$(date +%$DATESTR_FORMATTED)
say ". STR [$DATESTR_FORMATTED] is now [$CURDATEVAL], we match on [$DATEVAL]. "
# Process rules
if [[ $( echo $DATEVAL | egrep -o "^%" ) = '%' ]]; then
# check for division (eg every .. weeks/days/..)
say ". Checking [$CURDATEVAL] for division"
# Actual checking
NUMBER=$(echo $DATEVAL | egrep -o "[0-9]+")
if [[ ! $(echo $DATEVAL | egrep -q "^%N" ) ]] ; then
if [[ $(( $CURDATEVAL % $NUMBER )) -eq 0 ]]; then ADDME=yes ; else ADDME=no; break; fi
else
if [[ ! $(( $CURDATEVAL % $NUMBER )) -eq 0 ]]; then ADDME=yes ; else ADDME=no; break; fi
fi
else
# Exact value
say ". Checking for exact"
if [[ x$CURDATEVAL = x$DATEVAL ]] ; then ADDME=yes ; else ADDME=no; break; fi
fi
say "Passed tests. Addme is still $ADDME"
done
say "Exiting loop dateparts. ADDME=$ADDME"
# All parts are parsed
if [[ "x$ADDME" = "xyes" ]] ; then
addtask $TASK
fi
done
[ $COMMIT = 'true' ] && sort $TEMPTODOFILE > $TODOFILE
[ $COMMIT = 'true' ] && rm $TEMPTODOFILE
Questions are welcome at the ‘mail’ account on this domain.