Scripting hyperlink replacement

Tagged: 

Viewing 4 reply threads
  • Author
    Posts
    • #66812

      Hi, folks! New to the forums, but ancient to DTP (1985!). I have a question related to scripting and important a bunch of processed files for a book.

      The files have tons of embedded URLs. We had this nifty idea that for every URL, instead of simply removing them or footnoting them or what have you in the paper edition of the book, that we would create a unique three-letter code for URL that would appear in the margin. A little text treatment will indicate some text has a corresponding URL. Someone will tap in a short domain plus the code and be redirected. (I did something like this four years ago for a book and it worked out very well.)

      Now, I am a long-time scripting/database guy, and I have no trouble parsing out all the URLs in these documents in some source form, generating a unique code, plopping the results into a database, and putting the code into the source document. However, I am stymied by the next steps in InDesign.

      Four years ago, I relied on InDesign Tagged Text to encode the text I was creating. Worked great. This time around, INDTT is driving me insane, and I understand it’s no longer really supported. (My coding often causes a fatal InDesign error on import.)

      What makes sense to me at this stage is to code the source documents so that I can do easy search and replace. I was thinking that if I could tag the text, the URL, and the short code in some fashion in text, that a script would allow me to:

      * Apply the URL to the text as a hyperlink
      * Create an anchored box at that location in the text.
      * Put the short code (also set as a hyperlink) into the anchored box.
      * Apply an object style to the anchored box.

      It might be that I should apply the URL in the source document as a hyperlink, and then use scripting to just manage the anchored box setup.

      (The URL is needed because we are targeting print, PDF, and EPUB/MOBI as outputs.)

      I have a reasonable facility with JavaScript and less so with AppleScript. I’m using the latest InDesign CC.

      Thank you all for any advice!

    • #66819

      Here’s a screen capture of the effect (not entirely refined): the anchored box to the left but baseline aligned to the line in which a hyperlinked bit of text: https://www.dropbox.com/s/0dblp4aa3pj9xek/Screenshot%202014-01-26%2020.52.17.png

    • #66831

      This sure needed a round trip through InDesign’s Document Object Model — hyperlinks, anchored objects, text frames .. the lot! But I think the following will get you started. The following script scans your document for hyperlinks, and creates a new anchored frame to its left on a fixed position. It fills the frame with a placeholder text — how and where would your abbreviations come from? That part wasn’t entirely clear, but perhaps you can fiddle with my script and add it where you wish.

      The script assumes the following:
      1. An Object Style called “RedBorder”. Please note: make sure this object style does *NOT* define any Anchored Object settings! These will override the ones that I put in my script (as I only found out after some serious head scratching).
      2. A Paragraph Style called “RedCaps”.
      3. Some texts marked with a hyperlink to an external URL.
      4. The baseline of the new box will be aligned to the baseline of your text. I moved it down 1mm, but how much it needs to have the *text* inside it aligned depends (I think) on the font and size of the paragraph style RedCaps. I suppose it’s easiest to run the script once, move one of the anchored objects up or down until it aligns correctly, note down the vertical offset, and then discard your new document and run the script again, with the correct value inserted. I don’t think this step can be automated.

      First off, let me show a *short* sample script to illustrate how Hyperlinks work in InDesign. A Hyperlink is an abstract item, only visible in the Hyperlinks palette, which has two important properties: where it *points to* (which can be anything: to another page, to a text location, or — the one you want — to an external URL), and what the *link* item is in your document (this can be a Cross Reference, any clickable Page Item such as a button, or some plain text). The following script changes the font of all of your *text* links that point to *URLs* to something else:

      links = app.activeDocument.hyperlinks;
      for (i=0; i<links.length; i++)
      {
      if (links[i].source instanceof HyperlinkTextSource &&
      links[i].destination instanceof HyperlinkURLDestination)
      links[i].source.sourceText.appliedFont = “Comic Sans”;
      }

      You see it needs to check the *type* of both source and destination, because not every ‘clickable’ item may have a font, and not every link may point to an URL.

      The *sourceText* is where I am going to insert a new anchored object; then I set some properties, so your text can be inserted and the anchor is moved into position, and finally, the same *destination* is applied to this new object — not to its text as you requested, but — hey! — to the entire rectangle. Instant Hyperlink Buttons ahoy!

      Here is the full script; after copying, take care to check it for unexpected modifications, such as curly quotes (they should all be straight) and en-dashes (these probably should be two hyphens). Also, make sure the object and paragraph styles exist before running (it won’t work otherwise). Hope it’s enough to get you started!

      // Get list of links — the following forces a COPY of ID’s internal list
      // That is important, because we’re going to ADD a lot of them :-/
      links = app.activeDocument.hyperlinks.everyItem().getElements();

      for (i=0; i<links.length; i++)
      {
      if (links[i].source instanceof HyperlinkTextSource &&
      links[i].destination instanceof HyperlinkURLDestination)
      {
      r = links[i].source.sourceText.insertionPoints[0].textFrames.add();
      // initially inline; convert to Anchored Object
      r.anchoredObjectSettings.anchoredPosition = AnchorPosition.ANCHORED;

      // set some Anchored Object properties
      r.anchoredObjectSettings.horizontalReferencePoint = AnchoredRelativeTo.TEXT_FRAME;
      r.anchoredObjectSettings.verticalReferencePoint = VerticallyRelativeTo.LINE_BASELINE;
      r.anchoredObjectSettings.pinPosition = false;
      r.anchoredObjectSettings.anchorXoffset = “5mm”;
      r.anchoredObjectSettings.anchorYoffset = “1mm”; // <- Find proper value!

      // apply object style. Make sure it *sets* no Anchored Style!
      r.appliedObjectStyle = app.activeDocument.objectStyles.item(“RedBorder”);

      // write some text into it
      r.texts[0].contents = “AAA”;
      r.texts[0].appliedParagraphStyle = “RedCaps”;
      // make sure it has some space left and right
      r.textFramePreferences.firstBaselineOffset = FirstBaseline.CAP_HEIGHT;
      r.textFramePreferences.insetSpacing = [“1mm”, “3mm”,”1mm”,”3mm”];
      // ..first make it *way* too large (hopefully)
      r.geometricBounds = [0,0, “10mm”,”100mm”];
      // .. then resize to fit
      r.fit (FitOptions.FRAME_TO_CONTENT);

      // make the entire rectangle a hyperlink, pointing to the same
      // URL as the original one
      newlink = app.activeDocument.hyperlinks.add(app.activeDocument.hyperlinkPageItemSources.add(r), links[i].destination);
      newlink.visible = false;
      }
      }

    • #66837

      This is great, but I think it far outstrips my ability to make work! I’ll give it a shot. Thank you!

    • #66853

      Well, it should work right out of the box (providing you have some hyperlinks in your document).

      What sort of database are your Abbreviations/Hyperlinks in? If you can export them to a simple text list, you can have the script look them up automatically. That would be something like (warning: making this up as I type):

      // add this list at the very top of the script;
      // take note to close all the [ that you open ], nested as shown
      var abbrList = [ [“AAA”, “https://creativepro.com”%5D,
      [“AAB”, “https://www.adobe.com”%5D,
      [“XYZ”, “https://forums.adobe.com/community/indesign?view=discussions”%5D,
      [“MIT”, “https://jongware.mit.edu/idcs6js/index.html&#8221; ] ]; // etc. — full hyperlinks!

      and then instead of inserting a plain fixed text

      r.texts[0].contents = “AAA”;

      replace it with a loop over the abbrList array, checking if the link is in there and inserting the proper abbreviation if found:

      r.parentStory.contents = “???”;
      for (j=0; j<abbrList.length; j++)
      if (abbrList[j][1] == links[i].destination.destinationURL)
      {
      r.parentStory.contents = abbrList[j][0];
      break;
      }

      Also, add this line under the comment line:
      // set some Anchored Object properties

      r.anchoredObjectSettings.anchorPoint = AnchorPoint.BOTTOM_RIGHT_ANCHOR;

      — I found the position from the left margin and baseline depends on your current *default* settings, and they happened to be correct for my initial test.

Viewing 4 reply threads
  • You must be logged in to reply to this topic.
>