• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

How to apply hypertext marker to text with specific character tag

Community Beginner ,
Oct 30, 2018 Oct 30, 2018

Copy link to clipboard

Copied

I am trying to apply a gotolink marker in my text to a word that has a specific character tag. A couple of months ago, frameexpert helped me with some code that applies the newlink marker to text in a specific paragraph format, and I thought I could just modify it (see below). But I'm obviously missing something because it just won't work. The marker needs to be added to the specific words, so that they are a link, rather than to the beginning of the paragraph, so I know I need to do something about the offset location. But first, I just need it to work. Any help would be much appreciated! Thanks in advance.

#target framemaker

main ();

function main () {

    var doc = app.ActiveDoc;

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

            processDoc (doc);

    }

    else {

         alert ("There is no active document.");

    }

}

function processDoc (doc) {

    var findLink = doc.GetNamedCharFmt ("Link");   // Match Link character format.

    var pgf = doc.FirstPgfInDoc;

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

        if (findLink.ObjectValid (doc) === true) {

            processGoToLink (pgf, doc);

        }

        pgf = pgf.NextPgfInDoc;

     }

}

function processGoToLink (pgf, doc) {   

    var num = getFigOrTableNum (pgf);  // Calls the function to get the figure or table numbers

    if (num) {

       var marker = getMarker (doc, "Hypertext", "gotolink");    // See if a gotolink marker already exists in the paragraph.

       if (marker) {

            // Update the existing marker's text.

            marker.MarkerText = "gotolink " + num;

        }

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

            createMarker (doc, 0, "Hypertext", "gotolink " + num);  // I don't want the marker at the beginning of the paragraph. The combination of letter plus number (F1) should be the link.

        }

    }

    else {

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

    }

}

function getMarker (pgf, markerType, text) {  // See if a marker exists in a paragraph 

    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;

            }

        }

    }

}

// Create a new 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 doc = app.ActiveDoc;

    var regex = /((AF|AT|[FT])(\d+))/;  // Match F or T or AF or AT plus number in text

    var pgfText = getText (pgf, doc);  // Calls next function to get the text

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

        var match = pgfText.match (regex);

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

    }      

}

function getText (textObj, doc) {      // Gets the text from the text object.

    var text = "", textItems, i;

    if (textObj.constructor.name !== "TextRange") {     // Get a list of the strings in the text object or text range.

        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

499

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
Community Expert ,
Oct 30, 2018 Oct 30, 2018

Copy link to clipboard

Copied

The newlink marker part is easy :-). The gotolink portion is trickier because you have to get a TextRange of the text you want to apply the format to (after you add the gotolink marker to the text). I am jammed right now so I can't help too much.

Votes

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
Mentor ,
Oct 31, 2018 Oct 31, 2018

Copy link to clipboard

Copied

Along with what Rick said, this is too much code for me to analyze. Plus, I am not completely sure what you want to do. Do you want to insert a marker, then apply a character format, or are you trying to find an existing character format and put the marker within it?

Without really analyzing the code, I did notice this:

        if (findLink.ObjectValid (doc) === true) {

ObjectValid() does not take any arguments. It looks like you might be trying to use it as a "find" mechanism, which is not correct. If you want to invoke a search, you have to use doc.Find(), which is a healthy complexity by itself.

In any case, I think you should back up a bit and get this one part working, whatever it is you are trying to do. Pick one specific place in the doc and start with a function or two, then plug it into the larger iteration routine. If you did that, we could help you much more effectively. It's hard to decipher a large block of code like you presented, at least quickly.

Russ

Votes

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
Community Beginner ,
Oct 31, 2018 Oct 31, 2018

Copy link to clipboard

Copied

Thank you. To narrow it down, I want to find text that has the character format "Link" and add a gotolink hypertext marker. For example, in the phrase: "The quick brown fox jumped over the lazy dog," the word "over" has the character format "link" and I want it to click to somewhere else on the page.

I can find the character format in my document with this:

var doc = app.ActiveDoc;

function findLink(doc) { // looks for the character format Link

  charFmt = doc.GetNamedCharFmt("Link");

   

        if(charFmt.ObjectValid() == true)     {

        //Get the character format properties

        

        alert("Format found.");

        }

   

        //If we didn't find the character format, a warning....

        else alert("Could not find the Link character format!");

}

findLink(doc);

but I can't figure out how to get it to apply the gotolink marker.

Votes

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
Mentor ,
Oct 31, 2018 Oct 31, 2018

Copy link to clipboard

Copied

I get it. Nice idea, but complicated.

In your code above, you are not actually finding anything; rather you are just retrieving the character format object from the document. To actually find a location where the format is applied, you would need something like this:

      var findParams = AllocatePropVals(2);
     
      findParams[0].propIdent.num = Constants.FS_FindCharTag;   
      findParams[0].propVal.valType = Constants.FT_String;   
      findParams[0].propVal.sval = fmtName; 
     
      findParams[1].propIdent.num = Constants.FS_FindWrap;   
      findParams[1].propVal.valType = Constants.FT_Integer;   
      findParams[1].propVal.ival = false; 
 
      var textRange = new TextRange();
      textRange.beg.obj = textRange.end.obj = doc.MainFlowInDoc.FirstTextFrameInFlow.FirstPgf; 
      textRange.beg.offset = textRange.end.offset = 0; 
      doc.TextSelection = textRange;

      textRange = doc.Find(textRange.beg, findParams);

Then, with a successful find, you could add the marker like this, where I included the code to apply the character format:

      var charFmt = doc.GetNamedCharFmt("Link");

      var marker = doc.NewAnchoredMarker(textRange.beg);

      var markerRange = new TextRange(marker.TextLoc, marker.TextLoc);

      markerRange.end.offset++;

      doc.SetTextProps(markerRange, charFmt.GetProps());

You would also need to set the marker type (Hyperlink) and the marker text (goto something). You would need your getText() method to finish that last part.

It gets complicated when you want to loop through a whole doc. You can put Find into a loop, but it seems that every time you modify the doc with a new marker, it resets the Find action and you end up finding and adding markers endlessly. You could do all the Finds first and put the results in an array, but the problem with that is you could mess up a text range in the array by adding a marker earlier in the same paragraph.

I experimented some but ran out of time. I was thinking of a routine to first delete all markers out of the whole doc, then add them back with a second recursive search. But I didn't come up with anything simple and like I said, I'm out of time for now. Perhaps you can experiment with this some more with the ideas above and come back with an idea on how the routine should work. I hope this helps.

Russ

Votes

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
Community Beginner ,
Oct 31, 2018 Oct 31, 2018

Copy link to clipboard

Copied

LATEST

Thank you, Russ. I'll give it a shot.

Votes

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