content: property pTitle : "Selected FT Tree to Clipboard as MMD table"
  property pVer : "0.04"
  
  (* "|Heilmeier's catechism||||||||||
  |:-------:|:-------:|:-------:|:-------:|:-------:|:-------:|:-------:|:-------:|:-------:|:-------:|
  |A set of questions which you should always be able to answer.||||||||||
  |What ?|||Why ?|||At what cost ?|||And how will we know it has worked ?|
  |What are you trying to do? Articulate your objectives using absolutely no jargon.|How is it done today, and what are the limits of current practice?|What's new in your approach and why do you think it will be successful?|Who cares?||If you're successful, what difference will it make?|What are the risks and the payoffs?|How much will it cost?|How long will it take?|What are the midterm and final \"exams\" to check for success?|
  |-|-|-|Audience|Intermediaries|-|-|-|-|-|
  " *)
  
  -- Ver 0.4 optionally exclude the subtrees of folded nodes from the table
  
  property pblnSkipHidden : true -- EDIT TO FALSE TO INCLUDE SUB-TREES HIDDEN BY FOLDING
  
  property plstFolded : {}
  
  property plstSeen : {}
  property pstrCell : ":-------:|"
  
  property pstrFiller : space & space -- (for empty cells in the tree-table)
  
  
  
  
  on run
  	-- GET THE SUBTREE(S) OF THE LINE(S) SELECTED IN FOLDINGTEXT
  	set lstNested to GetFTSelnTree(pblnSkipHidden)
  	
  	-- CREATE A NESTED (SPANNING) TABLE VERSION IN MMD FORMAT
  	set strTable to MakeMMDTable(lstNested)
  	
  	-- PLACE IN THE CLIPBOARD
  	set the clipboard to strTable
  	strTable
  end run
  
  
  -- TRANSLATE A NESTED LIST OF TEXTS INTO AN MMD SPANNING TABLE
  on MakeMMDTable(lstNested)
  	set str to "|"
  	set lngRows to MaxDepth(lstNested)
  	set lngCells to LeafWidth(lstNested) -- flag each node with its own width in leaves
  	
  	-- TOP ROW
  	set lstRow to GetRow(lstNested, 1)
  	set str to MakeMMDRow(lstRow) & linefeed
  	
  	-- RULER
  	set str to str & "|"
  	repeat with i from 1 to lngCells
  		set str to str & pstrCell
  	end repeat
  	set str to str & linefeed
  	
  	-- REMAINING ROWs
  	repeat with i from 2 to lngRows
  		set lstRow to GetRow(lstNested, i)
  		set str to str & MakeMMDRow(lstRow) & linefeed
  	end repeat
  	
  	return str
  end MakeMMDTable
  
  -- TRANSLATE THIS (MEASURED) ROW OF THE TREE INTO A LINE OF MMD TABLE TEXT
  on MakeMMDRow(lstRow)
  	set str to "|"
  	repeat with oCell in lstRow
  		set {lngWidth, strText} to oCell
  		set str to str & strText
  		repeat with i from 1 to lngWidth
  			set str to str & "|"
  		end repeat
  	end repeat
  	return str
  end MakeMMDRow
  
  -- FETCH GENERATION X
  on GetRow(lst, lngDepth)
  	set lstRow to {}
  	if lngDepth ≤ 1 then
  		if lst ≠ {} then
  			repeat with oNode in lst
  				set end of lstRow to items 1 thru 2 of oNode
  			end repeat
  		else
  			set end of lstRow to {1, pstrFiller}
  		end if
  	else
  		if lst ≠ {} then
  			repeat with oNode in lst
  				set lstChiln to last item of oNode
  				set lstRow to lstRow & GetRow(lstChiln, lngDepth - 1)
  			end repeat
  		else
  			set end of lstRow to {1, pstrFiller}
  		end if
  	end if
  	return lstRow
  end GetRow
  
  -- HOW WIDE ARE THESE BRANCHES, MEASURED IN LEAF NODES ?
  on LeafWidth(lst)
  	set lngTotal to 0
  	repeat with i from 1 to length of lst
  		set oNode to item i of lst
  		set lstChiln to last item of oNode
  		if lstChiln ≠ {} then
  			set lngNode to LeafWidth(lstChiln)
  		else
  			set lngNode to 1
  		end if
  		set beginning of oNode to lngNode -- flag a node with its own width
  		set lngTotal to lngTotal + lngNode
  	end repeat
  	return lngTotal
  end LeafWidth
  
  -- HOW DEEP DO THESE BRANCHES GET ?
  on MaxDepth(lst)
  	set {lngDepth, lngMax} to {0, 0}
  	repeat with oNode in lst
  		set lstChiln to last item of oNode
  		if lstChiln ≠ {} then
  			set lngDepth to MaxDepth(lstChiln) + 1
  		else
  			set lngDepth to 1
  		end if
  		if lngDepth > lngMax then set lngMax to lngDepth
  	end repeat
  	return lngMax
  end MaxDepth
  
  -- GET THE SUBTREE(S) OF THE OUTLINE ROWS SELECTED IN FOLDINGTEXT
  on GetFTSelnTree(blnSkipHidden)
  	tell application "FoldingText"
  		set lstDocs to documents
  		if lstDocs ≠ {} then
  			set oDoc to item 1 of lstDocs
  			tell oDoc
  				set recSeln to read selection
  				if recSeln is missing value then return {}
  				set lstNodes to (read nodes at path (nodePath of recSeln))
  				set plstSeen to {}
  				set lstTree to {}
  				
  				if blnSkipHidden then
  					set plstFolded to run script (body of (read JSON (HTTP request URI "/view/collapsed.json")))
  				else
  					set plstFolded to {}
  				end if
  				
  				repeat with oNode in lstNodes
  					set strID to |id| of oNode
  					if plstSeen does not contain strID then
  						set end of plstSeen to strID
  						set end of lstTree to my GetSubTree(oDoc, oNode, blnSkipHidden)
  					end if
  				end repeat
  				return lstTree
  			end tell
  		else
  			return {}
  		end if
  	end tell
  end GetFTSelnTree
  
  -- GET THE FULL SUB-TREE OF NON BLANK LINES FOR A GIVEN OUTLINE ROW
  -- (IGNORING THE SUBTREES OF NODES WHICH ARE FOLDED)
  on GetSubTree(oDoc, oNode, blnSkipHidden)
  	tell application "FoldingText"
  		tell oDoc
  			set strID to |id| of oNode
  			
  			-- OPTIONALLY EXCLUDE THE SUBTREES OF FOLDED NODES
  			if blnSkipHidden and plstFolded contains strID then
  				set lstVisibleChiln to {}
  			else
  				set lstVisibleChiln to read nodes at path ("//@id=" & |id| of oNode & "/@type!=empty")
  			end if
  			
  			set lstTree to {}
  			if lstVisibleChiln ≠ {} then
  				repeat with i from 1 to length of lstVisibleChiln
  					set oChild to item i of lstVisibleChiln
  					set strID to |id| of oChild
  					if plstSeen does not contain strID then
  						set end of plstSeen to strID
  						set end of lstTree to my GetSubTree(oDoc, oChild, blnSkipHidden)
  					end if
  				end repeat
  			end if
  			return {|text| of oNode, lstTree}
  		end tell
  	end tell
  end GetSubTree
  
  