This information is for TaskPaper 2 which is old and outdated. TaskPaper 3 is the current version of TaskPaper. For TaskPaper 3 support please visit the support forums.

Download from here -- likely this will be a newer version if I fix any bugs in the version below.

Install this script in your TaskPaper scripts directory (~/Library/Application Support/TaskPaper/Scripts) and assign it a shortcut in System Preferences.

When called for the first time, it will add a note to the selected task (or the first task under the selected project) of the form to clock in:

CLOCK: [yyyy-mm-dd DDD hh:mm]

Subsequently, whenever you call the script it will look for the first line of the format above, and if found append the current time to clock out with the line changed to look like this:

CLOCK: [yyyy-mm-dd DDD hh:mm]--[yyyy-mm-dd DDD hh:mm] => HH:MM

Where the last part of the line HH:MM is the difference between the two timestamps it follows. If you want to see how much time you've spent clocked in so far, simply clock out and after looking at the time, undo the change.

If there is no unfinished clock in, then the script clocks in to the selected task as above, so you can log in and out by pressing the shortcut key you assign to the script repeatedly.

I already have some elisp that runs under emacs org-mode that builds an inline MultiMarkDown table of weekly hours by adding up the relevant clock lines. But you could easily write a script to search for CLOCK lines and add up those times to generate a report.

property clockString : "CLOCK: "

-- return a timestamp string from a date object
on dateToTimestamp(theDate)
    set {weekday:w, day:d, year:y, time:t} to theDate
    set theTime to time string of theDate
    -- Calculate the month number.
    copy theDate to b
    set b's month to January
    set m to (b - 2500000 - theDate) div -2500000

    -- Timestamp in "yyyy-mm-dd DDD www hh:mm" format.
    tell theTime
        set shortTime to text 1 thru 5
    end tell
    tell w as string
        set shortDay to text 1 thru 3
    end tell
    tell (y * 10000 + m * 100 + d) as string
        set dateString to text 1 thru 4 & "-" & text 5 thru 6 & "-" & text 7 thru 8 & " " & shortDay & " " & shortTime
    end tell

    return dateString
end dateToTimestamp

-- return a date object from a timestamp string
on timestampToDate(theTimestamp)
    set theDate to date ("1/1/1000" as string)
    tell theTimestamp
        set theDate's year to text 1 thru 4
        set theDate's month to text 6 thru 7
        set theDate's day to text 9 thru 10
        set theDate's time to (text 16 thru 17) * hours + (text 19 thru 20) * minutes
    end tell
    return theDate
end timestampToDate

-- calculate the difference between the two timestamps in a clock string
-- "CLOCK: [begin-timestamp]--[end-timestamp]"
on getElapsedTime(clockString)
    set elapsedString to ""
    tell clockString
        set beginDate to my timestampToDate(text 9 thru 28)
        set endDate to my timestampToDate(text 33 thru 52)
    end tell
    set deltaDate to endDate - beginDate
    set deltaHours to deltaDate div hours
    set deltaMinutes to (deltaDate mod hours) div minutes

    if deltaHours < 10 then
        set elapsedString to elapsedString & " "
    end if
    set elapsedString to elapsedString & deltaHours & ":"
    if deltaMinutes < 10 then
        set elapsedString to elapsedString & "0"
    end if
    set elapsedString to elapsedString & deltaMinutes

    return elapsedString
end getElapsedTime

set theDate to dateToTimestamp(current date)

tell front document of application "TaskPaper"
    set thisTask to get selected entry
    set clock to clockString & "[" & theDate & "]"
    set clocks to search with query (clockString & " and type = note")
    set clockout to false
    set runningClocks to {}

    -- make sure we have a task selected    
    if entry type of thisTask is note type then
        set thisTask to container of selected entry
    else if entry type of thisTask is project type then
        set projectTasks to entire contents of selected entry
        set thisTask to item 1 of projectTasks
    end if

    -- look for a running clock (clocked in but not clocked out) and clock out if we find one
    repeat with each in clocks
        set theContent to text content of each
        if entry type of each is note type and theContent begins with (clockString & "[") and theContent does not contain "]--[" then
            if clockout is false then
                set clockout to true

                tell each
                    set theContent to text content & "--[" & theDate & "] => "
                    set text content to theContent & my getElapsedTime(theContent)
                end tell
            end if
        end if
    end repeat

    -- if we didn't find anything to clock out of, then clock in to the current task
    if clockout is false then
        tell thisTask
            make new note with properties {text content:clock}
        end tell
    end if
end tell

Copyright (c) 2010 Gary V. Vaughan  <>

This script 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 2 of the License, or
(at your option) any later version.

This script is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
GNU General Public License for more details.