Skip to content

Instantly share code, notes, and snippets.

@SKaplanOfficial
Created August 26, 2025 04:47
Show Gist options
  • Save SKaplanOfficial/3f1f53c73256418bf4764e4e343377fe to your computer and use it in GitHub Desktop.
Save SKaplanOfficial/3f1f53c73256418bf4764e4e343377fe to your computer and use it in GitHub Desktop.
Overview of Bike's outline path behavior.

Outline paths can be significantly more performant than AppleScript's filtering operations.

For example, //*/run::@strong gets interpreted as:

  1. For all descendants of the root node,
  2. Look at their associated rich text by using run:: axes, then
  3. Run predicate against the attributes associated with each rich text run’s attributes.

Within Bike, outline paths can return different kinds of values:

  • count(//*) returns a number.
  • //* returns a list of “nodes” (rows and/or text runs).

To avoid implementation complexity, Bike's automation interfaces behave slightly differently:

  1. In Shortcuts, “Query Rows” only returns rows -- count(//*) returns an empty list.

  2. In AppleScript, the “query” command returns rows and numbers, but not text runs. Instead, add /.. to the end of the query to obtain the parent rows containing the matching text runs, not the text runs themselves. For example:

    • //*/run::@strong — Zero results in AppleScript since no text run results
    • //*/run::@strong/.. — Returns all rows that contain strong (bold) text.

For more information, see the following resources:

  1. Using Outline Paths | Bike User Guide
  2. Post about Outline Paths | Hog Bay Software
  3. Bike 1.17 Outline Path Automation Details | Bike Support Forum
(*
Gets all URLs in the current document that link to internal rows or other Bike documents (any link starting with 'bike://')
*)
tell application "Bike"
-- The `query` command in Bike's scripting interface only returns rows and/or numbers.
-- Use "/.." at the end of the outline path to get parent rows of matching text runs.
-- A row's `attribute runs` can be used to get equivalent text run info, if needed.
set theRows to query document 1 outline path "//*/run::@link beginswith \"bike://\"/.."
set internalLinks to {}
repeat with theRow in theRows
copy (link of text content of theRow) as text to end of internalLinks
end repeat
return internalLinks
end tell
/**
* Gets all URLs in the current document that link to internal rows or other Bike documents (any link starting with 'bike://')
*/
function run() {
const bike = Application("Bike");
// The `query` command in Bike's scripting interface only returns rows and/or numbers.
// Use "/.." at the end of the outline path to get parent rows of matching text runs.
// A row's `attribute runs` can be used to get equivalent text run info, if needed.
const rows = bike.query(bike.documents.first, { outlinePath: `//*/run::@link beginswith "bike://"/..` });
return rows.map(row => row.textContent.link())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment