is now part of CreativePro.com!

A Major Job Gets Easier with GREP and FindChangeByList

26

About two weeks ago I taught an InDesign advanced course for a client who needed to create a weekly product leaflet. After a short talk it became clear that his current layout workflow was basic and, unfortunately for him, repetitive. In a nutshell: Product information is uploaded by the company’s main branch (which is based in another country) to a website where all the designers can look up the products they need for their local weekly leaflet. From there, a copy/paste is made straight into InDesign. So the text comes in without formatting and always structured in the same way. In the end, the designer has 20 or 30 different product descriptions, all copied from the website, and all in separate text frames.

After seeing how the text would come in, I realized that this would be a great use for the InDesign GREP find/change function. I was excited because GREP is one of my favourite functions in InDesign. Here’s how I was able to make this client’s job easier.

First, for reference, let’s take a look at how the text would come in, here’s an example of one product frame.

This is how the text comes in, one product description in a separate text story.

The to-do list for every frame

  1. The first line of text is always the title of the product, so this needs to have its own paragraph style.
  2. The long line of text that follows is a list of specific characteristics, all separated by spaces and forward slashes. The spaces and forward slashes need to be deleted and we need to put a hard return instead to put each characteristic on its own line (so we can use a bulleted list paragraph style).
  3. The weight of the product (here in grams) needs to be included in the bulleted list but needs a different color. In fact, both the bullet and the text itself need a different color. For this we need to apply a different red bulleted paragraph style. Also, the weight of the product is not always in grams; it could also be in kilograms (kg), liter (l) or milliliter (ml).
  4. Next line is the price per kilogram (or liter). This line needs a different paragraph style too.
  5. Last line is the product number. This is always a 5-digit number that not only needs its ownparagraph style, but we also need to add  “nr. ” before the number.

This is how the layout looks after applying the styles and changing the text.

So in total we need to apply 5 different paragraph styles and we need to change the text itself (replace the forward slashes with returns and add the number prefix). You could do this with five different Find/Change operations, but it would be tedious! So instead, we were able to use the FindChangeByList script. This script comes with InDesign (so everyone already has it). The script uses a text file that holds a list of “typed out” find/change commands that you can edit. These commands can be text, GREP, or glyph level find/change commands.

If you want to see the actual text file that describes the list of find/change commands, you can find it by opening the scripts panel (Window > Utilities > Scripts), then opening up the Application > Samples > JavaScript > FindChangeSupport folder. You can right-click on the FindChangeList.txt file and choose “reveal in Finder” (or Explorer if you’re on a PC). In this text file you’ll discover the commands that the FindChangeByList script will execute. (You run the script itself by double-clicking the script in the Scripts panel in InDesign.)

After backing up the original FindChangeList.txt file (in case I needed it again), I deleted all the previous commands at the bottom of the text file and was then ready to put in my new commands. For easy notation I used the RecordFindChange script, written by Martin Fisher (Mike Rankin talked about this in this article). This copies my GREP expression from the Find/Change dialog box to a new empty text field in a text editor so I can select it and paste it in the FindChangeByList script text file. That way I can build my own list of find/change commands quickly. Following is a list of commands I used.

1. Finding the title line with GREP
Find: \A.+
Change: I chose the title paragraph style to apply it to the text.

Explanation
\A This expression is actually not documented in the InDesign help file, nor is it available in the GREP “@” flyout menu. It is also one of the rare GREP expressions where you need an uppercase letter for it to work. Normally using an uppercase letter would make the expression negative. (For example, \D which mean find everything that’s not a digit). However, the meaning of \A is “find text starting at the beginning of the story”. Then .+ Means that it can be any character(s).

2. Finding the product characteristics with GREP and applying the bullet style in order to get a bulleted list
Find:  / .+?
Change:  I chose the bulleted list paragraph style to apply it to the text.

Explanation
/ This finds a space followed by a forward slash followed by a space (all literal text).
.+ Means that the slash is followed by one or more other character(s).
? Is added to limit the search to every instance of the space-slash-space. If you leave the ? out it would find one instance of the text going from the first space-slash-space to the text of the last one at the end of the paragraph. But we need to replace each instance of the slash with a return (enter), so we would need to find the individuals instances of the slash.

3. Replacing the slashes with enters
Find:  / (.+?)
Change: \r$1

Explanation
Find  / (.+?) Finds the same text as the previous GREP expression — but this time we added parenthesis around the “any character(s)” expression because we want to make a reference to this in the change field.
Change \r$1 The $1 will put back whatever was in the parenthesis in the find field (in this case the text after the slash) and precedes it with an enter. The slash gets deleted (because I don’t make any reference to it here).

4. Finding the weight of the product and applying the right style
Find: ^\d+ (g|kg|l|ml)
Change:  I chose the weight paragraph style to apply it to the text.

Explanation
^\d+ Finds any digit at the beginning of the paragraph, followed by a space.
(g|kg|l|ml) Followed by g, kg, l or ml (the vertical bar between the letters acts like an “or”)

5. Finding the price of the product and applying the right style
Find: ^\d+,\d+ EUR/(kg|l)
Change:  I chose the price paragraph style to apply it to the text.

Explanation
^\d+,\d+ Finds any digit followed by a comma, followed by another digit at the beginning of the paragraph
EUR/(kg|l) Followed by a space, the EUR/ text and then kg or l

6. Finding the product number, giving it the right style and adding nr. as a prefix
Find: ^(\d{5})
Change:  I chose the number paragraph style to apply it to the text and added the GREP nr. $1

Explanation
^(\d{5}) Finds any 5 digit long number at the beginning of the paragraph.
nr. $1 Will put the text “nr. ” followed by whatever was between the parenthesis in the find field (in this case the original 5 digit number).

The final text file. I marked the added text in red for clarity.

Finishing it
When I was done copying all these commands to my FindChangeSupport.txt file I saved it and closed it. Now it was time to test it out. I went back to InDesign, created a fresh product text frame from the client, opened up the Scripts panel and double-clicked my FindChangeByList script. Et voilà! Instant layout! Needless to say that the client was extremely happy because he had to layout dozens of these every week.

So you see that with a little GREP knowledge and a few free scripts you’ll be able to save a great amount of time!

Bart Van de Wiele is a LinkedIn Learning author and public speaker currently working as a Principal Solutions Consultant at Adobe. Visit his website at bartvdw.com.
  • Awesome information, Bart! (A warm welcome to a new InDesignSecrets contributor. Bart is awesome, and will be speaking at PEPCON 2013. Click on his name at the top of the post to see more about him.)

  • JRB says:

    Hi,

    There is a french version of FindChangeByList freely available on the Adobe Exchange:
    https://www.adobe.com/cfusion/exchange/index.cfm?event=extensionDetail&extid=2015522

    ;-)

  • mckayk777 says:

    Nothing to do with the actual tutorial but love the font used in the product description.
    Could you possibly tell me the name of it.

    GREP is still a mystery to me :(

  • Florian says:

    That is Jos Buivenga?s Diavlo, and it is free: https://www.exljbris.com/diavlo.html

  • Salieri says:

    I am bookmarking this page, thanks for this.

    If anyone is reading these comments looking for a simpler solution to a similar problem, I think a Find/Replace ” / ” to “^n” and then paragraph styles set up with a Next Style applied will get you 90% of the way quite quickly, but it won’t add it the extra ‘nr’ that this solution does and it won’t give you the warm fuzzy glow of a ‘one click’ answer.

  • Bart Van de Wiele says:

    @David: Thank you for the warm introduction! Really glad I could join the club :-)

    @Salieri: Thanks for your comment, but I don’t think the find/change command will automatically apply the next style when you apply it in your search command.

  • Nadya Marimont says:

    Thank you for the expression
    Find: \A
    from the bottom of my heart! I’m loving GREP and FindChangebyList, but I’ve missed this command. Awesome.

  • Salieri says:

    @Bart: Sorry I should have been clearer. I meant first apply a Find/Replace as I specified, then apply your first style to the heading manually, with Next Style and it will fall into place.

  • Bart Van de Wiele says:

    Hi Salieri,
    Yes that might be a solution but the problem is (and I didn’t really say this in my blogpost so you couldn’t know), that the products don’t have the same amount of product details and the script needs to work regardless of the amount of product details. And the next style feature is fantastic but it requires the same pattern and amount of hard returns for it to work. Otherwise you’d be applying the wrong style to the wrong text.

    Thanks for the input

  • T Fritz says:

    Does anyone know how to get around the error that is generated because a style is in a style group… I’ve got all my styles nested 2 groups deep… I would rather leave them like that for organizations purposes.

  • Bart Van de Wiele says:

    @T Fritz: having styles in a style group should work. Can you maybe copy/paste the GREP line here? (or maybe in a link?)
    I noticed that the recordFindChange script sometimes messes up your code when used in CS6 so that might be the case here.

  • T Fritz says:

    THANKS Bart. pasted below is the code… it hangs on the paragraph style line, but the Character style version goes through just fine.

    grep {findWhat:”^February”} {appliedParagraphStyle:”DDate Separator”} {includeLockedStoriesForFind:false, includeLockedLayersForFind:false, includeHiddenLayers:false, includeMasterPages:false, includeFootnotes:true, kanaSensitive:true, widthSensitive:true} //Date Separator

    grep {findWhat:”^.+#”} {appliedCharacterStyle:”small caps”} {includeLockedStoriesForFind:false, includeLockedLayersForFind:false, includeHiddenLayers:false, includeMasterPages:false, includeFootnotes:true, kanaSensitive:true, widthSensitive:true} //# to Small Caps

  • Bart Van de Wiele says:

    @T Fritz can you try this code for the first one please?

    grep {findWhat:?^February?, appliedParagraphStyle:?DDate Separator?} {includeLockedStoriesForFind:false, includeLockedLayersForFind:false, includeHiddenLayers:false, includeMasterPages:false, includeFootnotes:true, kanaSensitive:true, widthSensitive:true} //Date Separator

  • T Fritz says:

    Thanks for your help Bart, I get this error:
    Error number 25
    Error string expected: ;

  • Bart Van de Wiele says:

    Fritz, that’s weird. I used that code to apply a colour to the ^February word that uses the DDate Separator style (which is buried in a 2-level styles folder), and it worked without any problem.

    Can you please send me your FindChangebyList txt file and an InDesign page with some text and your styles?
    bart.vandewiele [at] gmail.com
    I’ll try and check it out the moment I have time

  • T Fritz says:

    I created a new document, with one style nested in 2 folders and it works fine. Odd.

  • Veerle says:

    Thanks for this tutorial Bart!
    I didn’t knew you master Indesign that well, respect!

  • Bart Van de Wiele says:

    Thanks Veerle :-)

  • Celulloyd says:

    This does not concern the original script but I can’t find an answer anywhere, so maybe someone here could help.

    We are using InDesign CS4 on Windows XP to create 12 catalogs bi-annually (24 total) with thousands of parts in each one. We now need to change all those part numbers to new ones. I have a spreadsheet that has the old numbers in one column and the corresponding new numbers in a second column. There are approximately 59,000 part numbers in the spreadsheet. I know nothing at all about scripting. Is there a way to reference the spreadsheet to find the old part number in the InDesign document then replace it with the new number? This would save weeks of work.

    I tried one custom script I found in an Adobe user forum but I had to place the info from the spreadsheet into InDesign, convert it to a table, select the table, then run the script. The problem was that it only changed the numbers in the table, not in my document.

    I’ve also read that the FindChangeByList script can be used (as long as the Excel file is converted to a .txt file), but I have no idea how to edit the script to suit what I need done.

    I don’t care about the style sheets (we can apply them after all the part numbers have been changed).

    Any suggestions? Thanks,
    Lloyd

  • Raphael Tebarts says:

    Hello everyone,

    is it possible to change serveral documents? At this moment my DinfChangeByList just change the aktive document.

    Here`s my code:

    text {findWhat:”je 1 kg”} {changeTo:”je 1 kg”, appliedCharacterStyle:”02 Body A4 blau bold”, changeConditionsMode:1919250519} {includeLockedStoriesForFind:false, includeLockedLayersForFind:false, includeHiddenLayers:false, includeMasterPages:false, includeFootnotes:false, wholeWord:false, caseSensitive:false}

    text {findWhat:”je 100 g”} {changeTo:”je 100 g”, appliedCharacterStyle:”02 Body A4 blau bold”, changeConditionsMode:1919250519} {includeLockedStoriesForFind:false, includeLockedLayersForFind:false, includeHiddenLayers:false, includeMasterPages:false, includeFootnotes:false, wholeWord:false, caseSensitive:false}

    i’m looking forward to your help

    Thanks!

    Raphael

  • Raphael Tebarts says:

    Is it possible to use the script on CS4?

  • John says:

    Hi, I am having a really hard time with using this feature. I am trying to create a findchange list that will look for a number of paragraph styles that all contain an “i” character style, and then change the “i” character style to “r”. (But I can’t globally change “i” to “r” as there are some paragraph styles that still require the “i”. I would like to make a findchangelist, but I keep failing at even getting one right, much less the whole series that I need to execute. Thanks!

    -John

  • Hugh Nagle says:

    Can anyone tell me how I would change a command such as the one below so that the changed item would now also be BOLD?
    Thanks in advance.
    ======
    grep {findWhat:” +”} {changeTo:” “} {includeFootnotes:true, includeMasterPages:true, includeHiddenLayers:true, wholeWord:false} Find all double spaces and replace with single spaces.

  • Shy Sivapatham says:

    So grateful for this amazingly clear “tutorial”!! Many, many thanks!

    Only hitch was I was getting the same error that this guy (@chuck-nigash) solves below, (hope it’s okay to copy and paste his post here as it could help someone else!

    ***************************
    Theunis, guess what? Last night, compiling the GREP lines from Record/FindChange CS3-CS5 I found the error that was keeping the code from running. When you run a Find/Change, then run the Record script, look at the string and see that it captures it consistently like this.

    Example:

    grep {, findWhat:”~_~_~_r”} {, changeTo:”~>”}

    What has been hanging me up is the comma and space following the bracket. Once I cleaned that, the recorded string ran perfectly with FindChangeByList.

    Corrected:

    grep {findWhat:”~_~_~_r”} {changeTo:”~>”}

    Hope this helps anyone who toys with this in the future. Great to have threads that end in happiness. :-)

    ***************************

  • Rajiv arora says:

    In FindChangebyList, which term is used to search the font name. So that, it can search the text in particular font and replace the text in that font only and not in all other fonts.

  • >