Copy link to clipboard
Copied
Using InDesign CS6 (ya I know it's old) on Windows.
I need to use a script to move some specific characters in some text.
I have created the text, converted the text to outlines, ungrouped the outlines, and released the compound paths.
Then I located only the paths I need to move and ran
path_first.makeCompoundPath(paths);
When I do this via the GUI, a hole appears wherever selected paths overlap. When I do this via the script, the hole does not appear, so letters like a, p, b, etc, don't work properly.
Any suggestions would be appreciated, either to fix my compound path issue, or suggest some other way to move specific characters to a specific x,y position.
There is not really, without outlines. Theoretically, I suppose you could do some complicated math looking at a containing TextFrame's bounds, iterating through its Lines and checking the horizontalOffset of its characters. But there's gotta be an easier way. For instance, you can use a Grep search to find the target Texts:
//find three digits in a row with a Character Style "PageNumber" applied
app.findGrepPreferences.findWhat = "\d{3}";
app.findGrepPreferences.appliedCharacterStyle = "PageN
...
Copy link to clipboard
Copied
Update: it seems to work properly if I select everything and click Object, Paths, Open Path. Now to figure out how to script that. openPath does not seem to be a function. Ideas?
Copy link to clipboard
Copied
I would not mess with outlines. There are lots of ways to move text around. You mostly do it by navigating Story, TextFrame, Text, Paragraph, Character and InsertionPoint and Contents objects. The following would move the first three characters from the first text frame in the document to the last three.
var tf = app.activeDocument.textFrames[0];
var firstChars = tf.characters.itemByRange(0,3);
tf.insertionPoints[-1].contents += firstChars.contents;
firstChars.remove();
You also have to be mindful of Character and Paragraph Styles when using Contents, since it's just a raw string. You can also use the move method. Similar as above:
var tf = app.activeDocument.textFrames[0];
tf.characters.itemByRange(0,3).move(LocationOptions.AFTER, tf.insertionPoints[-1]);
Copy link to clipboard
Copied
Thank you for reply. I could do that, but I need to find out where the characters are. Is there a way to get the x,y coordinates of a specific character?
Something like tf.characters.item(1).geometricBounds (but that did not work).
Copy link to clipboard
Copied
There is not really, without outlines. Theoretically, I suppose you could do some complicated math looking at a containing TextFrame's bounds, iterating through its Lines and checking the horizontalOffset of its characters. But there's gotta be an easier way. For instance, you can use a Grep search to find the target Texts:
//find three digits in a row with a Character Style "PageNumber" applied
app.findGrepPreferences.findWhat = "\d{3}";
app.findGrepPreferences.appliedCharacterStyle = "PageNumber";
var myFinds = app.activeDocument.findGrep();
//findGrep will always return an array with all the matches
for (var i = 0; i < myFinds.length; i++) {
myFinds[i].move(...)
}
If you provide more detail of exactly the process you're looking to script, we can provide better guidance.
Copy link to clipboard
Copied
Dude, I could kiss you. But, don't worry - I won't.
var tf = app.activeDocument.textFrames[0];
var ch = tf.characters.item(2);
alert("The coordinates are (" +
ch.horizontalOffset + ", " +
(ch.baseline - ch.ascent) + "), (" +
ch.endHorizontalOffset + ", " +
(ch.baseline + ch.descent) + ")"
);
Now that I can find the x,y coordinates of a character, I don't have to convert the text to outlines!
> If you provide more detail of exactly the process you're looking to script, we can provide better guidance.
Trying to automate the process of creating lyric music videos. Your suggestion will save me so much time.
Copy link to clipboard
Copied
That's an interesting way to approach it! Glad I could help you get there.
Copy link to clipboard
Copied
Hi Mango123456,
you could also do a outline of a single character as duplicate and leave the text alive.
Doing a duplicate is an argument of the method createOutlines().
Just test this:
Have some text in a text frame and convert the first 5 characters to outline duplicates one by one:
var textFrame = app.selection[0];
for( var n=0; n<5; n++ )
{
var currentCharacter = textFrame.characters[n] ;
try
{
// createOutlines() always creates an array.
// In this case it should be of length 1
// Argument false will do a duplicate:
var outlinedChar = currentCharacter.createOutlines( false )[0] ;
$.writeln( n +"\t"+ outlinedChar +"\t"+ outlinedChar.geometricBounds ) ;
}catch(e){ /* Expected error if the character is a white space */ }
};
FWIW: In case the text frame is rotated, the result polygon is also rotated.
Before exploiting the geometricBounds to calculate width and height rotate it back to 0.
Regards,
Uwe Laubender
( ACP )