Links in PDF automatisieren

albe1000

Grünschnabel
Im PDF treten Gleichungen mit Gleichungsnummern , z.B. .... XYZ (1.2)
auf ; und im Text selbst Verweise auf diese Gleichung, z.B. ....siehe (1.2)......

Ziel: Links von Verweisen zu den jeweiligen Gleichungen automatisch setzen per Makro

Vielleicht hat jemand von Euch schon eine Lösung und stellt sie mir zur Verfügung.

Mir fehlen jegliche Programmier-und Javascript -Kenntnisse, aber ich bin auf einen
Code für Adobe Acrobat X Pro gestoßen ,welchen ich etwas umgeschrieben habe, so
daß ich ihn auf dem Reader testen kann (später dann ,falls Makro funktioniert, Abo von
Acrobat X Pro und Einsatz von add.Link-Funktion anstatt add.Annot) :
Javascript:
     for(var p=0;p<this.numPages&p<50;p++)
     {
     var numWords=this.getPageNumWords(p);
     for(var i=0; i<numWords; i++)
     {
     var ckWord=this.getPageNthWord(p,i,true);
     if (ckWord==(1.2))
     {var annot=this.addAnnot({page: p,type: "Underline",quads: this.getPageNthWordQuads(p,i)});
     app.alert(p);
     }
     }
     }

Ergebnis: Es werden zwar alle (1.2) unterstrichen (sehr schön !), aber zusätzlich auch alle 1.2, Abb.1.2, 12 !

Ich habe schon einiges ausprobiert, auch "(1.2)" -also als String- , bekomme dann aber keine Ausgabe.



P.S: Stringeigabe hätte den Vorteil, daß ich dann mit :
     for(k=1; k<50; k++)
     {
     for(l=1; l<100; l++)
     {
  
     if( ckWord==("("+k+"."+l+")"))

     }
     }
schon nach allen im Pdf auftretenden Nummern (1.1), (1.2), ... , (2.1), (2.2), ... suchen könnte, welches ja das Ziel ist ;
als (1.2)-Eingabe habe ich dafür keine Lösung gefunden.


Vielen Dank für die Mithilfe

albe1000
 
Zuletzt bearbeitet von einem Moderator:
Du brauchst irgendetwas, um die Nummer einer Gleichung von anderen Bezeichnern (Abb. 1.2) unterscheiden zu können.

Probier mal: if (ckWord == "1.2") (als String, jedoch ohne Klammern innerhalb des Strings!).
 
Hallo ComFreek,

vielen Dank für die Hilfe. Ich habe schon folgendes versucht: if ( ckWord == )

"Hallo" alle Wörter Hallo im PDF werden wie gewünscht unterstrichen
"(1.2)" kein Ergebnis
"1.2" , 1.2 , (1.2) jeweils gleiches Ergebnis: in allen Ausdrücken im PDF, in denen 1.2 auftritt, wird 1.2 unterstrichen

Mit der eingebauten Suchroutine im Adobe - Reader bekomme ich dagegen bei Eingabe von (1.2) auch
nur - wie gewünscht - die Ausdrücke (1.2) markiert.

Ich habe auch schon nach Möglichkeiten gesucht, um den gewünschten Ausdruck (1.2) aus den Suchergebnissen herauszufiltern, aber da der Code - wie angegeben - nicht zwischen "1.2" , 1.2 und (1.2) unterscheidet und immer
nur die 1.2 erkennt und unterstreicht, kann ich ja auch nicht z.B die Funktion ckWord.length zur Selektierung ein-
setzen, da ja alle 3 Ausdrücke den selben Wert 3 ergeben.

Nochmals tausend Dank für Deine Mithilfe, alleine komme ich an dieser Stelle wohl nicht weiter!

albe1000
 
Zuletzt bearbeitet:
"1.2" , 1.2 , (1.2)
Übrigens sind in JavaScript (und in praktisch jeder anderen Programmiersprache) 1.2 und (1.2) die gleichen Ausdrücke. Die Klammern bewirken in deinem Fall gar nichts. Sie wären nur von Bedeutung, wenn du Teile des Ausdrucks Priorität geben möchtest, z. B. 3*(1.2+5).

Ich vermute das Problem ist, dass du zwar in der PDF-Datei (1.2) als Mensch siehst, es so aber nicht in textueller Form wirklich vorliegt. Beispielsweise könnte zwischen der öffnenden Klammer und der 1 ein unsichtbares, kleines Leerzeichen existieren. Deswegen wird (1.2) nicht als ganzes Wort angesehen, sondern vielleicht als drei Wörter: (, 1.2 und ).
Die Suche über Adobe Reader würde eventuell dann daher klappen, weil dieser Leerzeichen oder andere Steuerzeichen zu einem gewissen Grad ignoriert.

Änder mal den Code so ab:
Javascript:
/**
* The functions fixedHex and unicodeLiteral were copied from StackOverflow:  http://stackoverflow.com/a/10937446.
* The original author is Zeta: http://stackoverflow.com/users/1139697/zeta
* The license is CC BY-SA (http://creativecommons.org/licenses/by-sa/3.0/) with attribution requried
*/

/* Creates a uppercase hex number with at least length digits from a given number */
function fixedHex(number, length){
    var str = number.toString(16).toUpperCase();
    while(str.length < length)
        str = "0" + str;
    return str;
}

/* Creates a unicode literal based on the string */  
function unicodeLiteral(str){
    var i;
    var result = "";
    for( i = 0; i < str.length; ++i){
        /* You should probably replace this by an isASCII test */
        if(str.charCodeAt(i) > 126 || str.charCodeAt(i) < 32)
            result += "\\u" + fixedHex(str.charCodeAt(i),4);
        else
            result += str[i];
    }

    return result;
}

var lastFoundWord = "";
for(var p=0; p<this.numPages & p<50; p++)
{
  var numWords = this.getPageNumWords(p);
  for(var i=0; i<numWords; i++)
  {
    var ckWord = this.getPageNthWord(p, i, true);
    if (ckWord == "1.2")
    {
      var annot=this.addAnnot({page: p, type: "Underline", quads: this.getPageNthWordQuads(p, i)});
      app.alert(unicodeLiteral(lastFoundWord));
    }
    lastFoundWord = ckWord;
  }
}
Nun gibt er das Wort ggf. in Unicode-Escapes aus, das er direkt vor der 1.2 findet. Im Idealfall ist das irgendein Zeichen, welches nur bei den Gleichungen auftritt, nicht jedoch bei den anderen Vorkommnissen von 1.2.
 
Zuletzt bearbeitet:
Ich habe den Code eingegeben, bekomme aber leider die Fehlermeldung: Syntax Error: Zeile 23
ohne weitere Fehlerangabe.

Unabhängig davon habe ich kurz vor Erhalt deines Codes einen Weg gefunden, einige der ungewollten Suchergebnisse , nämlich Abb.1.2 und Kap.1.2
durch

var a = this.get PageNthWord (p , i-1) ;
if ((ckWord=="1.2") && (a != "Abb") && (a != "Kap"))

herauszufiltern.

Um die bei der Sucheingabe von "1.2" immer noch zu viel markierten Ausdrücke : 1.2 Kapitelname und auch 1.20
zu unterdrücken habe ich aber noch keine Möglichkeit gefunden.

Die Eigabe des Codes habe ich mehrmals überprüft , dabei aber keinen Fehler entdeckt.

Deinen Ansatz zur Lösung der Aufgabe finde ich sehr gut . Danke für die Hilfe !

albe1000

.
 
Was ist genau Zeile 23 bei dir?

1.2 Kapitelname und auch 1.20
zu unterdrücken habe ich aber noch keine Möglichkeit gefunden.
Für 1.20 könntest du prüfen, ob das nächste Wort eine 0 ist. Es wundert mich allerdings, warum 1.20 nicht als ganzes Wort erkannt wird.
Javascript:
// Eventuell prüfen, ob i-1 bzw. i+1 außerhalb von [0, numWords] liegen
// Wenn getPageNthWord in solchen fehlerhaften Fällen nur "null" zurückgibt, musst du nichts ändern
// Wenn allerdings eine Exception geworfen wird, solltest du mittels if-Bedingungen die Werte prüfen
var prevWord = this.getPageNthWord (p, i-1) ;
var nextWord = this.getPageNthWord(p, i+1);

// Besser wäre eine außerhalb der beiden for-Schleifen deklarierte Blacklist
if ((ckWord=="1.2") && (["Abb", "Kap"].indexOf(prevWord) == -1) && nextWord != "0")
 
Ich hatte Zeile 23 in deinen Code angegeben, hätte ich natürlich angeben müssen !

Durch weiteres Vergleichen mit this .get PageNth Word (p, i-1); konnte ich die vollständige Selektion
erreichen:

if ((( ckWord == k+ "." + l ) && (a != "Abb") && ( a != "Kap") && ( a==" ")))

dabei habe ich schon die Schleife eingebaut, so daß nun ausschließlich alle gewünschten Ausdrücke
"1.1" , "1.2" , ... , "2.1" , "2.2" , ... markiert werden. Sehr schön !

Nun geht es um die Speicherung und Verlinkung der Suchergebnisse.

Dazu habe ich mir folgendes überlegt:

1) Speicherung: alle Ergebnisse "1.1" mit dazugehöriger - schon bestimmter - Seitenzahl p in einen Array schreiben

2) Verlinkung: in - so gut wie allen Fällen - ist das erste Suchergebnis die Gleichung selbst , welche das Lnkziel
darstellt ; es soll also von den Suchtreffern 2 , 3 , 4 , ... zum Suchtreffer 1 hin verlinkt werden.
dies mochte ich durch eine Schleife lösen, welche mir die Array- Einträge entsprechend
ausließt ;
dann kann ich mit der add.Link - Fkt von Adobe die gewünschten Links erstellen lassen.

Ist dies der richtige Weg?

Falls ja, werde ich mal mit dem ausgeliehenen Java-Script- Buch versuchen , dies umzusetzen.

Danke für die weitere Mithilfe!


albe1000
 
Zuletzt bearbeitet:
Hallo ComFreek,


ich habe den Code Dank Deiner Hilfe zum Laufen gebracht, aber die Laufzeit war viel zu groß , da ja für jede Gleichung alle Seiten durchsucht werden mußten.

Mir ist es gelungen, einen neuen Code zu schreiben, welcher in einem Durchgang alle Gleichungsnummern und Verweise herausfiltert.

Alles funktioniert (Speicherung,Sortierung,Verlinkung), nur die allerletzte Zuweisung-nämlich die Seitenzahl, zu dem der jeweilige Verweis gehen soll - läßt sich nicht darstellen.

Mir gelingt es nicht, dem Link - Object von Adobe eine Variable (Seitenzahl des Linkzieles) zu übergeben:

Das Object sieht so aus:

l=addLink(............);
l.setAction("this.pageNum=pziel");

Zur automatischen Linksetzung muß ich als pziel natürlich eine Variable pziel angeben, deren Wert jeweils die Seitenzahl des Linkzieles angiebt.
Leider bekomme ich das nicht hin. Zwar übergebe ich jeweils die richtigen Seitenzahlen, aber bei Mouse Up
aud den Link wird nicht auf die angegebenen Seiten, sondern -trotz variablem pziel- immer auf ein und dieselbe Seite gesprungen.
Man kann auch einen festen Wert z. b. pageNum=5 angeben und es wird dann richtigerweise zur Seite 5 gesprungen
aber ich muß ja wie schon erwähnt zu verschiedenen Seiten springen.


Mit freundlichen Grüßen
albe1000
 
Zurück