Indesign: get formatted text from frame

Hi.

I’m working in a script that takes the text of all text frames and put them in a Numbers file. It’s working fine, but just plain text. Is there a way to “set myText to (every paragraph)” and keep formatting?

Indesign comes with that script that exports all stories to RTF, but it seems that RTF only works while exporting.

Any idea?

Thank you,

Luiz

You yourself answered your question.

  1. export the next storie to the RTF file of the user domain temporary items. Let’s say this is myStorie.rtf file.
  2. get its contents to the clipboard: set the clipboard to (read myStorie.rtf)
  3. set the value of the next Numbers text frame to the contents of the clipboard:
    set value of … to (the clipboard) as «class RTF»

Maybe, it will work directly, without clipboard:
set … to (read myStorie.rtf) as «class RTF»

NOTE: These are just my guesses at the moment, since I uninstalled InDesign. Perhaps I said nonsense here. :lol:

KniazidisR,

Thank you. It’s a good idea, but I’ll need to open the RTF, “select all” and “copy”, because the read command doesn’t read as RTF and will get the RTF tags too. Or at least I couldn’t make it happen. :slight_smile:

Anyway, tried here open RTF file, get text, set the clipboard, activate numbers and paste and it’s working. Thanks again!

It can:


set myRTFdata to (read (choose file of type "RTF") as «class RTF »)

I am puzzled.
After copying a piece of rtf datas I ran this simple script:

clipboard info
log result
get (the clipboard) as «class RTF »-- don't miss the space after RTF

The log history was :

tell application "Script Editor"
	clipboard info
		--> {{«class RTF », 1207}, {«class utf8», 19}, {«class ut16», 40}, {uniform styles, 624}, {string, 19}, {scrap styles, 82}, {Unicode text, 38}}
end tell
(*«class RTF », 1207, «class utf8», 19, «class ut16», 40, uniform styles, 624, string, 19, scrap styles, 82, Unicode text, 38*)
tell application "Script Editor"
	the clipboard
		--> "on clipboardAsRtf()"
Résultat :
error "Impossible de convertir \"on clipboardAsRtf()\" en type «class RTF »." number -1700 from "on clipboardAsRtf()" to «class RTF »

So I tried to use :

use AppleScript version "2.3.1"
use scripting additions
use framework "Foundation"
use framework "AppKit"

tell application "Numbers"
	tell document 1 to tell sheet 1
		
		set textItem to make text item
		
		set object text of textItem to my clipboardAsRtf()
		
		properties of every iWork item
	end tell
end tell

on clipboardAsRtf()
	set |⌘| to current application
	set theClipboard to |⌘|'s class "NSPasteboard"'s generalPasteboard()
	set clipboardContents to (theClipboard's readObjectsForClasses:{|⌘|'s class "NSAttributedString"} options:({}))'s mutableCopy()
	set theAttributedString to clipboardContents's firstObject()'s mutableCopy()
	
	tell theClipboard
		its clearContents()
		its writeObjects:{theAttributedString}
	end tell
	return the clipboard
end clipboardAsRtf

But the created box contains the datas as Unicode text with no color or font attributes.

How may I force the clipboard to pass only its rtf piece of data ?

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) lundi 20 avril 2020 15:53:55

use this:

clipboard info
log result
get (the clipboard as «class RTF ») -- don't miss the space after RTF

But, anyway, object text of Numbers.app with this RTF data for some reason does not work. Although the paste operation succeeds. My conclusion is that object text property is poorly programmed. I tried to set this property as rich text too. Nothing…

Thanks for the correct syntax

Try this:

tell application "Numbers"
	tell document 1 to tell sheet 1
		my pasteClipboard()
	end tell
end tell

on pasteClipboard()
	tell application "System Events" to tell process "Numbers"
		set frontmost to true
		tell window 1
			keystroke "v" using {command down}
		end tell
	end tell
end pasteClipboard

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) lundi 20 avril 2020 17:30:28

Hi again. Thank you to you two. Very nice solution.

I’ll just need to make it go thru all RTF files in a folder and I’m okay.

Thanks a lot.
Luiz

I started several intensive processes on my Mac at once to test the stability of the script. I achieved stability only like this:


set the clipboard to (read (choose file of type "RTF") as «class RTF »)
delay 5

tell application "System Events" to tell process "Numbers"
	set frontmost to true
	repeat until window 1 exists
		delay 0.02
	end repeat
	tell window 1 to keystroke "v" using {command down}
end tell

NOTE: here text item should be selected (focused) manually before running the script.

Then I found how to make the script be able to focused on the new text item automatically. Here is:


set the clipboard to (read (choose file of type "RTF") as «class RTF »)
delay 5

tell application "Numbers" to tell document 1 to tell sheet 1
	set textItem to make new text item
	repeat until textItem exists
		delay 0.02
	end repeat
	set object text of textItem to "placeholder"
end tell

tell application "System Events" to tell process "Numbers"
	set frontmost to true
	repeat until window 1 exists
		delay 0.02
	end repeat
	tell window 1 to keystroke "v" using {command down}
end tell

There is no need to create a text item before pasting.
As you may see in what I already posted, pasting creates such object.

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) lundi 20 avril 2020 19:56:41

Hi.

Yes, I’m using like this and it’s working fine:

set myRTFdata to (read ("/Users/(...)/StoryID5742.rtf") as «class RTF »)

set the clipboard to myRTFdata
clipboard info
log result
get (the clipboard as «class RTF »)


tell application "Numbers"
	tell document 1 to tell sheet 1
		set the value of cell "B2" of table 1 to ""
		
		my pasteClipboard()
	end tell
end tell

on pasteClipboard()
	tell application "System Events" to tell process "Numbers"
		set frontmost to true
		tell window 1
			keystroke return using {option down}
			keystroke "v" using {command down}
		end tell
	end tell
end pasteClipboard

I’ve included a “keystroke return using {option down}” so I can paste the whole text inside the cell.

Thanks a lot! Really.

You may try :

set myRTFdata to (read ("/Users/(...)/StoryID5742.rtf") as «class RTF »)

set the clipboard to myRTFdata

tell application "Numbers"
	tell document 1 to tell sheet 1 to tell table 1
		set selection range to range "B2"
		my pasteClipboard()
	end tell
end tell

on pasteClipboard()
	tell application "System Events" to tell process "Numbers"
		set frontmost to true
		tell window 1
			keystroke "v" using {command down}
		end tell
	end tell
end pasteClipboard

It will paste a group of paragraphs containing tab characters starting from the range selected before pasting.
I used that for years with Numbers version 2.3.
With version 6.1, the late version accepted by my machine, there is a huge problem.
Sometimes sentences are spread in different cells of a row with no apparent reason.
To get rid of that, I paste the datas in Numbers 2.3, save the document then, at last I open it with Numbers 6.1.
It’s boring but it works.
It seems that it’s what is called “progress" at Infinite Loop.

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) lundi 20 avril 2020 21:18:56

In my case, is better to include all text in the same cell. My flow here is:

  1. One script takes all text from Indesign and put in column B. One row for each text frame in Indesign (in most pages I have 1 text frame only, so it’s mostly one row per page). In column A I have the page number.

  2. After “extracting” all the text, I take a look at everything and check if it’s okay. Usually, nothing to do.

  3. The second script will go row by row in column B and split the text into sentences (breaking by “.”, “:”, “?”, “!” or a return), putting each sentence in one row in column C.

  4. My final result is column A with page numbers, column B with the full text of a page, column C with all sentences from that text.

It’s a very strange script, but it helps me a lot. If you want to take a look, it’s below. :slight_smile:

Thanks again,
Luiz


tell application "Numbers"
	activate
	
	tell table 1 of active sheet of document 1
		set selection range to range "B2" -- select place to start	
		set totalLinhas to row count
		set linhaFinal to 2
		
		repeat row count - 1 times
			
			set colunaInicial to 2
			set linhaInicial to linhaFinal
			
			-- get the text
			set celulaInicial to "B" & linhaFinal
			set theText to value of cell celulaInicial as string
			
			--- Start split text
			set tamanho to length of theText
			
			set myList to {}
			set corteInicio to 1
			
			repeat with textPosition from 1 to tamanho -- check start and end
				if text textPosition of theText = "." or text textPosition of theText = "?" or text textPosition of theText = "!" or text textPosition of theText = ":" or textPosition = tamanho then
					set myList to myList & text corteInicio thru (textPosition - 0) in theText
					set corteInicio to textPosition + 2
					
				else
					if text textPosition of theText = "
" then -- check for RETURN, in this case, it is a "\n"
						if text (textPosition - 1) of theText = "." or text (textPosition - 1) of theText = ":" or text (textPosition - 1) of theText = "?" or text (textPosition - 1) of theText = "!" then
							-- do nothing
						else
							set myList to myList & text (corteInicio - 0) thru (textPosition - 1) in theText
							set corteInicio to textPosition + 1
						end if
					else
						if text textPosition of theText = "
" then -- -- check for RETURN, in this case, it is a "\r"
							if text (textPosition - 1) of theText = "." or text (textPosition - 1) of theText = ":" or text (textPosition - 1) of theText = "?" or text (textPosition - 1) of theText = "!" then
								-- do nothing
							else
								set myList to myList & text (corteInicio - 0) thru (textPosition - 1) in theText
								set corteInicio to textPosition + 1
							end if
						end if
					end if
				end if
			end repeat
			
			
			------ end split ---- 
			
			set listSize to count of myList
			
			-- add rows ------- 
			repeat listSize - 1 times
				add row below row linhaInicial
			end repeat
			-------------------------------------------
			
			-- take every item and put in one row
			repeat with a from 1 to (length of myList)
				set linhaAtual to a + linhaFinal
				set theCurrentListItem to item a of myList
				set value of cell (colunaInicial + 1) of row (linhaAtual - 1) to theCurrentListItem
			end repeat
			
			-- merge column B and add row
			set thisRangeName to "B" & linhaInicial & ":" & "B" & (linhaInicial + listSize - 1)
			set the selection range to range thisRangeName
			try -- because if the source has only one sentence, will be just one row and won't merge
				merge range thisRangeName
			end try
			
			-- set range final
			set thisRangeName to "B" & (linhaInicial + listSize)
			try -- because if it will be the last row, it won't work
				set the selection range to range thisRangeName
			end try
			set linhaFinal to (linhaInicial + listSize)
			
		end repeat
		
	end tell
end tell