• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

How to Anchor a Text Frame to a Specific Character Style in InDesign Scripting

Enthusiast ,
Oct 02, 2024 Oct 02, 2024

Copy link to clipboard

Copied

Hi

I have a requirement to anchor a text frame with numbers in it to a text where a particular character style is applied.  The text frame which needs to be anchored has a paragraph style and an object style applied to it.

 

I have attached a screenshot and and IDML file also.

 

Here is the code:

 

//First copy the text frame with object style applied to it.
//This frame will be anchored at the word/sentence with a particular character style

// Get the active document
var doc = app.activeDocument;

//Get the object style
var objectStyle = doc.objectStyles.itemByName("boxedObject");

//Change object style setting
objectStyle.anchoredObjectSettings.anchoredPosition = AnchorPosition.ANCHORED;
objectStyle.anchoredObjectSettings.anchorPoint = AnchorPoint.TOP_LEFT_ANCHOR;
objectStyle.anchoredObjectSettings.horizontalReferencePoint = AnchoredRelativeTo.ANCHOR_LOCATION;


//Reset findchange grep preferences
app.findGrepPreferences = app.changeGrepPreferences = null;

//find one or more words separated by a space
app.findGrepPreferences.findWhat="\\w+(?:\\s\\w+)*";

//Filter the search for a particular character style
app.findGrepPreferences.appliedCharacterStyle = "boxedul";

//Paste the copied textframe back
app.changeGrepPreferences.changeTo="~c$0";

//Execute the find change
var found = doc.changeGrep();

 

 

All is working fine except that I am unable to change the width of the anchored textframe as per the width of the text where a particular character style is appiled. I believe the screenshot attached will make my question more clear .

 

I am unable to write that last part of the code. It seems be way above my knowlege.

Thanks

 

 

<Title renamed by MOD>

TOPICS
How to , Scripting

Views

305

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
community guidelines

correct answers 3 Correct answers

Enthusiast , Oct 02, 2024 Oct 02, 2024

Ok. I have managed to achieve what I want. I just needs little fine-tuning.

 

Here is the updated code just in case if anyone needs it.

 

// Get the active document
var doc = app.activeDocument;

//Filter the search for a particular character style
app.findGrepPreferences.appliedCharacterStyle = "boxedul";

//Execute the find change
var found = doc.findGrep();

//Reset findchange grep preferences
app.findGrepPreferences = app.changeGrepPreferences = null;


for(i=found.length-1;i >=0;i--){
tf = foun
...

Votes

Translate

Translate
Community Expert , Oct 04, 2024 Oct 04, 2024

Hi @shahidr100, you have done a marvelous job here. Your scripting skills are really improving!

 

For your learning, I have cleaned up your code a little bit (not too much!) and also included a slightly modified demo document (I moved some of the scripted properties into the Object Style).

- Mark

 

/**
 * @file Add Numbered Boxes Below Text.js
 * @author sharhidr100 (modified by m1b)
 * @discussion https://community.adobe.com/t5/indesign-discussions/how-to-anchor-a-text-frame-to-a-specific-chara
...

Votes

Translate

Translate
Community Expert , Oct 04, 2024 Oct 04, 2024

I am pleased it was helpful. Yes I like to put my Indesign scripts through the `doScript` method which consolidates the actions into a single Undo.

 

I've adjusted the script to work with either selected text frames, or selected text or, if nothing is selected, then the whole document. I hope you can see how I did it here:

/**
 * @File Add Numbered Boxes Below Text.js
 * @author sharhidr100 and m1b
 * @discussion https://community.adobe.com/t5/indesign-discussions/how-to-anchor-a-text-frame-to-a
...

Votes

Translate

Translate
Enthusiast ,
Oct 02, 2024 Oct 02, 2024

Copy link to clipboard

Copied

For some reason the last line doc.changeGrep() is not working properly I guess.

 

I added following lines at the last:

for(i=0;i<found.length;i++){
alert(found[i].horizontalOffset);
alert(found[i].endHorizontalOffset);
alert(found[i].contents);

 

It is not showing the whole matched text. Following text is printed after adding the lines:

"underli" and "pt whic"

It should match "underline selection" and "written". I dont know where "pt whic" came from. It does not have "boxedul" character style applied.

 

Votes

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
community guidelines
Enthusiast ,
Oct 02, 2024 Oct 02, 2024

Copy link to clipboard

Copied

Ok. I have managed to achieve what I want. I just needs little fine-tuning.

 

Here is the updated code just in case if anyone needs it.

 

// Get the active document
var doc = app.activeDocument;

//Filter the search for a particular character style
app.findGrepPreferences.appliedCharacterStyle = "boxedul";

//Execute the find change
var found = doc.findGrep();

//Reset findchange grep preferences
app.findGrepPreferences = app.changeGrepPreferences = null;


for(i=found.length-1;i >=0;i--){
tf = found[i].insertionPoints[0].textFrames.add();
    tf.properties =
    {
      geometricBounds :[0,found[i].horizontalOffset,2,found[i].endHorizontalOffset],
      strokewidth: 0,
      fillColor : "None",
      appliedObjectStyle: doc.objectStyles.item("boxedObject")
    };
		
    tf.anchoredObjectSettings.properties = {
      anchoredPosition: AnchorPosition.ANCHORED,
      anchorPoint : AnchorPoint.TOP_LEFT_ANCHOR,
      verticalReferencePoint : AnchoredRelativeTo.ANCHOR_LOCATION
    };

}

Votes

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
community guidelines
Community Expert ,
Oct 04, 2024 Oct 04, 2024

Copy link to clipboard

Copied

Hi @shahidr100, you have done a marvelous job here. Your scripting skills are really improving!

 

For your learning, I have cleaned up your code a little bit (not too much!) and also included a slightly modified demo document (I moved some of the scripted properties into the Object Style).

- Mark

 

/**
 * @file Add Numbered Boxes Below Text.js
 * @author sharhidr100 (modified by m1b)
 * @discussion https://community.adobe.com/t5/indesign-discussions/how-to-anchor-a-text-frame-to-a-specific-character-style-in-indesign-scripting/m-p/14894001
 */
function main() {

    // Get the active document
    var doc = app.activeDocument;

    // Reset find grep preferences
    app.findGrepPreferences = NothingEnum.NOTHING;

    // Filter the search for a particular character style
    app.findGrepPreferences.appliedCharacterStyle = "boxedul";

    // Execute the find change
    var found = doc.findGrep();

    for (var i = found.length - 1, tf; i >= 0; i--) {
        tf = found[i].insertionPoints[0].textFrames.add();
        tf.properties = {
            geometricBounds: [0, found[i].horizontalOffset, 2, found[i].endHorizontalOffset],
            appliedObjectStyle: doc.objectStyles.item("boxedObject"),
            contents: ' ',
        };
    }

};
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Make Numbered Boxes');

 

Votes

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
community guidelines
Enthusiast ,
Oct 04, 2024 Oct 04, 2024

Copy link to clipboard

Copied

@m1b Thank you so much. It because of this group and people like you that I have come this far in scripting.

 

I still face lot of issues while scripting but gradually picking up.

 

I wanted to to make this script work for only the selected text. Looking for what options do I have in this kind of situation.

 

I have kept your script as a final copy. It actually is great because a single Ctrl Z takes care of undo of the entire script.

 

Thanks once again @m1b 

Votes

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
community guidelines
Community Expert ,
Oct 04, 2024 Oct 04, 2024

Copy link to clipboard

Copied

I am pleased it was helpful. Yes I like to put my Indesign scripts through the `doScript` method which consolidates the actions into a single Undo.

 

I've adjusted the script to work with either selected text frames, or selected text or, if nothing is selected, then the whole document. I hope you can see how I did it here:

/**
 * @File Add Numbered Boxes Below Text.js
 * @author sharhidr100 and m1b
 * @discussion https://community.adobe.com/t5/indesign-discussions/how-to-anchor-a-text-frame-to-a-specific-character-style-in-indesign-scripting/m-p/14894001
 */
function main() {

    // Get the active document
    var doc = app.activeDocument,
        items = doc.selection;

    if (0 === items.length) {
        // whole document
        addNumberedTextBoxes(doc);
    }

    else {
        // selected items
        for (var i = 0; i < items.length; i++)
            addNumberedTextBoxes(doc, items[i]);
    }

};
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Make Numbered Boxes');

/**
 * Adds numbered boxes to text of `target`.
 * Removes existing numbered boxes first.
 * If no `target` is given, then perform
 * function on whole document `doc`.
 * @author sharhidr100 and m1b
 * @version 2024-10-04
 * @Param {Document} doc - an Indesign Document.
 * @Param {TextFrame|Text} [target] - add numbered boxes to this object (default: doc).
 */
function addNumberedTextBoxes(doc, target) {

    const BOX_OBJECT_STYLE_NAME = 'boxedObject',
        UNDERLINE_CHARACTER_STYLE_NAME = 'boxedul';

    target = target || doc;

    if (
        undefined == target.findGrep
        || !target.hasOwnProperty('textFrames')
    )
        // Can't use this item
        return;

    // Remove existing boxes
    var found = (target.hasOwnProperty('stories'))
        ? target.stories.everyItem().textFrames.everyItem().getElements()
        : target.textFrames;

    for (var i = found.length - 1; i >= 0; i--)
        if (BOX_OBJECT_STYLE_NAME === found[i].appliedObjectStyle.name)
            found[i].remove();

    // Reset find grep preferences
    app.findGrepPreferences = NothingEnum.NOTHING;

    // Filter the search for a particular character style
    app.findGrepPreferences.appliedCharacterStyle = UNDERLINE_CHARACTER_STYLE_NAME;

    // Perform the find
    found = target.findGrep();

    for (var i = found.length - 1, tf; i >= 0; i--) {

        // Add the box
        tf = found[i].insertionPoints[0].textFrames.add();
        tf.properties = {
            geometricBounds: [0, found[i].horizontalOffset, 2, found[i].endHorizontalOffset],
            appliedObjectStyle: doc.objectStyles.item(BOX_OBJECT_STYLE_NAME),
            contents: ' ',
        };

    }

};

Votes

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
community guidelines
Enthusiast ,
Oct 04, 2024 Oct 04, 2024

Copy link to clipboard

Copied

LATEST

@m1b Wow!! I have no words to express my thanks. Such a neat and clean code.

 

In the mean time I was trying to achieve the same thing using app.Selection[0] but was not successfull.

 

I am going to study your code try to understand.

 

Thanks a ton @m1b 

Votes

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
community guidelines