Discussion:
Replacing range of characters in TextFrame.Contents
(too old to reply)
A***@adobeforums.com
2007-01-10 13:48:48 UTC
Permalink
Hello,

I need to do such thing: replace a range of characters in TextFrame.Contents between start index and end index with another string. Lengths of these two string may vary.

For example:

Replace characters between 2 am 4 in TextFrame.Contents = "initial string", with string "REPLACEMENT". Result must be "iREPLACEMENTial string".

Can anybody, please, tell me how to do this?
P***@adobeforums.com
2007-01-10 14:16:14 UTC
Permalink
To replace just one character (as in your example), use this:

TextFrame.characters[1].contents = 'REPLACEMENT'




To replace a range of characters longer than 1, use something like this:

TextFrame.characters.itemByRange(2,6).contents = 'REPLACEMENT'




Peter
A***@adobeforums.com
2007-01-11 08:54:32 UTC
Permalink
Peter,

thanks for help.

Your code works perfectly in JavaScript.

The problem is, that in COM Characters.ItemByRange() returns not [Character] object, but [Objects] collection each element of which is [Character], so i can't assign to range, just to the single character :-/ Did anybody face with this problem or knows how to pass it around?

Alexey
Robert Tkaczyk
2007-01-11 18:07:36 UTC
Permalink
in VB:

myStory.Texts.ItemByRange _
( _
myStory.Characters.Item(start), _
myStory.Characters.Item(stop) _
).Item(1).Contents = "new text"

robin
--
www.adobescripts.com
A***@adobeforums.com
2007-01-12 08:53:00 UTC
Permalink
Robert,

In COM it changes not the range of characters, but first character in the range:

//frame.Contents is "initial string"

frame.Characters.ItemByRange(2, 10)[1].Contents = "REPLACEMENT" //(Type conversions are omitted).

//frame.Contents is "iREPLACEMENTitial string".

I am currently replacing 1st character in the range and deleting the rest, but hope that there is a better way

Alexey
Robert Tkaczyk
2007-01-12 23:44:41 UTC
Permalink
what COM ??

robin
--
www.adobescripts.com
A***@adobeforums.com
2007-01-16 08:53:22 UTC
Permalink
InDesign Server CS2 can be automated through its COM component. Its interfaces correspond to object model in scripting languages. Though it seems that some functions (like Characters.ItemByRange()) of some interfaces works in different way to scripting languages
O***@adobeforums.com
2007-01-16 20:05:10 UTC
Permalink
Hi Alexey,

There's a better way. When you ask for an object using ItemByRange, you get back the type of object you ask for. Therefore, when you use Characters.ItemByRange you get a collection of characters. Instead, use Texts.ItemByRange, as shown in the following example:



Rem TextItemByRange.vbs
Rem Replaces a specific range of characters in a paragraph.
Rem
Set myInDesign = CreateObject("InDesign.Application.CS2")
Set myDocument = myInDesign.Documents.Add
Rem Create a text frame on page 1.
Set myTextFrame = myDocument.Pages.Item(1).TextFrames.Add
Rem Set the bounds of the text frame.
myTextFrame.GeometricBounds = myGetBounds(myDocument, myDocument.Pages.Item(1))
Rem Fill the text frame with placeholder text.
myTextFrame.Contents = idTextFrameContents.idPlaceholderText
Set myStory = myDocument.Stories.Item(1)
Set myStartCharacter = myStory.Paragraphs.Item(2).Characters.Item(1)
Set myEndCharacter = myStory.Paragraphs.Item(2).Characters.Item(-2)
Set myText = myStory.Texts.ItemByRange(myStartCharacter, myEndCharacter).Item(1)
myText.Contents = "This text replaces the text of paragraph 2."
Function myGetBounds(myDocument, myPage)
myPageWidth = myDocument.DocumentPreferences.PageWidth
myPageHeight = myDocument.DocumentPreferences.PageHeight
If myPage.Side = idPageSideOptions.idLeftHand Then
myX2 = myPage.MarginPreferences.Left
myX1 = myPage.MarginPreferences.Right
Else
myX1 = myPage.MarginPreferences.Left
myX2 = myPage.MarginPreferences.Right
End If
myX2 = myPageWidth - myX2
myY1 = myPage.MarginPreferences.Top
myY2 = myPageHeight - myPage.MarginPreferences.Bottom
myGetBounds = Array(myY1, myX1, myY2, myX2)
End Function

Thanks,

Ole
A***@adobeforums.com
2007-01-31 14:06:26 UTC
Permalink
Ole,

thank you, your tip helped me a lot.

I wouldn't find this solution myself: in scripting reference it isn't mentioned, that Texts.ItemByRange can get Character objects as parameters. In addition, in my case, ItemByRange can return various type of objects (Text, Paragraph, Character etc)

My code for obtaining Text is:

...
IDS.Character startCharacter = textFrame.Characters[startCharacterIndex] as IDS.Character;
IDS.Character endCharacter = textFrame.Characters[endCharacterIndex] as IDS.Character;

IDS.Text resultText = null;
object range = textFrame.Texts.ItemByRange(startCharacter, endCharacter)[1];
if (range is IDS.Text)
resultText = range as IDS.Text;
else if (range is IDS.Paragraph)
resultText = (range as IDS.Paragraph).Texts[1] as IDS.Text;
else if (range is IDS.TextStyleRange)
resultText = (range as IDS.TextStyleRange).Texts[1] as IDS.Text;
else if (range is IDS.Character)
resultText = (range as IDS.Character).Texts[1] as IDS.Text;
else if (range is IDS.Word)
resultText = (range as IDS.Word).Texts[1] as IDS.Text;
else if (range is IDS.Line)
resultText = (range as IDS.Line).Texts[1] as IDS.Text;
else if (range is IDS.TextColumn)
resultText = (range as IDS.TextColumn).Texts[1] as IDS.Text;

Alexey
Robert Tkaczyk
2007-02-05 18:52:16 UTC
Permalink
Do your language support TypeName(variable) and Select..Case ??

Select Case TypeName(IDS)
Case "Text":
Case "Paragraph":
Case "Characters":
...
End Select

robin
--
www.adobescripts.com
Loading...