Verknüpfte Dokumente: Hyperlinks suchen und ersetzen

Einleitung

Die Suchen-/Ersetzen-Funktion im SW erlaubt zwar eine ziemlich ausgiebige Suche auch nach Attributen, diese erstreckt sich jedoch leider nicht auf Hyperlinks (URLs). Dieses Manko kann mit einem Makro behoben werden. Wie diese Hyperlinks mit StarBasic bearbeitet werden können, und welche Fallen und Probleme dabei auftauchen können, das soll Inhalt dieses Abschnitts sein. Dem ganzen liegt ein umfangreiches (und brauchbares!) Beispiel zugrunde, das hier nicht in voller Länge besprochen werden kann. Das Programm ist so bei mir seit einiger Zeit im Einsatz und dient damit nicht nur Demonstrationszwecken! Es erlaubt die Suche nach und das Ersetzen von URLs und/oder Ziel-Frames dafür. Dabei lassen sich auch Teil-URLs (z.B. nur der Server-Teil) ersetzen.

Hyperlinks als Textformatierung erstellen

Hyperlinks in Texten sind ebenfalls eine Eigenschaft von Font. Hierfür sind gleich mehrere sehr spezifische Methoden geschaffen worden. Mit Font.URL und Font.TargetFrame kann auf andere Dokumente verwiesen werden. Diese Eigenschaften können auch mit den der Klasse BaseText entstammenden Eigenschaften LinkTarget und LinkURL bestimmt werden.

Sollen für spezielle Ereignisse (Maus über Hyperlink etc.) Makros oder Scripts der URL zugewiesen werden, so können hierfür die mit SetHyperlink verwandten Methoden Font.SetHyperlinkMacro und Font.SetHyperlinkScript zur Anwendung kommen.

Das folgende Beispiel-Makro fügt einen Hyperlink ein, der diesem entspricht:

Selection.Font.URL = "http://www.jo-sac.ch.ch/lindenberg"
Selection.Font.TargetFrame = "_blank"
Selection.Font.SetHyperlinkScript(1, _
               "self.status='Homepage der JO Lindenberg'")
Selection.Font.SetHyperlinkScript(3, "self.status=''")

Er sollte damit obigen Hyperlink erstellen, welcher nach «http://www.jo-sac.ch/lindenberg» verweist, diese Seite in einem neuen Fenster öffnet und beim Drüberfahren mit der Maus einen Hinweis in der Statuszeile ausgibt.

Soll ein normaler Link auf eine andere Seite eingefügt werden, so gelingt dies einfacher mit Selection.SetHyperlink(). Zudem gibt es noch weitere Eigenschaften, die sich eigentlich auf das gleiche oder ähnliches beziehen, wie oben für die Font-Eigenschaft:

Selection.Font-Eigenschaft

Selection-Eigenschaft

URL

LinkURL

TargetFrame

LinkTarget

[der Text, der die aktuelle Font-Eigenschaft hat]

LinkName



Bestehende Hyperlinks bearbeiten

Schwieriger wird's, wenn man die Hyperlinks eines Dokuments bearbeiten will. Denn hierfür steht leider keine eigentliche Collection zur Verfügung. Dafür besteht ein Befehl, um diese anzuspringen: JumpToURL(). Mittels URLFieldCount() lässt sich noch in Erfahrung bringen, wieviele Hyperlinks in einem Dokument enthalten sind. Das ist es dann schon einmal. (Es soll jedoch nicht verschwiegen werden, dass es auch Methoden für den Zugriff auf Hyperlinks, die mit Graphiken und erst recht ImageMaps verknüpft sind, gibt. Dies soll an anderer Stelle erörtert werden.)

Das folgende kleine Beispiel listet alle in einem Dokument enthaltenen URLs auf:

Sub ShowAllURLs()
   For i% = 1 To ActiveWindow.URLFieldCount
      ActiveWindow.JumpToURL(i%)
      MsgBox(Selection.LinkURL, 64, "URL gefunden!")
      ' Hier würde der Hyperlink verändert...
   Next
End Sub

Auf diese Weise müssen wir, wenn wir auf die Hyperlinks zugreifen wollen, vorgehen: einen nach dem anderen abklappern. Leider ist nicht einmal die hierbei verfolgte Reihenfolge eindeutig. Zudem ist zu beachten, dass ein Hyperlink, der verändert wird, wieder ans Ende der Liste gesetzt wird. Folgen wir also vom Beginn her, so taucht dieser plötzlich wieder auf... Es ist also bei Veränderungen der Hyperlinks sinnvoller, am Ende zu beginnen, obige Routine also umzukehren:

Sub ShowAllURLs()
   For i% = ActiveWindow.URLFieldCount To 1 Step -1
      ActiveWindow.JumpToURL(i%)
      MsgBox(Selection.LinkURL, 64, "URL gefunden!")
      ' Hier würde der Hyperlink verändert...
   Next
End Sub

Da die Reihenfolge sowieso wenig mit der Anordnung im Dokument zu tun hat, ist es auch egal, wenn von «unten» her gesucht wird. Dieses Verhalten deutet übrigens auf die Verwendung einer Collection hin, deren Einträge sich nicht ändern lassen. Eine Änderung bringt also das Anhängen des neuen Wertes und das Löschen des alten mit sich.

Möchte man nun also beispielsweise alle URLs eines Dokumentes mit einer neuen ersetzen, so reichen grundsätzlich schon wenige Zeilen Code:

Sub ReplaceAllURLs(OldURL$, NewURL$)
   Dim Counter%

   For Counter% = ActiveWindow.URLFieldCount to 1 Step -1
      ActiveWindow.JumpToURL(Counter%)

      If URLMatch(OldURL$, NewURL$) Then
         URLReplace(OldURL$, NewURL$)
      End If
   Next
End Sub

Leider ist das Vergleichen (URLMatch()) und Ersetzen (URLReplace()) nicht ganz so einfach, wie es sein sollte, denn erst muss der ganze Hyperlink markiert werden, bevor er weiter verarbeitet werden kann...

Hyperlink markieren

Will man den ganzen Hyperlink im Text markieren, so ist man mit einigen Problemen konfrontiert. Das beginnt damit, dass sich ein Hyperlink über mehrere Worte, im Extremfall über das ganze Dokument erstrecken kann. Man muss ihn also manuell markieren. Und hier beginnt der Kampf mit den «Unschönheiten» im SO4 (die mit dem SO5 ausgebügelt sein könnten).

Ist man mit JumpToURL() zu einem Hyperlink gesprungen, so steht danach der Cursor direkt vor dem Hyperlink im Dokument. StarBasic in SO4 hat nun die komische Eigenschaft, an dieser Position mit Selection.LinkURL (und Verwandten) einen Leerstring zurückzuliefern, es sei denn, der Cursor befinde sich am Anfang eines Abschnitts (Selection.IsStartOfPara). Für die normalen Fälle wird nun also einfach der Cursor eins nach rechts in den Link versetzt. Dort liefert er dann das gewünschte Ergebnis. Es sei denn wiederum, die Hyperlink-Bezeichnung im Text (Selection.LinkName) bestehe nur aus einem einzigen Zeichen. Dann nämlich schiesst eine Bewegung nach rechts bereits wieder über den Link hinaus... Dieses Problem habe ich einigermassen pragmatisch angegangen: springt JumpToURL() zu einem Link, dessen Länge Null sei, so nehme ich an, dass er in Wirklichkeit ein Zeichen lang ist. Denn wäre dort kein Link, so wäre JumpToURL() nicht gelandet :-). Daraus ergibt sich folgende Routine, um einen kompletten Hyperlink zu markieren:

Sub SelectHyperlink
   Dim LinkLength%

   ' allenfalls vorhandene Markierung löschen
   Selection.Escape()

   ' wenn nicht Absatzbeginn
   If Not Selection.IsStartOfPara Then
      Selection.GoRight(1, True)
   End If

   LinkLength% = Len(Selection.LinkName) = 0

   ' Sonderfall Länge des Hyperlinks = 1
   LinkLength% = IIf(Len(LinkLength% = 0, 1, LinkLength%)

   If Not Selection.IsStartOfDoc Then
      Selection.GoLeft(1, False)
   End If

   ' Link markieren
   Selection.GoRight(LinkLength%, True)
End Sub

Die hierdurch erreichte Markierung des Hyperlinks ist Voraussetzung für dessen weitere Bearbeitung oder den Vergleich mit einer vorgegebenen URL, wie es im beigefügten Beispiel benutzt wird. Wie ein so gefundener Hyperlink mit einer neuen Verknüpfung versehen werden kann, wurde eingangs bereits erwähnt.



Letzte Änderung: 02.04.98
Copyright ©1998 by Michael Herger