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

Script that converts selected text to a GREP find - Experimental script

Community Expert ,
Dec 16, 2025 Dec 16, 2025

I started working on this script some time ago and it's since fallen to the wayside - I'm not using it. But I was tinkering around some unused and unfinished script projects 

 

I've taken it as far as I can go in terms of a learning curve for me - if anyone wants it or wants to tinker with it and make it better feel free.


All it was meant to do is give a starting point to a GREP search for people not familiar with GREP to give them a leg up on the starting point of the GREP. 

But I feel it could be more robust.

 

#target indesign

(function () {

    if (app.documents.length === 0) {
        alert("No document open.");
        return;
    }

    if (app.selection.length === 0 || !app.selection[0].hasOwnProperty("contents")) {
        alert("Please select some text.");
        return;
    }

    var txt = app.selection[0].contents;
    var grep = "";

    var i = 0;

    function isDigit(c) { return /\d/.test(c); }
    function isLower(c) { return /[a-z]/.test(c); }
    function isUpper(c) { return /[A-Z]/.test(c); }
    function isLetter(c) { return /[A-Za-z]/.test(c); }
    function isSpace(c) { return /\s/.test(c); }

    while (i < txt.length) {
        var c = txt[i];

        // DIGITS (collapse runs)
        if (isDigit(c)) {
            var start = i;
            while (i < txt.length && isDigit(txt[i])) i++;
            var count = i - start;
            grep += (count === 1) ? "\\d" : "\\d{" + count + "}";
            continue;
        }

        // LOWERCASE LETTERS
        if (isLower(c)) {
            var start = i;
            while (i < txt.length && isLower(txt[i])) i++;
            var count = i - start;
            grep += (count === 1) ? "[a-z]" : "[a-z]{" + count + "}";
            continue;
        }

        // UPPERCASE LETTERS
        if (isUpper(c)) {
            var start = i;
            while (i < txt.length && isUpper(txt[i])) i++;
            var count = i - start;
            grep += (count === 1) ? "[A-Z]" : "[A-Z]{" + count + "}";
            continue;
        }

        // SPACES
        if (isSpace(c)) {
            while (i < txt.length && isSpace(txt[i])) i++;
            grep += "\\s+";
            continue;
        }

        // ESCAPED GREP METACHARACTERS
        if (/[\\.^$*+?()[\]{}|]/.test(c)) {
            grep += "\\" + c;
            i++;
            continue;
        }

        // EVERYTHING ELSE (commas, hyphens, slashes, etc.)
        grep += c;
        i++;
    }

    // Push to Find GREP
    app.findGrepPreferences = NothingEnum.nothing;
    app.findGrepPreferences.findWhat = grep;

    alert("Generated GREP:\n\n" + grep);

})();

 
This is another iteration of the same thing 

#target indesign

(function () {

    if (app.documents.length === 0) {
        alert("No document open.");
        return;
    }

    if (app.selection.length === 0 || !app.selection[0].hasOwnProperty("contents")) {
        alert("Please select some text.");
        return;
    }

    var txt = app.selection[0].contents;
    var grep = "";
    var i = 0;

    function isDigit(c) { return /\d/.test(c); }
    function isLower(c) { return /[a-z]/.test(c); }
    function isUpper(c) { return /[A-Z]/.test(c); }
    function isLetter(c) { return /[A-Za-z]/.test(c); }
    function isSpace(c) { return /\s/.test(c); }

    while (i < txt.length) {
        var c = txt[i];

        /* =========================
           NUMBERS (smart handling)
           ========================= */

        if (isDigit(c)) {
            var start = i;
            while (i < txt.length && /[\d,.]/.test(txt[i])) i++;
            var token = txt.substring(start, i);

            // Comma-grouped number
            if (/^\d{1,3}(,\d{3})+$/.test(token)) {
                grep += "\\d{1,3}(,\\d{3})*";
                continue;
            }

            // Decimal number
            if (/^\d+(\.\d+)?$/.test(token)) {
                grep += "\\d+(\\.\\d+)?";
                continue;
            }

            // Plain digits
            grep += "\\d{" + token.replace(/\D/g, "").length + "}";
            continue;
        }

        /* =========================
           LETTERS
           ========================= */

        if (isLower(c)) {
            var start = i;
            while (i < txt.length && isLower(txt[i])) i++;
            grep += "[a-z]{" + (i - start) + "}";
            continue;
        }

        if (isUpper(c)) {
            var start = i;
            while (i < txt.length && isUpper(txt[i])) i++;
            grep += "[A-Z]{" + (i - start) + "}";
            continue;
        }

        /* =========================
           SPACES
           ========================= */

        if (isSpace(c)) {
            while (i < txt.length && isSpace(txt[i])) i++;
            grep += "\\s+";
            continue;
        }

        /* =========================
           ESCAPED METACHARACTERS
           ========================= */

        if (/[\\.^$*+?()[\]{}|]/.test(c)) {
            grep += "\\" + c;
            i++;
            continue;
        }

        /* =========================
           EVERYTHING ELSE
           ========================= */

        grep += c;
        i++;
    }

    app.findGrepPreferences = NothingEnum.nothing;
    app.findGrepPreferences.findWhat = grep;

    alert("Generated GREP:\n\n" + grep);

})();



TOPICS
Experiment , Scripting
197
Translate
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 ,
Dec 16, 2025 Dec 16, 2025

Hi @Eugene Tyson thanks for sharing. It's a great idea and I'm sure it was fun to code. Your algorithm tends to generate grep that is very prescriptive. An improvement (an exercise for someone?) could be to read two lists compiled by the user: match all the strings in this list A, and match none of the strings in list B. This would give the grep generator a lot more to focus on, but I fear the coding would not be trivial.

- Mark

 

(As a complement to Eugene's script, I would heartily recommend @Peter Kahrel's wonderful Grep Editor due to its preview capability.)

Translate
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 ,
Dec 16, 2025 Dec 16, 2025

Oh @Peter Kahrel GREP editor is a wonder. I use it regularly.

 

I just wanted to see if it was possible to select some text and generate some basic GREP with it - as some people I know don't use GREP or know how to do it and it's a bit complex for some. 

So I thought of maybe a little bit to get started with - learn as you go stuff. 

 

But yes - there are better solutions 😄 

Translate
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 ,
Dec 16, 2025 Dec 16, 2025

Actually, Eugene, I don't know of any better solutions for what you aimed to do with this script. I think it's a brilliant idea and I'd love to see someone take it to the next level, as you hinted at in your post. It would be a really cool way for a non-grep savvy user to get a starting point.

 

Now that I think about it, all you plug-in developers out there: why not create a plug-in that access a suitable LLM to create the grep? User would type:

Match "x" or "y" or "z" unless it is preceded by "a" or "b" or "c"

 and chatGPT gave me this:

(?<![abc])[xyz]

I mean, that would be great for beginners to grep.

Translate
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 ,
Dec 16, 2025 Dec 16, 2025

Yeh it's a nice idea, there's one or two AI plugins around for InDesign that kinda do that. 

https://www.omata.io/mate/indesign

 

I have a bunch of other 'useless' scripts I had for testing. Might post 1 a month see if anyone can improve them or use them as they are. 

I thought this was a nifty one if someone wanted to learn a bit of GREP and automate the code into the find. 

 

 

Sharing is caring.

Translate
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
Valorous Hero ,
Dec 16, 2025 Dec 16, 2025

Thanks for posting it!

By the way, the isLetter function is defined, but is never called.

— Kas

Translate
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 ,
Dec 16, 2025 Dec 16, 2025
LATEST

Good spot you’re right 
isLetter() is currently unused.
It was left in intentionally for a follow-up version that collapses mixed-case words into a single GREP token. Safe to remove for now, or wire it in as a mixed-case handler.

This is what happens when you abandon things I guess 😄 

Translate
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