ldicroce’s post has 2 requirements: that the contents of a paragraph be changed “on the fly” and that this be done without converting the initial string to a list.
Stefan’s script works “on the fly” but uses a list. My script below does not use a list (except to count paragraphs) but does not operate “on the fly”. Also, it’s slow because it concatenates text.
Stefan’s script works great and, FWIW, is the one I would use, although I’m sure ldicroce has a reason for his specific requirements.
set mytext to "Luciano" & linefeed & "Luciano_Luciano"
set myText2 to ""
set countParagraph to count paragraphs of mytext
repeat with i from 1 to countParagraph
set aParagraph to paragraph i of mytext
if length of aParagraph > 10 then
set myText2 to myText2 & text 1 thru 5 of mytext & linefeed
else
set myText2 to myText2 & aParagraph & linefeed
end if
end repeat
set myText2 to text 1 thru -2 of myText2
I enjoy playing around with Script Geek and tested Stefan’s and my script. With the text specified in line 1 of your original post, the two scripts were essentially equal as to time. I then substituted a string that probably contained 100 paragraphs, and Stefan’s script was (as expected) faster. The difference was about 10 percent.
Is good to know since the input string I am using as 19.000 paragraph !!!
Thanks again !
L.
PS: Maybe Shane will come up with some of this magic script that are even faster …
Yes! It won’t be 5 chars, it will be most likely 50.
It is part of larger project. I am using Ubersicht to display things on my monitor in a window-less and dynamic manner. A kind of personalised “Notification” system.
I have put some part (including my Calendar, To do…) together. See here:
I guess that Shane Stanley try to tell you that the correct code would be :
set mytext to "Luciano" & linefeed & "Lucyano_Luciano"
set allParagraphs to paragraphs of mytext
repeat with aParagraph in allParagraphs
if length of aParagraph > 10 then
set contents of aParagraph to text 1 thru 5 of aParagraph -- was wrongly mytext
end if
end repeat
set {TID, text item delimiters} to {text item delimiters, linefeed}
set theResult to allParagraphs as text
set text item delimiters to TID
theResult
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) dimanche 9 février 2020 10:19:37
In that case you could use a regex search/replace:
use AppleScript version "2.5" -- macOS 10.11 or later
use framework "Foundation"
use scripting additions
set myText to "Luciano" & linefeed & "Lucyano_Luciano"
set myText to current application's NSString's stringWithString:myText
set myText to (myText's stringByReplacingOccurrencesOfString:"(.{5}).{6,}" withString:"$1" options:(current application's NSRegularExpressionSearch) range:{0, myText's |length|()}) as text
I assumed that I understood what it did so I tried a more general syntax:
set beg to 5
set myString to "(.{" & beg & "}).{" & (beg + 1) & ",}"
set myText to (myText's stringByReplacingOccurrencesOfString:(myString) withString:"$1" options:(current application's NSRegularExpressionSearch) range:{0, myText's |length|()}) as text
Alas, it works with beg from 2 thru 7 but doesn’t with beg greater than 7.
What is wrong in my attempt ?
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) dimanche 9 février 2020 18:51:01
set maxLen to 10 -- alowable length
set trimLen to 5 -- length to trim to
set myString to "(.{" & trimLen & "}).{" & (maxLen - trimLen + 1) & ",}"
set myText to (myText's stringByReplacingOccurrencesOfString:(myString) withString:"$1" options:(current application's NSRegularExpressionSearch) range:{0, myText's |length|()}) as text
1000 repetition of this, takes 5 seconds on my MacBook (2015).
use AppleScript version "2.5" -- macOS 10.11 or later
use framework "Foundation"
use scripting additions
repeat 1000 times
set myText to "Luciano" & linefeed & "Luciano_Luciano"
set myText to current application's NSString's stringWithString:myText
set myText to (myText's stringByReplacingOccurrencesOfString:"(.{5}).{6,}" withString:"$1" options:(current application's NSRegularExpressionSearch) range:{0, myText's |length|()}) as text
end repeat
While 100000 repetition of this takes 3 seconds. So, 2 order of magnitude faster !!
Is that true or I am doing something wrong …
repeat 100000 times
set mytext to "Luciano" & linefeed & "Luciano_Luciano"
set allParagraphs to paragraphs of mytext
repeat with aParagraph in allParagraphs
if length of aParagraph > 10 then
set contents of aParagraph to text 1 thru 5 of aParagraph -- was wrongly mytext
end if
end repeat
set {TID, text item delimiters} to {text item delimiters, linefeed}
set theResult to allParagraphs as text
set text item delimiters to TID
theResult
end repeat
To test something longer, I created a text file with 19000 paragraphs alternating the following:
I then ran the following scripts in Script Geek with only 1 repetition:
use AppleScript version "2.5" -- macOS 10.11 or later
use framework "Foundation"
use scripting additions
tell current application to set myText to read file "Save:Temp:TestFile.txt"
set myText to current application's NSString's stringWithString:myText
set myText to (myText's stringByReplacingOccurrencesOfString:"(.{5}).{6,}" withString:"$1" options:(current application's NSRegularExpressionSearch) range:{0, myText's |length|()}) as text
set myText to read file "Save:Temp:TestFile.txt"
set allParagraphs to paragraphs of myText
repeat with aParagraph in allParagraphs
if length of aParagraph > 10 then
set contents of aParagraph to text 1 thru 5 of aParagraph -- was wrongly mytext
end if
end repeat
set {TID, text item delimiters} to {text item delimiters, linefeed}
set theResult to allParagraphs as text
set text item delimiters to TID