Il existe deux types de références croisées dans FrameMaker : les références croisées ponctuelles et les références croisées par paragraphe. (Il existe un troisième type, les références croisées d'élément, disponible uniquement dans FrameMaker+SGML. Ce tutoriel ne traitera pas des références croisées d'élément). Les références croisées par paragraphe et ponctuelles sont similaires en ce sens que vous devez insérer un objet Xref qui pointe vers un marqueur de référence croisée. L'objet Xref possède une propriété XRefSrcText qui doit correspondre exactement au texte du marqueur du marqueur de référence croisée. Commençons par les références croisées ponctuelles, car elles sont un peu plus simples à utiliser.
Références croisées ponctuelles
À titre d'exemple, voici un tableau contenant les noms des procédures de maintenance qui se produisent dans un document. Nous voulons utiliser FrameScript pour faire des références croisées des entrées du tableau aux procédures réelles du document. Chaque titre de procédure utilise un format de paragraphe Heading2.
Ajout de marqueurs de référence croisée
Un principe que nous aimons ajouter ici lors de la résolution de problèmes avec FrameScript est de décomposer le problème en petites tâches. Notre première tâche est de placer des marqueurs de référence croisée dans chaque paragraphe de titre de procédure. Puisque nous savons que les procédures commencent par des paragraphes Heading2, nous ne placerons des marqueurs que dans ces paragraphes. Le texte du marqueur sera défini au texte du paragraphe. Il est important que chaque marqueur de référence croisée du document contienne un texte unique. Nous supposerons dans notre exemple que chaque paragraphe Heading2 contient un texte qui est unique par rapport à tous les autres paragraphes Heading2 du document.
// Test pour un document actif.
If ActiveDoc = 0
MsgBox 'No active document. ';
LeaveSub;
Else
Set vCurrentDoc = ActiveDoc;
EndIf
Loop ForEach(Pgf) In(vCurrentDoc) LoopVar(vPgf)
If vPgf.Name = 'Heading2'
New Marker NewVar(vMarker) MarkerName('Cross-Ref')
TextLoc(vPgf);
// Set the marker text to the paragraph text.
Set vMarker.MarkerText = vPgf.Text;
EndIf
EndLoop
Chaque paragraphe Heading2 aura un marqueur de référence croisée au début avec le texte du paragraphe comme texte du marqueur. Voici l'un des paragraphes Heading2 avec la fenêtre du marqueur affichant le texte du marqueur.
Parce que nous créons des marqueurs avec FrameScript au lieu de l'interface FrameMaker, examinons les propriétés du marqueur. Vous pouvez exécuter le code suivant avec l'ancre du marqueur sélectionnée pour voir les propriétés du marqueur. Notez que la propriété MarkerText est le texte qui s'affiche dans le dialogue Marqueur.
Get TextList InRange(TextSelection) MarkerAnchor
NewVar(vTextList);
If vTextList.Count > 0
Get Member Number(1) From(vTextList) NewVar(vMarker);
Set vMarker = vMarker.TextData;
Display vMarker.Properties;
Else
MsgBox 'There is no marker selected. ';
EndIf
Ajout des références croisées
Startseitetenant, nous pouvons accéder au tableau et faire en sorte qu'un script ajoute des références croisées aux marqueurs (« points ») que nous avons insérés précédemment. Nous supposerons que le curseur se trouve dans le tableau lorsque le code suivant est exécuté.
// Test pour un document actif.
If ActiveDoc = 0
MsgBox 'There is no active document. ';
LeaveSub;
Else
Set vCurrentDoc = ActiveDoc;
EndIf
// Set a variable for the current table.
Set vTbl = vCurrentDoc.SelectedTbl;
// Make sure a the cursor is in a table.
If vTbl.ObjectName not= 'Tbl'
MsgBox 'There is no selected table. ';
LeaveSub; // Exit the script.
EndIf
// Find the first body row in the table.
Set vRow = vTbl.FirstRowInTbl;
Loop While(vRow.RowType = RowHeading)
Set vRow = vRow.NextRowInTbl;
EndLoop
// Go to the first cell in the first body row.
Set vCell = vRow.FirstCellInRow;
Startseitetenant que nous sommes dans la première cellule, nous pouvons commencer une boucle à travers les cellules. Pour chaque cellule, nous devons « sélectionner » le texte afin que la nouvelle référence croisée puisse le remplacer. La propriété XRefSrcText de XRef (référence croisée) sera définie au texte sélectionné puisque cela correspondra au texte du marqueur du marqueur de référence croisée correspondant qui a été inséré précédemment. Pour sélectionner le texte, nous créerons une plage de texte, supprimerons le texte, puis insérerons l'objet XRef à sa place.
// Begin the loop.
Loop While(vCell)
// Select the text by making a TextRange.
New TextRange NewVar(vTextRange) Object(vCell.FirstPgf)
Offset(0) Offset(ObjEndOffset-1);
// Set a variable for the TextRange text.
Set vXRefSrcText = vTextRange.Text;
// Delete the text.
Delete Text TextRange(vTextRange);
// Insert the cross-reference.
New XRef Format('Heading & Page') TextLoc(vCell.FirstPgf)
NewVar(vXRef);
Set vXRef.XRefSrcText = vXRefSrcText;
// Go to the next cell and repeat the loop.
Set vCell = vCell.CellBelowInCol;
EndLoop
// Update the cross-references.
Update DocObject(vCurrentDoc) XRefs Everything;
Le tableau affiche maintenant le texte original remplacé par les références croisées. Si vous double-cliquez sur l'une des références croisées, la boîte de dialogue Référence croisée s'ouvre comme indiqué ci-dessous.
L'important à retenir est que la propriété XRef.XRefSrcText doit correspondre exactement à la propriété XRef.MarkerText du marqueur correspondant, sinon vous aurez une référence croisée non résolue. Pour voir les propriétés de la référence croisée, mettez l'une des références croisées en surbrillance et exécutez le code suivant. Notez la propriété XRefSrcText.
Get TextList InRange(TextSelection) XRefBegin
NewVar(vTextList);
If vTextList.Count > 0
Get Member Number(1) From(vTextList) NewVar(XRefBegin);
Set XRefBegin = XRefBegin.TextData;
Display XRefBegin.Properties;
Else
MsgBox 'There is no cross-reference selected. ';
EndIf
Références croisées vers d'autres documents
Une autre propriété importante à noter est la propriété XRefFile. Pour la référence croisée ci-dessus, c'est une chaîne NULL car c'est une référence croisée interne. Si nous faisions une référence croisée vers un autre fichier, la propriété XRefFile contiendrait le chemin d'accès absolu vers l'autre fichier.
Références croisées par paragraphe
Avant de discuter de l'insertion de références croisées par paragraphe avec FrameScript, examinons comment elles diffèrent des références croisées ponctuelles dans l'interface FrameMaker. Lorsque vous insérez une référence croisée ponctuelle avec FrameMaker, vous devez insérer un marqueur de référence croisée avant d'insérer la référence croisée. Vous devez créer un « point » qui apparaîtra dans la boîte de dialogue Référence croisée.
En contraste, les références croisées par paragraphe ne nécessitent pas l'insertion d'un marqueur de référence croisée à l'avance. À la place, vous pointez vers le paragraphe souhaité dans la boîte de dialogue Référence croisée, cliquez sur Insérer, et FrameMaker insère la référence croisée et le marqueur de référence croisée aux endroits appropriés.
Une fois insérées, les références croisées ponctuelles et par paragraphe ne diffèrent pas dans leurs propriétés de base sous-jacentes. Toutes les références croisées sont accessibles comme objets XRef par FrameScript. Il y a cependant une différence dans la façon dont elles sont présentées dans la boîte de dialogue Référence croisée FrameMaker. Lorsque vous double-cliquez sur une référence croisée ponctuelle, le dialogue affiche les marqueurs de référence croisée sous le type de source et le texte du marqueur dans la liste de droite. Le double-clic sur une référence croisée par paragraphe affiche l'étiquette de paragraphe du paragraphe source sous Type de source et le texte du paragraphe de chacun des paragraphes d'étiquette de paragraphe sélectionnés dans la liste de droite. Ci-dessous se trouve la boîte de dialogue Référence croisée affichant une référence croisée par paragraphe.
La différence entre les types de références croisées provient d'une différence dans la syntaxe des marqueurs de référence croisée. Pour voir cela, insérez une référence croisée par paragraphe, Ctrl+Alt+cliquez sur la référence croisée pour aller à la source, et ouvrez la fenêtre du marqueur. Vous verrez la syntaxe du marqueur que FrameMaker insère avec une référence croisée par paragraphe. Ci-dessous se trouve une fenêtre de marqueur exemple suivie des propriétés XRef.
Comme les marqueurs de référence croisée ponctuelle que nous avons insérés précédemment, vous pouvez voir le texte du paragraphe source dans la fenêtre du marqueur et la propriété XRefSrcText. De plus, le texte du paragraphe est précédé par un nombre à cinq chiffres (suivi d'un deux-points et d'un espace), et le nom du format de paragraphe du paragraphe source (suivi d'un deux-points et d'un espace). Ce sont ces deux composants supplémentaires dans la propriété XRefSrcText de XRef qui font que FrameMaker « voit » cela comme une référence croisée par paragraphe.
Startseitetenir les marqueurs de référence croisée uniques
Il y a une autre raison pour la différence de syntaxe entre les références croisées ponctuelles et par paragraphe. Il est essentiel que les marqueurs de référence croisée dans un document soient uniques. Bien que vous puissiez avoir plus d'une référence croisée pointant vers un seul marqueur de référence croisée, vous ne pouvez pas avoir une seule référence croisée essayant de pointer vers plus d'un marqueur avec le même texte de marqueur. Lorsque vous insérez des références croisées ponctuelles, c'est à vous de vous assurer que chaque marqueur de référence croisée est unique. Lorsque vous insérez des références croisées par paragraphe, FrameMaker s'assure que les marqueurs qu'il insère sont uniques en utilisant la syntaxe spéciale, en particulier le numéro de série à cinq chiffres à l'avant.
Le texte du marqueur de référence croisée ne doit jamais être modifié après l'insertion des marqueurs. Vous pourriez avoir plusieurs références croisées pointant vers le même marqueur ; si vous modifiez le texte du marqueur, les références croisées deviendraient non résolues. De même, la modification du texte du paragraphe source ne modifiera pas le texte du marqueur.
Avant d'écrire du code pour insérer des références croisées par paragraphe, voici les points importants à retenir concernant les références croisées par paragraphe et ponctuelles.
Ajout de références croisées par paragraphe
Nous utiliserons le même exemple que nous avons utilisé avec les références croisées ponctuelles, sauf que cette fois nous insérerons les références croisées et son marqueur correspondant en même temps. Dans notre exemple précédent, nous avons inséré tous les marqueurs d'abord puis les références croisées. Nous avons supposé que pour chaque entrée du tableau, il y aurait un paragraphe Heading2 exactement correspondant dans le document. Ce ne peut pas toujours être une hypothèse sûre et pourrait entraîner des références croisées non résolues.
Nous commencerons par notre boucle à travers le tableau. La liste complète du code est ci-dessous.
// Test pour un document actif.
If ActiveDoc = 0
MsgBox 'There is no active document. ';
LeaveSub;
Else
Set vCurrentDoc = ActiveDoc;
EndIf
// Set a variable for the current table.
Set vTbl = vCurrentDoc.SelectedTbl;
// Make sure a the cursor is in a table.
If vTbl.ObjectName not= 'Tbl'
MsgBox 'There is no selected table. ';
LeaveSub; // Exit the script.
EndIf
// Make a property list for the color red.
Get Object Type(Color) Name('Red') DocObject(vCurrentDoc)
NewVar(vColor);
New PropertyList NewVar(vProps) Color(vColor);
// Find the first body row in the table.
Set vRow = vTbl.FirstRowInTbl;
Loop While(vRow.RowType = RowHeading)
Set vRow = vRow.NextRowInTbl;
EndLoop
// Go to the first cell in the first body row.
Set vCell = vRow.FirstCellInRow;
// Begin the loop.
Loop While(vCell)
// Select the text by making a TextRange.
New TextRange NewVar(vTextRange) Object(vCell.FirstPgf)
Offset(0) Offset(ObjEndOffset-1);
// Set a variable for the TextRange text.
Set vXRefSrcText = vTextRange.Text;
// Run a subroutine to find the corresponding
heading.
Set vHeadingFound = 0;
Run FindSourceHeading Returns vMarkerText(vXRefSrcText);
If vHeadingFound = 1
// Delete the text.
Delete Text TextRange(vTextRange);
// Insert the cross-reference.
New XRef Format('Heading & Page') TextLoc(vCell.FirstPgf)
NewVar(vXRef);
Set vXRef.XRefSrcText = vXRefSrcText;
Else
// If the corresponding heading can't be found, color the
// text red so it stands out.
Apply TextProperties TextRange(vTextRange)
Properties(vProps);
EndIf
// Go to the next cell and repeat the loop.
Set vCell = vCell.CellBelowInCol;
EndLoop
// Update the cross-references.
Update DocObject(vCurrentDoc) XRefs Everything;
Pour chaque entrée du tableau, nous allons exécuter une sous-routine appelée FindSourceHeading qui tente de localiser le titre correspondant dans le document. Si elle ne trouve pas un titre correspondant avec le même texte, elle appliquera la couleur rouge au texte de la cellule du tableau afin que vous sachiez facilement qu'il y a un problème. Voici le code de la sous-routine.
Sub FindSourceHeading
//
Loop ForEach(Pgf) In(vCurrentDoc) LoopVar(vPgf)
If vPgf.Name = 'Heading2'
// See if the paragraph text is the same as the table
// cell text.
If vPgf.Text = vXRefSrcText
// Make marker text with paragraph cross-ref syntax.
// Get the unique Id of the paragraph and convert it to
// a string.
New String NewVar(vMarkerText) Value(vPgf.Unique);
// Drop the first character so we end up with 5 digits.
Get String FromString(vMarkerText) NewVar(vMarkerText)
StartPos(vMarkerText.Size - 4);
// Add the paragraph tag and text.
Set vMarkerText = vMarkerText + ': ' + vPgf.Name + ': ' +
vPgf.Text;
// Add the cross-reference marker.
New Marker NewVar(vMarker) MarkerName('Cross-Ref')
TextLoc(vPgf);
// Set the marker text to the paragraph text.
Set vMarker.MarkerText = vMarkerText;
// Set the vHeadingFound variable to 1.
Set vHeadingFound = 1;
// Leave the subroutine.
LeaveSub;
EndIf
EndIf
EndLoop
//
EndSub
Notez que ce code est similaire au script antérieur qui a inséré les marqueurs de référence croisée ponctuelle. C'est une simple boucle à travers les paragraphes du document à la recherche de paragraphes Heading2. Il y a un test supplémentaire pour voir si le texte du paragraphe correspond au texte de la cellule du tableau.