Highlighted

Need help with applying hypertext markers with specific commands to paragraphs

New Here ,
Sep 05, 2018

Copy link to clipboard

Copied

Hi all. I'm new here and new to scripting. Been reading a lot and watching some videos but it still hasn't quite clicked. I'm am trying to write a script that will apply a hypertext marker to a specific paragraph format, and customize each marker with a specific newlink command based on the contents of the paragraph. For example, the following paragraph, which has the format CaptionFigure, would need a hypertext marker called newlink f3 to correspond with Figure F3:

Figure F3. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec non pretiu

Figure F4 will have newlink f4, Figure F5 will have newlink f5, and so on.

There are sometimes up to 50 or 60 figures in a document, thus I’m looking to streamline it with ExtendScript. I found this code to apply a marker to a paragraph format in the forum (thanks mrsjackharkness) and modified it, and it works great. Now I need help with the next step, to customize the marker.

var doc = app.ActiveDoc;

var flow = doc.MainFlowInDoc;

var tframe = flow.FirstTextFrameInFlow;

var pgf = tframe.FirstPgf;

var target1 = doc.GetNamedObject(Constants.FO_PgfFmt, "CaptionFigure");

var target2 = doc.GetNamedObject(Constants.FO_PgfFmt, "CaptionTable");

while (pgf.ObjectValid())   {

if (pgf.Name == target1.Name)   {

    createMarker (doc, pgf, 0, "Hypertext", "Newlink f");

}

else if (pgf.Name == target2.Name)  {

    createMarker (doc, pgf, 0, "Hypertext", "Newlink t");

}

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;

    }

Any advice will be much appreciated. Please and thank you!

Julie

Adobe Community Professional
Correct answer by frameexpert | Adobe Community Professional

myersjh91 and I worked on this on the phone. Here is our complete solution. fonrig's solution should work too, but using regular expressions made this work for both Figure and Table captions.

#target framemaker

main ();

function main () {

   

    var doc;

   

    doc = app.ActiveDoc;

    if (doc.ObjectValid () === 1) {

        processDoc (doc);

    }

    else {

        alert ("There is no active document.","www.frameexpert.com");

    }

}

function processDoc (doc) {

   

    var pgfRegex, pgf;

   

    // Turn off the displaying property to speed the script and prevent flicker.

    if (app.Displaying === 1) {

        app.Displaying = 0;

    }

    // Match both CaptionFigure and CaptionTable paragraph formats.

    pgfRegex = /^(CaptionFigure|CaptionTable)$/;

    pgf = doc.FirstPgfInDoc;

    while (pgf.ObjectValid () === 1) {

        if (pgfRegex.test (pgf.Name) === true) {

            processNewlinkPgf (pgf, doc);

        }

        pgf = pgf.NextPgfInDoc;

    }   

    // Restore the document's display and refresh the screen.

    if (app.Displaying === 0) {

        app.Displaying = 1;

        doc.Redisplay ();

    }

}

function processNewlinkPgf (pgf, doc) {

   

    var num, marker;

   

    num = getFigOrTableNum (pgf);

    if (num) {

        // See if a newlink marker already exists in the paragraph.

        marker = getMarker (pgf, "Hypertext", "newlink");

        if (marker) {

            // Update the existing marker's text.

            marker.MarkerText = "newlink " + num;

        }

        else {  // No existing marker; create a new one.

            createMarker (doc, pgf, 0, "Hypertext", "newlink " + num);

        }

    }

    else {

        Console ("Couldn't find number: " + pgf.Name);

    }

}

function getMarker (pgf, markerType, text) {

   

    var markers = [], marker, textList, i;

    textList = pgf.GetText (Constants.FTI_MarkerAnchor);

    for (i = 0; i < textList.len; i += 1) {

        marker = textList.obj;

        if (marker.MarkerTypeId.Name === markerType) {

            if (marker.MarkerText.indexOf (text) > -1) {

                return marker;

            }

        }

    }

}

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;

}

function getFigOrTableNum (pgf) {

   

    var regex, pgfText, match;

   

    regex = /(?:Table|Figure) ([FT]\d+)/;

   

    pgfText = getText (pgf, doc);

    if (regex.test (pgfText) === true) {

        match = pgfText.match (regex);

        return (match[1].toLowerCase ());

    }      

}

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.sdata);

    }

    return text; // Return the text

}

TOPICS
Scripting

Views

308

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

Need help with applying hypertext markers with specific commands to paragraphs

New Here ,
Sep 05, 2018

Copy link to clipboard

Copied

Hi all. I'm new here and new to scripting. Been reading a lot and watching some videos but it still hasn't quite clicked. I'm am trying to write a script that will apply a hypertext marker to a specific paragraph format, and customize each marker with a specific newlink command based on the contents of the paragraph. For example, the following paragraph, which has the format CaptionFigure, would need a hypertext marker called newlink f3 to correspond with Figure F3:

Figure F3. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec non pretiu

Figure F4 will have newlink f4, Figure F5 will have newlink f5, and so on.

There are sometimes up to 50 or 60 figures in a document, thus I’m looking to streamline it with ExtendScript. I found this code to apply a marker to a paragraph format in the forum (thanks mrsjackharkness) and modified it, and it works great. Now I need help with the next step, to customize the marker.

var doc = app.ActiveDoc;

var flow = doc.MainFlowInDoc;

var tframe = flow.FirstTextFrameInFlow;

var pgf = tframe.FirstPgf;

var target1 = doc.GetNamedObject(Constants.FO_PgfFmt, "CaptionFigure");

var target2 = doc.GetNamedObject(Constants.FO_PgfFmt, "CaptionTable");

while (pgf.ObjectValid())   {

if (pgf.Name == target1.Name)   {

    createMarker (doc, pgf, 0, "Hypertext", "Newlink f");

}

else if (pgf.Name == target2.Name)  {

    createMarker (doc, pgf, 0, "Hypertext", "Newlink t");

}

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;

    }

Any advice will be much appreciated. Please and thank you!

Julie

Adobe Community Professional
Correct answer by frameexpert | Adobe Community Professional

myersjh91 and I worked on this on the phone. Here is our complete solution. fonrig's solution should work too, but using regular expressions made this work for both Figure and Table captions.

#target framemaker

main ();

function main () {

   

    var doc;

   

    doc = app.ActiveDoc;

    if (doc.ObjectValid () === 1) {

        processDoc (doc);

    }

    else {

        alert ("There is no active document.","www.frameexpert.com");

    }

}

function processDoc (doc) {

   

    var pgfRegex, pgf;

   

    // Turn off the displaying property to speed the script and prevent flicker.

    if (app.Displaying === 1) {

        app.Displaying = 0;

    }

    // Match both CaptionFigure and CaptionTable paragraph formats.

    pgfRegex = /^(CaptionFigure|CaptionTable)$/;

    pgf = doc.FirstPgfInDoc;

    while (pgf.ObjectValid () === 1) {

        if (pgfRegex.test (pgf.Name) === true) {

            processNewlinkPgf (pgf, doc);

        }

        pgf = pgf.NextPgfInDoc;

    }   

    // Restore the document's display and refresh the screen.

    if (app.Displaying === 0) {

        app.Displaying = 1;

        doc.Redisplay ();

    }

}

function processNewlinkPgf (pgf, doc) {

   

    var num, marker;

   

    num = getFigOrTableNum (pgf);

    if (num) {

        // See if a newlink marker already exists in the paragraph.

        marker = getMarker (pgf, "Hypertext", "newlink");

        if (marker) {

            // Update the existing marker's text.

            marker.MarkerText = "newlink " + num;

        }

        else {  // No existing marker; create a new one.

            createMarker (doc, pgf, 0, "Hypertext", "newlink " + num);

        }

    }

    else {

        Console ("Couldn't find number: " + pgf.Name);

    }

}

function getMarker (pgf, markerType, text) {

   

    var markers = [], marker, textList, i;

    textList = pgf.GetText (Constants.FTI_MarkerAnchor);

    for (i = 0; i < textList.len; i += 1) {

        marker = textList.obj;

        if (marker.MarkerTypeId.Name === markerType) {

            if (marker.MarkerText.indexOf (text) > -1) {

                return marker;

            }

        }

    }

}

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;

}

function getFigOrTableNum (pgf) {

   

    var regex, pgfText, match;

   

    regex = /(?:Table|Figure) ([FT]\d+)/;

   

    pgfText = getText (pgf, doc);

    if (regex.test (pgfText) === true) {

        match = pgfText.match (regex);

        return (match[1].toLowerCase ());

    }      

}

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.sdata);

    }

    return text; // Return the text

}

TOPICS
Scripting

Views

309

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
Sep 05, 2018 0
Community Beginner ,
Sep 06, 2018

Copy link to clipboard

Copied

You can use the PgfNumber property of your caption paragraph. So, assuming your Autonumber formatting for the caption paragraph is:  "F<+n> ", PgfNumber will return F1 , F2 , F3 , ..., Fn for each instance of the caption paragraph.

You can then extract the figure number from that string, for example inside your function createMarker, you can add:

var myPgfNumber = pgf.PgfNumber // This returns F1, F2, etc.

var figNumber = myPgfNumber.substr(1); // this extracts the number 1, 2, ..., 99, etc.

marker.MarkerText = text + figNumber; // adds figure number to your marker, i.e. Newlink f1, Newlink f2, etc.

Hope this makes sense...

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
Reply
Loading...
Sep 06, 2018 0
Mentor ,
Sep 07, 2018

Copy link to clipboard

Copied

H Julie,

Foring's response seems like a reasonable approach, if you are using autonumbers and that is what you were asking in the first place. Your question is a bit vague, though... can you clarify that is what you need help with? That you want to parse out the figure number from the paragraph, for use in the marker text? It seems like that is the case, which means maybe you have the answer.

Russ

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
Reply
Loading...
Sep 07, 2018 0
New Here ,
Sep 07, 2018

Copy link to clipboard

Copied

I do want to parse out the figure number from the paragraph but the paragraphs are not autonumbered and are not part of the main flow of the document. I tried just adding "+ i++" (and ++i) to the function [createMarker (doc, pgf, 0, "Hypertext", "Newlink f" + i++); ]. It worked except for figure F1, which didn't number in the right order (showed up as F4), so I don't think this is the correct approach.

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
Reply
Loading...
Sep 07, 2018 0
Adobe Community Professional ,
Sep 07, 2018

Copy link to clipboard

Copied

Is there any way you can post a sample FrameMaker document? You can send it to me directly if you want to: rick at frameexpert dot com. Thanks.

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
Reply
Loading...
Sep 07, 2018 0
New Here ,
Sep 07, 2018

Copy link to clipboard

Copied

I'll send one. Thanks!

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
Reply
Loading...
Sep 07, 2018 0
Community Beginner ,
Sep 07, 2018

Copy link to clipboard

Copied

  // Parse figure number from figure caption text. Caption is not AutoNumbered

  function parseCaption(pgf){

      // Caption format: Figure F3. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec non pretiu

      var figNumber = ''; // Initialize

      var caption = getText(pgf); // Gets text content from paragraph

    

      // Parse text to extract figure number

      var firstSpace = caption.indexOf(" ", 7); // Gets first space position after second "F" in Figure FX._

      figNumber = caption.substr(8, firstSpace - 9); // Grabs all text between "F" and period "." = Figure number

      return figNumber;

  }

  //Returns text stored in a Text Object ********************************

  function getText(textObj) {

      var objText = '';

      // Get a list of strings from the object.

      var textItems = textObj.GetText(Constants.FTI_String); // Text only

      // Concatenate strings in array

      for (var i = 0; i < textItems.len; i += 1) {

          objText += (textItems.sdata);

      }

      return objText;

  } // end function

You can use it as:

createMarker (doc, pgf, 0, "Hypertext", "Newlink f" + parseCaption(pgf));

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
Reply
Loading...
Sep 07, 2018 0
New Here ,
Sep 07, 2018

Copy link to clipboard

Copied

Thank you!

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
Reply
Loading...
Sep 07, 2018 0
Adobe Community Professional ,
Sep 07, 2018

Copy link to clipboard

Copied

myersjh91 and I worked on this on the phone. Here is our complete solution. fonrig's solution should work too, but using regular expressions made this work for both Figure and Table captions.

#target framemaker

main ();

function main () {

   

    var doc;

   

    doc = app.ActiveDoc;

    if (doc.ObjectValid () === 1) {

        processDoc (doc);

    }

    else {

        alert ("There is no active document.","www.frameexpert.com");

    }

}

function processDoc (doc) {

   

    var pgfRegex, pgf;

   

    // Turn off the displaying property to speed the script and prevent flicker.

    if (app.Displaying === 1) {

        app.Displaying = 0;

    }

    // Match both CaptionFigure and CaptionTable paragraph formats.

    pgfRegex = /^(CaptionFigure|CaptionTable)$/;

    pgf = doc.FirstPgfInDoc;

    while (pgf.ObjectValid () === 1) {

        if (pgfRegex.test (pgf.Name) === true) {

            processNewlinkPgf (pgf, doc);

        }

        pgf = pgf.NextPgfInDoc;

    }   

    // Restore the document's display and refresh the screen.

    if (app.Displaying === 0) {

        app.Displaying = 1;

        doc.Redisplay ();

    }

}

function processNewlinkPgf (pgf, doc) {

   

    var num, marker;

   

    num = getFigOrTableNum (pgf);

    if (num) {

        // See if a newlink marker already exists in the paragraph.

        marker = getMarker (pgf, "Hypertext", "newlink");

        if (marker) {

            // Update the existing marker's text.

            marker.MarkerText = "newlink " + num;

        }

        else {  // No existing marker; create a new one.

            createMarker (doc, pgf, 0, "Hypertext", "newlink " + num);

        }

    }

    else {

        Console ("Couldn't find number: " + pgf.Name);

    }

}

function getMarker (pgf, markerType, text) {

   

    var markers = [], marker, textList, i;

    textList = pgf.GetText (Constants.FTI_MarkerAnchor);

    for (i = 0; i < textList.len; i += 1) {

        marker = textList.obj;

        if (marker.MarkerTypeId.Name === markerType) {

            if (marker.MarkerText.indexOf (text) > -1) {

                return marker;

            }

        }

    }

}

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;

}

function getFigOrTableNum (pgf) {

   

    var regex, pgfText, match;

   

    regex = /(?:Table|Figure) ([FT]\d+)/;

   

    pgfText = getText (pgf, doc);

    if (regex.test (pgfText) === true) {

        match = pgfText.match (regex);

        return (match[1].toLowerCase ());

    }      

}

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.sdata);

    }

    return text; // Return the text

}

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
Reply
Loading...
Sep 07, 2018 0
New Here ,
Sep 07, 2018

Copy link to clipboard

Copied

frameexpert​,

Thank you so much for your time on the phone today and for your expertise. This will save us so much time, especially on the very long documents we often have.

~Julie

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
Reply
Loading...
Sep 07, 2018 0
Community Beginner ,
Sep 07, 2018

Copy link to clipboard

Copied

Impressive response Rick! Thanks for all your help. I learn something new with each one of your solutions!

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
Reply
Loading...
Sep 07, 2018 0
Adobe Community Professional ,
Sep 07, 2018

Copy link to clipboard

Copied

Thank you very much. As you can see, I like to use a lot of functions and generalize them as much as possible so I can reuse them. I should have recorded our meeting so you could see how we built it up from a handful of lines to the working script. Maybe I will next time. Thanks again!

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
Reply
Loading...
Sep 07, 2018 0
Mentor ,
Sep 07, 2018

Copy link to clipboard

Copied

I had a feeling that a regex would be involved. Therefore, I was glad to see that Rick was not on vacation. Every occasional time I need one of those, it's back to the tutorial.

Russ

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
Reply
Loading...
Sep 07, 2018 0
Adobe Community Professional ,
Sep 07, 2018

Copy link to clipboard

Copied

I read Jeffrey Friedl's "Mastering Regular Expressions" years ago, and it really got me liking regular expressions. It is one of the best computer books I have ever read. Regular expressions and xml technologies are two of my favorite things to work with as a programmer.

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
Reply
Loading...
Sep 07, 2018 0
New Here ,
Sep 12, 2018

Copy link to clipboard

Copied

I just found this great site for testing and explaining regular expressions. It's pretty simple (which is what I need) but it helped me modify the code above to capture more types of captions. https://regex101.com/r/cU5lC2/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
Reply
Loading...
Sep 12, 2018 0
New Here ,
Sep 07, 2018

Copy link to clipboard

Copied

Thank you for replying. Unfortunately, the captions/figures are in independent text frames separate from the main flow and they are not autonumbered. I think I need the script to read the text that goes with the markers, and if the text says Figure F1, it needs to add the "1" to the marker.

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
Reply
Loading...
Sep 07, 2018 0