Copy link to clipboard
Copied
I want to grab the heading text and add it as a marker to all the respective H1 headings in my FrameMaker document. I am using the following script but it gives me an error and FM crashes after adding the marker.
Also, this is adding only a fixed text as a marker:
var doc = app.ActiveDoc;
var flow = doc.MainFlowInDoc;
var tframe = flow.FirstTextFrameInFlow;
var pgf = tframe.FirstPgf;
var target1 = doc.GetNamedObject(Constants.FO_PgfFmt, "h1");
while (pgf.ObjectValid()) {
if (pgf.Name == target1.Name) {
createMarker (doc, pgf, 0, "newlink h1", "");
}
pgf = pgf.NextPgfInDoc;
}
function createMarker(doc, pgf, offset, type, text) {
var tLoc = new TextLoc(pgf, offset);
var marker = doc.NewAnchoredObject(Constants.FO_Marker, tLoc);
var markerType = doc.GetNamedObject(Constants.FO_MarkerType, type);
marker.MarkerTypeId = markerType;
marker.MarkerText = text;
return 1;
}
Please help.
You disregarded my advice NOT to use NextPgfInDoc !!
So it couldn't work.
Try this version. As writen above, it only works, if you have only one Flow (MainFlowInDoc) in your bodypages.
Otherwise you'll have to follw my advices above.
#target framemaker
#strict on
var doc = app.ActiveDoc;
var flow = doc.MainFlowInDoc;
var tframe = flow.FirstTextFrameInFlow;
var goPgf = tframe.FirstPgf;
var markerTypeName = "Hypertext";
var target1 = "h1 head 1";
var targe
...
Copy link to clipboard
Copied
Hi sanjivb,
there are some problems in your code:
1. You are starting with MainFlowInDoc, but continue with NextPgfInDoc instead of NextPgfInFlow.
So you can't be sure, that the next pgf is in main flow.
2. You don't check, if the MarkerType exists (ObjectValid()). So this is probably the reason for the crash.
3. If you use more flows in your bodypages than only the MainFlow you won't get all paragraphs.
How to go through all flows you can find here:
https://community.adobe.com/t5/framemaker/script-no-longer-working/td-p/11071057?page=1
#target framemaker
#strict on
var goDoc = app.ActiveDoc;
var goFlow = goDoc.MainFlowInDoc;
var goTextFrame = goFlow.FirstTextFrameInFlow;
var pgf = goTextFrame.FirstPgf;
var MarkerTypeName = "newlink h1";
var gsTargetName = "h1";
var goMarkerType = goDoc.GetNamedObject(Constants.FO_MarkerType, MarkerTypeName);
if (goMarkerType.ObjectValid())
{
while (pgf.ObjectValid())
{
if (pgf.Name == gsTargetName)
{
createMarker(goDoc, pgf,goMarkerType,"TestText");
}
pgf = pgf.NextPgfInFlow;
}
}
else
{
alert("MarkerType not found") ;
}
function createMarker(foDoc, foPgf,foMarkerType,fsText)
{
var tLoc, oMarker;
tLoc = new TextLoc(foPgf, 0);
oMarker = foDoc.NewAnchoredObject(Constants.FO_Marker, tLoc);
oMarker.MarkerTypeId = foMarkerType;
oMarker.MarkerText = fsText;
}
Copy link to clipboard
Copied
Here is a convenience function for getting a marker type. If a marker type doesn't exist in the document, it will get created.
function getMarkerType (markerName, doc) {
// Get a marker type from the document; if it doesn't exist, create it.
var markerType = doc.GetNamedMarkerType (markerName);
if (markerType.ObjectValid () === 0) {
markerType = doc.NewNamedMarkerType (markerName);
}
return markerType;
}
Copy link to clipboard
Copied
Thank you @Klaus_Gobel and @frameexpert for your responses.
I am not good at FM Scripting but managed to add markers (with your help) like "marker_text" + 1 to the h1 headings.
Now, what I want the script to do is to read the heading text and add that text as a hypertext marker to that heading.
I used @frameexpert's solution on this link and some part of the code from the link mentioned by @Klaus_Gobel.
But, I am facing following issues:
I want to remove space from the marker text.
Please suggest a correction.
var doc = app.ActiveDoc;
var flow = doc.MainFlowInDoc;
var tframe = flow.FirstTextFrameInFlow;
var pgf = tframe.FirstPgf;
var target1 = doc.GetNamedObject(Constants.FO_PgfFmt, "h1 head 1");
var target2 = doc.GetNamedObject(Constants.FO_PgfFmt, "h1t head 1.top");
function getText (textObj, doc) {
// Gets the text from the text object.
var text = "", textItems, i;
// Get a list of the strings in the text object or text range.
if (textObj.constructor.name !== "TextRange") {
textItems = textObj.GetText(Constants.FTI_String);
} else {
textItems = doc.GetTextForRange(textObj, Constants.FTI_String);
}
// Concatenate the strings.
for (i = 0; i < textItems.len; i += 1) {
text += (textItems[i].sdata);
}
return text; // Return the text
}
while (pgf.ObjectValid()) {
if (pgf.Name == target1.Name) {
createMarker (doc, pgf, 0, "Hypertext", "newlink Filename:" + getText(pgf));
}
else if (pgf.Name == target2.Name) {
createMarker (doc, pgf, 0, "Hypertext", getText(pgf));
}
pgf = pgf.NextPgfInDoc;
}
function createMarker(doc, pgf, offset, type, text) {
var tLoc = new TextLoc(pgf, offset);
var marker = doc.NewAnchoredObject(Constants.FO_Marker, tLoc);
var markerType = doc.GetNamedObject(Constants.FO_MarkerType, type);
marker.MarkerTypeId = markerType;
marker.MarkerText = text;
return 1;
}
Copy link to clipboard
Copied
You disregarded my advice NOT to use NextPgfInDoc !!
So it couldn't work.
Try this version. As writen above, it only works, if you have only one Flow (MainFlowInDoc) in your bodypages.
Otherwise you'll have to follw my advices above.
#target framemaker
#strict on
var doc = app.ActiveDoc;
var flow = doc.MainFlowInDoc;
var tframe = flow.FirstTextFrameInFlow;
var goPgf = tframe.FirstPgf;
var markerTypeName = "Hypertext";
var target1 = "h1 head 1";
var target2 = "h1t head 1.top";
var markerType = doc.GetNamedObject(Constants.FO_MarkerType, markerTypeName);
if (!markerType.ObjectValid())
{
markerType = doc.NewNamedMarkerType (markerTypeName);
}
setMarker(doc,goPgf);
function setMarker(foDoc,foPgf)
{
var sText;
while (foPgf.ObjectValid())
{
if (foPgf.Name == target1)
{
sText = GetTextFromPgf(foPgf);
createMarker(foDoc, foPgf,markerType,"newlink Filename:" + sText);
}
if (foPgf.Name == target2)
{
sText = GetTextFromPgf(foPgf);
createMarker(foDoc, foPgf,markerType,sText);
}
foPgf = foPgf.NextPgfInFlow;
}
}
function GetTextFromPgf(foPgf)
{
var oTextItems = foPgf.GetText (Constants.FTI_String);
var sText = "";
for (var i = 0; i <= oTextItems.length -1; i++)
{
sText = sText + oTextItems[i].sdata;
}
sText = sText.replace(" ","_"); // you've asked for in PM
return sText;
}
function createMarker(foDoc, foPgf,foMarkerType,fsText)
{
var tLoc, oMarker;
tLoc = new TextLoc(foPgf, 0);
oMarker = foDoc.NewAnchoredObject(Constants.FO_Marker, tLoc);
oMarker.MarkerTypeId = foMarkerType;
oMarker.MarkerText = fsText;
}
Copy link to clipboard
Copied
Thank you Klaus_Göbel
This is working fine now. I have used your advice also and my script is also adding markers to all headings.
Copy link to clipboard
Copied
Thank you Klaus_Göbel
Now I am facing a different issue with this script. Whenever I run it, it adds multiple markers. Is there a way to add a check to this script so that if it finds a marker with "newlink", it does not add any marker and reports it, and if it does not finds the marker, it adds it.
Copy link to clipboard
Copied
You just have to add a query:
function setMarker(foDoc,foPgf)
{
var sText;
var bMarkerExists = false;
while (foPgf.ObjectValid())
{
bMarkerExists = false;
var oMarkers = foPgf.GetText(Constants.FTI_MarkerAnchor);
for (var i = 0; i < oMarkers.length; i++)
{
if (oMarkers[i].obj.MarkerTypeId.Name == gMarkerTypeName)
{
bMarkerExists = true;
break;
}
}
if (!bMarkerExists)
{
if (foPgf.Name == target1)
{
sText = GetTextFromPgf(foPgf);
createMarker(foDoc, foPgf,markerType,"newlink Filename:" + sText);
}
if (foPgf.Name == target2)
{
sText = GetTextFromPgf(foPgf);
createMarker(foDoc, foPgf,markerType,sText);
}
}
foPgf = foPgf.NextPgfInFlow;
}
}
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Though this script is working fine. But it is not adding markers if any other Hypertext marker is present. Is there a way it does not adds markers if there is marker type Hypertext and/or marker text newlink Filename present?