is now part of CreativePro.com!

Transpose two characters

26

I was editing a large file yesterday, and repeatedly needed to move periods from outside closing quotes to the inside. I like to use drag and drop text editing for moving text around, but trying to select and then drag and drop a single character is infuriating.

InCopy has a cool “Transpose” command that will change the order of the characters on either side of the cursor. But alas, InDesign has no such command.

So I whipped up a quick script called TransposeTwoCharacters that does just that: It will swap the order of the characters to the right and left of the insertion point. Just put your cursor between two characters that need to be swapped, and double-click on the script in the Scripts panel. Even better, use the Keyboard Shortcut Editor to assign a keyboard shortcut to the script so that you can transpose characters with a simple keystroke.

Keith Gilbert is a design consultant, developer, educator, speaker, and author. His work has taken him throughout North America, Africa, Europe, and Asia. During his 35+ year career his clients have included Adobe, Apple, Target, Oracle, and the United Nations. He is the author of several popular titles for LinkedIn Learning, Adobe Press, and CreativePro. Find him at gilbertconsulting.com and on Twitter @gilbertconsult
  • James Fritz says:

    Great script!

    Transpose is one of my favorite InCopy features that I miss in InDesign. The other favorite of mine is the position marker, but I think that would be much more difficult to script.

  • Keith Gilbert says:

    Peter Kahrel has a script called “set/find a bookmark” at https://www.kahrel.plus.com/indesign/qm.html that does essentially the same thing as the position marker in InCopy.

  • Would it be better using a Grep Find/Change if you “repeatedly” have to do this in a document?

    Here what you can do:
    Find (?)(.)
    Replace $2$1

  • Sorry, wrong formating

    Find (~})(.)
    Replace$2$1

  • Keith Gilbert says:

    @Jean-Claude, Find/Change would definitely be a better solution for “repeatedly” doing this, as you point out. But on this particular project, I received a PDF back from the editors with so many red markups it looked like the measles! Many, many of the markups were simple transposition problems, but without much of a pattern or repeatability. There were lots of unique exceptions. So I couldn’t really use Find/Change in this case, and had to visit each edit manually.

  • @Keith – I knew there was a reason. Look like someone have some sort of a dyslexia problem when writing. ;-)

    Thanks for the script, always useful.

  • Pat LaCosse says:

    For things like this I have long wished InDesign had a Range object analogous to the Range object in MS Word. It would make manipulating selected text a lot easier.

  • Pat: Translation please?

  • Aaron Priven says:

    See, if InDesign just had an embedded version of vi, you could just type “xp” at the cursor.

    It’s a natural progression from “GREP styles”…

  • Keith Gilbert says:

    What I think Pat is referring to in the comment above has to do with how I wrote the script. The “object model” for Word has a unique way to refer to a “range” of text, from a starting character position to an ending character position. The InDesign object model has no such device, so referencing a “range” of characters with a script in InDesign is a little trickier than in Word.

    What Arron is referring to in his post is the “VI” text editor for Unix. https://www.onlineitdegree.net/vi-editor/

  • David Eisenberg says:

    One feature Microsoft Word has is the built in “move up” and “move down” functions. You click the up or down arrow in the toolbar and the entire paragraph (or multiple paragraphs if selected) moves up or down. This also works in a table.

    This is the one capability that requires me to do most of my editing workflow in Word rather than InDesign, which is quite a shame.

    (The other major missing feature is script recording which would make InDesign scripting accessible to everyone.)

  • Jongware says:

    David: That was not too hard to script! I haven’t checked out the Transpose script yet, perhaps it works in a similar way. I’ve posted my two scripts here: in the Script forum.

    One moves your current paragraph (the one with the cursor in it) or all of the selected paragraphs (in their entirety) one paragraph up, the other one paragraph down.
    It’s not a perfect copy of the Word function; it doesn’t work inside tables, because that has a vastly different text model.

  • Keith Gilbert says:

    Gah! Jongware, in the time it took me to write myself a note to “someday” see about writing a script to move paragraphs up and down, you wrote the actual script! Cool.

  • Boris says:

    This is Dave Sanders Script ToggleChars (from 2008, LassoSoft List)

    // Check for a selection of the right type

    if (app.selection.length > 0 && app.selection[0].constructor.name == «InsertionPoint») {
    toggleChars(app.selection[0]);
    }

    /*First thing the toggleChars function must do is check is that the
    insertion point is not first or last (get text flow reference along
    the way */

    function toggleChars (myIP) {
    myTextFlow = myIP.parent; // gives story or cell, as appropriate
    if (myIP != myTextFlow.insertionPoints[0] && myIP != myTextFlow.insertionPoints[-1]) {
    reallyToggleChars (myTextFlow, myIP);
    }
    }

    /*But even the reallyToggleChars function still has a check to do,
    to see if the character to the right of the insertion point is a
    paragraph marker; ask user if so */

    function reallyToggleChars (myTextFlow, myIP) {
    myIndex = myIP.index
    myChar = myTextFlow.characters[myIndex]; // Char to right has same index as insertion point
    if (myChar.contents == «\r») {
    if (confirm(»Are you sure you want to move the paragraph marker?») == false) {
    // User said No, so get out of here
    return;
    }
    }
    // Finally, we?re ready to rumble
    myTextFlow.characters[myIndex].move(LocationOptions.before,
    myTextFlow.insertionPoints[myIndex-1]);
    app.select(myTextFlow.insertionPoints[myIndex]);
    }

  • Keith Gilbert says:

    I didn’t take into account the need to transpose characters in a table or within an inline text frame. It looks like Dave’s script accommodates table cells, at least. I’ll try to update the script to handle these two cases when I have a chance.

  • Mayoor says:

    This post is not related to transpose characters, but i had no idea where to post it. In Dotless_i script, where a dotless i is inserted at the insertion point according to the unicode number – Can the script be altered so that a glyph can be inserted based on its GID number & not unicode number (as certain glyphs share the same unicode numbers but have different GID numbers-like arrows in Minion Pro font)

  • Keith: Very cool script and I hope you keep posting more! Our enthusiastic, helpful and brainiac members are always willing to bang on them and offer suggestions to make them better, if not digging in and doing the work themselves, as you can see. They’re wonderful!

  • mayoor says:

    Anne-Marie : Thanks a lot. Have posted the query on the forum. This site is just awesome & am pretty pleased with some of the “secrets” about Indesign that you all routinely dole out.

  • Keith Gilbert says:

    I’ve updated the script, adding the ability to transpose text characters in table cells as well as inline text frames, also adding some more error checking and alert dialogs if you try to run the script without an insertion point. I’ve posted the new script at https://gilbertconsulting.com/resources-scripts.html

  • Jamie says:

    As a side note, systems that use OS X’s standard text services (not Adobe) have a shortcut key for ‘transpose’: Control+T.

  • Uwe Laubender says:

    @Keith ? there is another case where your script does not work:
    Text in footnotes.

    “parentStory” is not available there?

    Uwe

  • Derek Pell says:

    This script is not working in ID 17.0.1 Mac.

    • Keith Gilbert says:

      @Derek, the script should work now. I’ve been doing some housecleaning on my Web site and overlooked something. If you continue to have problems, let me know.

  • >