Skip navigation
Currently Being Moderated

Adding Character Tag based on used Font Family

Feb 22, 2013 6:56 AM

Tags: #extendscript #character_tag

Hi there,

 

There are quites some examples available on changing existing styles etc, but is it possible to add them using extend script if they are not added yet ?

 

Example :

 

I'm having quite some frame documents using for instance [symbol] as font. Normally spoken all strings in my file that use symbol should have the symtag character tag, however for some it's missing and that's causing issues when structuring my documents. symtag is just a fictional name for a charactertag in my catalog.

 

So what I'd like to achieve is the following :

 

1) Open document

2) traverse through document, and for each character using symbol as a font, check if it's having the symtag character tag, if not, add it.

3) save and close

 

1) and 3) are easy enough (well, sort off...) , but I can't find anything on how to make 2) work, I'm not even sure it's possible with extendscript to start with.

 

If it might simplify things, it's always just a single character that is using the font(s) in question.

 

Thanks in advance for anything that can get me started !

 
Replies
  • Currently Being Moderated
    Feb 22, 2013 7:38 AM   in reply to wokoman1234

    In my opinion, this is one of the most difficult aspects of scripting FrameMaker to understand: dealing with text items. But it is very powerful, because you can break down a paragraph by every single character property change. Here is basically what you have to do. First, start with a single paragraph with some character property changes; in your case, apply the Symbol font to some of the text. Then, put your cursor in the paragraph and run the code below. You will see that it goes through and highlights each range of text that is uniquely formatted and displays an alert box.

     

    #target framemaker
    
    var doc = app.ActiveDoc;
    var pgf = doc.TextSelection.beg.obj;
    
    var textList = pgf.GetText (Constants.FTI_CharPropsChange);
    
    var begOffset = 0, endOffset = 0, textRange;
    for (var i = 0; i < textList.length; i += 1) {
        endOffset = textList[i].offset;
        if (endOffset  > begOffset) {
            textRange = new TextRange(new TextLoc (pgf, begOffset), new TextLoc (pgf, endOffset));
            doc.TextSelection = textRange;
            alert (textRange);
            begOffset = endOffset;
        }
    }
    textRange = new TextRange(new TextLoc (pgf, begOffset), new TextLoc (pgf, Constants.FV_OBJ_END_OFFSET));
    doc.TextSelection = textRange;
    alert (textRange);
    

     

    Of course, you are not done, because you have to test the properties at the beginning of each text range. But a lot of the work is done with this code, which could (should) be generalized into a function.

     

    --Rick

     
    |
    Mark as:
  • Currently Being Moderated
    Feb 23, 2013 3:06 PM   in reply to wokoman1234

    A small point, but you don't need this:

     

    doc.TextSelection = textRange;
    

     

    This was used so that you could see each range of text highlighted while you were testing it on a single paragraph, but it is not necessary in the finished script.

     

    Also, allow an old man to scold you for your approach. I had my original code set up to work on the paragraph containing the insertion point. This is a useful approach because you can test and troubleshoot on a single paragraph. Then, once everything is working on that paragraph, you can expand the script to work on multiple paragraphs, documents, etc. But you went ahead and expanded the script before you got it working on the single paragraph. This makes it difficult to know exactly where the problem is. So, at the risk of being tedious, let's go back to the original code and a paragraph containing the insertion point. I have modified the code slightly and put it into a function.

     

    #target framemaker
    
    var doc = app.ActiveDoc;
    var pgf = doc.TextSelection.beg.obj;
    cleanPgf (pgf, doc);
    
    function cleanPgf (pgf, doc) {
    
        var textList = pgf.GetText (Constants.FTI_CharPropsChange);
        var fontName; 
        var begOffset = 0, endOffset = 0, textRange;
    
        for (var i = 0; i < textList.length; i += 1) {
            endOffset = textList[i].offset;
            if (endOffset  > begOffset) {
                textRange = new TextRange(new TextLoc (pgf, begOffset), new TextLoc (pgf, endOffset));
                fontName = (doc.GetTextPropVal(textRange.beg, Constants.FP_FontPlatformName).propVal.sval);
                if (/symbol/i.test (fontName) === true) {
                    alert (fontName);
                }
                begOffset = endOffset;
            }
        }
        textRange = new TextRange(new TextLoc (pgf, begOffset), new TextLoc (pgf, Constants.FV_OBJ_END_OFFSET));
        fontName = (doc.GetTextPropVal(textRange.beg, Constants.FP_FontPlatformName).propVal.sval);
        if (/symbol/i.test (fontName) === true) {
            alert (fontName);
        }
    }
    

     

    When you run this in a paragraph containing Symbol, you should see the alert displaying the font name. You can replace the alert lines with calls to another function:

     

    function applyCharFmt (textRange, charFmtName, doc) {
    
        var charFmt = doc.GetNamedCharFmt (charFmtName);
        if (charFmt.ObjectValid()) {
            doc.SetTextProps (textRange, charFmt.GetProps());
        }
    
    }
    

     

    The problem in your code was this line:

     

    props = doc.GetProps(CharFmtId);
    

     

    which should have been:

     

    props = CharFmtId.GetProps();
    

     

    I use a slightly different syntax with the same result. Once you get it working on a single paragraph, you can safely expand it to work on all of the paragraphs in the document.

     

    --Rick

     
    |
    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (0)

Answers + Points = Status

  • 10 points awarded for Correct Answers
  • 5 points awarded for Helpful Answers
  • 10,000+ points
  • 1,001-10,000 points
  • 501-1,000 points
  • 5-500 points