Skip to main content
Inspiring
August 13, 2017
Answered

Centering Left-aligned Text On Longest Line Per Page

  • August 13, 2017
  • 7 replies
  • 6353 views

I am working on a book of poems. I need to make sure that the (left aligned) text running within each page is centred on the longest line. As far as I am aware there is no mechanism for doing this automatically in inDesign and besides, the optical centre will always be different from the actual centre.

So I need to manually add an indent to every page to indent the text until it feels centred on the page. My problem is that some of the stanzas/paragraphs run between two pages which each need different indentation. I can only apply indent to a whole paragraph, meaning it will effect the beginning of the paragraph on one page and the end on another. If the second page requires a different indent this means the end of the paragraph that has run over from the previous page will indented correctly for the previous page and not the current page or vice-versa.

Is there any sensible solution to this problem?

    Correct answer Peter Kahrel

    I've had some good fun setting poetry in the past. Most of it can be scripted. As Ariel and Bill mentioned, each line should be a separate paragraph. Then you can left-align the lines and centre the page on the longest line using the following script:

    Select a text frame, then run the script

    if (app.selection.length && app.selection[0] instanceof TextFrame) {

      frame = app.selection[0];

      longest = Math.max.apply (null, frame.lines.everyItem().endHorizontalOffset);

      indent = (frame.geometricBounds[3]/2) - (longest/2);

      frame.lines.everyItem().leftIndent = indent;

    }

    You'll often find that you need to tweak the alignment because centring on the longest line isn't always optically aligned.

    Peter

    7 replies

    Community Expert
    November 26, 2019

    FWIW: I marked Peter Kahrel's post from Aug 13, 2017 as the Correct one.

    Why? It contains the core code for solving this issue.

     

    Regards,
    Uwe Laubender

    ( ACP )

    Participant
    April 2, 2025

    Dear gurus! I never would have thought that I would be writing in the same thread as the legendary Peter )))
    I am having trouble with Uwe Laubender's script (also quite legendary). It worked perfectly until recently, and I was able to create a collection of poems quite quickly, thanks to you all. However, now, unfortunately, something has broken in it. It functions properly with a small number of poems or pages, but as soon as I add a significantly larger batch of poems, it tries to center them, then reverts the lines back to their original place and gives an error: Data is out of range (line 301).
    Unfortunately, I don't understand anything about scripting, and I am asking for your help.
    Thank you, and I apologize for the English; it's Google.

    Community Expert
    April 2, 2025

    Hi @popz29907986ftco ,

    hm, is it perhaps the script code commented with this line:

    0190_PoetryLines_MichelAllio.jsx

    This code was not wriiten by me, it is @Obi-wan Kenobi 's one.

    Without having a sample InDesign document at hand it's hard to tell what's going wrong.

    Also important is the version of your InDesign.

     

    Could you attach a sample document and give the URL of the post where the script code is posted?

    NOTE: Attaching an InDesign document will only work if you are using the forum's editor and not when you answer by mail.

     

    Regards,
    Uwe Laubender
    ( Adobe Community Expert )

    Community Expert
    November 25, 2019

    Hi Mike,

    this is the second time in some days where the same error pops up. In different scripts posted here.

    Cannot tell if this is by chance or because transferring old code from the old Jive forum to this new one is the cause.

    At least something is missing.

     

    This should work:

     

    /*
    
        0190_PoetryLines_MichelAllio.jsx
        based on an orginal code written by Peter Kahrel | See: https://forums.adobe.com/thread/2370094
        Written 2017/08/13
    
    */
    
    app.doScript(main, ScriptLanguage.JAVASCRIPT, [], UndoModes.ENTIRE_SCRIPT, "Poetry Lines! …" );
    
    function main()      
    {
        var myDoc = app.activeDocument,
        myPages = myDoc.pages,
        P = myPages.length,  p;    
    
        for ( p = 0; p < P; p++ )
    	{  
            var myFrames = myPages[p].allPageItems,
            F = myFrames.length,  f;
    
            for ( f = 0; f < F; f++ ) {
                var myFrame = myFrames[f];
    			
                if ( myFrame instanceof TextFrame && myFrame.contents.length > 0 )
    			{
                   var longest = Math.max.apply (null, myFrame.lines.everyItem().endHorizontalOffset); 
                   var indent = (myFrame.geometricBounds[3]/2) - (longest/2);
                    myFrame.lines.everyItem().leftIndent = indent;
                }   
            }
        }
    }

     

    If all your text in the document should be handled, leave it at that.

     

    If you want to apply this only to text with a distinct paragraph style, you have also to add some of the original code.

    The style's name you want to add the changes to is important. In Michel's original code this name is "Body". Change it to your style's name and do not move the style into a style group!

     

    /*
    
        0190_PoetryLines_MichelAllio.jsx
        based on an orginal code written by Peter Kahrel | See: https://forums.adobe.com/thread/2370094
        Written 2017/08/13
    
    */
    
    app.doScript(main, ScriptLanguage.JAVASCRIPT, [], UndoModes.ENTIRE_SCRIPT, "Poetry Lines! …" );
    
    function main()      
    {
        var myDoc = app.activeDocument,
        myPages = myDoc.pages,
        P = myPages.length,  p;    
    
        for ( p = 0; p < P; p++ )
    	{  
            var myFrames = myPages[p].allPageItems,
            F = myFrames.length,  f;
    
            for ( f = 0; f < F; f++ ) {
                var myFrame = myFrames[f];
    			
                if ( myFrame instanceof TextFrame && myFrame.contents.length > 0 )
    			{
                   var longest = Math.max.apply (null, myFrame.lines.everyItem().endHorizontalOffset); 
                   var indent = (myFrame.geometricBounds[3]/2) - (longest/2);
                    myFrame.lines.everyItem().leftIndent = indent;
                }   
            }
        }
    
        var myParas = myDoc.stories.everyItem().paragraphs.everyItem().getElements();
        var P = myParas.length,  p;    
        for ( p = 0; p < P; p++ ) myParas[p].appliedParagraphStyle != myDoc.paragraphStyles.item("Body") && myParas[p].clearOverrides();
    };

     

    Regards,
    Uwe Laubender

    ( ACP )

    Known Participant
    November 25, 2019

    It works - thank you!! 

    Community Expert
    November 23, 2019

    Hi Mike,

    that's rather strange. The mentioned object in the error message should be a Page object.

    Page objects support property allPageItems . Even if there is no object on the page; then the length of that array is simply 0.

     

    Best post your code using the forum's code markup for JavaScript.

    Maybe something is missing…

     

    Regards,
    Uwe Laubender

    ( ACP )

    Known Participant
    November 25, 2019

    Hi Uwe,

    Back at work now, thanks for your help. Here is the code:

    /*
    
        0190_PoetryLines_MichelAllio.jsx
    
        based on an orginal code written by Peter Kahrel | See: https://forums.adobe.com/thread/2370094
    
        Written 2017/08/13
    
    */
    
    app.doScript(main, ScriptLanguage.JAVASCRIPT, [], UndoModes.ENTIRE_SCRIPT, "Poetry Lines! …" );  
    
            
    
    function main()      
    
    {
    
        var myDoc = app.activeDocument,
    
        myPages = myDoc.pages,
    
        P = myPages.length,  p;    
    
        for ( p = 0; p < P; p++ ){  
    
            var myFrames = myPages.allPageItems,
    
            F = myFrames.length,  f;
    
            for ( f = 0; f < F; f++ ) {
    
                var myFrame = myFrames;
    
                if ( myFrame instanceof TextFrame && myFrame.contents.length > 0 ) {
    
                    longest = Math.max.apply (null, myFrame.lines.everyItem().endHorizontalOffset);  
    
                    indent = (myFrame.geometricBounds[3]/2) - (longest/2);  
    
                    myFrame.lines.everyItem().leftIndent = indent;  
    
                }   
    
            }
    
        }
    
        var myParas = myDoc.stories.everyItem().paragraphs.everyItem().getElements();
    
        var P = myParas.length,  p;    
    
        for ( p = 0; p < P; p++ ) myParas.appliedParagraphStyle != myDoc.paragraphStyles.item("Body") && myParas.clearOverrides();      
    
    }  

     

     

    Community Expert
    November 22, 2019

    Mike_Jensen_TG said: I've tried Obi-Wan's script, but it doesn't seem to work, and not sure why.

     

    Hi Mike,

    what exactly does that mean?

    Is there an error message?

    Is the result not the result you are hoping for?

    Something else?

     

    Regards,
    Uwe Laubender

    ( ACP )

    Known Participant
    November 22, 2019

    Hi Uwe,

    This is the error I get (Indesign CC 2019):

     

    Scott Falkner
    Community Expert
    Community Expert
    August 13, 2017

    I would use the direct select tool to select the right edge of each text frame and use cursor keys to move the edge to the left, make the text frame narrower. Each press of a cursor key moved the frame on unit, as defines in Preferences > Units & Increments. Shift + cursor keys moves ten units, Command or Control + cursor key moves one tenth of a unit. Keep going until you find the narrowest working size. Finally use the Alignment panel to align the frame to the page. Repeat for each page. It’s time consuming, but short of scripting it is the easiest solution I can think of.

    Obi-wan Kenobi
    Legend
    August 18, 2017

    Scott Falkner, join The Rebellion!

    MTFBWY! 

    (^/)

    Jongware
    Community Expert
    Community Expert
    August 13, 2017

    Copying your question, prefixed with "InDesign", into Google turned up lots of suggestions, including a Lynda course.

    As well as this: adobe indesign - Centring Text On Longest Line - Graphic Design Stack Exchange - no need to answer here and now, then.

    Obi-wan Kenobi
    Legend
    August 13, 2017

    Screenshots!

    (^/)

    Inspiring
    August 13, 2017

    Hopefully this will help. In this example, the paragraph in red runs over two pages, but each page needs a different left indent.

    TᴀW
    Legend
    August 13, 2017

    Each line should be a separate paragraph.

    When you need extra space between the stanzas, use a different paragraph style that has that extra space.

    That way you will be able to control the indents of individual lines within each stanza independently.

    Ariel

    Visit www.id-extras.com for powerful InDesign scripts that save hours of work — automation, batch tools, and workflow boosters for serious designers.