Composite Headers Never Before Possible!

In this “how-to” we are going to address a really difficult problem in creating headers which seems almost impossible to automate. We will show you how you can do the impossible with Power Headers! The example used is an actual Hebrew publication, but the concepts can be applied to any language or use.

Beware that this is an advanced topic and not for the faint of heart! It is a complicated setup, but it does a good job of demonstrating the deeply powerful capabilities of Power Headers.

Here are the problems:

1. The headers must contain the range of both the chapters and the verses which appear in the text. Because there a ranges for both chapers and verse, but the verses are contained in the chapters, the headers can appear in two forms:


The red arrows show the chapter numbers, while the green arrows show the verse numbers. When there is only one chapter on a page, the format is: 1. Chapter number-slash, 2. first verse – hyphen, 3. last verse.

When there are two chapters on the page, the format must be: 1. First Chapter number-slash, 2. first verse, 3. N-dash, 4. Last Chapter Number – slash, 5. last verse. Being that there are a minimum of at least four different variables which might or might not appear on the page, this is a seemingly hopeless situation!

2. To further complicate matters, there are sometimes one, and sometimes two verses per line. When there are two verses per line the verse numbers appear with a dash separating them like this:


If we were to simply use a First and/or Last instance, we would sometimes end up with text that looks like [verse_a]-[verse_b]-[verse_c], so we need a way to pick up the first number if it’s the first instance, but the second number if it’s the last instance.


If not for problem #2, we could automate this with three variables, and even factoring in that problem it would probably be possible with four variables (or three with an additional variable-level GREP Processor), but for simplicity sake, we will use six variables to make each instance a separate variable. Since each variable adds time to the updating, you would normally want to do it with as few variables as possible, but we wanted to keep this how-to as simple as possible.

Step #1: Create six different character styles — one for each variable:


Step #2: Right click on the header frame and give the header frame a label:



Step #3: Create the chapter variables.

The first chapter variable should be a “Current Instance” variable which will display the previously found chapter unless the chapter number is at the start of the new page — in which case it will display the one appearing at the top of the page.

The chapter header adds text after which will act as a separator between the chapter number and the verse number:


The second chapter variable should be a “Last Instance” variable.

The chapter header adds text after which will act as a separator between the chapter number and the verse number, as well as a dash to act as the separator between the first chapter/verse and the second one:


Step #4: Create the four verse variables.

Variable 1


Variable #2


Variable #3


Variable #4


As you can see, we inserted a dash (Hebrew “makaf”) to serve as a separator between variables #1 and #2, and between variables #3 and #4.

Step #5:We now have the basic setup for all our variables. We will insert the variables on the master page, and see what these variables produce:

To insert the variables, we put the text cursor in the header frame and right click:


Repeat the process for each of the headers in their correct order:


Step #6: Update the headers to see what they produce:


Verse Range


Chapter Range

As you see, all the information appears in the header, but it makes no sense in any context. When it’s a verse range, the entire second half of the header should be removed, and when it’s a chapter range, we need to do “surgery” to remove the third and fifth variables.

Step #7: Add conditional text to variable “ChapterB”:

To enable the removal of the last three variables on a page where we will have a “verse range”, we insert a “Conditional Text” of “Remove”. This text will be inserted on any page which does not contain a chapter number (which by definition means it will need a “verse range” as apposed to a “chapter range”.


Step #8: Create the first Global GREP Processor

Global GREP Processors run after all the variables are updated, so we can use them to assess the general state of all the variables as they interact with each other. This Global GREP Processor is actually quite simple. It will remove all text from the word Remove until the end of the header frame text:


Now let’s check that it worked:






Step #9: Create Global GREP Processors for chapter ranges.

To fix up the “chapter range” headers shown above we will need two different Global GREP Porcessors. One will remove the third variable and the other will remove the fifth variable. Once those two variables are removed, our “chapter range” headers will appear as they should:

Remove Third Variable

Remove Third Variable

Remove Fifth Variable

Remove Fifth Variable

These GREP queries are actually a lot simpler than they appear. The fact that they are search right-to-left text make them much harder to read than they would be if they were in Latin letters.

The first GREP query is as follows:

([\x{05D0}-\x{05EA}]+)?[\x{05D0}-\x{05EA}]+(?= — )

Because of peculiarities of using GREP with right-to-left languages, we used the unicode notation of the GREP string instead of the actual characters. The unicode value of the first letter of the Hebrew alphabet is o5D0 and the last is 05EA. Basically this string searches for any number of Hebrew letters which it saves as a saved group. This is followed by a Hebrew makaf (dash) followed by any number of Hebrew characters with a positive look-ahead for a space, em-dash, space. A rough equivalent in English would be: ([a-z]+)-[a-z]+(?= — )

The GREP which removes the fifth variable is similar: ( — [\x{05D0}-\x{05EA}]+ / )[\x{05D0}-\x{05EA}]+?(?=[\x{05D0}-\x{05EA}])

After creating these two GREP Processors and updating the headers we get what we need for the “chapter ranges”:





Step #10: Fix a hole in the logic:

There is one problem with the logic we used to identify “chapter ranges” and “verse ranges”. When a page starts a new chapter, there is in fact only one chapter on the page, so it needs a verse range, but since ther was an instance of a chapter number on the page, the extra chapter variable was not correctly removed:


To fix this problem requires two more GREP Processors. The first one fixes the content, but a second one is required to fix the formatting. The second one is needed due to a peculiarity of InDesign’s GREP functionality: When you use GREP to remove content in text of mixed formatting, the formatting can get messed up under certain circumstances.

The first GREP Processor finds Chapter numbers which repeat themselves:


The GREP query for this is: ([\x{05D0}-\x{05EA}]+)( / [\x{05D0}-\x{05EA}]+) ~_ \1 /

The “\1” is used to locate the text found in the first group which will find chapter numbers which repeat themselves.

This will result in a header which looks like this (notice the bold letters in the first half of the verse range):


This requires this GREP Processor to fix up the formatting which searches for text strings unique to the verse headers and applies one of the verse header character styles:


We now end up with a correctly formatted “verse range”:


Step #11: Fix Verse Ranges:

The only step left to do is to fix the cases where we more than one verse per line,verse_range_in_source

and by consequence, a source range in the source text which results in a header like this:


If we were not using the Hebrew makaf to separate the ranges, this would not be a problem, because we could just use “First Word” and “Last Word” variables. The problem is that Hebrew makafs are identified as regular word characters.

To fix this, we need to create variable-specific GREP Processors. The difference between variable specific GREP Processors, and Global GREP Processors is that the variable-specific ones are run on only the text specific to that variable, while the global ones are run on the entire header frame after all the headers are updated.

We will create one for variable VerseA:


and another one for variable VerseB:


Now after updating, the headers are all correct:


There you have it! Simple as pi! :)

Tags: , , ,


  1. Nathan000000 says:

    This is a vital article for me. However, because the example you used involves Hebrew, it’s very hard to follow. Would it be possible for you to create a similar article using standard Arabic numerals like we use in English, etc.?

Leave feedback