7 Replies Latest reply on Jan 8, 2014 10:02 PM by gert verrept

    switching words

    gert verrept Level 2

      We want to achieve the following (in works with F&C, but because of the hundreds of changes to be made, we tried a scripting solution):
      In a paragraph we need to switch two consecutive words, so word 1 word2 becomes word 2 word1 .
      I tried this, but it changes all words in the paragraph

      app.findGrepPreferences = NothingEnum.nothing;
      app.changeGrepPreferences = NothingEnum.nothing;

      app.findGrepPreferences.findWhat = “(\\w+) (\\w+) “;
      app.changeGrepPreferences.changeTo = “$2 $1 “;

      app.activeDocument.changeGrep();

        • 1. Re: switching words
          [Jongware] Most Valuable Participant

          If you do not want to switch *every* two words, what is the criterium? How would the script know which words to target?

          • 2. Re: switching words
            gert verrept Level 2

            Indeed, in fact the script should do this:

            we put the cursor before the two words to be switched the script should select those words and reverse the order of them. I tried adding \b, but that only works in some cases. ( an example: "artikel bedoeld " should become "bedoelde artikel", the "e" we can add easily afterwards).

            The advantage of the script is that we can assign shortcut to it and so gain a lot of time.

            • 3. Re: switching words
              Jump_Over Level 5

              Hi,

               

              You could use a code pasted below. To mark 1st word:

              • place cursor before it
              • place cursor somewhere inside this word
              • select more text to mark 1st word of selection

               

              if ( ! (app.selection[0] && app.selection[0].hasOwnProperty ('baseline') ) )
                        { alert ('wrong selection'); exit(); }
              var 
                        mDoc = app.activeDocument,
                        mIPs = app.selection[0].insertionPoints[0],
                        mIPe = mIPs.paragraphs[0].insertionPoints[-1],
                        mTarget = mIPs.parentStory.insertionPoints.itemByRange(mIPs, mIPe).texts[0];
              
              app.findGrepPreferences = app.changeGrepPreferences = null;
              app.findGrepPreferences.findWhat = '(\\b\\w+\\b)(\\s+)(\\b\\w+\\b)';
              app.changeGrepPreferences.changeTo = '$3$2$1';
              
              if (mTarget.words.length > 1) {
                        mTarget = mTarget.words.itemByRange(0,1).texts[0];
                        mTarget.changeGrep();
                        }
              else alert ('wrong position');
              app.findGrepPreferences = app.changeGrepPreferences = null;
              

               

              It should stop if count of words from current point to the end of curr para is less then 2.

               

              Jarek

              • 4. Re: switching words
                [Jongware] Most Valuable Participant

                Unfortunately, the gains may not be as high as you expect. All interaction of a script with InDesign objects (such as text) is slow, especially when working with text -- and it's more noticeable near the end of a long story, where all text manipulations may be agonizingly slow.

                 

                Nevertheless ... here is my attempt. It moves the word the cursor is in (at start, in the middle, or even right after the last character) afrer the next word. In itself it should have been a simple "Word" object manipulation, but I noticed the space at the end is not included in this! So I had to resort to the lower level of moving "Character" objects.

                 

                It seems to work sort of allright, as long as the words don't include punctuation or a hard return (it always seems to take the unexpected route with these).

                 

                p = app.selection[0].parentStory;
                i = app.selection[0].insertionPoints[0].index;
                wrds = p.words.everyItem().getElements();
                w = 0;
                while (wrds[w+1].index <= i) w++;
                p.characters.itemByRange(wrds[w].characters[0],p.characters[wrds[w+1].characters[0].index-1]).move(LocationOptions.AFTER, p.characters[wrds[w+1].characters[-1].index+1]);
                

                 

                Tested on a moderately long article (10 pages of continuous text), and the slowdown near the end is already noticeable.

                • 5. Re: switching words
                  Laubender Adobe Community Professional & MVP

                  @Jongware – I already was about to post my snippet here, but your code is much more efficent than mine!


                  Very cool!!

                   

                  Whether the selection is the first insertion point of the first word, or just parts of the two words are selected:
                  your code will work!

                   

                  You mentioned problems arising because of the ExtendScript definition of a "word" vs. what the user is expecting.

                  Especially if it comes to punctuation; or words coupled together with the wrong character.


                  For these special cases one can see an oversight here:

                   

                  Marc Autret

                  What Exactly is a Word?

                  http://www.indiscripts.com/post/2011/09/what-exactly-is-a-word

                   

                   

                  See below my attempt, that is also working with character ranges.
                  A bit more convoluted than your code and the user has to select at least parts of the two words (no less, no more):

                   

                  //SwitchWordsInSelection_TWO-WORDS-PARTLY-SELECTED.jsx
                  //Uwe Laubender
                  
                  /**
                  * @@@BUILDINFO@@@ SwitchWordsInSelection_TWO-WORDS-PARTLY-SELECTED.jsx !Version! Thu Jan 09 2014 01:39:16 GMT+0100
                  */
                  
                  //PROBLEMS: SEPARATORS !!
                  //What is considered a word?? And how to cope with that???
                  
                  app.scriptPreferences.userInteractionLevel = UserInteractionLevels.interactWithAll;
                  
                  app.doScript(_SwitchWordsInSelection, ScriptLanguage.JAVASCRIPT, [], UndoModes.ENTIRE_SCRIPT, "Switch words in selection");
                  
                  function _SwitchWordsInSelection(){
                  
                  //In case there is punctuation after the second word, the script above will not wotk as expected!!
                  //If the two words have a separate character like a long — it will not work as expected.
                  //Words separated with any of the following signs are not considered as two words:
                  // ;-:|
                  
                  if(app.selection.length === 0 || app.selection.length > 1 || !app.selection[0].hasOwnProperty("baselineShift")){
                      alert("No text selected! Select text that is part of two words.");
                      exit();
                      };
                  
                  var mySelection = app.selection[0];
                  var myWords = mySelection.words;
                  
                  if(myWords.length !== 2){
                      alert("Length of words is: "+myWords.length+". Select text that is part of 2 words.");
                      exit();
                      };
                  
                  //~ //The separation character will not move:
                  //~ mySelection.words[1].move(LocationOptions.AT_BEGINNING,mySelection.words[0]);
                  
                  //So we need something more elaborate:
                  
                  var firstInsPointWordOne = mySelection.words[0].insertionPoints[0].index;
                  var lastInsPointWordOne = mySelection.words[0].insertionPoints[mySelection.words[0].insertionPoints.length-1].index;
                  
                  var firstInsPointWordTwo = mySelection.words[1].insertionPoints[0].index;
                  var lastInsPointWordTwo = mySelection.words[1].insertionPoints[mySelection.words[1].insertionPoints.length-1].index;
                  
                  var wordOne = mySelection.parentStory.characters.itemByRange(firstInsPointWordOne,lastInsPointWordOne);
                  var wordTwo = mySelection.parentStory.characters.itemByRange(firstInsPointWordTwo,lastInsPointWordTwo);
                  
                  wordTwo.duplicate(LocationOptions.AT_BEGINNING,wordOne);
                  wordTwo.remove();
                  app.select(null);
                  
                  };
                  

                   

                  Uwe

                  • 6. Re: switching words
                    Laubender Adobe Community Professional & MVP

                    And yes, I also see speed issues when working at the end of a very large story (about 210,000 characters).

                     

                    Uwe

                    • 7. Re: switching words
                      gert verrept Level 2

                      @Jongware and Laubender, Thankx a million, I'll give this surely a test. I noticed the problems with the spaces and hard returns too in other scripts. This one, I thought would be an easy one, but see, the code is a bit more difficult than I expected. Nevertheless, what bothers the most, the slowing down or the need to use several manipulations before switching two words, we will see. I must say, I noticed the loss of speed already in long docs when using the "F&C by list" script. Law texts can be a real pain when the authors decide to start changing things.