Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Adding Anchors Based on Paragraph Style in Javascript

Community Beginner ,
Dec 29, 2011 Dec 29, 2011

I have been reading over the documentation for days and am just trying to figure out how to add an anchor to a paragraph style in javascript. This is what I have so far:

function main(){

var myDoc = app.activeDocument;

var num_pars = myDoc.stories[0].paragraphs.length;

for (i =0; i<num_pars; i++) {

    if( myDoc.stories[0].paragraphs.item(i).appliedParagraphStyle.name == "Title" ) {

aText = app.activeDocument.stories[0].paragraphs[0];

aDest = app.activeDocument.hyperlinkTextDestinations.add(aText,{name:aText.contents});

}

}

}

What am I doing wrong?

TOPICS
Scripting
5.2K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Beginner , Jan 14, 2012 Jan 14, 2012

I figured it out! Thanks for all your help! Here is the final code for anyone who might be looking for what I could not find before:

function main() {

    var myDoc = app.activeDocument;

    var anchorsAddedCnt = 0;

    app.findGrepPreferences.appliedParagraphStyle = "Title";

          app.findGrepPreferences.findWhat = "^.";

          var myTitleResult = myDoc.findGrep();

   

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

        var anchor = myDoc.hyperlinkTextDestinations.add(myTitleResult)

...
Translate
Community Beginner ,
Dec 30, 2011 Dec 30, 2011

Two things:

1. The line

aText = app.activeDocument.stories[0].paragraphs[0];

should say "paragraphs" instead of "paragraphs[0]."

and

2. the line

aDest = app.activeDocument.hyperlinkTextDestinations.add(aText,{name:aText.co ntents});

has a space in the middle of the word "contents." Once I changed those two things, your script worked for me.

Here is another version of your code, slightly cleaned up and with the global variables "aText" and "i" changed to local variables using var statements, because global variables kind of defeat the purpose of encapsulating your code in the function "main."

The variable "aDest" I have removed entirely, since you're not saving it somewhere else every time it's reassigned anyway. Of course, if you really happen to want "aDest" to be assigned to the last destination to be created, then you should leave it in.

function main() {

    var myDoc = app.activeDocument;

    var myStory = myDoc.stories[0];

    var num_pars = myStory.paragraphs.length;

    var aText;

    for (var i = 0; i < num_pars; i++) {

        if (myStory.paragraphs.appliedParagraphStyle.name == "Title") {

            aText = myStory.paragraphs;

            myDoc.hyperlinkTextDestinations.add( aText, {name: aText.contents} );

        }

    }

}

By the way, an excellent resource on the Internet for instantly and easily re-indenting and tidying up the spacing of Javascript code is a website called jsbeautifier.org.

Happy New Year,

Richard

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Dec 30, 2011 Dec 30, 2011

I appriciate your assistance and Happy New Year(!) but it still does not work... Any other suggestions? It didn't add the anchor...

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Dec 30, 2011 Dec 30, 2011

Sorry, I don't have any more suggestions. It works for me.

By the way, after you create the text anchor, you have to choose a different block of text to be the hyperlink, and link it to that text anchor, either with the "New Hyperlink" dialog box or with a script.

Even then, all this has no effect if you're just using InDesign, as far as I know. It only becomes important when you export to a pdf, and then if you have all the settings correct, your hyperlinks become clickable links in the pdf.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jan 02, 2012 Jan 02, 2012

I've got a script that does almost exactly what you need!

It was written to add anchors to the beginning of footnote paragraphs, so the anchors are set and numbered sequentially. To include the text of the found paragraph you would have to change the findWhat grep search to one that would include the whole paragraph, then replace "FNText" + i with myFootnoteTextResult I think (I haven't tested that, you might need to turn it into a string/text)

Below are the two snippets you will need:

    app.findGrepPreferences.appliedParagraphStyle = "footnote";

    app.findGrepPreferences.findWhat = "^.";

    var myFootnoteTextResult = app.activeDocument.findGrep();

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

        var anchor = myDocument.hyperlinkTextDestinations.add(myFootnoteTextResult);

        anchor.name = "FNText" + i;

   }

Good luck!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jan 14, 2012 Jan 14, 2012

I figured it out! Thanks for all your help! Here is the final code for anyone who might be looking for what I could not find before:

function main() {

    var myDoc = app.activeDocument;

    var anchorsAddedCnt = 0;

    app.findGrepPreferences.appliedParagraphStyle = "Title";

          app.findGrepPreferences.findWhat = "^.";

          var myTitleResult = myDoc.findGrep();

   

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

        var anchor = myDoc.hyperlinkTextDestinations.add(myTitleResult);

        anchor.name = "A00.01.00";

        anchor.label = "A00.01.00";

           

        anchorsAddedCnt += 1;

    }

    // alert("Added " + anchorsAddedCnt + " anchors");

    $.writeln("Added " + anchorsAddedCnt + " anchors");

}

main();

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 15, 2012 Jan 15, 2012

All of your anchors end up with the same name. Isn't that going to be a problem?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jan 17, 2012 Jan 17, 2012

My documents are set up so there is only one result per a page for the anchor.

Now I am trying to create the hyperlinks.

---

//Add Hyperlinks

function main() {

    var myDoc = app.activeDocument;

    var LinksAddedCnt = 0;

    app.findTextPreferences = null;

    app.findTextPreferences.findWhat = "Back to Summary";

          var myLinkResult = myDoc.findText();

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

        //Define Link Text

        var myLinkText = myDoc.hyperlinkTextSources.add(myLinkResult);  

        //Choose Link's Destination Anchor

        var myLinkAnchorDest = myDoc.hyperlinkTextDestinations.add("A00.01.00");

        //Create Hyperlink

        var myHyperlink = myDoc.hyperlinks.add(myLinkText,myLinkAnchorDest);

        myHyperlink.name = "A00.01.00";

        myHyperlink.label = "A00.01.00";

        LinksAddedCnt += 1;

    }

    // alert("Added " + LinksAddedCnt + "links");

    $.writeln("Added " + LinksAddedCnt + " links");

}

main();

---

I keep getting an error stating:

"The object you have chosen is alre4ady in use by another hyperlink."

Any advice on how to get this working? I am trying to get the hyperlink to go to the already defined anchor from the other script...

I appreciate your time in advance!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jan 17, 2012 Jan 17, 2012

Which line gives you that error?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 17, 2012 Jan 17, 2012

Uh, this is exactly why naming all of your anchors was going to be a problem. See the other answers above for ways to generate unique anchor names.

It doesn't matter you only have one anchor per page, they work document-wide.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jan 17, 2012 Jan 17, 2012

I meant per a document - my apologies.

The line producing the error is this:

        var myLinkText = myDoc.hyperlinkTextSources.add(myLinkResult);  

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jan 17, 2012 Jan 17, 2012

Jongware is right. This script is only operating on one document, so it's creating many hyperlinks and destinations with the same names in a single document. You'll need them to have different names.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jan 17, 2012 Jan 17, 2012

Can they all have the same destination though?

How about this?

//Add Hyperlinks

function main() {

    var myDoc = app.activeDocument;

    var LinksAddedCnt = 0;

    app.findTextPreferences = null;

    app.findTextPreferences.findWhat = "Back to Summary";

          var myLinkResult = myDoc.findText();

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

        var myLinks = myLinkResult

        //Define Link Text

        var myLinkText = myDoc.hyperlinkTextSources.add({sourceText: myLinks, name: "A00.01.00" || Math.random().toString()});  

        //Choose Link's Destination Anchor

        var myLinkAnchorDest = myDoc.hyperlinkTextDestinations.add({destinationText: "A00.01.00", name: "A00.01.00" || Math.random().toString()});

        //Create Hyperlink

        var myHyperlink = myDoc.hyperlinks.add(myLinkText,myLinkAnchorDest);

        LinksAddedCnt += 1;

    }

    // alert("Added " + LinksAddedCnt + "links");

    $.writeln("Added " + LinksAddedCnt + " links");

}

main();

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jan 20, 2012 Jan 20, 2012

You want all of these things to point to one destination, right?

So what you need to do is create that one destination outside of the for loop. Then point everything towards it.

The script below should do what you want. You don't even need all those assignments of name properties that you had in your script, unless you want to save the names for future reference, which you're not doing in the current version of the script. All of the new hyperlink objects and sourceText objects do need to have unique names, but InDesign will automatically generate those for you.

var main = function() {

    // Constants (so that you can easily change this in the future).

    var DEST_TEXT_STRING = "A00.01.00";

    var SRC_TEXT_STRING = "Back to Summary";

    // Regular variables

    var myDoc = app.activeDocument;

    var myLinkResult, myLinkAnchorDest, myLink, myLinkText;

    var LinksAddedCnt = 0;

    var i;

    // Get reference to destination text and create the hyperlink destinatin.

    app.findTextPreferences = NothingEnum.nothing;

    app.findTextPreferences.findWhat = DEST_TEXT_STRING;

    myLinkResult = myDoc.findText();

    if (myLinkResult.length === 1) {

        myLinkAnchorDest = myDoc.hyperlinkTextDestinations.add(myLinkResult[0]);

    } else {

        alert("There should be one and only one destination. Please fix this and try again.");

        exit();

    }       

     // Now get all the references to source texts and create the hyperlinks.

    app.findTextPreferences = NothingEnum.nothing;

    app.findTextPreferences.findWhat = SRC_TEXT_STRING;

    myLinkResult = myDoc.findText();

    for (i = 0; i < myLinkResult.length; i += 1) {

        myLink = myLinkResult;

        //Define Link Text

        myLinkText = myDoc.hyperlinkTextSources.add(myLink);

        //Create Hyperlink

        myDoc.hyperlinks.add(myLinkText, myLinkAnchorDest);

        LinksAddedCnt += 1;

    }

    $.writeln("Added " + LinksAddedCnt + " links");

};

main();

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jan 21, 2012 Jan 21, 2012

I strongly appreciate this but the problem I have is that the text anchor being searched for is intentionally in another document. It will work once the two documents are in a book file...

I know this probably goes against all programming principles but how do I get this to work without using this strategy? Since every time, it will not be found...

// Get reference to destination text and create the hyperlink destinatin.

    app.findTextPreferences = NothingEnum.nothing;
    app.findTextPreferences.findWhat = DEST_TEXT_STRING;
    myLinkResult = myDoc.findText();

    if (myLinkResult.length === 1) {
        myLinkAnchorDest = myDoc.hyperlinkTextDestinations.add(myLinkResult[0]);
    } else {
        alert("There should be one and only one destination. Please fix this and try again.");
        exit();
    }   

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jan 21, 2012 Jan 21, 2012

No problem. Here is a version that will work for you. It only has a couple minor changes, none of which violate any programming principles at all.

Make sure all the relevant documents are open and saved, before running this script.

var main = function() {

    // Constants (so that you can easily change this in the future).

    var DEST_TEXT_STRING = "A00.01.00";

    var SRC_TEXT_STRING = "Back to Summary";

    // Regular variables

    var myLinkResult, myLinkAnchorDest, myLink, myLinkText;

    var LinksAddedCnt = 0;

    var myDoc;

    var i;

    // Get reference to destination text and create the hyperlink destinatin.

    app.findTextPreferences = NothingEnum.nothing;

    app.findTextPreferences.findWhat = DEST_TEXT_STRING;

    myLinkResult = app.findText();

    if (myLinkResult.length === 1) {

        myLink = myLinkResult[0];

        myDoc = myLink.parentStory.parent;

        myLinkAnchorDest = myDoc.hyperlinkTextDestinations.add(myLink);

    } else {

        alert("There should be one and only one destination. Please fix this and try again.");

        exit();

    }

     // Now get all the references to source texts and create the hyperlinks.

    app.findTextPreferences = NothingEnum.nothing;

    app.findTextPreferences.findWhat = SRC_TEXT_STRING;

    myLinkResult = app.findText();

    for (i = 0; i < myLinkResult.length; i += 1) {

        myLink = myLinkResult;

        myDoc =  myLink.parentStory.parent;

        //Define Link Text

        myLinkText = myDoc.hyperlinkTextSources.add(myLink);

        //Create Hyperlink

        myDoc.hyperlinks.add(myLinkText, myLinkAnchorDest);

        LinksAddedCnt += 1;

    }

    $.writeln("Added " + LinksAddedCnt + " links");

};

main();

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jan 22, 2012 Jan 22, 2012

Alright so witht this:

var main = function() {

    // Constants (so that you can easily change this in the future).

    var DEST_TEXT_STRING = "A00.01.00";

    var SRC_TEXT_STRING = "Back to Summary";

    // Regular variables

    var myLinkResult, myLinkAnchorDest, myLink, myLinkText;

    var LinksAddedCnt = 0;

    var myDoc;

    var i;

    // Get reference to destination text and create the hyperlink destinatin.

      app.findTextPreferences = NothingEnum.nothing;

    app.findTextPreferences.findWhat = DEST_TEXT_STRING;

    myLinkResult = app.activeDocument.findText();

    for (i = 0; i < myLinkResult.length; i += 1) {

        myLink = myLinkResult[0];

        myDoc =  myLink.parentStory.parent;

        myLinkAnchorDest = myDoc.hyperlinkTextDestinations.add(myLink);

    }

     // Now get all the references to source texts and create the hyperlinks.

    app.findTextPreferences = NothingEnum.nothing;

    app.findTextPreferences.findWhat = SRC_TEXT_STRING;

    myLinkResult = app.activeDocument.findText();

    for (i = 0; i < myLinkResult.length; i += 1) {

        myLink = myLinkResult;

        myDoc =  myLink.parentStory.parent;

        //Define Link Text

        myLinkText = myDoc.hyperlinkTextSources.add(myLink);

        //Create Hyperlink

        myDoc.hyperlinks.add(myLinkText, myLinkAnchorDest);

        LinksAddedCnt += 1;

    }

    $.writeln("Added " + LinksAddedCnt + " links");

};

main();

It adds the hyperlink but points no where...

Here is one of the results:

1.png

So the question is via javascript, how to I get the code to point like this:

2.png

I hope this helps clarify...

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jan 22, 2012 Jan 22, 2012

Interesting.

We are getting different results, so I probably can't help you any further. On my copy of InDesign (version 7.0.2 on the Mac) the script provides the results shown in your second picture, your desired results. Actually, it's not exactly the same, in that since the script I posted is not naming the destination, InDesign is providing the generic name "Anchor 1" for the anchor, instead of "A00.01.00" as you want. But it's not saying "[none]", which is what it's saying for you, and that's the real issue.

You can change the name, if you want, by changing the line


myLinkAnchorDest = myDoc.hyperlinkTextDestinations.add(myLink);

to

myLinkAnchorDest = myDoc.hyperlinkTextDestinations.add(myLink, {name: DEST_TEXT_STRING});


but this will probably not fix your problem. Sorry I can't be of further help.

Good luck,

Richard

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jan 23, 2012 Jan 23, 2012

Richard:

On my copy of InDesign (version 7.0.2 on the Mac)

FYI, 7.0.3 fixed a veritable panoply of bugs. Upgrading is well worth it (to 7.0.4 at this point).

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jan 24, 2012 Jan 24, 2012
LATEST

John,

Thanks for reminding me!

Yes, we did this at work to help with a horrendous InCopy/InDesign problem where stories were frequently being checked out by two people at once. Just never got around to doing it at home, which I'm doing right now.

- Richard

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines