I love org-mode, don't get me wrong, but as I do more work
inside of ikiwiki, I think I'd like to have an org-agenda
like
functionality inside of an ikiwiki. I've cobbled together the
following script with that goal in mind.
This is probably the best script I've written so far: it has nifty
arguments and (some) error checking (see the help text for more), and
best of all it works like a dream. The only thing to configure is the
list of keywords in the three *_KEYWORDS=()
arrays (the difference
affects orders.) It's also possible to blacklist certain files using
the "-o
" option, or the "TASK_LIST_EXCLUSION
" environment
variable.
Enjoy, and as always, comments are welcome!
#!/bin/zsh
# ikiwiki-tasklist
# Copyright (c) 2011 Sam Kleinman
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the 'Software'), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
# ABOUT IKIWIKI-TASKLIST
#
# This script searches an [ikiwiki](http://ikiwiki.info) and creates
# an up to date index of TODO items in a wiki page, which can then be
# (optionally) commited and published to the wiki.
######################################################################
##
## Edit the following arrays to specify the keywords that
## `ikiwiki-tasklist` will search your wiki for. The remaining
## variables specify the metadata attached to the wiki page.
##
BASE_KEYWORDS=(TODO FIXME WRITE RESEARCH IRL EDIT ONGOING)
PROJECT_KEYWORDS=(DOCS PROJECT-NAME)
UNACTIONABLE_KEYWORDS=(PUBLISH FUTURE FROZEN)
TODO_PAGE_TITLE=""
EXT="mdwn"
EXCLUSION=($TASK_LIST_EXCLUSION build \#)
##
## You should not need to edit anything below this line unless you
## want to modify or expand the fuctionality of the script.
##
print-help(){
echo "USAGE: ikiwiki-tasklist [-c|-p|-o|-s] [WIKI_DIRECTORY] [OUTPUT_PAGE]"
echo " option: \"-c\" toggles an automatic git commit of the task list"
echo " option: \"-p\" toggles an automatic git pull/push of the task list"
echo " option: \"-o\" toggles an exclusion override, specify only one"
echo " option: \"-s\" toggles a silent mode"
echo " "
echo " The OUTPUT_PAGE is assumed to have the same extension as set in ikiwiki-tasklist,"
echo " unless an extension is specified. Furthermore, output will be placed in the"
echo " WIKI_DIRECTORY, unless OUTPUT_PAGE has a '/' character in the filename."
echo " "
echo " Set the $TASK_LIST_PAGE_TITLE environment variable to control the page tile of"
echo " the output page. Add values to the $TASK_LIST_EXCLUSION array environment "
echo " variable to blacklist them from the tasklist. [-o] does not affect the behavior"
echo " of the $TASK_LIST_EXCLUSION variable"
exit 0
}
init(){
KEYWORDS=($BASE_KEYWORDS $PROJECT_KEYWORDS $UNACTIONABLE_KEYWORDS)
# Initialize script, check for command line errors and set variables
COMMIT="`echo $@ | grep -c -e "\W*\-c\W\|\W\-c\W*"`"
PUBLISH="`echo $@ | grep -c -e "\W*\-p\W\|\W\-p\W*"`"
SILENT="`echo $@ | grep -c -e "\W*\-s\W\|\W\-s\W*"`"
EXCLUSION_ARG="`echo $@ | grep -c -e "\W*\-o\W\|\W\-o\W*"`"
ARG=`echo "$@" | sed -r 's/\s*\-[c|p|s|o]\s*//g'`
NOTARG="`echo $ARG | grep -c -e "\W*\-\w\W\|\W\-\w\W*"`"
NUMARG="`echo $ARG | wc -w`"
if [ "$NOTARG" = "1" ]; then
echo "ERROR: illegal argument"
print-help
elif [ "$NUMARG" = "1" ]; then
echo "ERROR: incomplete command"
print-help
elif [ "$NUMARG" -gt "3" ]; then
echo "ERROR: too many arguments"
print-help
else
WIKI_DIR="`echo $ARG | cut -d " " -f 1`"
if [ "`echo $ARG | cut -d " " -f 2 | grep -c /`" -ge 1 ]; then
TODO_PAGE="`echo $ARG | cut -d " " -f 2`"
elif [ "`echo $ARG | cut -d " " -f 2 | grep -c $EXT`" = 1 ]; then
TODO_PAGE="$WIKI_DIR/`echo $ARG | cut -d " " -f 2`"
else
TODO_PAGE="$WIKI_DIR/`echo $ARG | cut -d " " -f 2`.$EXT"
fi
fi
if [ ! -d "$WIKI_DIR" -o "$TODO_PAGE" = "" ]; then
echo "ERROR: directory and file unspecified"
print-help
fi
if [ "$EXCLUSION_ARG" -ge "1" ]; then
EXCLUSION=($TASK_LIST_EXCLUSION \#)
fi
excl=`echo $EXCLUSION | sed 's/ /\\\|/g'`
}
main() {
rm $TODO_PAGE
touch $TODO_PAGE
echo "# $PAGE_TITLE"
echo
cat >$TODO_PAGE<<EOF
\[[!meta title="$TODO_PAGE_TITLE"]]
EOF
cd $WIKI_DIR
for item in $KEYWORDS; do
ITEM=`grep -e "^$item.*$" * -R | grep -v -e "$excl" | sed -r "s/^(.*)\..{3,}:(.*)$/- \2: \[[\1]]/g"`
if [ "$ITEM" = "" ]; then
echo \>\> Skipping $item
echo
else
echo "## $item List"
echo $ITEM
echo
cat >>$TODO_PAGE<<EOF
## $item List
$ITEM
EOF
fi
done
if [ `grep -e "^.*\/\#.*\..*\#:.*$" $TODO_PAGE -c` -gt 0 ]; then
COMMIT=0
PUBLISH=0
/home/tychoish/garen/scripts/xmpp-notify "<`hostname -s`.tasklist> there are unsaved changes, save all open files before commiting and publishing changes"
fi
if [ "$COMMIT" = "1" ]; then
git add $TODO_PAGE
git commit -m "automated task list commit"
fi
if [ "$PUBLISH" = "1" ]; then
git pull
git push
fi
}
######################################################################
init $@;
if [ "$SILENT" = "1" ]; then
main >/dev/null 2>&1
else
main;
fi