I want to add marker to all H1 headings in a FrameMaker document

Explorer ,
May 21, 2020 May 21, 2020

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.

Views

2.2K

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct Answer

Enthusiast , May 28, 2020 May 28, 2020
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...

Likes

Translate

Translate
Enthusiast ,
May 21, 2020 May 21, 2020

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;
}

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
May 21, 2020 May 21, 2020

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;  
} 

 

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
May 26, 2020 May 26, 2020

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:

  1. Script is adding markers to only some headings (skipping some headings)
  2. This is adding space also as a marker. For e.g. Heading 1 is the heading text, the marker is added as marker = Heading 1

      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;

    }

 

 

 

 

 

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
May 28, 2020 May 28, 2020

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;
}

 

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
May 28, 2020 May 28, 2020

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. 

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jun 05, 2020 Jun 05, 2020

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.  

 

 

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Jun 05, 2020 Jun 05, 2020

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;
        }
}

 

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jun 05, 2020 Jun 05, 2020

Copy link to clipboard

Copied

Thank you Klaus

 

This is working perfectly fine.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jun 05, 2020 Jun 05, 2020

Copy link to clipboard

Copied

LATEST

Hi Klaus_Göbel,   frameexpert

 

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?

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines