Skip to main content
dublove
Legend
March 23, 2025
Answered

Is it possible to extract the 001-01 between “@001-01@” in the text and apply the objectstyle?

  • March 23, 2025
  • 2 replies
  • 762 views

The object style aa is also created automatically, and the paragraph style "for aa" is applied to the text.

 I have set up the positioning of the object and the frame auto-fit, as well as the coloring.

It's created automatically first, and I'll follow up by manually modifying the styles myself.

 

Thank you.

 


 

Correct answer m1b

Hi @dublove to replicate what your demo document shows, how about this?

- Mark

 

/**
 * @file Find Anchor Codes.js
 *
 * Finds text bracketed by "@" and moves it into
 * an anchored text frame with an object style.
 *
 * Adjust the `settings` object as needed.
 *
 * @author m1b
 * @version 2025-03-25
 * @discussion https://community.adobe.com/t5/indesign-discussions/is-it-possible-to-extract-the-001-01-between-001-01-in-the-text-and-apply-the-objectstyle/m-p/15226880
 */
function main() {

    app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;

    var doc = app.activeDocument;

    // change this as needed
    var settings = {
        findWhat: '\\s*@([^@]+)@\\s*',
        changeToA: '$1', // text to appear in anchored frames
        changeToB: ' ', // add a space to replace the codes
        anchoredObjectStyleName: 'aa', // will create this if necessary
        paragraphStyleName: 'for aa', // will create this if necessary
        frameColorName: 'for aa', // will create this if necessary
        targets: getStoriesOrDocument(doc),
        showResult: true,
    };

    var targets = settings.targets;

    if ('Document' === targets.constructor.name) {

        if (!confirm('Do you want to process the whole document?'))
            return;

        // store document in an array for processing
        var targets = [targets];

    }

    // set up document first
    var anchoredFrameStyle = getAnchoredObjectStyle(doc, settings.anchoredObjectStyleName);

    // set up grep
    app.findGrepPreferences = app.changeGrepPreferences = NothingEnum.NOTHING;
    app.findGrepPreferences.findWhat = settings.findWhat;

    // process each target
    var counter = 0;
    for (var i = 0; i < targets.length; i++) {
        var target = targets[i];

        if ('function' !== typeof target.changeGrep)
            continue;

        // find the codes
        var found = target.findGrep();

        // process each found code
        for (var j = found.length - 1; j >= 0; j--) {

            var index = found[j].characters[0].index;
            var contents = found[j].contents;

            // add the anchored text frame
            var frame = found[j].parentStory.insertionPoints[index].textFrames.add({
                appliedObjectStyle: anchoredFrameStyle,
                contents: contents,
            });

            if (frame.overflows) {
                frame.remove();
                continue;
            }

            app.changeGrepPreferences.changeTo = settings.changeToA;
            frame.changeGrep();

            counter++;

        }

        // remove the original codes
        app.changeGrepPreferences.changeTo = settings.changeToB;
        target.changeGrep();

    }

    if (settings.showResult)
        alert('Found ' + counter + ' codes.');


    /**
     * Returns a custom object style.
     * Note: Will create swatches and
     * paragraph style if necessary.
     * @author m1b
     * @version 2025-03-25
     * @returns {ObjectStyle}
     */
    function getAnchoredObjectStyle() {

        var objectStyle = getThing(doc.allObjectStyles, 'name', settings.anchoredObjectStyleName);

        if (objectStyle)
            // don't need to do anything else
            return objectStyle;

        // 1. get the paragraph style

        var paragraphStyle = getThing(doc.allParagraphStyles, 'name', settings.paragraphStyleName);

        if (!paragraphStyle) {

            // create the paragraph style
            paragraphStyle = doc.paragraphStyles.add({
                name: settings.paragraphStyleName,
                appliedFont: 'Arial',
                fontStyle: 'Regular',
                pointSize: 12,
                leading: 14,
                fillColor: 'Paper',
            });

        }

        // 2. get the frame color

        var frameColor = getThing(doc.colorGroups.everyItem().colorGroupSwatches.everyItem().swatchItemRef, 'name', settings.frameColorName);

        if (!frameColor) {

            // create the color
            frameColor = doc.colors.add({
                name: settings.frameColorName,
                space: ColorSpace.CMYK,
                model: ColorModel.PROCESS,
                colorValue: [0, 100, 0, 0],
            });

        }

        // 2. create the object style

        objectStyle = doc.objectStyles.add({
            name: settings.anchoredObjectStyleName,
            basedOn: "[None]",
            enableFrameFittingOptions: true,
            enableAnchoredObjectOptions: true,
            enableFill: true,
            enableParagraphStyle: true,
            enableStroke: false,
            enableStrokeAndCornerOptions: false,
            enableTextFrameAutoSizingOptions: true,
            enableTextFrameGeneralOptions: true,
            enableTextWrapAndOthers: false,
            appliedParagraphStyle: paragraphStyle,
            fillColor: frameColor,
        });

        objectStyle.textFramePreferences.properties = {
            autoSizingType: AutoSizingTypeEnum.HEIGHT_AND_WIDTH,
            autoSizingReferencePoint: AutoSizingReferenceEnum.LEFT_CENTER_POINT,
            insetSpacing: 1,
            useNoLineBreaksForAutoSizing: true,
        };

        objectStyle.anchoredObjectSettings.properties = {
            anchorPoint: AnchorPoint.BOTTOM_LEFT_ANCHOR,
            anchorSpaceAbove: 0,
            anchorXoffset: 0,
            anchorYoffset: -14.17325, // 5 mm
            anchoredPosition: AnchorPosition.ANCHORED,
            horizontalAlignment: HorizontalAlignment.LEFT_ALIGN,
            horizontalReferencePoint: AnchoredRelativeTo.ANCHOR_LOCATION,
            lockPosition: false,
            pinPosition: false,
            verticalAlignment: VerticalAlignment.BOTTOM_ALIGN,
            verticalReferencePoint: VerticallyRelativeTo.LINE_BASELINE,
        };

        return objectStyle;

    };

};
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Find Anchor Codes');

/**
 * Returns a thing with matching property.
 * If `key` is undefined, evaluate the object itself.
 * @author m1b
 * @version 2024-04-21
 * @param {Array|Collection} things - the things to look through.
 * @param {String} [key] - the property name (default: undefined).
 * @param {*} value - the value to match.
 * @returns {*?} - the thing, if found.
 */
function getThing(things, key, value) {

    for (var i = 0, obj; i < things.length; i++)
        if ((undefined == key ? things[i] : things[i][key]) == value)
            return things[i];

};

/**
 * Returns the document's selected
 * stories or the document itself.
 * @author m1b
 * @version 2025-03-25
 * @param {Document} doc - an Indesign Document.
 * @returns {Array<Story>|Document}
 */
function getStoriesOrDocument(doc) {

    var stories = [],
        unique = {},
        items = doc.selection;

    if (0 === items.length)
        return doc;

    for (var i = 0; i < items.length; i++) {

        if (items[i].hasOwnProperty('parentStory')) {

            if (unique[items[i].parentStory.id])
                // already collected this story
                continue;

            unique[items[i].parentStory.id] = true;
            items[i] = items[i].parentStory;
        }

        if ('function' === typeof items[i].changeGrep)
            stories.push(items[i]);

    }

    return stories;

};

 

Edit 2025-03-24: added check for overflows (when object style doesn't set the width correctly) and improved spaces left in main text after execution.

Edit 2025-03-24: added code to create the object style if necessary.

Edit 2025-03-25: added code to get the styles closer to what OP wanted. Also implemented getStoriesOrDocument.

2 replies

m1b
Community Expert
m1bCommunity ExpertCorrect answer
Community Expert
March 23, 2025

Hi @dublove to replicate what your demo document shows, how about this?

- Mark

 

/**
 * @file Find Anchor Codes.js
 *
 * Finds text bracketed by "@" and moves it into
 * an anchored text frame with an object style.
 *
 * Adjust the `settings` object as needed.
 *
 * @author m1b
 * @version 2025-03-25
 * @discussion https://community.adobe.com/t5/indesign-discussions/is-it-possible-to-extract-the-001-01-between-001-01-in-the-text-and-apply-the-objectstyle/m-p/15226880
 */
function main() {

    app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;

    var doc = app.activeDocument;

    // change this as needed
    var settings = {
        findWhat: '\\s*@([^@]+)@\\s*',
        changeToA: '$1', // text to appear in anchored frames
        changeToB: ' ', // add a space to replace the codes
        anchoredObjectStyleName: 'aa', // will create this if necessary
        paragraphStyleName: 'for aa', // will create this if necessary
        frameColorName: 'for aa', // will create this if necessary
        targets: getStoriesOrDocument(doc),
        showResult: true,
    };

    var targets = settings.targets;

    if ('Document' === targets.constructor.name) {

        if (!confirm('Do you want to process the whole document?'))
            return;

        // store document in an array for processing
        var targets = [targets];

    }

    // set up document first
    var anchoredFrameStyle = getAnchoredObjectStyle(doc, settings.anchoredObjectStyleName);

    // set up grep
    app.findGrepPreferences = app.changeGrepPreferences = NothingEnum.NOTHING;
    app.findGrepPreferences.findWhat = settings.findWhat;

    // process each target
    var counter = 0;
    for (var i = 0; i < targets.length; i++) {
        var target = targets[i];

        if ('function' !== typeof target.changeGrep)
            continue;

        // find the codes
        var found = target.findGrep();

        // process each found code
        for (var j = found.length - 1; j >= 0; j--) {

            var index = found[j].characters[0].index;
            var contents = found[j].contents;

            // add the anchored text frame
            var frame = found[j].parentStory.insertionPoints[index].textFrames.add({
                appliedObjectStyle: anchoredFrameStyle,
                contents: contents,
            });

            if (frame.overflows) {
                frame.remove();
                continue;
            }

            app.changeGrepPreferences.changeTo = settings.changeToA;
            frame.changeGrep();

            counter++;

        }

        // remove the original codes
        app.changeGrepPreferences.changeTo = settings.changeToB;
        target.changeGrep();

    }

    if (settings.showResult)
        alert('Found ' + counter + ' codes.');


    /**
     * Returns a custom object style.
     * Note: Will create swatches and
     * paragraph style if necessary.
     * @author m1b
     * @version 2025-03-25
     * @returns {ObjectStyle}
     */
    function getAnchoredObjectStyle() {

        var objectStyle = getThing(doc.allObjectStyles, 'name', settings.anchoredObjectStyleName);

        if (objectStyle)
            // don't need to do anything else
            return objectStyle;

        // 1. get the paragraph style

        var paragraphStyle = getThing(doc.allParagraphStyles, 'name', settings.paragraphStyleName);

        if (!paragraphStyle) {

            // create the paragraph style
            paragraphStyle = doc.paragraphStyles.add({
                name: settings.paragraphStyleName,
                appliedFont: 'Arial',
                fontStyle: 'Regular',
                pointSize: 12,
                leading: 14,
                fillColor: 'Paper',
            });

        }

        // 2. get the frame color

        var frameColor = getThing(doc.colorGroups.everyItem().colorGroupSwatches.everyItem().swatchItemRef, 'name', settings.frameColorName);

        if (!frameColor) {

            // create the color
            frameColor = doc.colors.add({
                name: settings.frameColorName,
                space: ColorSpace.CMYK,
                model: ColorModel.PROCESS,
                colorValue: [0, 100, 0, 0],
            });

        }

        // 2. create the object style

        objectStyle = doc.objectStyles.add({
            name: settings.anchoredObjectStyleName,
            basedOn: "[None]",
            enableFrameFittingOptions: true,
            enableAnchoredObjectOptions: true,
            enableFill: true,
            enableParagraphStyle: true,
            enableStroke: false,
            enableStrokeAndCornerOptions: false,
            enableTextFrameAutoSizingOptions: true,
            enableTextFrameGeneralOptions: true,
            enableTextWrapAndOthers: false,
            appliedParagraphStyle: paragraphStyle,
            fillColor: frameColor,
        });

        objectStyle.textFramePreferences.properties = {
            autoSizingType: AutoSizingTypeEnum.HEIGHT_AND_WIDTH,
            autoSizingReferencePoint: AutoSizingReferenceEnum.LEFT_CENTER_POINT,
            insetSpacing: 1,
            useNoLineBreaksForAutoSizing: true,
        };

        objectStyle.anchoredObjectSettings.properties = {
            anchorPoint: AnchorPoint.BOTTOM_LEFT_ANCHOR,
            anchorSpaceAbove: 0,
            anchorXoffset: 0,
            anchorYoffset: -14.17325, // 5 mm
            anchoredPosition: AnchorPosition.ANCHORED,
            horizontalAlignment: HorizontalAlignment.LEFT_ALIGN,
            horizontalReferencePoint: AnchoredRelativeTo.ANCHOR_LOCATION,
            lockPosition: false,
            pinPosition: false,
            verticalAlignment: VerticalAlignment.BOTTOM_ALIGN,
            verticalReferencePoint: VerticallyRelativeTo.LINE_BASELINE,
        };

        return objectStyle;

    };

};
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Find Anchor Codes');

/**
 * Returns a thing with matching property.
 * If `key` is undefined, evaluate the object itself.
 * @author m1b
 * @version 2024-04-21
 * @param {Array|Collection} things - the things to look through.
 * @param {String} [key] - the property name (default: undefined).
 * @param {*} value - the value to match.
 * @returns {*?} - the thing, if found.
 */
function getThing(things, key, value) {

    for (var i = 0, obj; i < things.length; i++)
        if ((undefined == key ? things[i] : things[i][key]) == value)
            return things[i];

};

/**
 * Returns the document's selected
 * stories or the document itself.
 * @author m1b
 * @version 2025-03-25
 * @param {Document} doc - an Indesign Document.
 * @returns {Array<Story>|Document}
 */
function getStoriesOrDocument(doc) {

    var stories = [],
        unique = {},
        items = doc.selection;

    if (0 === items.length)
        return doc;

    for (var i = 0; i < items.length; i++) {

        if (items[i].hasOwnProperty('parentStory')) {

            if (unique[items[i].parentStory.id])
                // already collected this story
                continue;

            unique[items[i].parentStory.id] = true;
            items[i] = items[i].parentStory;
        }

        if ('function' === typeof items[i].changeGrep)
            stories.push(items[i]);

    }

    return stories;

};

 

Edit 2025-03-24: added check for overflows (when object style doesn't set the width correctly) and improved spaces left in main text after execution.

Edit 2025-03-24: added code to create the object style if necessary.

Edit 2025-03-25: added code to get the styles closer to what OP wanted. Also implemented getStoriesOrDocument.

dublove
dubloveAuthor
Legend
March 23, 2025

Hi  m1b,

Thank you very muck.

There seems to be an error.
It is possible to find the part @17208671-01@ with the regularization of the id directly

m1b
Community Expert
Community Expert
March 23, 2025

Hi @dublove unfortunately that doesn't help, because the doScript call captures the error and so I don't know which line caused the error. Can you change this line:

app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Find Anchor Codes');

 to

// app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Find Anchor Codes');

main();

 

Note that this change is only for debugging. When I fix the bug, change it back.

 

Or, even better, send me a small indesign file that throws the error.

- Mark

Community Expert
March 23, 2025

Might be possible - but it's a strange request. I suspect there's more to this - can you tell us what you're trying to do and the overall goal is here? It would be great if you could elaborate on what you're trying to achieve so we can offer the best help possible. 

 

How do you want this to be executed?