Temporarily highlight a specific text after clicking the link to it (using Javascript)
Copy link to clipboard
Copied
Hi!
I got a scientific paper with many bibliographical references.
It would be useful if readers after clicking an author's year not only got redirected to the page's reference, but that same reference could be temporarily highlited.
For example: text text text (Goetze, 2016)
After clicking the link (2016) the reader is redirected to the page where the complete bibliographical reference is, in this case:
GOETZE, C. (2016). Warlords and States: A Contemporary Myth of the International System. In B. B. de Guevara (Ed.), Myth and Narrative in International Politics: Interpretive Approaches to the Study of IR (pp. 129–146). Palgrave Macmillan.
Since there are a lot o references in the same page it would useful if it got temporarily highlited.
Is it possible to do this using Javascript?
Thanks
Copy link to clipboard
Copied
It is, but it's quite tricky to implement. One option would be to select the first word in the reference, but you'll have to hard-code the word's index for each link.
Another option is to create a Highlight comment for each link, set it as hidden, and then show it when the link is clicked. Then use a TimeOut object (via app.setTimeOut) to hide it again after the desired amount of time.
Copy link to clipboard
Copied
Thanks @try67!
The 2nd option is not what I want.
Could you elaborate on the 1st option? I'm new to using Javascript in Acrobat... 😅
Copy link to clipboard
Copied
Sure. You can use the selectPageNthWord method for that.
For example, this will select word #21 on page 2 (both values are zero-based):
this.selectPageNthWord(1, 20);
To find out which word index to use you would need to print out the whole page's contents and then look for it. You can do that using this code from the JS Console (this will print the current page's text):
var p = this.pageNum;
var numWords = this.getPageNumWords(p);
for (var i=0; i<numWords; i++) {
var word = this.getPageNthWord(p,i,true);
console.println(i+":"+word);
}
Copy link to clipboard
Copied
I mean... what I want is the whole reference to be highlighted.
Would the highlighted comment be under the reference text?
Copy link to clipboard
Copied
For that you must use the second method I described. The comment can be a highlight that spans the entire reference, yes.
Copy link to clipboard
Copied
Right. And how can I do that?
Copy link to clipboard
Copied
I don't have a soup to nuts solution, but if you are using InDesign, you can create layers for each reference highlight (an overprinting highlight shape), export to a layered pdf and use buttons (and/or scripting) to control the pdf layer visibility. Note the viewer would need to use Acrobat or Reader to view layers.
Copy link to clipboard
Copied
Before you get started with the code you need to carefully think about how it will work.
Let's say you did it and the comment becomes visible once you click the link. When should it become hidden again? What needs to trigger that?
Copy link to clipboard
Copied
As try67 says, you have to think carefully about what you want at the end before launching into this programming!
... and good luck if you're new to JavaScript, but it's possible. One of my firs progam was something like that. At the time, it took me several days of programming...
Most of the time we use links to carry out this type of ation, but if we want to indicate the reference in a tooltip, couldn't we use buttons with a transparent background?
Is the link always a year (e.g. 2016)?
What is the size of the document?
Would there be a lot of different links to reference?
Do you want to execute several link at the same time...
@+
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Hi,
Here is a "simple" script that should suit your request.
var searchedText="expressions";
var linkPage=37; // Absolute
for (var p=0; p<this.numPages; p++) {
var nbWords=this.getPageNumWords(p);
for (var i=0; i<nbWords-1; i++) {
if (this.getPageNthWord(p,i,true)==searchedText) {
var q=this.getPageNthWordQuads(p,i);
var m=(new Matrix2D).fromRotated(this,p);
var mInv=m.invert();
var r=mInv.transform(q);
var r=r.toString();
var r=r.split(",");
var f=this.addField(searchedText+"Bt","button",p,[Number(r[0]),Number(r[1]),Number(r[6]),Number(r[7])]);
f.fillColor=color.transparent;
f.userName="Link on page "+linkPage;
f.setAction("MouseUp", "this.pageNum="+(linkPage-1)+";");
}
}
}
But the processing time for word recognition depends on the number of pages and the number of words per page and can be very long. I remember some years ago do approximately the same script and that took more than 12 hours for a 1500-page document. So, it is therefore important to display the progress of the process in order to check where it is and if Acrobat doesn't crash. For the example I did:
Here is the script:
console.show();
console.clear();
d0=new Date();
debut=util.printd("dd-mm HH:MM",d0);
laDate=util.printd("dd-mm-yy",d0);
var searchedText="expressions";
var linkPage=37; // Absolute
var nbFound=0;
var wordsInBook=0;
for (var p=0; p<this.numPages; p++) {
var nb=0;
var nbWords=this.getPageNumWords(p);
for (var i=0; i<nbWords-1; i++) {
wordsInBook++;
console.clear();
console.println("Process Starting: "+debut);
console.println("––––––––––––––");
console.println(nb+" word(s) found on page #"+(p+1)+", "+nbFound+" word(s) in total.");
if (this.getPageNthWord(p,i,true)==searchedText) {
var q=this.getPageNthWordQuads(p,i);
var m=(new Matrix2D).fromRotated(this,p);
var mInv=m.invert();
var r=mInv.transform(q);
var r=r.toString();
var r=r.split(",");
var f=this.addField(searchedText+"Bt","button",p,[Number(r[0]),Number(r[1]),Number(r[6]),Number(r[7])]);
f.fillColor=color.transparent;
f.userName="Link on page "+linkPage;
f.setAction("MouseUp", "this.pageNum="+(linkPage-1)+";");
nbFound++;
nb++;
}
}
}
df=new Date();
fin=util.printd("dd-mm HH:MM",df);
temps=(df.valueOf()-d0.valueOf())/1000/60;
var lesMinutes=parseInt(temps);
var lesSecondes=(temps-lesMinutes)*60;
var lesSecondes=parseInt(lesSecondes*10)/10;
var leTemps="";
if (lesMinutes>0) {
if (lesMinutes==1) {
var leTemps="1 minute";
} else {
var leTemps=lesMinutes+" minutes";
}
}
if (lesSecondes>0) {
if (lesSecondes<2) {
var leTemps=leTemps+" "+lesSecondes+" second"
} else {
var leTemps=leTemps+" "+lesSecondes+" seconds"
}
}
var leTemps=leTemps.replace(/^\s+|\s+$/gm,"");
console.clear();
console.println("Process Starting: "+debut);
console.println("Process Ending: "+fin);
console.println("––––––––––––––");
console.println("Process Duration: "+leTemps);
console.println(nbFound+" word(s) found on the "+this.numPages+" pages with a total of "+wordsInBook+" words.");
Of course, this script can be improved according to your real needs.
Let me know.
@+

