16 Replies Latest reply on May 20, 2013 8:53 AM by Trevorׅ

    Find hyperlink text source from destination

    McShaman Level 1

      If you go to a hyperlink text destination and look in the story editor you should be able to see a little symbol that looks like a rounded corner square with a circle and cross hairs in it. I assume this is an invisible text element which is used to link it to the source.


      What I want to be able to do is select one of these elements and using JavaScript select the source element... However I am having a hard time getting the script to recognise this element as anything... Let alone find out its relationship to a source.


      I hope this is explanatory enough.

        • 1. Re: Find hyperlink text source from destination
          Kasyan Servetsky Level 5
          var doc = app.activeDocument;
          // the 1st hyperlink
          var h1 = doc.hyperlinks[0];
          // Jumps to the hyperlink source and selects it
          // Jumps to the hyperlink destination but doesn't select it
          • 2. Re: Find hyperlink text source from destination
            Trevorׅ Adobe Community Professional

            Hi Kasyan,


            Can you fill in the gap?

            I.e. How to get the contents of a specific hyperlinks destination?


            var myHyperlinks = app.selection[0].findHyperlinks(), l = myHyperlinks.length, myAlert = "";
            while (l--) myAlert += "Source Text: " + myHyperlinks.contents 
                           + "\tDestination Text: " + ??????????? +"\r"; // What to put here ??????
            alert (myAlert)




            • 3. Re: Find hyperlink text source from destination
              Kasyan Servetsky Level 5

              Hi Trevor,


              Assuming we’re talking about hyperlinks pointing to text anchors -- in theory, this should work but in practice it doesn’t.


              function Main() {
                  var hyperlink, destination, source,
                  doc = app.activeDocument,
                  hyperlinks = doc.hyperlinks;
                  for (var i = 0; i < hyperlinks.length; i++) {
                      hyperlink = hyperlinks[i];
                      $.writeln("-------------------------------\r" + i + "\tHyperlink Name: " + hyperlink.name);
                      destination = hyperlink.destination;
                      source = hyperlink.source;
                      if (destination.destinationText.constructor.name == "InsertionPoint") {
                          $.writeln("\tDestination -- Insertion Point");
                      else {
                          $.writeln("\tDestination Text: " + destination.destinationText.contents);
                      $.writeln("\tSource Text: " + source.sourceText.contents);

              According to the scripting reference, destinationText can be either InsertionPoint or Text. In fact, it always returns Insertion Point so we can't get the contents.




              • 4. Re: Find hyperlink text source from destination
                Trevorׅ Adobe Community Professional

                Hi Kasyan,


                Thanks for that,


                Destination.name will give the text PROVIDING that the name is the text contents.


                There were some interesting things I obseved on this topic, but I'm off for a couple of weeks so will not be in touch until then



                • 5. Re: Find hyperlink text source from destination
                  McShaman Level 1

                  I kinda pointed this out in my OP. If you look in the story editor a destination is shown by a single icon (rounded corner square with a circle and cross hairs in it)... as opposed to the source which is identified by a pair of icons with a chain link icon in them. In the case of a source these wrap around content... The destination is a single point, it shold not contain text.


                  What I want to be able to do is select the destination, the single icon (you can do this most easily through story editor) and then using JavaScript identify the source or sources.

                  • 6. Re: Find hyperlink text source from destination
                    Kasyan Servetsky Level 5

                    I think it's impossible to do .

                    • 7. Re: Find hyperlink text source from destination
                      Pickory Level 3



                      Maybe try it the other way round. Get all the hyperlink sources and find which goes to this destination.



                      • 8. Re: Find hyperlink text source from destination
                        McShaman Level 1

                        Ok I looked up the technical name of the symbol in Adobe's hidden character list so I can refer to it correctly.



                        This symbol is called the Bookmark or hyperlink destination marker.


                        It has to be possible to find the source from the destination marker. It is possible possible to find the source from a destination... So all i realy need to do is work out how to get a destination from a destination marker.

                        • 9. Re: Find hyperlink text source from destination
                          Peter Kahrel Adobe Community Professional & MVP

                          Not all text anchors (a.k.a. hyperlink text destinations) are linked to hyperlinks or cross-references. When you delete a cross-reference or a hyperlink, InDesign leaves any attached text anchor alone, and over time you can (and will) end up with numerous orphaned anchors. (Anchors linked to bookmarks are deleted when the corresponding bookmarks are deleted.) I forget the details now, but this script (http://www.kahrel.plus.com/indesign/text_anchors.html) shows how you can find the connections between anchors and hyperlinks/cross-references.



                          • 10. Re: Find hyperlink text source from destination
                            David W. Goodrich Level 3

                            Thank you, Peter, for another wonderful script.



                            • 11. Re: Find hyperlink text source from destination
                              Trevorׅ Adobe Community Professional

                              Hi all


                              Back from my break.


                              I figured out the 2 problem.

                              1) How to get the hyperlink sources from the destinations, i.e. you can't so do it the other way round like Pickory suggested.

                              2) How to search for the Destination symbol that can be seen on the story editor but doesn't have a hidden character symbol.


                              This cannot be done with the indesign GREPs as there is no symbol on the main screan (Peter correct me if I'm wrong) but can be found with a javascript regex

                              reg = /\ufeff/g;
                              q = mySelection.contents.search (reg);


                              All this does is find the symbol but which is just a symbol that contains no information, to find out to which destination it is associated one has to compare the story and insertion point coordinated of the symbol with the values given in the destinations.


                              To do this quickly I make a table (see script)

                              There is a problem with this is that the values or static which is ok for creating an index or something like that but if one changes the main text the story / insertion point of the symbol will change and the script won't find the destination associated with the symbol.  I this is a problem enjoy re-scripting it.










                              // Hyperlink Destination Source Script byTrevor http://forums.adobe.com/message/4721797#4721797
                              // MAKE SURE THAT THE JAVASCRIPT CONSOLE IS OPEN !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                              // SCROLL  UP THE CONSOLE UNTIL YOU SEE (:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)
                              var myDoc = app.documents[0],
                              myDestinations = myDoc.hyperlinkTextDestinations.everyItem().getElements(),
                              mySources = myDoc.hyperlinkTextSources.everyItem().getElements(),
                              myHyperLinks = myDoc.hyperlinks.everyItem().getElements(),
                              dl = dll = myDestinations.length,
                              hl = hll = myHyperLinks.length,
                              myDestinationsSearchTable = [],
                              myHypers = {}, hyps = [], dests = [], n,
                              mySelection = app.selection[0];
                              // Make an index of destionation sources from the hyperlinks that contain both sources and destinations
                              // This will miss any Destinations that don't have sources
                              $.writeln ("\r\r(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)\r(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)(:-)\r\rHyperlinks Sources from Destinations Script\r\rThese are my look up keys")
                              while (hll--) 
                                      if (myHyperLinks[hll].destination != null)
                                          if (hyps[myHyperLinks[hll].destination.index] == null) 
                                              hyps[myHyperLinks[hll].destination.index] = {};
                                              hyps[myHyperLinks[hll].destination.index]["Destination"] = myHyperLinks[hll].destination;
                                              hyps[myHyperLinks[hll].destination.index]["Sources"] = [];
                              // make an array of all destinations with what every properties you want to extract i.e. name location sources page number etc.
                              // add or remove as prperties as needed "DestinationID" is used here for the search look up table
                              while (dl--)
                                      dests[dl] = {};
                                      destIndex = myDestinations[dl].index;
                                      dests[dl]["DestinationID"] = myDestinations[dl].destinationText.parentStory.index+"x"+myDestinations[dl].destinationText.insertionPoints.lastItem ().index;
                                      myDestinationsSearchTable[dests[dl]["DestinationID"]]=dl; // makes a look up table to use for search
                                      $.writeln("myDestinationsSearchTable ["+dests[dl]["DestinationID"]+"] = "+dl);
                                      if (hyps[dl] != null)
                                          dests[dl]["HasSource"] = 1;
                                          dests[dl]["DestinationName"] = hyps[destIndex]["Destination"].name;
                                          dests[dl]["DestinationIndex"] = destIndex;
                                          dests[dl]["DestinationInsertionPoint"] = hyps[destIndex]["Destination"].destinationText.insertionPoints;
                                          dests[dl]["DestinationCharater"] = hyps[destIndex]["Destination"].destinationText.insertionPoints.lastItem ().index;
                                          dests[dl]["DestinationStory"] = hyps[destIndex]["Destination"].destinationText.parentStory.index;
                                          dests[dl]["DestinationCharaterCode"] = myDoc.stories[dests[dl]["DestinationStory"]].characters[dests[dl]["DestinationCharater"]].contents.charCodeAt(0).toString(16);
                                          dests[dl]["DestinationPage"] = (hyps[destIndex]["Destination"].destinationText.parentTextFrames[0].parentPage != null) ?  hyps[destIndex]["Destination"].destinationText.parentTextFrames[0].parentPage.name : "Off the Page";;
                                          dests[dl]["SourceNames"] = [];
                                          dests[dl]["SourceIndexs"] = [];
                                          dests[dl]["SourcePages"] = [];
                                          l = hyps[destIndex]["Sources"].length;
                                          dests[dl]["Destination"] = hyps[destIndex];
                                          while (l--) 
                                                  (hyps[destIndex]["Sources"][l].sourceText.parentTextFrames[0].parentPage != null) ?
                                                  dests[dl]["SourcePages"].push(hyps[destIndex]["Sources"][l].sourceText.parentTextFrames[0].parentPage.name) :
                                                  dests[dl]["SourcePages"].push("Off the page");
                                     else dests[dl]["HasSource"] = 0;
                               // if there's text selected search for destination anchors
                              if ( app.documents.length && app.selection.length && mySelection.hasOwnProperty ( 'baseline' ) && mySelection.constructor.name != "InsertionPoint")
                                      var mySelectionDestinations = [],
                                      // this is the unicode for the destination symbol
                                      indexAdjust = mySelection.parentStory.texts.itemByRange (mySelection.parentStory.characters[0], mySelection.characters[0]).characters.length-1,
                                      reg = /\ufeff/g;
                                      $.writeln("*********** Destinations in Selection **********")
                                      while (q != -1) 
                                              q = mySelection.contents.search (reg)
                                              if (q != -1) // when used in practise remove the if condition and pop array after loop
                                                      $.writeln("mySelectionDestinations ["+(mySelectionDestinations.length-1)+"] = myDestinationsSearchTable ["+[myStory+"x"+(q+indexAdjust)]+"] = "+myDestinationsSearchTable[myStory+"x"+(q+indexAdjust)])
                                      $.writeln ("################\rThese are these are the destinations in the selection: "+mySelectionDestinations+"\r")
                                      for (n in mySelectionDestinations) $.writeln (mySelectionDestinations.toSource()+"\r###########\r\r")
                              $.writeln ("%%%%%%%%%%%%%%\rThese are all the document's hyperlinks that have destination\r");
                              for (n in hyps) $.writeln (n+"\t"+hyps[n].toSource()+"\r--------------------------");
                                  "These are all the document's hyperlink destinations with source and other properties\r");    
                              for (n in dests) $.writeln (n+"\t"+dests[n].toSource()+"\r**********************");
                              • 12. Re: Find hyperlink text source from destination
                                Trevorׅ Adobe Community Professional



                                Was there something not answered here?

                                • 13. Re: Find hyperlink text source from destination
                                  McShaman Level 1

                                  Trevor, sorry for the late responce, I have been out of the country for a while and just going through responce now. Lot of fantastic information there... Thank you very much for your time.

                                  • 14. Re: Find hyperlink text source from destination
                                    Pooja_IDDev Level 1



                                    Can someone please help, i need to find hyperlink text destination from source.

                                    I have pargarph object, so i can find HyperlinkTextSource from paragraph using findHyperlinks(), but i need its corresponding HyperlinkTextDestination.





                                    • 15. Re: Find hyperlink text source from destination
                                      [Jongware] Most Valuable Participant

                                      Poo, see this thread: http://forums.adobe.com/thread/1070892?tstart=0 -- I didn't read it in its entirety but your problem is discussed in there, with several solutions and at least one marked "answered".