Skip to main content
Participant
June 27, 2024
Question

Find and replace text by font / format

  • June 27, 2024
  • 2 replies
  • 565 views

I'm looking for a Find and Change solution, can anyone help?

I want to find all text that matches a specific font family / format, and then change the actual text content.

 

In this instance, I want to find all text using the font Fira Mono Regular and delete it.

I would really appreciate any help! 🙂

This topic has been closed for replies.

2 replies

m1b
Community Expert
Community Expert
June 29, 2024

Hi @melaniejaane, I have made a start. This script aims at deleting any text with matching font name. I have coloured the target font in blue just for the visuals. If you don't want to delete the target text, it can be adapted, but the hardest part is done. Let me know if it's useful.

- Mark

Tip: if you have trouble finding the exact name of the font your want, adjust the script so that

var listFontNames = true,

and the script will print a list of the actual names:

 

 

Here is the script:

/**
 * @file Remove TextFont Content From Document.js
 * ----------------------------------------
 * Removes content found set in the specified
 * textFont from the active document.
 *
 * TIP: if you aren't sure on the exact name
 * of a font, change script below to:
 *    var listFontNames = true
 * and script will list all fonts in document.
 * @author m1b
 * @version 2024-06-29
 * @discussion https://community.adobe.com/t5/illustrator-discussions/find-and-replace-text-by-font-format/m-p/14706746
 */
(function () {

    var listFontNames = false,
        targetFontName = 'Abstract-Thin';

    var doc = app.activeDocument,
        textFrames = doc.textFrames,
        textStyleRanges = [];

    for (var i = 0; i < textFrames.length; i++)
        textStyleRanges = textStyleRanges.concat(
            getTextStyleRanges(textFrames[i].textRange, ['textFont'])
        );

    if (listFontNames) {

        var fontNames = [];

        // just show all the font names
        for (var i = textStyleRanges.length - 1, unique = {}; i >= 0; i--)
            if (!unique[textStyleRanges[i].textFont.name]) {
                fontNames.push(textStyleRanges[i].textFont.name);
                unique[textStyleRanges[i].textFont.name] = true;
            }

        alert('Font names:\n' + fontNames.join('\n'))

    }

    else

        // remove text in the target font
        for (var i = textStyleRanges.length - 1; i >= 0; i--)
            if (targetFontName === textStyleRanges[i].textFont.name)
                textStyleRanges[i].remove();

    /**
     * Returns an array of TextRanges,
     * determined by mapping changes
     * in supplied keys. For example,
     * supplying the 'fillColor' key
     * will return ranges divided when
     * the text's fillColor changes.
     * @author m1b
     * @version 2023-04-26
     * @param {TextRange} textRange - an Illustrator TextRange.
     * @param {Array<String>} keys - an array of keys to match, eg ['fillColor'].
     */
    function getTextStyleRanges(textRange, keys) {

        if (
            textRange == undefined
            || textRange.constructor.name != 'TextRange'
        )
            throw Error('getTextStyleRanges: bad `textRange` supplied.');

        if (
            keys == undefined
            || keys.constructor.name != 'Array'
        )
            throw Error('getTextStyleRanges: bad `textRange` supplied.');

        // check keys are valid
        for (var j = 0; j < keys.length; j++)
            if (!textRange.characterAttributes.hasOwnProperty(keys[j]))
                throw Error('getTextStyleRanges: bad key supplied ("' + keys[j] + '")');

        var ranges = [],
            start = 0,
            currentValues = {};

        charactersLoop:
        for (var i = 0; i < textRange.length; i++) {

            var tr = textRange.textRanges[i],
                matches = true;

            // check each key
            keysLoop:
            for (var j = 0; j < keys.length; j++) {

                if (i == 0)
                    currentValues[keys[j]] = tr.characterAttributes[keys[j]];

                else if (stringify(tr.characterAttributes[keys[j]]) !== stringify(currentValues[keys[j]])) {
                    matches = false;
                    break keysLoop;
                }
            }

            currentValues[keys[j]] = tr.characterAttributes[keys[j]];

            if (
                i == textRange.length - 1
                || !matches
            ) {
                // start a new range
                var newTextRange = textRange.textRanges[start];
                newTextRange.end = i == textRange.length - 1 ? i + 1 : i;
                ranges.push(newTextRange);
                start = i;
            }

        }

        return ranges;

    };


    /**
     * Simple stringify object, with
     * special handling of Swatches.
     * @author m1b
     * @version 2023-04-26
     * @param {Object} obj - the object to stringify.
     * @returns {String}
     */
    function stringify(obj) {

        var str = obj.toString();

        for (var key in obj) {

            if (!obj.hasOwnProperty(key))
                continue;

            if (
                key == 'spot'
                || key == 'color'
            )
                str += stringify(obj[key]);

            else
                str += obj[key];

        }

        return str;

    };

})();

 

Participant
June 28, 2024

As a note I did try using [select > same > font family] but it does not work on textboxes that use more than one font. 😕😕