Highlighted

InDesign CS6 scripting - make compound paths doesn't work the same way as the GUI

Community Beginner ,
Jul 11, 2020

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.

Adobe Community Professional
Correct answer by brianp311 | Adobe Community Professional

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. 

 

TOPICS
Scripting

Views

153

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more

InDesign CS6 scripting - make compound paths doesn't work the same way as the GUI

Community Beginner ,
Jul 11, 2020

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.

Adobe Community Professional
Correct answer by brianp311 | Adobe Community Professional

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. 

 

TOPICS
Scripting

Views

154

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Jul 11, 2020 0
Community Beginner ,
Jul 11, 2020

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?

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Jul 11, 2020 0
Adobe Community Professional ,
Jul 12, 2020

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]);

 

 

 

 

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Jul 12, 2020 1
Community Beginner ,
Jul 12, 2020

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).

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Jul 12, 2020 0
Adobe Community Professional ,
Jul 12, 2020

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. 

 

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Jul 12, 2020 1
Community Beginner ,
Jul 12, 2020

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.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Jul 12, 2020 0
Adobe Community Professional ,
Jul 12, 2020

Copy link to clipboard

Copied

That's an interesting way to approach it! Glad I could help you get there. 

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Jul 12, 2020 0
Adobe Community Professional ,
Jul 13, 2020

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 )

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Jul 13, 2020 0