You could do it using AppleScript reasonably quickly. Let's assume that your text is stored in a file at ~/Example/dialogue.txt
.
The following AppleScript (which can be inserted into a Execute An AppleScript
action) reads the contents of the text file; splits the text into individual items at every space, essentially breaking it into a word list; then inserts the rate marker text at the calculated position.
I hope it doesn't need to be precise with the number of words that fall in between each rate marker: ideally, from what you said, between rate markers "[[rate N]]"
and "[[rate N+1]]"
, there should be (N+1)
words of dialogue. However, for some reason, I ended up with (N+4)
words of dialogue, so there's an extra three words in each rate block. Sorry. My maths was a bit off and I can't put the mental energy right now into figuring out where I went wrong. [ It's not as straightforward as removing the + 2
or something similar, as it will affect where the placement of the first rate marker occurs, plus the viability of the insertItem()
handler, which, of course, can only operate within indices at which items exist. ]
After the rate markers have been inserted into the word list, the items are all joined back together and (over-)written back to the file.
property startRate : 180
property endRate : 700
property posixfile : POSIX file "/Users/%You%/Example/dialogue.txt"
property text item delimiters : space
--------------------------------------------------------------------------------
set dialogue to read the posixfile
set dialogueTextItems to the dialogue's text items
repeat with rate from startRate to endRate
set position to 0.5 * ¬
(rate - (startRate + 1)) * ¬
(rate + startRate + 2) + ¬
rate + 2 as integer
if the position > (count dialogueTextItems) then exit repeat
set dialogueTextItems to insertItem("[[rate " & rate & "]]", ¬
a reference to the dialogueTextItems, ¬
position)
end repeat
set dialogue to the dialogueTextItems as text
set eof of the posixfile to 0
write the dialogue to the posixfile as «class utf8»
display dialog "Document processing complete."
--------------------------------------------------------------------------------
###HANDLERS
#
# insertItem():
# Inserts a new element, x, into list L at position (index) i.
to insertItem(x, L as list, i as integer)
local x, L, i
if i = 1 or i = -((L's length) + 1) then return {} & x & L
if i = -1 or i = ((L's length) + 1) then return {} & L & x
if i < 0 then set i to i + 1
script Array
property |x₋| : items 1 thru (i - 1) of L
property |x₊| : items i thru -1 of L
end script
tell the Array to return {} & its |x₋| & x & its |x₊|
end insertItem
The script should terminate when either the last rate marker has been placed, or the end of the dialogue text is reached, whichever comes first.
I tested this script on a 930KB
text file containing 3,300 lines
, totalling 136,500 words
. Starting at rate marker 180
, it reached rate marker 550
. It took about 60 seconds to complete from within Script Editor on a MacBook 1.2 GHz Intel Core m5 8GB RAM.
You can likely increase performance by running it from Script Debugger or FastScripts. I'm not sure what Keyboard Maestro's AppleScript performance is like as a rule, since speed is very rarely, if ever, one of my personal priorities for the sorts of macros and scripts I run.