Reputation: 3825
I need to navigate and extract the content of a TextFrame
; this means: the text, with its styles, the variables and the inner pageItems.
I can list all paragraphs, and for each paragraph I can get the TextStyleRanges
(see this question), but their content
won't contain variables' values nor pageItems.
I can list all textVariableInstances
, but that won't tell me where they are inside the text.
Similarly, I can list pageItems
, but without reference to where they are with regard to text.
Sometimes (only sometimes) I get a range comprehending just one character, and in that case I can get variables and pageItems; but since it isn't always the case, this is not the solution.
I can iterate all characters of a paragraph, thus getting everything I need, but this seems to be too damn slow.
What am I missing?
How can I get all text and non-text parts of a paragraph in their intended order?
EDIT
Dirk's suggestion works, actually, but apparently only if I access textVariableInstances
from the TextFrame. I was accessing it from a Text within a TextStyleRange within a Paragraph within a TextFrame, because I'm trying to recursively traverse and convert the document. In a Text object I have textVariableInstances, but their storyOffset
property lacks the properties isValid
, toSpecifier
, index
and who knows how many others.
So, I guess my question now is: to know where the variableInstance is within a Text object, can I reliably use something like:
myVariableInstance.storyOffset.index - myText.insertionPoints[0].index
so that I can replace the corresponding char with the variable's resultText
value?
Upvotes: 1
Views: 452
Reputation: 666
The storyOffset property of your textVariableInstance yields an insertionPoint, whose index is the actual numeric offset inside the containing story. the storyOffset property is available on many other objects that can be placed within text.
For anchored page items use the parent property instead - it will yield a character.
var t = app.activeDocument.textFrames.item(0);
$.writeln(t.textVariableInstances.item(0).storyOffset.index);
$.writeln(t.rectangles.item(0).parent.index);
EDIT
Following your edit, you must be doing something wrong how you build the Text. As already suggested, you can use isValid and toSpecifier() in the debugger to find out where it breaks.
The following code works for me, but for a generic approach you'll need to consider plenty more things that can be embedded within text, e.g. special characters including the various paragraph ends, hyperlinks, xml elements, anchored page items.
#target indesign-8.0
function main() {
var doc = app.activeDocument;
for( var fi=0; fi<doc.textFrames.length; fi++ ) {
var f = app.activeDocument.textFrames.item(fi);
var s = f.parentStory;
for( var pi=0; pi<f.paragraphs.length; pi++ ) {
var p = f.paragraphs.item(pi);
var pl = p.characters.lastItem();
for( var ri=0; ri<p.textStyleRanges.length; ri++ ) {
var r = p.textStyleRanges.item(ri);
var rf = r.characters.firstItem();
var rl = r.characters.lastItem();
var t = r;
if( rl.index>pl.index ) // range goes beyond paragraph
t = s.texts.itemByRange(rf,pl);
$.writeln("text=",t.contents);
if( t.textVariableInstances.length>0 ) {
var tv = t.textVariableInstances.item(0);
$.writeln("variable=",tv.name," ",tv.storyOffset.index);
}
}
$.writeln("\\n");
}
}
}
main();
Upvotes: 2