TaskPaper 3 example :: links preserving filter state

TaskPaper 3 combines plain text files with a very rich scripting API (key-value tag processing, outline-aware filtering, folding etc etc).

This allows us to write Hook scripts for capturing and following links which can preserve not only file path but also any other aspects of editor state which we might be interested in, for example:

  • Filter state,
  • fold state,
  • selection start and end.

Here is an illustrative draft of sample scripts for Hook in which:

  • Get Address captures the current filter state of the TaskPaper 3 document, as well as its file path
  • Open item opens the linked file and also restores its filter state from an option in the link.

Open Item
use framework "Foundation"

on run
    tell application "TaskPaper"
        set fpOption to my decodedPath(text (1 + (length of "taskpaper://")) thru -1 of "$0")
        set xs to my splitOn("?", fpOption)
        open item 1 of xs
        activate
        if 1 < length of xs then
            set kv to my splitOn("=", item 2 of xs)
            if 2 ≤ length of kv then
                set k to item 1 of kv
                set v to item 2 of kv
                if "filter" = k and "" ≠ v then
                    tell front document
                        evaluate script "e => e.itemPathFilter = " & my quoted("\"", v)
                    end tell
                end if
            end if
        end if
    end tell
end run

-- GENERIC 
-- https://github.com/RobTrew/prelude-applescript

-- decodedPath :: Percent Encoded String -> FilePath
on decodedPath(fp)
    tell current application
        (its ((NSString's stringWithString:fp)'s ¬
            stringByRemovingPercentEncoding)) as string
    end tell
end decodedPath

-- quoted :: Char -> String -> String
on quoted(c, s)
    c & s & c
end quoted

-- splitOn :: String -> String -> [String]
on splitOn(pat, src)
    set {dlm, my text item delimiters} to ¬
        {my text item delimiters, pat}
    set xs to text items of src
    set my text item delimiters to dlm
    return xs
end splitOn
Get Name
tell application "TaskPaper" to name of front document
Get Address
use framework "Foundation"

on run
    tell application "TaskPaper"
        set fp to (POSIX path of ((file of front document) as alias)) as string
        tell front document
            set strFilter to evaluate script "e => e.itemPathFilter"
        end tell
    end tell
    
    if "" ≠ strFilter then
        set strOptions to "?filter=" & encodedPath(strFilter)
    else
        set strOptions to ""
    end if
    
    "taskpaper://" & encodedPath(fp) & strOptions
end run

-- encodedPath :: FilePath -> Percent Encoded String
on encodedPath(fp)
    tell current application
        (its ((NSString's stringWithString:fp)'s ¬
            stringByAddingPercentEncodingWithAllowedCharacters:(its NSCharacterSet's ¬
                URLPathAllowedCharacterSet))) as string
    end tell
end encodedPath
1 Like

Rob is the “Get Name” example incomplete? It fails loudly.

Tell me more ? Not failing here with that single line …

What do you see at the bottom of the Hook dialog if you select (without tapping) the Copy as Markdown option ?

With the two sibling scripts you do need to make sure that you have copied everything, including:

  • the use framework "Foundation" line at the top,
  • all the generic functions below,

and that you are using Sierra onwards macOS.

(The Applescript Foundation classes used here requires only Yosemite macOS onwards, but the compact TaskPaper JavaScript syntax above requires Sierra macOS onwards)

We verified support for Task Paper before Hook went public beta, noting internally it works on documents but not tasks; unfortunately, by the time I published the compatible apps page I forgot to provide that qualification. I’ve now added the qualification and linked the TaskPaper bullet to to the current topic.

1 Like

(FWIW one could write scripts which used the TaskPaper API to derive a unique path/address for tasks, but of course they would have to fall back to document addresses if that path was disrupted by subsequent reorganisation of the TaskPaper file contents.)

See also:

1 Like