해결됨
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.
Enter your E-mail address. We'll send you an e-mail with instructions to reset your password.

