Moving text from row's note to end of row

When writing meeting minutes, I find it convenient to comment every item during the meeting in their respective note section. The note section has its own style in bold text, so it’s easy to see what was discussed in the current meeting. I then finalize the minutes and all attendees have their to do list.

When the next meeting comes, I want to use again the notes’ section to follow up. I move the text from the notes’ sections to the rows of the previous meeting, then add the date of the previous meeting to follow up what was discussed and when for every topic. This is what I’m trying to automate with Applescript.

For every row, this

should become that (bold text from notes’ section moved to the end of its row)

and then clear the note section, but I get this error message :

Impossible to set name of row to "xxxx". 

The script:

tell application "OmniOutliner"
	tell front document
	try
		
		set rowCount to every row
		repeat with i in rowCount
			
			set rowName to name of i
			set noteName to note of i
			set newName to (rowName & noteName)
			set name of i to newName
		delete note of i

		end repeat
		
	on error errormessage number errornumber
		display dialog errormessage buttons {"OK"} default button 1
	end try
end tell
end tell

I can’t find how to adjust the script, any help would be appreciated!

Found the solution!
Replaced

set name of i to newName

with

set text of cell 2 of i to newName

You might find that there is no space between the original text and the appended text from the note. You can include it when you set newName.

set newName to (rowName & space & noteName)

Also, in your example there is no formatting in your topic but in case you have some rows with formatting, then here is a variation that will make the appended text the same format as the last character of the topic. It also ignores level 1 rows, rows with empty topics and rows without a note but you can edit or remove these as desired.

Attribute runs are segments of text that share the same formatting. So this finds the last such text in the topic and combines it with the text from the note, thus applying its formatting to the appended text.

tell application "OmniOutliner"
	tell document 1
		set rowList to every row whose level is not 1
		
		repeat with i in rowList
			if topic of i is not "" or note of i is not "" then
				-- replace note of i matching regular expression "\\(?(\\d{4}-\\d{2}-\\d{2})\\)?" replacement "($1)"
				-- attribute runs of topic of i
				set lar to last attribute run of topic of i
				set last attribute run of topic of i to (lar & space & note of i)
				delete note of i
			end if
		end repeat
		
	end tell
end tell

You may have noticed the ‘replace note…’ line that is commented out. If you uncomment the line then the script will find date strings in the note and put them inside parentheses as in your example, e.g. from 2022-11-23 to (2022-11-23). If they already have parentheses then it does not add a second pair. This may save you from having to add them manually. Let me know if you would like some elaboration on the command.

Thank you for your help, it’s very appreciated.

Correct, there might be no space between the end of the orignal text in the topic. How could a regular expression be set to account for this condition?

Regarding the dates in parenthesis, they keep a trail of what was discussed at each meeting for a given topic. In my example, (2022-11-28) will be included at the end of each row with ongoing discussions. I found a plug-in to add text at the end of selected rows, but it would be better to have everything in one script.
Following your response, I have been trying to set that date in parenthesis using a regular expression (similar to the ‘replace note’ comment you shared). This was my uneducated guess but there is always an error where it sets the meetingDate variable. Either it can’t find the topic or the row (if I remove ‘topic of’).

tell application "OmniOutliner"
	tell document 1
	set rowList to every row whose level is not 1
	set meetingDate to replace (topic of row whose level is 1) matching regular expression "\\(?(\\d{4}-\\d{2}-\\d{2})\\)?" replacement "($1)"
	repeat with i in rowList
		if topic of i is not "" or note of i is not "" then
			-- replace note of i matching regular expression "\\(?(\\d{4}-\\d{2}-\\d{2})\\)?" replacement "($1)"
			-- attribute runs of topic of i
			set lar to last attribute run of topic of i
			set last attribute run of topic of i to (lar & space & note of i & meetingDate)
			delete note of i
		end if
	end repeat
	
end tell
end tell

Specific to how to change all the dates at once (in the topics, not the notes), this script will do that, as well as remove any spaces found after a period at the end of a topic. This will affect every row.

tell application "OmniOutliner"
	tell document 1
		set rowList to a reference to (every row)
		
		-- remove spaces after period at end of topic
		replace topic of contents of rowList matching regular expression "\\.[:space:]+$" replacement "."
		-- parenthesize dates, from '2022-11-30' to '(2022-11-30)'
		replace topic of contents of rowList matching regular expression "\\(?(\\d{4}-\\d{2}-\\d{2})\\)?" replacement "($1)"
		
	end tell
end tell

Note the use of reference to. It is necessary in order to run the replace on the topic of every row (unless you use a repeat loop). Its use further requires the contents of in each replace command.

You could run this once on any existing documents. The other script would be run after each meeting.

One question… I can’t be certain what the level of each row in your example is, nor what rows should be affected by the script. My initial impression was that the edited topics were not level 1 but I’m thinking now that I was wrong. So the script below works on rows of any level as long as they have a note with at least 1 character in it.

When updating the document after a meeting, I would use the following script. It affects text that is in the note before appending the note to the topic. This is advantageous as it means that you can use dates without parentheses (as in your example) and not have changes made to existing text.

tell application "OmniOutliner"
	tell document 1
		set rowList to a reference to every row
		
		repeat with i in rowList
			if topic of i is not "" and size of note of i is not 0 then -- when both topic and note contain text
				-- replace '2022-12-01' with '(2022-12-01)'
				replace note of i matching regular expression "\\(?(\\d{4}-\\d{2}-\\d{2})\\)?" replacement "($1)"
				
				-- append 'space' and note to topic
				set lar to last attribute run of topic of i
				set last attribute run of topic of i to (lar & space & note of i)
				delete note of i
			end if
		end repeat
	end tell
end tell

If desired, you could combine the two scripts into a single one. Simply take the repeat loop from this script and insert it below the second replace from the other script. Just remember that it will put parentheses around every date.

Thank you again. I was able to come up with the code below. Regarding the dates, the ones in parentheses are only necessary at the end of each row to follow up on topics discussed. In some cases, dates indicate deadlines and I do not want these in parentheses.

As for the level of each row, yes the main header and subheaders are all level 1 rows. The discussion items are level 2 rows. I’ll see how it goes but in case I use levels 3 and up for further discussions, the script is already set up for these as well and I can keep comments in notes of level 1 rows which would not be affected by the script.

I think the script below would be fine for what I need, but I’d be interested to read your comments/suggestions if you have any.

tell application “OmniOutliner”

tell document 1

set rowList to a reference to (every row whose level is not 1)

set shortDate to short date string of (current date)

set shortDatestring to “(” & shortDate & “)”

display dialog “Choose date” default answer shortDatestring buttons {“Cancel”, “Continue”} default button “Continue”

copy the result to {button returned:buttonPressed, text returned:meetingDate}

repeat with i in rowList

if topic of i is not “” and size of note of i is not 0 then – when both topic and note contain text

– replace ‘2022-12-01’ with ‘(2022-12-01)’

– replace note of i matching regular expression “\(?(\d{4}-\d{2}-\d{2})\)?” replacement “($1)”

replace topic of contents of rowList matching regular expression “\.[:space:]+$” replacement “.”

replace note of contents of rowList matching regular expression “\.[:space:]*$” replacement “”

– append ‘space’ and note to topic

set lar to last attribute run of topic of i

set last attribute run of topic of i to (lar & space & note of i & space & meetingDate & “.”)

delete note of i

end if

end repeat

end tell

end tell

Looks good to me.

The one edit that I would consider would be to move the date/dialogue lines above the OO tell block. Currently, it generates a -10004 error because you are telling OO directly to do something with the current date.

So basically, the script would begin like this…

set shortDate to short date string of (current date)
set shortDatestring to "(" & shortDate & ")"
display dialog "Choose date" default answer shortDatestring buttons {"Cancel", "Continue"} default button "Continue"
copy the result to {button returned:buttonPressed, text returned:meetingDate}

tell application "OmniOutliner"
	tell document 1
		set rowList to a reference to (every row whose level is not 1)

Alternatively, preface the set short date to… line with tell me to which would remove the error.

Works like a charm, thanks!

1 Like