Die Comet-Plugins unterstützen Sie bei der Erstellung und Aktualisierung von Querverweisen in Dokumenten und Büchern. Querverweise können Seitennummern und -namen, Dokumentnamen und -pfade und andere Informationen bis hin zur XY-Koordinate des Verweiszieles anzeigen.

Diese Dokument beschreibt, wie Sie Querverweise definieren, einrichten und aktualisieren können.

Querverweise bestehen jeweils aus einer Verweisdefinition und beliebig vielen Verweisen auf diese Definition. Verweisdefinition und Verweise müssen dabei nicht im selben Dokument (aber im selben Buch) stehen.

Die Verweisdefinitionen werden mit Hilfe von InDesign®-Hyperlinks gemacht.

Die Querverweise sind spezielle Comet-Platzhalter. In den Ladenskripten dieser Platzhalter können Sie die Verweisdefinitionen des Buches oder Dokumentes durchsuchen und die erhaltenen Ergebnisse ins Dokument einsetzen.

Mit möglichst eindeutigen Namen stellen Sie sicher, dass die Verweise ihre richtigen Verweisziele finden. Das ist natürlich nicht immer einfach. Wir unterstützen Sie deshalb dabei : Zur Identifizierung eines Verweiszieles können Sie neben dem Namen auch eine Comet-ID bestehend aus bis zu drei Zahlen und einem Text mitgeben. Diese IDs werden beispielsweise in der Produktrecherche verwendet. Bei der Suche nach Verweiszielen können Sie daher in der Regel ganz auf den Namen des Verweiszieles verzichten und ausschließlich Comet-IDs verwenden.

Im Dokument werden die Verweisziele als sogenannte Hyperlinks eingefügt. Die Hyperlinks eines Dokumentes werden in der Hyperlink-Palette angezeigt. Sie gehört zum Standardumfang von InDesign® und kann mit Hilfe des Menüs Fenster -> Interaktiv -> Hyperlinks geöffnet werden. Für die Erstellung von Querverweisen wird sie nicht benötigt.

Auch mit den Comet-IDs ist natürlich nicht auszuschließen, dass gleiche Verweisziele definiert werden. InDesign® verlängert Namen und Ziele gleichen Namens deshalb jeweils mit einem Zähler, also z.B Paul, Paul 1, Paul 2 usw.. Bei der Suche nach den Verweiszielen werden diese Zähler ignoriert.

Sie haben folgende Möglichkeiten zur Erstellung von Verweiszielen :

Beachten Sie in jedem Fall, dass InDesign® keine geschachtelten Hyperlinks unterstützt. Sie können also auch Verweisziele nicht schachteln. Beim Einfügen eines neuen Verweiszieles werden alle Hyperlinks, die den Bereich des neuen Verweiszieles berühren, aus dem Dokument entfernt.

Um Fehler zu vermeiden, dürfen Verweisziele nur vollständig außerhalb oder vollständig innerhalb eines Comet-Platzhalters liegen.

Verweisziele können im Dokument hervorgehoben werden. InDesign® bietet dazu verschiedene Rahmen und Unterstreichungen an. Diese Markierungen werden nicht mitgedruckt! Wir verwenden für die Darstellung der Verweisziele die aktuellen Voreinstellungen Ihres InDesigns. Hier ein Besipiel mit einem gestrichelten orangen Rahmen:

InDesign® löscht mitunter die Endmarkierung eines Verweises ohne die Anfangsmarkierung zu entfernen. In diesem Fall wird ihr InDesign® demnächst abstürzen und ihr Dokument möglicherweise kaputt sein. Um das zu vermeiden, sollten Sie Verweisziele immer nur mit einem Zeichen definieren:

Das Beispiel zeigt ein Skript, mit dem eine Querverweis-Definition ins Dokument eingesetzt wird. Der Verweis wird über die aktuelle Dokumentauswahl gelegt und bekommt seinen Namen aus diesem Text. Zum Anlegen des Querverweises wird die Funktion textmodel::insert_crossref verwendet.

int main ()
{
	ItemRef		frame 	= item::alloc();
	String		str 	= string::alloc ();
	Table		t 		= table::alloc ();
	List		prod 	= list::alloc (3,2,1);
	List		prod2 	= list::alloc (3,2,2);
	List		prod3 	= list::alloc (3,2,3);
	StringList	prodsid	= stringlist::alloc (3, 2);
	int 		start, len, col, row;
	int 		res;
	
	// Produktauswahl prüfen
	if (list::length (prod) == 0)
	{
		showmessage ("Kein Produkt ausgewählt");
		return 0;
	}
	
	// Dokumetauswahl holen
	textmodel::selection (&start, &len, frame, 0, t, &col, &row);
	if (len > 0) textmodel::gettext (str, start, len);
	
	// Querverweis-Definition einsetzen
	res = textmodel::insert_crossref (
			start, len,
			string::get (str),
			3,
			list::get (prod, 0),
			list::get (prod2, 0),
			list::get (prod3, 0),
			stringlist::get (prodsid, 0),
			1,	// Visible
			3, 	// 1-3 Rahmenstärke
			3, 	// 1 Invert, 2 Inset, 3 Outline
			1, 	// 0 Solid, 2 Dashed
			100.0, 0.0, 0.0, -1.0
			0);
	
	return 0;
}

Hier ein Beispiel für ein gültiges w2cross-Tag :

<w2cross:
    ''
    3
    14 1 2008 'Paul'
    0
    1
    1
    Outline
    Dashed
    100.0 50.0 0.0 -1.0
    1 >

Querverweise werden als normale Platzhalter vom Typ "Querverweis" realisiert. Die folgende Tabelle zeigt, welches Attribut einer Platzhalterdefinition Sie setzen müssen, um einen Querverweis-Platzhalter zu erhalten.

Attribut Wert Umgebung
type crossref XML und SOAP
RelatedToID 9 ODBC und Oracle

Die Querverweise haben in der Platzhalterpalette ein eigenes Icon ().

        

Ein ähnliches Bild wird auch zur Kennzeichnung der Querverweise im Dokument verwendet :

       

Hier die Definition eines Querverweisplatzhalters unter XML:

<placeholder>
    <id>123470</id>
    <name>Cross-Referenz</name>
    <description></description>
    <type>crossref</type>
    <domain>Tutorial</domain>
    <domainid>2000</domainid>
    <class>3</class>
    <load>2027</load>
    <sync></sync>
    <store>0</store>
    <lov>0</lov>
    <color name="">
        <id>6</id>
    </color>
    <style></style>
    <styleid>0</styleid>
    <syncstateinvisible>0</syncstateinvisible>
    <loadconstraint>0</loadconstraint>
    <active>1</active>
</placeholder>

Der Anhänger kann grün, gelb oder rot sein.

Farbe Wert Automatik
Grün Okay / 0 gesetzt nach erfolgreichem Laden
Gelb Nicht eindeutig / 2
Geändert / -1
gesetzt nach Verknüpfen mit einem Objekt
Rot Sonst keine

Der Status wird nur in den oben beschriebenen Situationen automatisch gesetzt. Insbesondere wird der Status eines Verweises nicht automatisch auf Gelb gesetzt, wenn sich das Dokument oder ein Dokument des Buches ändert.

Sie können natürlich in den Laden- und Sync-Skripten den Status setzen. Bedenken Sie aber, dass der Status Gelb auch dann nur gesetzt wird, wenn der Platzhalter auch bearbeitet wird - also immer noch auf Grün steht, obwohl sich irgendwo im Buch etwas geändert hat, was den Querverweis möglicherweise geändert hat. Sie würden damit die Aussage "Grün" untergraben.

Querverweise werden als Ergebnis der folgenden Aktionen aktualisiert. In diesen Situationen werden nur die Querverweise neu geladen. Alle anderen Platzhalteraktionen werden ignoriert.

Beachten Sie bitte, dass Querverweise nicht automatisch aktualisiert werden.

Die eigentliche Arbeit des Querverweises wird in dessen Ladenskript gemacht. Ob es sich bei der Skriptausführung um einen normalen Laden-Aufruf oder um eine Querverweis-Aktualisierung handelt, können Sie mit Hilfe der globalen Variable gRepagination feststellen : Ist gRepagination gleich 0, handelt es sich um einen normalen Ladeaufruf. Hier können Sie den Status des Querverweises setzen und ihn auf einen Defaultwert setzen. Ist gRepagination gleich 1, handelt es sich um eine Aktualisierung der Querverweise, jetzt können Sie das Dokument oder Buch nach dem Verweisziel durchsuchen und das Ergebnis im Platzhalter eintragen.

Es gab einige Überlegungen, ob die Skripte der Querverweise auch im normalen Ladenmodus ausgeführt sollen. Wir haben diese Möglichkeit schließlich doch vorgesehen, um Benutzern die Möglichkeit zu geben, Querverweise einzeln zu laden, ihren Status zu setzen, Defaultwerte einzusetzen und was Ihnen sonst noch einfallen mag.

Im Ladenskript der Platzhalter suchen Sie mit Hilfe der Skriptfunktionen hyperlink::find1 oder hyperlink::find nach dem gewünschten Verweisziel (oder einer Liste dieser Verweisziele) und setzen (z.B. mit textmodel::replace) den gewünschten Text ins Dokument ein. Im Normalfall reicht Ihnen die Funktion find1, hier können Sie genau eine Information eines Verweiszieles als String holen und direkt einsetzen.

Wollen Sie mehrere Informationen (auch von immer dem selben Verweis) ins Dokument einsetzen, verwenden Sie besser die Funktion find. Find1 muss nämlich für jede einzelne Information wieder das gesamte Buch durchsuchen.

Das Beispiel sucht die erste Definition des aktuellen Platzhalterobjektes und schreibt dessen Seitennummer und Dokumentnamen ins Dokument. Als aufmerksamer Leser stellen Sie auch sofort fest, dass das Skript mind. drei Schwachstellen hat :

1. Es wird auch beim normalen Laden ausgeführt
2. Es wird nicht ausgehandelt, was passiert, wenn die Definition nicht gefunden wurde.
3. Wir verwenden zweimal find1.

Bevor Sie dieses Skript also verwenden, schauen Sie sich zuerst noch das nächste Beispiel an.

int main ()
{
	char 	pg [512];
	
	wlog ("", "Cross refed called, placeholder %d (%d)\n",
			gPlaceholderID, 
			gRepagination);
	
	strcpy (pg, "Seite ");
	strcat (pg, 
			hyperlink::find1 (
				0,		// Rückgabevariable (unbenutzt)
				"Page",	// Wertname
				0,		// Erstes Verweisziel
				0,		// Aktuelles Dokument oder dessen Buch
				"",		// Verweisnamen nicht testen
				3,		// Objektklasse "Produkt"
				gRecordID, gRecordID2, gRecordID3, gRecordStringID,
				1)
			);			// Suche im gesamten Buch
	
	strcat (pg, " (<CharStyle:Italic>");
	strcat (pg, 
			hyperlink::find1 (
				0,
				"DocName",
				0, 0, "",
				3, gRecordID, gRecordID2, gRecordID3, gRecordStringID,
				1, 1, 1, 1, 1)
			);
	strcat (pg, "<CharStyle:>)");
	
	textmodel::replace (pg);
	
	return 0;
	}

Das folgende Beispiel ist etwa ausgefuchster. Es werden zwar auch die Werte der ersten Querverweis-Definition geholt. Aber dann wird auch der Dokumenttext an der Definitionstelle geholt und in den Querverweis übernommen. Beachten Sie hier, dass Sie erst eine Position hinter der Definition anfangen, Text zu holen. An der Definitionsstelle selbst steht das Hyperlinkzeichen von InDesign®.

Das Skript beachtet darüber hinaus seine Ausführungssituation und setzt im normalen Laden-Modus den Platzhalterstatus auf 'Geändert'. Konnte der Querverweis nicht aufgelöst werden, wird der Platzhalterstatus auf 'Fehler' gesetzt.

int find_word (String str, char * result)
{
	char	*	abbrev	= 0;
		
	*result		= 0;
	if (!str || !string::length (str)) return 1;
	abbrev = string::get (str);
		
	if (strtokencount (abbrev, ' ') < 2)	
	{
		strcpy (result, abbrev);
	}
	else
	{
		strcat (result, strword (abbrev, 0));
		strcat (result, strword (abbrev, 1));
		strcat (result, strword (abbrev, 2));
	}
		
	return 0;
}
	
int main ()
{
	LinkList	lks		= 0;
	int			res		= 0;
	Link		lk		= 0;
	char		txt	[2000];
	String		str		= 0;
		
	wlog ("", "Cross refed called, placeholder %d (%d)\n",
				gPlaceholderID, 
				gRepagination);
		
	// Normaler Ladenaufruf
	if (!gRepagination)
	{
		// Setze Status auf "Geändert"
		placeholder::set_sync (-1);
		*gSyncChanged = 1;
		return 0;
	}
		
	// Suche die Querverweis-Definitionen zum Platzhalter
	lks		= linklist::alloc ();
	res		= hyperlink::find (
				lks,		// Ergebnisliste
				0,			// Aktuelles Dokument
				"",			// Ignore den Querverweis-Namen
				3,			// Objektklasse "Produkt"
				gRecordID, gRecordID2, gRecordID3, gRecordStringID,
				1,			// Durchuche das gesamte Buch
				1, 1, 1, 1,	// Formatierung der Seitennamen
				1);			// XY-Position des Querverweises berechnen
	if (res != 0)
	{
		// Setze den Status auf "Fehler"
		wlog ("", "# Error %d while searching cross references\n", res);
			
		linklist::release (lks);
		placeholder::set_sync (-4);
		*gSyncChanged = 1;
			
		return 0;
	}
		
	// Text des Querverweises
	if (linklist::length (lks) == 0)
	{
		sprintf (txt, "Verweis nicht gefunden [%d, %d, %d, '%s']",
				gRecordID, gRecordID2, gRecordID3, gRecordStringID);
	}
	else
	{
		lk = linklist::first (lks);
			
		// Text hinter der Definitionsstelle holen
		str = string::alloc ();
		frame::gettext (
				link::crossref::frame (lk), 
				str,
				link::crossref::pos (lk)+1, 
				200);
			
		sprintf (txt, "Seite %d [%fx%f]",
		link::crossref::page (lk, 0),
		link::crossref::x (lk),
		link::crossref::y (lk));
			
		if (string::length (str))
		{
			char	word[2000];
				
			find_word (str, word);
			strcat (txt, " (");
			strcat (txt, word);
			strcat (txt, ")");
			string::release (str);
		}
	}
		
	// Text einsetzen
	textmodel::replace (txt);
		
	linklist::release (lks);
		
	return 0;
}

Die folgenden Skriptfunktionen unterstützen Sie bei der Erstellung des Verweistextes :

Funktion Kurzbeschreibung
hyperlink::find Suche alle Verweisziele eines Namens und/oder einer ID im Dokument oder Buch
hyperlink::find1 Ermittle den Wert einer Eigenschaft eines Verweiszieles eines gegebenen Namens und/oder einer ID im Dokument oder Buch
link::crossref::document Dokumentname, -ordner und -pfad des Verweiszieles
link::crossref::page Seitennummer des Verweiszieles
link::crossref::pagename Seitenname des Verweiszieles
link::crossref::name Name des Verweiszieles
link::crossref::destination ID des Verweiszieles
link::crossref::x xy-Koordinate des Verweiszieles im Text
link::crossref::y
link::crossref::left Rahmenkoordinaten des Verweiszieles im Dokument
link::crossref::top
link::crossref::right
link::crossref::bottom
link::crossref::pos Textposition des Verweiszieles
link::crossref::frame Rahmenreferenz des Verweiszieles