4 Replies Latest reply on Feb 24, 2013 5:00 AM by wokoman1234

    Adding Character Tag based on used Font Family

    wokoman1234

      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 !

        • 1. Re: Adding Character Tag based on used Font Family
          frameexpert Level 4

          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

          • 2. Re: Adding Character Tag based on used Font Family
            wokoman1234 Level 1

            Thanks Rick, I was able to figure most steps out using your script as starting point, but I'm stuck at the final bit, so I hope someone can tell me what I'm missing here.

             

            here's the script I use :

             

            var doc = app.ActiveDoc;

            var pgf = doc.FirstPgfInDoc;

            var log = "";   

            var CharTagVal = "";

            var CharFont = "";

             

            while(pgf.ObjectValid())

              {

                 //ignore master page paragraphs         

            if(pgf.Name.indexOf("¦") === -1){

                         cleanPgf();

                       }

                    pgf = pgf.NextPgfInDoc;

            }

             

             

            function cleanPgf(){

             

            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;

                    SetCharVal(textRange);

            begOffset = endOffset;

                }

            }

            textRange = new TextRange(new TextLoc (pgf, begOffset), new TextLoc (pgf, Constants.FV_OBJ_END_OFFSET));

            doc.TextSelection = textRange;

            SetCharVal(textRange);

            }

             

             

             

            function SetCharVal(textRange){

            var CharTag = doc.GetTextPropVal(textRange.beg, Constants.FP_CharTag);       

            var FontPlatformName = doc.GetTextPropVal(textRange.beg, Constants.FP_FontPlatformName);

            FontPlatformName = FontPlatformName.propVal.sval;

             

            CharFmtId = doc.GetNamedObject(Constants.FO_CharFmt, "symbol");

            props = doc.GetProps(CharFmtId);

             

            if (/symbol/i.test(FontPlatformName) === true) {

            //alert (CharTag.propVal.sval + " - " +  FontPlatformName );

            doc.SetTextProps(textRange, props);

            }

            }

             

            I managed to get the script run through all the paragraphs, ignores the irrelevant ones, and each time the script sees the symbol font it should add the charformat. This however doesn't work as I was hoping for, it sees the textRange, but instead of adding the hoped for chartag, it sets teh default setting, actually clearing out the format. I assume I'm doing something wrong when setting the props, but have no clue what it could be.

             

            Any suggestion ?

             

            Thanks,

            Koen

            • 3. Re: Adding Character Tag based on used Font Family
              frameexpert Level 4

              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

              • 4. Re: Adding Character Tag based on used Font Family
                wokoman1234 Level 1

                Thanks Rick, the syntax did the trick indeed.

                 

                And I can only agree the best way to work is taking it step by step, so I focussed on getting the alert working first. Once that was done I tried to make the change, but as I failed I constructed the rest of the script to have some progress.

                It's an approach that works for me so I don't get depressed too fast :-)