Skip to content

Instantly share code, notes, and snippets.

@tychoish
Created October 13, 2014 23:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tychoish/e2cbc994ce922f4fa6d4 to your computer and use it in GitHub Desktop.
Save tychoish/e2cbc994ce922f4fa6d4 to your computer and use it in GitHub Desktop.

Ikiwiki Tasklist

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment