content: property pTitle : "Mark as done and optionally log to a done today file"
  property pVer : "0.05"
  
  -- Appends new done items (with an ancestral/parental context node) to a DoneToday.txt
  -- Archives previous days work with archival date-stamp in a previous file
  
  property pstrLogFolder : (POSIX path of (path to home folder)) & "FTLog"
  property pstrDoneStem : "FTDone"
  property pstrLoggedToday : "FTLoggedToday.txt"
  property pstrArchive : "FTArchiveDone"
  
  property pstrFldDelim : "~|~"
  
  property pblnDayPart : true
  property pblnTimePart : true
  property pblnSeconds : false
  
  property pblnLogTasks : true
  
  -- Stamp the selected FoldingText node with a @done tag including date-time @done(yyyy-mm-dd HH:MM:SS)
  -- GET THE PARENT PROJECT (ANCESTRAL .TODO, IF THERE IS ONE, OR immedate hash header or  IMMEDIATE ANCESTOR)
  on run
  	tell application "FoldingText"
  		set lstDocs to documents
  		if lstDocs ≠ {} then
  			tell item 1 of lstDocs
  				set strDocName to name
  				set oFile to its file
  				if oFile is not missing value then
  					set strDocPath to POSIX path of oFile
  				else
  					display dialog "The document \"" & strDocName & "\" needs to be saved" buttons {"OK"} default button "OK" with title pTitle & "  ver. " & pVer
  					return
  				end if
  
  				try
  					set {lstId, strSelnPath, recTextRange} to {nodeIDs, nodePath, textRange} of (read selection)
  				on error
  					return -- (no selection)
  				end try
  
  				-- GET THE 'PROJECT'NODE FOR THIS ACTION (PROXIMAL .TODO, HASH HEADER, OR JUST PARENT)
  				set lstAncestors to read nodes at path strSelnPath & "/ancestor::@mode=todo or @type=heading"
  				if lstAncestors ≠ {} then
  					set strParent to |text| of item 1 of lstAncestors
  				else
  					set lstAncestors to read nodes at path strSelnPath & "/parent::@type!=root"
  					if lstAncestors ≠ {} then
  						set strParent to |text| of item 1 of lstAncestors
  					else
  						set strParent to strDocName
  					end if
  				end if
  
  				set strTodayTag to "@done(" & my DateStamp(pblnDayPart, false, false)
  				set strDateStamp to my DateStamp(pblnDayPart, pblnTimePart, pblnSeconds)
  
  				-- Shape the pstrFldDelim delimited records :  "DocName|Project|TimeStampedTask
  				update nodes at range (recTextRange) ¬
  					with changes {|addTags|:{done:strDateStamp}}
  
  				if pblnLogTasks then
  					-- Establish the names of output folder and files
  					if not my IsFolder(pstrLogFolder) then
  						set strCmd to "mkdir " & pstrLogFolder
  						do shell script strCmd
  						if not my IsFolder(pstrLogFolder) then
  							display dialog "Could not find or create folder:" & linefed & linefeed & pstrLogFolder buttons {"OK"} default button "OK" with title pTitle & "  ver. " & pVer
  						end if
  					end if
  					if text -1 of pstrLogFolder ≠ "/" then set pstrLogFolder to pstrLogFolder & "/"
  
  					set {strDoneToday, strLoggedToday, strArchive} to ¬
  						{pstrLogFolder & pstrDoneStem & my TodayStamp() & ".txt", pstrLogFolder & pstrLoggedToday, pstrLogFolder & pstrArchive}
  
  					-- Fetch the text
  					set varSelnTasks to read nodes at ids lstId
  					if class of varSelnTasks ≠ list then set varSelnTasks to {varSelnTasks}
  					set strPath to strDocPath & pstrFldDelim & strParent & pstrFldDelim
  
  					set strTasks to ""
  					repeat with oTask in varSelnTasks
  						set strTasks to strTasks & strPath & my LTrim(|line| of oTask) & linefeed
  					end repeat
  					if length of strTasks > 1 and (text -2 of strTasks = linefeed) then ¬
  						set strTasks to text 1 thru -2 of strTasks -- (sh(1) echo adds another linefeed (no -n option))
  
  					-- IF WE HAVE ANY DATA
  					if strTasks ≠ "" then
  						-- WRITE OUT THE LIST OF DONE ITEMS
  
  						-- APPEND IF THERE ARE EARLIER ITEMS FROM TODAY
  						if my FileNotEmpty(strDoneToday) then
  							if my FileContains(strDoneToday, strTodayTag) then
  								set strCmd to "echo " & quoted form of strTasks & " >> " & quoted form of strDoneToday
  								do shell script strCmd
  							else
  								-- MAKE A BACKUP DATESTAMPED NOW ...
  								set strCmd to "mv " & quoted form of strDoneToday & space & quoted form of (strArchive & my FileNameDateStamp() & ".txt")
  								do shell script strCmd
  								-- AND OVERWRITE WITH FIRST DATA OF THE DAY
  								my WriteText2Path(strTasks, strDoneToday)
  							end if
  						else
  							my WriteText2Path(strTasks, strDoneToday)
  						end if
  						-- AND MAKE A COPY OF THE DATED VERSION CALLED FTDONETODAY.TXT FOR HAZEL TO WATCH
  						set strCmd to "cp -f " & quoted form of strDoneToday & space & quoted form of (pstrLogFolder & pstrDoneStem & "Today.txt")
  						do shell script strCmd
  					end if
  				end if
  			end tell
  		end if
  	end tell
  end run
  
  on DateStamp(blnDayPart, blnTimePart, blnSeconds)
  	if blnDayPart then
  		set strDate to "%Y-%m-%d"
  	else
  		set strDate to ""
  	end if
  	if blnTimePart then
  		set strDate to strDate & space & "%H:%M"
  		if pblnSeconds then set strDate to strDate & ":%S"
  	end if
  	set strCmd to "date \"+" & strDate & "\""
  	do shell script strCmd
  end DateStamp
  
  on TodayStamp()
  	do shell script "date \"+%Y-%m-%d\""
  end TodayStamp
  
  on FileNameDateStamp()
  	do shell script "date \"+%Y-%m-%d_%H%M\""
  end FileNameDateStamp
  
  on FileExists(strPath)
  	(do shell script ("test -e " & quoted form of strPath & "; echo $?")) = "0"
  end FileExists
  
  on FileNotEmpty(strPath)
  	(do shell script ("test -s " & quoted form of strPath & "; echo $?")) = "0"
  end FileNotEmpty
  
  on FileContains(strPath, strPattern)
  	(do shell script "grep -q " & quoted form of strPattern & space & quoted form of strPath & "; echo $?") = "0"
  end FileContains
  
  on IsFolder(strPath)
  	(do shell script ("test -d " & quoted form of strPath & "; echo $?")) = "0"
  end IsFolder
  
  on LTrim(strText)
  	set lngChars to length of strText
  	if lngChars is 0 then return ""
  	set lstWhite to {space, tab, return, ASCII character 10, ASCII character 0}
  
  	set blnFound to false
  	repeat with iChar from 1 to lngChars
  		if character iChar of strText is not in lstWhite then exit repeat
  	end repeat
  	set strText to text iChar thru lngChars of strText
  
  	return strText
  end LTrim
  
  on WriteText2Path(strText, strPosixPath)
  	set f to (POSIX file strPosixPath)
  	open for access f with write permission
  	write strText as «class utf8» to f
  	close access f
  end WriteText2Path
  
  
  