15 Replies Latest reply on Dec 1, 2014 7:17 AM by JuleeBruce

    Creating a variable that contains the value of the Modification Date (Long) system variable

    JuleeBruce Level 1

      Can someone tell me how to write a script for creating a variable, named DocDate, that contains the value of the Modification Date (Long) system variable? Or to write a script that creates a variable,named DocDate, that contains the current date??? I can't seem to find a whole lot of documentation on ExtendScript script writing.

        • 1. Re: Creating a variable that contains the value of the Modification Date (Long) system variable
          frameexpert Level 4

          Hi Julee, When you create a user variable in the interface, you can't include the date/time building blocks in the definition. These can only be used in system variables like the Modification Date (Long) system variable. So the question is, why not just use the Modification Date (Long) system variable in your document? What is the purpose of the DocDate user variable? Let me know what you are thinking here, and I can try to help you.

           

          Here are some ExtendScript resources:

           

          My blog: FrameAutomation.com | Making FrameMaker faster and more efficient

          Debra Herman's blog: Extending FrameMaker

          Russ Ward's extensive samples: FrameMaker ExtendScript Samples - West Street Consulting

           

          -Rick

          • 2. Re: Creating a variable that contains the value of the Modification Date (Long) system variable
            JuleeBruce Level 1

            I use Mif2Go to create my HTML output. I have a DocDate paragraph that contains the Modification Date (Long) system variable and is conditionalized to only appear in the HTML output. I configured Mif2Go to convert the system variable to text, store the text from that variable, and write it in a META tag. However, with the FM12 upgrade (I skipped FM11 but I found out it has the same problem), Mif2Go's TextStore feature stopped working.

             

            I'm trying everything I can imagine to get that date to appear in the HTML META tags. I don't have Jeremy to help me any more and I don't think anyone is interested in fixing Mif2Go because it isn't a feature that anyone else is using...

            • 3. Re: Re: Creating a variable that contains the value of the Modification Date (Long) system variable
              frameexpert Level 4

              Hi Julie, These tasks are rarely simple, but they are fun anyway. First some background: with a user variable, it is easy to get it's value, because the definition itself is usually its value. Say you have a user variable named "DocDate"; you can run this to get its value:

               

              #target framemaker
              
              var doc = app.ActiveDoc;
              
              varFmt = doc.GetNamedVarFmt ("DocDate");
              if (varFmt.ObjectValid () === 1) {
                  alert (varFmt.Fmt);
              }
              

               

              Of course, if you have used character format building blocks in the definition, these will be displayed as well. With system variables, things are different. The definitions consist of building blocks and literal text so to get the actual display value, you have to insert the variable somewhere in the document. The code below does exactly that.

               

              #target framemaker
              
              // Make a constant for the points metric value.
              var PT = 65536;
              
              var doc = app.ActiveDoc;
              alert (getSystemVariableValue ("Modification Date (Long)", doc));
              
              function getSystemVariableValue (varName, doc) {
                  
                  var masterPage, textFrame, pgf, textLoc, varObj, value = "";
              
                  // Get the first master page in the document.
                  masterPage = doc.FirstMasterPageInDoc;
                  // Add a temporary text frame to the master page.
                  textFrame = doc.NewTextFrame (masterPage.PageFrame);
                  textFrame.Width  = 288 * PT;
                  // Add the variable to the first paragraph in the temporary text frame.
                  pgf = textFrame.FirstPgf;
                  textLoc = new TextLoc (pgf, 0);
                  varObj = doc.NewAnchoredFormattedVar (varName, textLoc);
                  if (varObj.ObjectValid () === 1) {
                      // Get the value of the variable.
                      value = getText (varObj.TextRange, doc);
                  }
                  // Delete the temporary text frame.
                  textFrame.Delete ();
                  
                  return value;
              }
              
              function getText (textObj, doc) {
                  
                  // Gets the text from the text object or text range.
              
                  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
              }
              

               

              I have most of the code in a couple of functions for portability. The getText function is a utility function that gets the text from a text object (paragraph, text frame, table cell, etc.) or a text range. The getSystemVariableValue function does the majority of the work needed; the comments should give you an overview of what is happening.

               

              The next step will be to insert the text retrieved on line 7 and insert it into a custom marker. I will do this in another reply. Please test the code above and let me know if you have any questions or comments. Thanks. -Rick

              • 4. Re: Creating a variable that contains the value of the Modification Date (Long) system variable
                JuleeBruce Level 1

                You are ABSOLUTELY AWESOME! I ran it and got a script alert to appear with the current date.

                • 5. Re: Creating a variable that contains the value of the Modification Date (Long) system variable
                  JuleeBruce Level 1

                  I understand exactly what you mean about how much fun they are! I had lots of fun configuring Mif2Go to do what I wanted it to do... but Jeremy had LOTS of great documentation to work with and that made it easy for me. I knew it had to be possible to do what I wanted to do but I was at an absolute loss as to where to start. I truly appreciate your help.

                  • 6. Re: Re: Creating a variable that contains the value of the Modification Date (Long) system variable
                    frameexpert Level 4

                    Hi Julie, Here is the code to take the date and add it to a DocDate marker, which will be inserted in the first paragraph in the document's main flow. Replace lines 01-07 in the previous post with the code below and give it a try.

                     

                    #target framemaker
                    
                    // Make a constant for the points metric value.
                    var PT = 65536;
                    
                    var doc = app.ActiveDoc;
                    var modDate = getSystemVariableValue ("Modification Date (Long)", doc);
                    
                    // Get the first paragraph in the main document flow.
                    var pgf = doc.MainFlowInDoc.FirstTextFrameInFlow.FirstPgf;
                    
                    // Insert the custom marker at the beginning of the paragraph.
                    addMarker (pgf, "DocDate", modDate, doc);
                    
                    function addMarker (pgf, markerName, markerText, doc) {
                       
                        var textLoc, marker, markerType;
                    
                        // Make a text location at the beginning of the paragraph.
                        textLoc = new TextLoc (pgf, 0);
                        // Get the specified marker type.
                        markerType = doc.GetNamedMarkerType (markerName);
                        if (markerType.ObjectValid () === 1) {
                            // Insert the marker at the text location and set its properties.
                            marker = doc.NewAnchoredMarker (textLoc);
                            marker.MarkerTypeId = markerType;
                            marker.MarkerText = markerText;
                        }
                    }
                    

                     

                    Note that you will need code to delete any existing DocDate markers before the code above runs so that you don't get a new marker every time you run the script. I may leave that as an exercise for you. -Rick

                    • 7. Re: Creating a variable that contains the value of the Modification Date (Long) system variable
                      JuleeBruce Level 1

                      Hmmmmm.... That didn't work. It didn't create a marker. I copied your code and replaced lines 1-7 in my script.

                      • 8. Re: Re: Creating a variable that contains the value of the Modification Date (Long) system variable
                        frameexpert Level 4

                        OK, the current addMarker function requires that the marker type exist in the document; that is probably why it didn't work for you. Replace lines 15-29 above with the code below; this will create the marker type if it doesn't already exist.

                         

                        function addMarker (pgf, markerName, markerText, doc) {
                            
                            var textLoc, marker, markerType;
                        
                            // Make a text location at the beginning of the paragraph.
                            textLoc = new TextLoc (pgf, 0);
                            // Get the specified marker type. 
                            markerType = doc.getMarkerType (markerName, doc);
                            if (markerType.ObjectValid () === 1) {
                                // Insert the marker at the text location and set its properties.
                                marker = doc.NewAnchoredMarker (textLoc);
                                marker.MarkerTypeId = markerType;
                                marker.MarkerText = markerText;
                            }
                        }
                        
                        function getMarkerType (markerName, doc) {
                            
                            var markerType = doc.GetNamedVarFmt (markerName);
                            if (markerType.ObjectValid () == 0) {
                                markerType = doc.NewNamedMarkerType (markerName);
                            }
                            return markerType;
                        }
                        

                         

                        Here is code to delete any existing markers. You will want to do this near the beginning of the script so that your custom markers don't "pile up" every time you run the script. Put the function at the bottom of the script.

                         

                        function deleteMarkers (markerName, doc) {
                            
                            var marker, nextMarker;
                            
                            marker = doc.FirstMarkerInDoc;
                            while (marker.ObjectValid () === 1) {
                                nextMarker = marker.NextMarkerInDoc;
                                if (marker.MarkerTypeId.Name === markerName) {
                                    marker.Delete ();
                                }
                                marker = nextMarker;
                            }
                        }
                        

                         

                        Here is the function call:

                         

                        // Delete any existing markers.
                        deleteMarkers ("DocDate", doc);
                        

                         

                        The lines above should go somewhere before these lines in the script:

                         

                        // Insert the custom marker at the beginning of the paragraph.
                        addMarker (pgf, "DocDate", modDate, doc);
                        

                         

                        Please let me know if you have any questions or comments. Thanks! -Rick

                        • 9. Re: Re: Re: Creating a variable that contains the value of the Modification Date (Long) system variable
                          frameexpert Level 4

                          Hi Julie, There is an error in the first block of code in the previous post. Line 08 should be:

                           

                              markerType = getMarkerType (markerName, doc);
                          

                           

                          Sorry about that. -Rick

                          • 10. Re: Creating a variable that contains the value of the Modification Date (Long) system variable
                            JuleeBruce Level 1

                            I did something wrong... It isn't working. I'm wondering if I put that line in the wrong place. This is what I have:

                               #target framemaker 

                             

                            // Make a constant for the points metric value. 

                            var PT = 65536; 

                             

                            var doc = app.ActiveDoc; 

                            var modDate = getSystemVariableValue ("Modification Date (Long)", doc); 

                             

                            // Get the first paragraph in the main document flow. 

                            var pgf = doc.MainFlowInDoc.FirstTextFrameInFlow.FirstPgf; 

                             

                            function deleteMarkers (markerName, doc) {

                               

                                var marker, nextMarker;

                               

                                marker = doc.FirstMarkerInDoc;

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

                                    nextMarker = marker.NextMarkerInDoc;

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

                                        marker.Delete ();

                                    }

                                    marker = nextMarker;

                                }

                            }

                            // Delete any existing markers.

                            deleteMarkers ("DocDate", doc);

                             

                            // Insert the custom marker at the beginning of the paragraph. 

                            addMarker (pgf, "MetaModDate", modDate, doc); 

                             

                            function addMarker (pgf, markerName, markerText, doc) {

                               

                                var textLoc, marker, markerType;

                             

                                // Make a text location at the beginning of the paragraph.

                                textLoc = new TextLoc (pgf, 0);

                                // Get the specified marker type.

                                markerType = getMarkerType (markerName, doc);

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

                                    // Insert the marker at the text location and set its properties.

                                    marker = doc.NewAnchoredMarker (textLoc);

                                    marker.MarkerTypeId = markerType;

                                    marker.MarkerText = markerText;

                                }

                            }

                             

                            function getMarkerType (markerName, doc) {

                               

                                var markerType = doc.GetNamedVarFmt (markerName);

                                if (markerType.ObjectValid () == 0) {

                                    markerType = doc.NewNamedMarkerType (markerName);

                                }

                                return markerType;

                            }

                             

                                 

                                function getSystemVariableValue (varName, doc) { 

                                     

                                    var masterPage, textFrame, pgf, textLoc, varObj, value = ""; 

                                 

                                    // Get the first master page in the document. 

                                    masterPage = doc.FirstMasterPageInDoc; 

                                    // Add a temporary text frame to the master page. 

                                    textFrame = doc.NewTextFrame (masterPage.PageFrame); 

                                    textFrame.Width  = 288 * PT; 

                                    // Add the variable to the first paragraph in the temporary text frame. 

                                    pgf = textFrame.FirstPgf; 

                                    textLoc = new TextLoc (pgf, 0); 

                                    varObj = doc.NewAnchoredFormattedVar (varName, textLoc); 

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

                                        // Get the value of the variable. 

                                        value = getText (varObj.TextRange, doc); 

                                    } 

                                    // Delete the temporary text frame. 

                                    textFrame.Delete (); 

                                     

                                    return value; 

                                } 

                                 

                                function getText (textObj, doc) { 

                                     

                                    // Gets the text from the text object or text range. 

                                 

                                    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 

                                } 

                            • 11. Re: Creating a variable that contains the value of the Modification Date (Long) system variable
                              JuleeBruce Level 1

                              OK, so I figured out one problem... the marker name was not the same (MetaModDate and DocDate). I corrected that but it still didn't work.

                              • 12. Re: Re: Creating a variable that contains the value of the Modification Date (Long) system variable
                                frameexpert Level 4

                                Hi Julie, Here is the full script with everything in order:

                                 

                                #target framemaker
                                
                                // Make a constant for the points metric value.
                                var PT = 65536;
                                
                                var doc = app.ActiveDoc;
                                var modDate = getSystemVariableValue ("Modification Date (Long)", doc);
                                
                                // Get the first paragraph in the main document flow.
                                var pgf = doc.MainFlowInDoc.FirstTextFrameInFlow.FirstPgf;
                                
                                // Delete any existing DocDate markers.
                                deleteMarkers ("MetaModDate", doc);
                                
                                // Insert the custom marker at the beginning of the paragraph.
                                addMarker (pgf, "MetaModDate", modDate, doc);
                                
                                function addMarker (pgf, markerName, markerText, doc) {
                                   
                                    var textLoc, marker, markerType;
                                
                                    // Make a text location at the beginning of the paragraph.
                                    textLoc = new TextLoc (pgf, 0);
                                    // Get the specified marker type.
                                    markerType = getMarkerType (markerName, doc);
                                    if (markerType.ObjectValid () === 1) {
                                        // Insert the marker at the text location and set its properties.
                                        marker = doc.NewAnchoredMarker (textLoc);
                                        marker.MarkerTypeId = markerType;
                                        marker.MarkerText = markerText;
                                    }
                                }
                                
                                function getMarkerType (markerName, doc) {
                                   
                                    var markerType = doc.GetNamedVarFmt (markerName);
                                    if (markerType.ObjectValid () == 0) {
                                        markerType = doc.NewNamedMarkerType (markerName);
                                    }
                                    return markerType;
                                }
                                
                                function getSystemVariableValue (varName, doc) {
                                   
                                    var masterPage, textFrame, pgf, textLoc, varObj, value = "";
                                
                                    // Get the first master page in the document.
                                    masterPage = doc.FirstMasterPageInDoc;
                                    // Add a temporary text frame to the master page.
                                    textFrame = doc.NewTextFrame (masterPage.PageFrame);
                                    textFrame.Width  = 288 * PT;
                                    // Add the variable to the first paragraph in the temporary text frame.
                                    pgf = textFrame.FirstPgf;
                                    textLoc = new TextLoc (pgf, 0);
                                    varObj = doc.NewAnchoredFormattedVar (varName, textLoc);
                                    if (varObj.ObjectValid () === 1) {
                                        // Get the value of the variable.
                                        value = getText (varObj.TextRange, doc);
                                    }
                                    // Delete the temporary text frame.
                                    textFrame.Delete ();
                                   
                                    return value;
                                }
                                
                                function getText (textObj, doc) {
                                   
                                    // Gets the text from the text object or text range.
                                
                                    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
                                }
                                
                                function deleteMarkers (markerName, doc) {
                                   
                                    var marker, nextMarker;
                                   
                                    marker = doc.FirstMarkerInDoc;
                                    while (marker.ObjectValid () === 1) {
                                        nextMarker = marker.NextMarkerInDoc;
                                        if (marker.MarkerTypeId.Name === markerName) {
                                            marker.Delete ();
                                        }
                                        marker = nextMarker;
                                    }
                                }
                                

                                 

                                I just tested this and it seems to work fine. Let me know if you still have problems. -Rick

                                • 13. Re: Creating a variable that contains the value of the Modification Date (Long) system variable
                                  JuleeBruce Level 1

                                  Aha! If I delete the MetaModDate custom marker from the book manually it works. If I leave it there, it does not...

                                  • 14. Re: Re: Creating a variable that contains the value of the Modification Date (Long) system variable
                                    frameexpert Level 4

                                    Oops, I made a mistake in the getMarkerType function. Here is the corrected function. It should work now whether or not the marker type exists.

                                     

                                    function getMarkerType (markerName, doc) {
                                       
                                        var markerType = doc.GetNamedMarkerType (markerName);
                                        if (markerType.ObjectValid () == 0) {
                                            markerType = doc.NewNamedMarkerType (markerName);
                                        }
                                        return markerType;
                                    }
                                    

                                     

                                    Thanks for your patience. -Rick

                                    • 15. Re: Creating a variable that contains the value of the Modification Date (Long) system variable
                                      JuleeBruce Level 1

                                      Thank you for all of your help Rick, that worked like a CHARM! You are

                                      amazing!!!!

                                       

                                      Thanks,

                                       

                                      Julie Bruce

                                      AO-DTS-SDSO-SD

                                      julie_bruce@aotx.uscourts.gov

                                      210-301-6309