Skip to main content
Inspiring
September 24, 2012
Answered

Find hyperlink text source from destination

  • September 24, 2012
  • 2 replies
  • 8852 views

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.

This topic has been closed for replies.
Correct answer Trevor:

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.

Regards,

Trevor.

P.s.

MAKE SURE THAT THE JAVASCRIPT CONSOLE IS OPEN OR YOU WILL NOT SEE THE SCRIPT DO ANYTHING!!!

// 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"] = [];

             }

            hyps[myHyperLinks[hll].destination.index]["Sources"].push(myHyperLinks[hll].source);

        }

     }

// 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--)

                {

                    dests[dl]["SourceNames"].push(hyps[destIndex]["Sources"].sourceText.contents);

                    dests[dl]["SourceIndexs"].push(hyps[destIndex]["Sources"].index);

                    (hyps[destIndex]["Sources"].sourceText.parentTextFrames[0].parentPage != null) ?

                    dests[dl]["SourcePages"].push(hyps[destIndex]["Sources"].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

        q=0,

        indexAdjust = mySelection.parentStory.texts.itemByRange (mySelection.parentStory.characters[0], mySelection.characters[0]).characters.length-1,

        myStory=mySelection.parentStory.index,

        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

                    {

                        mySelectionDestinations.push(dests[myDestinationsSearchTable[myStory+"x"+(q+indexAdjust)]]);

                        $.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.toSource()+"\r--------------------------");

$.writeln("++++++++++++++++++++++++++++++++++++\r\r"+

    "These are all the document's hyperlink destinations with source and other properties\r");   

for (n in dests) $.writeln (n+"\t"+dests.toSource()+"\r**********************");

2 replies

Trevor:
Trevor:Correct answer
Legend
October 10, 2012

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.

Regards,

Trevor.

P.s.

MAKE SURE THAT THE JAVASCRIPT CONSOLE IS OPEN OR YOU WILL NOT SEE THE SCRIPT DO ANYTHING!!!

// 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"] = [];

             }

            hyps[myHyperLinks[hll].destination.index]["Sources"].push(myHyperLinks[hll].source);

        }

     }

// 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--)

                {

                    dests[dl]["SourceNames"].push(hyps[destIndex]["Sources"].sourceText.contents);

                    dests[dl]["SourceIndexs"].push(hyps[destIndex]["Sources"].index);

                    (hyps[destIndex]["Sources"].sourceText.parentTextFrames[0].parentPage != null) ?

                    dests[dl]["SourcePages"].push(hyps[destIndex]["Sources"].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

        q=0,

        indexAdjust = mySelection.parentStory.texts.itemByRange (mySelection.parentStory.characters[0], mySelection.characters[0]).characters.length-1,

        myStory=mySelection.parentStory.index,

        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

                    {

                        mySelectionDestinations.push(dests[myDestinationsSearchTable[myStory+"x"+(q+indexAdjust)]]);

                        $.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.toSource()+"\r--------------------------");

$.writeln("++++++++++++++++++++++++++++++++++++\r\r"+

    "These are all the document's hyperlink destinations with source and other properties\r");   

for (n in dests) $.writeln (n+"\t"+dests.toSource()+"\r**********************");

Kasyan Servetsky
Legend
September 24, 2012

var doc = app.activeDocument;

// the 1st hyperlink

var h1 = doc.hyperlinks[0];

// Jumps to the hyperlink source and selects it

h1.showSource();

// Jumps to the hyperlink destination but doesn't select it

h1.showDestination();

Trevor:
Legend
September 24, 2012

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)

Thanks

Trevor

Kasyan Servetsky
Legend
September 24, 2012

Hi Trevor,

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

Main();

function Main() {

    var hyperlink, destination, source,

    doc = app.activeDocument,

    hyperlinks = doc.hyperlinks;

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

        hyperlink = hyperlinks;

        $.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.

Regards,

Kasyan