AppleScript to Export Outlines to a Kanban-Style HTML View

Hey everyone,

I’ve been looking for a way to visualize my Bike outlines in a more horizontal, Kanban-like layout, where top-level items appear on the left and their children are nested to the right.

With a lot of helpful iteration, I’ve ended up with an AppleScript that does this automatically. It reads your outline, generates an HTML file with the new layout, and opens it in your browser. The top-level items are in boxes, and all their children are formatted as a clean, bulleted list. here is a screenshot. left the html and right the original bike.

Now the question arises for me, would additional views be a potential possibility?

Here is the final script if anyone else finds this useful!
-- AppleScript to convert a Bike outline to a nested column HTML file with bulleted lists for children

-- --- SCRIPT CONFIGURATION ---

property backgroundColor : "#f8f9fa"
property rowBackgroundColor : "#ffffff"
property rowBorderColor : "#dee2e6"
property rowTextColor : "#212529"
property fontFamily : "-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif"

-- --- END CONFIGURATION ---

try
	tell application "Bike"
		if not (exists document 1) then error "No Bike document is open."
		set frontDocument to document 1
		
		try
			set docPath to file of frontDocument
		on error
			error "The Bike document must be saved before running this script."
		end try
		
		set docName to name of frontDocument
		set allRows to rows of frontDocument
		set childRowIDs to {}
		
		repeat with aRow in allRows
			set childRows to rows of aRow
			repeat with aChild in childRows
				set the end of childRowIDs to id of aChild
			end repeat
		end repeat
		
		set htmlBody to ""
		repeat with aRow in allRows
			if id of aRow is not in childRowIDs then
				set htmlBody to htmlBody & my processTopRow(aRow)
			end if
		end repeat
	end tell
	
	set htmlContent to my buildFullHtml(docName, htmlBody)
	my saveAndOpenFile(docPath, htmlContent)
	
on error errMsg number errNum
	display dialog "An error occurred: " & errMsg & " (" & errNum & ")" with icon stop
end try

-- --- SUBROUTINES ---

on processTopRow(aRow)
	set html to ""
	tell application "Bike"
		set rowName to name of aRow
		set childRows to rows of aRow
		set html to html & "<div class=\"row-container\">"
		set html to html & "<div class=\"row-text\">" & my escapeHtml(rowName) & "</div>"
		
		if (count of childRows) > 0 then
			set html to html & "<div class=\"children-container\">"
			set html to html & my processChildrenAsList(childRows)
			set html to html & "</div>"
		end if
		
		set html to html & "</div>"
	end tell
	return html
end processTopRow

on processChildrenAsList(childRows)
	set html to "<ul>"
	tell application "Bike"
		repeat with aChild in childRows
			set html to html & "<li>" & my escapeHtml(name of aChild)
			if (count of rows of aChild) > 0 then
				set html to html & my processChildrenAsList(rows of aChild)
			end if
			set html to html & "</li>"
		end repeat
	end tell
	set html to html & "</ul>"
	return html
end processChildrenAsList

on buildFullHtml(docName, htmlBody)
	set html to "<!DOCTYPE html>
<html lang=\"en\">
<head>
	<meta charset=\"UTF-8\">
	<title>" & my escapeHtml(docName) & "</title>
	<style>
		body { font-family: " & fontFamily & "; background-color: " & backgroundColor & "; color: " & rowTextColor & "; margin: 20px; line-height: 1.5; }
		.row-container { display: flex; align-items: flex-start; border: 1px solid " & rowBorderColor & "; background-color: " & rowBackgroundColor & "; margin-bottom: 8px; border-radius: 6px; overflow: hidden; }
		.row-text { padding: 10px 15px; font-weight: 500; border-right: 1px solid " & rowBorderColor & "; flex-shrink: 0; }
        /* MODIFIED: Added gray background for diagnostics */
		.children-container { padding: 1px 15px; flex-grow: 1; background-color: #f0f0f0; }
        .children-container ul { list-style-type: disc; padding-left: 20px; margin-top: 10px; margin-bottom: 10px; }
		.children-container ul ul { list-style-type: circle; }
		.children-container li { margin-bottom: 4px; }
	</style>
</head>
<body>
	<h1>" & my escapeHtml(docName) & "</h1>
	" & htmlBody & "
</body>
</html>"
	return html
end buildFullHtml

on saveAndOpenFile(originalPath, htmlContent)
	set originalPathStr to originalPath as text
	if originalPathStr ends with ".bike" then
		set newPathStr to (text 1 thru -6 of originalPathStr) & ".html"
	else
		set newPathStr to originalPathStr & ".html"
	end if
	
	try
		set fileRef to open for access file newPathStr with write permission
		set eof of fileRef to 0
		write htmlContent to fileRef as «class utf8»
		close access fileRef
		tell application "Finder"
			open file newPathStr
		end tell
		return true
	on error errMsg
		display dialog "Failed to save or open the file: " & errMsg
		return false
	end try
end saveAndOpenFile

on escapeHtml(txt)
	set AppleScript's text item delimiters to "&"
	set a to text items of txt
	set AppleScript's text item delimiters to "&amp;"
	set txt to a as text
	
	set AppleScript's text item delimiters to "<"
	set a to text items of txt
	set AppleScript's text item delimiters to "&lt;"
	set txt to a as text
	
	set AppleScript's text item delimiters to ">"
	set a to text items of txt
	set AppleScript's text item delimiters to "&gt;"
	set txt to a as text
	
	set AppleScript's text item delimiters to "\""
	set a to text items of txt
	set AppleScript's text item delimiters to "&quot;"
	set txt to a as text
	
	set AppleScript's text item delimiters to ""
	return txt
end escapeHtml
1 Like

A quick footnote – to paste code in a format which others can read and copy (and which won’t be corrupted by edit-field auto-corrections etc), you can either use the code icon above the post-editing field:

Screenshot 2025-09-29 at 9.34.13 am

or directly type:

  1. three backticks before the first code line, and
  2. another three backticks after the last code line.

```
type or paste code here

```

Thanks for sharing! I’ve just edited your post so that the script is easier for others to copy and use for themselves. It looks like you are already an expert AppleScript wrangler, but in the Bike 2.0 extension API you could integrate this type of visualization even more closely with Bike’s outline.

Here’s one approach, you could do same thing except generate your Kanban layout instead of the d3 layout that I’ve generated:

And “some” documentation: