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

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

Explorer ,
Nov 26, 2014 Nov 26, 2014

Copy link to clipboard

Copied

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.

TOPICS
Formatting and numbering , Scripting

Views

1.6K

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

correct answers 1 Correct answer

Community Expert , Nov 26, 2014 Nov 26, 2014

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

...

Votes

Translate

Translate
Community Expert ,
Nov 26, 2014 Nov 26, 2014

Copy link to clipboard

Copied

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

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
Explorer ,
Nov 26, 2014 Nov 26, 2014

Copy link to clipboard

Copied

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...

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 Expert ,
Nov 26, 2014 Nov 26, 2014

Copy link to clipboard

Copied

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.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

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
Explorer ,
Nov 26, 2014 Nov 26, 2014

Copy link to clipboard

Copied

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

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
Explorer ,
Nov 26, 2014 Nov 26, 2014

Copy link to clipboard

Copied

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.

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 Expert ,
Nov 26, 2014 Nov 26, 2014

Copy link to clipboard

Copied

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

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
Explorer ,
Nov 26, 2014 Nov 26, 2014

Copy link to clipboard

Copied

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

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 Expert ,
Nov 26, 2014 Nov 26, 2014

Copy link to clipboard

Copied

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

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 Expert ,
Nov 26, 2014 Nov 26, 2014

Copy link to clipboard

Copied

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

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
Explorer ,
Nov 26, 2014 Nov 26, 2014

Copy link to clipboard

Copied

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

        } 

        return text; // Return the text 

    } 

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
Explorer ,
Nov 26, 2014 Nov 26, 2014

Copy link to clipboard

Copied

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.

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 Expert ,
Nov 26, 2014 Nov 26, 2014

Copy link to clipboard

Copied

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.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

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
Explorer ,
Nov 26, 2014 Nov 26, 2014

Copy link to clipboard

Copied

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

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 Expert ,
Nov 26, 2014 Nov 26, 2014

Copy link to clipboard

Copied

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

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
Explorer ,
Dec 01, 2014 Dec 01, 2014

Copy link to clipboard

Copied

LATEST

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

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