3 Replies Latest reply on Oct 15, 2014 9:48 PM by JulianFT

    Append double hyperlink name (myHyperlink, myHyperlink (2), etc.)

    JulianFT Level 1

      Hi there,

       

      I'm writing a script that automatically creates hyperlinks based on XML-tagged source references within a text and their identically tagged counterparts in the reference list. This works fine, except that a reference is sometimes mentioned twice in a text, causing the hyperlink to have the same name and crashing the script. I would like to have the hyperlink names automatically appended with (2), (3) etc. if this occurs. I've tried previously with if/else statements, but sadly to no avail.

       

      My current script, without the appending:

       

      // General declarations
      var myDocument = app.activeDocument;   
      var myRootXML = myDocument.xmlElements[0];   
          
      // Include glue code
      #include "glue code.jsx";
      
      // Some main definitions
      main();
      function main(){
          if (app.documents.length != 0){
              var myDocument = app.documents.item(0);
              //This rule set contains a single rule.
              var myRuleSet = new Array (new findCitationRef);
          with(myDocument){
              var elements = xmlElements;
              __processRuleSet(elements.item(0), myRuleSet);
              }
          }
          else{
              alert("No open document");
          }
      }
      
      // Define function findCitationRef
      function findCitationRef() 
          {
            this.name = "findCitationRef";
            this.xpath = "//CitationRef";
            this.apply = function(myXMLPathSource, myRuleSet){    
               with(myXMLPathSource){
      
                   var myXMLPathSourceID = myXMLPathSource.xmlAttributes.itemByName("CitationID").value;
                    var myXMLPathDestinationID = myXMLPathSource.xmlAttributes.itemByName("CitationID").value;          
                    var myXMLPathDestination = myRootXML.evaluateXPathExpression("//Citation[@ID='" + myXMLPathDestinationID + "']"); 
                    $.writeln(myXMLPathDestination[0].contents);          
                    
                    var citationRefAnchor = myXMLPathSource.texts;
                    var citationDestination = myXMLPathDestination[0].texts;
                    // Store as a variable
                                     
                    var myHyperlinkSource = myDocument.hyperlinkTextSources.add(citationRefAnchor);  
                    var myTextAnchor = myDocument.hyperlinkTextDestinations.add(citationDestination);  
      
                    var myHyperlink = myDocument.hyperlinks.add(myHyperlinkSource, myTextAnchor, {name: "Hyperlink " + myXMLPathDestinationID });
                    
                    false;
      
                }
              }  
           };
      
       // Call function findCitationRef
       findCitationRef();
      

       

      My ill-fated attempt to get it to work, which won't get past the first hyperlink:

       

      // General declarations
      var myDocument = app.activeDocument;   
      var myRootXML = myDocument.xmlElements[0];   
          
      // Include glue code
      #include "glue code.jsx";
      
      // Some main definitions
      main();
      function main(){
          if (app.documents.length != 0){
              var myDocument = app.documents.item(0);
              //This rule set contains a single rule.
              var myRuleSet = new Array (new findCitationRef);
          with(myDocument){
              var elements = xmlElements;
              __processRuleSet(elements.item(0), myRuleSet);
              }
          }
          else{
              alert("No open document");
          }
      }
      
      // Define function findCitationRef
      function findCitationRef() 
          {
            this.name = "findCitationRef";
            this.xpath = "//CitationRef";
            this.apply = function(myXMLPathSource, myRuleSet){    
               with(myXMLPathSource){
      
                // Save the CitationRef ID to the variable, for future reference
                var myXMLPathSourceID = myXMLPathSource.xmlAttributes.itemByName("CitationID").value; 
            
                $.writeln("Eerste bevestiging: " + myXMLPathSource.contents + ": " + myXMLPathSourceID); // TO BE REMOVED
                $.writeln("Tweede bevestiging: " + myXMLPathSource.xmlAttributes.itemByName("CitationID").value); // TO BE REMOVED
                
                // Save the ID for the corresponding Citation        
                var myXMLPathDestinationID = myXMLPathSource.xmlAttributes.itemByName("CitationID").value;   
                
                // Find the corresponding Citation using aforementioned ID
                var myXMLPathDestination = myRootXML.evaluateXPathExpression("//Citation[@ID='" + myXMLPathDestinationID + "']");  
                $.writeln(myXMLPathDestination[0].contents);          // TO BE REMOVED
                
                // Store source and destination items in variables for future use in hyperlink
                var citationRefAnchor = myXMLPathSource.texts;
                var citationDestination = myXMLPathDestination[0].texts;
                                 
                // Create the hyperlink source and destination
                var myHyperlinkSource = myDocument.hyperlinkTextSources.add(citationRefAnchor);  
                var myTextAnchor = myDocument.hyperlinkTextDestinations.add(citationDestination);  
                    
                //Then, create the hyperlink, but first...
                      //... check if there's already at least one hyperlink
                      if(!myDocument.hyperlinks[0].isValid) //
                      {
                          // If not, that's where we'll create it
                          var myHyperlink = myDocument.hyperlinks.add(myHyperlinkSource, myTextAnchor, {name: myXMLPathSourceID});
                      }
      
                      // Otherwise, if there is at least one hyperlink...
                      else 
                      {     
                          // Go through all the hyperlinks
                          for(count=0; count<myDocument.hyperlinks.length; count++){
                              // If there's one with the current ID, create another one, but add the 'b' suffix
                              if(myDocument.hyperlinks[count].name === myXMLPathSourceID) {
                                  var myHyperlink = myDocument.hyperlinks.add(myHyperlinkSource, myTextAnchor, {name: myXMLPathSourceID + "b"});
      
                               }
                              else // If there's none with the current ID...
                              {   
                                  // Check if you've previously created one, and if not, create one:
                                  if(!myDocument.hyperlinks[count].isValid) {
                                  var myHyperlink = myDocument.hyperlinks.add(myHyperlinkSource, myTextAnchor, {name: myXMLPathSourceID});
                                  }
                                  
                                  // If not, that's fine, we're done here. Let's go check the next citation.
                                  else {
                                      } 
                                 } // End check for the current ID
                          } // Stop going through all the hyperlinks
                    } // Stop checking if there's at least one hyperlink
                  }  // Stop going through all the citations
              
              }  
           };
      
       // Call function findCitationRef
       findCitationRef();
      
      
      

       

      Thanks so much for any directions you can give!

       

      Kind regards,

       

      Julian

        • 1. Re: Append double hyperlink name (myHyperlink, myHyperlink (2), etc.)
          JulianFT Level 1

          Anyone that can perhaps give me a direction on why my proposed solution doesn't work? It seemed rather straightforward when I wrote it, but I must've slipped up somewhere. Very frustrating.

          • 2. Re: Re: Append double hyperlink name (myHyperlink, myHyperlink (2), etc.)
            cchimi Level 2

            I do something like this:

             

                    //Hyperlink names must be unique. If a hyperlink has already been created with this name, this iterates a number to append
                    //to the name in the format "(1)".
                    var iter = 0;
                   //Check if a hyperlink with the name I want to use already exists and that it isn't this hyperlink.
                    while (myDoc.hyperlinks.itemByName(myHyperName).isValid 
                            && myDoc.hyperlinks.itemByName(myHyperName).source.sourceText !== myThingToHyper){
                        //Bump up the number to append by one.
                        iter++;
                       //Change the hyperlink name so that the old number is replaced with the new one.
                        myHyperName = myHyperName.replace(/ \(\d+\)$/, "") + " (" + iter + ")";
                    }
            

             

            You could modify that to append a letter instead; the easiest way I know to do that is to create a variable string that holds the alphabet and slice out the letter you need, but there might be other ways.

             

            I think the problem with your script is that you're not accounting for cases where there are more than two hyperlinks with the same name. You want to use a while loop to ensure you keep looping until you hit a free number/letter.

            • 3. Re: Re: Append double hyperlink name (myHyperlink, myHyperlink (2), etc.)
              JulianFT Level 1

              That works absolutely brilliantly, thank you so much! I should probably look into while loops some more, apparently I haven't really grasped the full possibilities of them yet.