Changing content of paragraph "on the fly"

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

Thanks to both. I will check which of the two methods is faster.

Thanks again !!

ldicroce. You’re most welcome.

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 … :wink:

Are you sure that’s what you want? You’re replacing all long paragraphs with the first five characters of the first paragraph.

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:

https://funkyimg.com/i/326KH.jpg

I understand that, but your sample script will put the same five characters for every long paragraph. Is that what you wanted?

@ldicroce

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

Absolutely correct. Thanks Yvan.
I want to replace the first “x” characters of each (long) paragraph.

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

Thanks, even tough I do get everything the code does. But I will search for info on stringByReplacingOccurrencesOfString command.
Thanks !
L

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

You need to define two variables, something like:

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

Thanks to all. Learning more and more …
L.

Thank you Shane.
Now it’s clear.

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) lundi 10 février 2020 08:44:24

I didn’t expect this!!!

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

That sounds reasonable.

You’re only dealing with two paragraphs. I suspect you’ll see different results with 19,000, or even just a couple of thousand.

I ran the two scripts without modification in Script Geek and the timings on my computer were:

ApplescriptObjC - 1.54 seconds

Basic AppleScript - 1.36 seconds

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

The results reported by Script Geek were:

ApplescriptObjC - 0.27 seconds
Basic AppleScript - 11.84 seconds

This surprised me, so I ran the both scripts in Script Editor. They worked as expected and the times reported by Script Geek seemed ballpark correct.

BTW, the following line only took 4 milliseconds to run:

set myText to read file "Save:Temp:TestFile.txt"

Thanks !
I got similar results with my new iMac. The results I reported earlier were done my my laptop which is older.
L.