Skip to main content
Known Participant
August 12, 2023
Question

Script to reverse characters whole page or document

  • August 12, 2023
  • 11 replies
  • 4537 views

Hi All

I have a document that have text frames containes characters are in reverse order

Ex : ( olleh ymar ) intstead of  ( hello ramy )

I want to script that change these reverse to be correct sentences in the curret page or in whole document

Thanks in advance

 

This topic has been closed for replies.

11 replies

Adobe Expert
August 21, 2023

@Robert at ID-Tasker is right, you can get the words in all the cells in one go. So you need three steps to get all words in a document: the level-1 stories, the tables, and the footnotes. The script I posted then needs the addition of tables and footnotes:

 

words = app.documents[0].
  stories.everyItem().
  words.everyItem().getElements();

tables = app.documents[0].stories.everyItem().tables;
if (tables.length > 0) {
  words = words.concat (tables.everyItem().
    cells.everyItem().
    texts.everyItem().
    words.everyItem().getElements()
  );
}

fnotes = app.documents[0].stories.everyItem().footnotes;
  if (fnotes.length > 0) {
    words = words.concat (fnotes.everyItem().
      texts.everyItem().
      words.everyItem().getElements()
  );
}


for (i = words.length-1; i >= 0; i--) {
  // Use either of the following two:
  //words[i].characterDirection = 
	  //CharacterDirectionOptions.RIGHT_TO_LEFT_DIRECTION;
  words[i].characterDirection = 
	  CharacterDirectionOptions.LEFT_TO_RIGHT_DIRECTION;
}

 

M.Hasanin
Inspiring
August 24, 2023

Hi @Peter Kahrel  thank you, your updated script very good for one hit reversing, but using character direction is not the right choice, it reverse the characters wrongly, if you use :

      words[i].contents = words[i].contents.split('').reverse().join('');

it will work but will swap the locations of word, so simple table will be table simple, etc also in arabic

BestMohammad Hasanin
Adobe Expert
August 24, 2023

Did you set the table direction correctly?

Known Participant
August 20, 2023

Hi

Sorry for delaynig in reply , now I am confused

Where is the whole script that i can try ?

m1b
Brainiac
August 20, 2023

Hi @r28071715i111, first try my full script above. Then tell us how it went. - Mark

Robert at ID-Tasker
Brainiac
August 20, 2023

Hi @r28071715i111 , here is a version for reversing text in tables cells:

//Reverse Characters in All Document Tables
app.doScript(CatchMyError, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, "Reverse Characters in Doc Tables");

// Error Catcher for Function
function CatchMyError() {
  try {
    DoReverseAllTables();
  } catch (myError) {
    alert(myError, "ERROR!");
    exit();
  }
}

function DoReverseAllTables() {
    //Get All Tables Table Style Apply
    var myDoc = app.activeDocument;
    var tables = myDoc.stories.everyItem().tables.everyItem().getElements();
        
    // Iterate through each table in the document
    for (var tableIndex = 0; tableIndex < tables.length; tableIndex++) {
      var table = tables[tableIndex];

      // Iterate through each cell in the table
      for (var rowIndex = 0; rowIndex < table.rows.length; rowIndex++) {
        var row = table.rows[rowIndex];

        for (var cellIndex = 0; cellIndex < row.cells.length; cellIndex++) {
          var cell = row.cells[cellIndex];
          var textFrames = cell.texts; // Get the text frames in the cell

          // Iterate through each text frame in the cell
          for (var textFrameIndex = 0; textFrameIndex < textFrames.length; textFrameIndex++) {
            var textFrame = textFrames[textFrameIndex];
            var text = textFrame.contents;

            // Reverse the character direction
            var reversedText = reverseCharacterDirectionTables(text);
            // Set the reversed text back to the text frame
            textFrame.contents = reversedText;        
          }
        }
      }
    }
   //wait a maximum of 10 second for the active process.
  app.activeDocument.activeProcess.waitForProcess(10);
  alert("Character direction reversed in all tables!","Finished");
}

function reverseCharacterDirectionTables(text) {
  var reversedText = "";
  for (var i = text.length - 1; i >= 0; i--) {
    reversedText += text.charAt(i);
  }
  return reversedText;
}

I'm not JS guy, so... 

 

Why are you iterating through Cells looking for TextFrames? 

 

You can get them from:

 

myDoc.Stories 

 

Even when the TextFrame is inside a Cell - it's ParentStory is still part of the Stories of the Document - so there is no point iterating Cells.

 

And if you are just iterating through all Cells - why can't you use JS's .everyItem() to get all Cells from the tableT and then process this "collection"?

 

Like I've said, I'm not JS guy so just asking... 

 

Adobe Expert
August 13, 2023

To change the character direction in each word but not the order of words -- i.e. olleh ymar > hello ramy -- use this:

 

words = app.documents[0].stories.everyItem().words.everyItem().getElements();
for (var i = words.length-1; i >= 0; i--) {
  // Use either of the following two:
  //words[i].characterDirection = CharacterDirectionOptions.RIGHT_TO_LEFT_DIRECTION;
  words[i].characterDirection = CharacterDirectionOptions.LEFT_TO_RIGHT_DIRECTION;
}

 

To change the character direction and the order of the words (olleh ymar > ramy hello), use this:

app.documents[0].stories
  .everyItem()
  .words.everyItem().characterDirection = 
    CharacterDirectionOptions.LEFT_TO_RIGHT_DIRECTION;

 (change the last line to RIGHT_TO_LEFT if needed)

 

For both methods to work the composer must be set to one of the World composers.

m1b
Brainiac
August 13, 2023

That is a promising approach Peter! All depends on the specific properties of the OP's converted-from-pdf text I think. I'm quite curious to see how this project goes.

Adobe Expert
August 13, 2023

Every word is reversed in situ, so the character styles remain as they are.

Robert at ID-Tasker
Brainiac
August 13, 2023

Sorry, I meant part of the word will have different CharStyles / local formatting: 

 

Lorem Ipsum

 

Will become

 

meroL muspI

 

 

Adobe Expert
August 13, 2023

Oh, in that way. Yes, well, tough. Too bad.

Adobe Expert
August 13, 2023

@m1b 

Mark -- Reversing each individual word (i.e. changing the character direction but not the paragraph direction) may not be the correct approach, but, just for interest's sake, there is a much shorter and quicker way to do it. Copying (or moving) characters as character objects is very slow. Just reverse the strings:

 

words = app.documents[0].stories.everyItem().words.everyItem().getElements();
for (var i = words.length-1; i >= 0; i--) {
  words[i].contents = words[i].contents.split('').reverse().join('');
}

 

See also https://community.adobe.com/t5/indesign-discussions/reversing-selected-text-or-paragraph/m-p/6497724

 

P.

Robert at ID-Tasker
Brainiac
August 13, 2023

But I think you are forgetting about one thing @Peter Kahrel - what if there are different CharStyles applied - or local formatting?

 

Brainiac
August 13, 2023

Reversing the character order is the wrong approach.

There are ME versions of InDesign for a reason.

https://helpx.adobe.com/indesign/using/arabic-hebrew.html

 

 

Robert at ID-Tasker
Brainiac
August 13, 2023

The source is something extracted from the PDF - not the original INDD file... 

 

Willi Adelberger
Adobe Expert
August 13, 2023

Did you try to choose a different composer in the paragraph style settings > Fine Tuning?

Known Participant
August 13, 2023

The subject is that I installed a plugin that convert from pdf to indd that works only LTR , when i tried it on an arabic pdf , arabic characters are reversed , I want the script for this reason

m1b
Brainiac
August 13, 2023

Ah! So what happens to punctuation?

Is "hello ramy." written as (1) "olleh .ymar" or (2) "olleh ymar."

m1b
Brainiac
August 12, 2023

Just confirming, your situation is:

1. Ex : ( olleh ymar ) intstead of  ( hello ramy )

or

2. Ex : ( ymar olleh ) intstead of  ( hello ramy )

?

Known Participant
August 13, 2023

1. Ex : ( olleh ymar ) intstead of  ( hello ramy )

m1b
Brainiac
August 13, 2023

Interesting! I am very curious how you got a document with words that are reversed. Quite unique! I have written a script that will reverse each word. Give it a try and see if it helps.

- Mark

 

 

/**
 * @discussion https://community.adobe.com/t5/indesign-discussions/script-to-reverse-characters-whole-page-or-document/m-p/14003574
 */
app.doScript(reverseWords, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Script');


/**
 * Reverse order of characters of words of
 * (a) selection, if any, or of
 * (b) the entire active document.
 * @7111211 m1b
 * @version 2023-08-13
 * @9397041 {Text|TextFrame|Document} [texts] - the text or contiainer to reverse (default: active document).
 */
function reverseWords(texts) {

    texts = texts || app.selection[0];

    if (!texts)
        texts = app.activeDocument.stories.everyItem().getElements();

    if (texts.hasOwnProperty('stories'))
        texts = texts.stories.everyItem().getElements();

    if (texts.constructor.name !== 'Array')
        texts = [texts];

    /* uncomment the following lines to customize the deinfition of "word"
        app.findGrepPreferences = NothingEnum.NOTHING;
        app.changeGrepPreferences = NothingEnum.NOTHING;
        app.findGrepPreferences.findWhat = '[[:alnum:]]+';
    */

    for (var i = 0; i < texts.length; i++) {

        if (
            !texts[i].isValid
            || !texts[i].hasOwnProperty('words')
        )
            continue;

        /* use the following definition of "words" if using findGrep */
        // var words = texts[i].findGrep();

        /* ... otherwise use Indesign's definition */
        var words = texts[i].words;

        for (var w = 0; w < words.length; w++) {

            var charCount = words[w].characters.length - 1;

            // add characters in reverse order
            for (var j = charCount; j >= 0; j--)
                words[w].characters[j].duplicate(LocationOptions.AT_END, words[w]);

            // remove the original text
            words[w].characters.itemByRange(0, charCount).remove();

        }

    }

};

 

 

Edit 2023-08-13: changed definition of "words" to use Indesign's normal definition.

Known Participant
August 12, 2023

help here please