Quantcast
Channel: Adobe Community : All Content - FrameMaker Scripting
Viewing all 888 articles
Browse latest View live

ExtendScript Find() methods - FS_FindCustomizationFlags constants

$
0
0

Hi,

 

While attempting to do Find operations with ExtendScript, FM2015, I find that the documented constants for FS_FindCustomizationFlags do not resolve. From the doc:

 

Constant.FS_FindCustomizationFlags (15) - An optional parameter of type FT_Integer that may be any of the following bit flags OR’ed together:

• Constants.FF_FIND_CONSIDER_CASE (0x01)

• Constants.FF_FIND_WHOLE_WORD (0x02)

• Constants.FF_FIND_USE_WILDCARDS (0x04)

• Constants.FF_FIND_BACKWARDS (0x08)

 

For example, this just reports "undefined":

 

   alert(Constants.FF_FIND_CONSIDER_CASE);   

 

I worked around it by specifying the hex integer directly, but I'm wondering if I'm just missing something. And FWIW, I originally bumped into this looking for a way to search with regular expressions. I found this in the FDK fapidefs.h file, which fortunately allowed me to get it to work:

 

#define FF_FIND_USE_REGEX   ((IntT)   0x10)

 

Russ


Programmatic equivalent for the Find dialog Change functions

$
0
0

Hi,

 

Is there a reasonable programmatic equivalent for the Change buttons in the Find dialog? FDK or ES? I have no urgency to find one, but I was going to use it if available. I'm looking for something simple and direct, no wild button-pushing-automation-routines or anything like that.

 

I hope this isn't a dumb question. I'm amused that after all these years, it is the first time I've ever thought of a need for it.

 

Russ

ES regex does not recognise umlauts etc...

$
0
0

Friends of regular expressions!

I want to check for valid (special) variable names and use

\w

for word characters. This does not find characters such as ä - or any other none-ASCI character.

My test script is this:

var toTest = [], j, n;    toTest.push("#Apple");                            // true    toTest.push("#Apfel, #apple, #Gurkensalateska");  // true    toTest.push("#t_27Apples");                       // true    toTest.push("#côté");                             // false    toTest.push("#Grüne_5Äpfel");                     // false    toTest.push("#Äpfel");                            // false

n = toTest.length;
for (j=0; j < n; j++) {  $.writeln(ContainsVariable (toTest[j]), " ", toTest[j]);
}

function ContainsVariable (text) {
var re_variable= /(^#[\w][\d_\w]*)(, +)?/,
    indexOfChar, character, lSkip, kText;  for(indexOfChar = 0; character = text[indexOfChar]; indexOfChar++) {    kText = text.substring(indexOfChar); // rest of the statement    sFound = kText.match(re_variable);    if (sFound != null) {      lSkip = sFound[0].length;      indexOfChar = indexOfChar + lSkip -1;      continue;    }    return false;  }  return true;
}

Any ideas how to get valid results for non-english variable names?

There seem to be other shortcomings also: indesign-scripting-forum-roundup-7#hd4sb3.

I have not found any documation about the regex-flavour of ES. Isn't there any?

Klaus

FrameMaker script: alignment of all anchored frames in document to "Left"

$
0
0

I'm a long term FrameMaker (11) user, but completely new to scripting.

Can someone help me make a script that will set the alignment for all anchored frames in a document to "Left"?

Can someone help me make a script that will set the positioning for all anchored frames in a document to "Below current line"?

Nested dialogue problem

$
0
0

Dear experts,
From a palette i need to divert into a dialgoue and then come back into the palette.
This works fine for the first time i enter the dialogue. The dialogue fails when entered the second time.
A stripped down version of my scripts is following. The palette is to the left, the 'test' dialogue to the right:

dialogues.png

  • Usage is as follows:
  • In the palette active the checkbox and clik the Handle Content button.
  • This invokes the 'test' dialogue.
  • According to the settings in the script the OK/Return button is hidden.
  • Clicking the Cancel button closes this dialogue and we are back in the palette.
  • Since the 'test' was cancelled, an alert appears with NO as default.
  • Click NO
  • The check box is cleared for a new decision
  • Now the user 'changes the input (top field)', checks the box and clicks the Handle ... button.
  • => Error on line 48: undefined is not an object.

What may be wrong here?

// NestedDialogue.jsx
#target framemaker
// target needed for Alert ...
var gsVariable;
var wPalDS = new Window('palette',"FM-calc : Manage Variables",undefined);
var wPalV  = new Window('dialog', "FM-calc : Check contents of variable", undefined);

PaletteDocSettings();
// ================================================================================================
function PaletteDocSettings(){ //=== Outer function
    wPalDS.sVarValue = wPalDS.add('edittext',undefined,"Content to be handled", {multiline:true});    wPalDS.sVarValue.alignment = ['right',' '];    wPalDS.cbChkContent = wPalDS.add('checkbox',undefined,"Use secondary dialogue");     wPalDS.btnAdd = wPalDS.add('button',undefined,"Handle content");  wPalDS.Cancel = wPalDS.add('button',undefined,"Cancel");  wPalDS.Cancel.onClick = function () {    wPalDS.close();   }    wPalDS.btnAdd.onClick = ButtonAddVarConst;    // externalised callback function!   wPalDS.show();
} //---  end PaletteDocSettings

function ButtonAddVarConst () {
var bContinue, content;
// $.bp(true);
  content =  wPalDS.sVarValue.text;  if (wPalDS.cbChkContent.value) {  // check contents    gsVariable = "=" + content;    DialogueVerify();                             // Inner function    bContinue = wPalV.btnReturn.enabled;    if (!bContinue) {      if (Alert ("Test failed, continue anyway?", Constants.FF_ALERT_NO_DEFAULT) != 0) {        wPalDS.cbChkContent.value = false;        // uncheck        return;                                   // user clicked NO      }    }    content = gsVariable.substring (1);         // skip the = sign    wPalDS.sVarValue.text = content;  }
} //--- end ButtonAddVarConst

function DialogueVerify(){ //=== Dialogue for verifying variable contents
  wPalV.st1 = wPalV.add('statictext',undefined,"Content to check");  wPalV.st1.graphics.font = ScriptUI.newFont(wPalV.st1.graphics.font.family,"BOLD",wPalV.st1.graphics.font.size);  wPalV.btnReturn = wPalV.add('button',undefined,"OK / Return");  wPalV.btnReturn.helpTip = "Return to calling dialogue";  wPalV.Cancel = wPalV.add('button',undefined,"Cancel");  wPalV.Cancel.alignment = ['right',' '];  wPalV.btnReturn.onClick =   ButtonReturnV;   // externalised callback function!  wPalV.Cancel.onClick = function () {    wPalV.close();  }  wPalV.btnReturn.enabled = false;             // test situation 1 (using Cancel to exit)
//wPalV.btnReturn.enabled = true;              // test situation 2 (using this button to exit)  wPalV.show();
}

function ButtonReturnV () {
  wPalV.close();
} //---  end ButtonReturnV

Any ideas are welcome ...

wrap text with element

$
0
0

Hello,

 

I'm using FM12 with structured docs. I'm looking to convert some Framescript into Extendscript language.

I finish my first Extendscript this morning (too me 3 days) : searching Element and saving the attributes value into a text file.

But I'm stuck converting my second one.

 

In a structured doc, i want to wrap a selected text with a element "PRESS" into a element "PARA" (the element PRESS is allowed in the element PARA by the DTD/EDD).

 

My Framescript (FS 6.0)

Set vCurrentDoc = ActiveDoc;

Set vSelect = vCurrentDoc.TextSelection;

// Get the Element Def

Get Object NewVar(vEltDef) Type(ElementDef) Name('PRESS');

// Wrap the selected text

Wrap ElementDef(vEltDef);

// Select the new PRESS element

Set vPRESS = ElementSelection.begin.child;

// Create the attribs

New AttributeList NewVar(vPRESSatt) AttrName('SMALLCAPS') Value('1');

// Assign the Attributes to the tag

Set vPRESS.Attributes = vPRESSatt;

In Extendscript, how do i write it?

 

var vCurrentDoc = app.ActiveDoc;

var vSelect = vCurrentDoc.TextSelection;

var vElem = vCurrentDoc.GetNamedElementDef("PRESS");

var attrs = vElem.AttributeDefs;

attrs[1].values = "ITAL";

vElem.Attributes = attrs;

vElem.WrapElement();

The script add the PRESS element but the attribute is not fill. Why? and how to correct it?

 

Many thanks for considering my request.

 

Ce message a été modifié par : Philippe Pinpin Add info

Does anybody knows, where i can get the Graphic2Dir data, for the Elm/Frame Script Tool ?

$
0
0

Does anybody knows, where i can get the Graphic2Dir data, for the Elm/Frame Script Tool ?

How to find a variable just after a marker?

$
0
0

Dear experts,

My project steps further - but as soon as I have to deal with FM-objects I still struggle. The script should do this:

  • In the document (http://www.daube.ch/zz_tests/Markers-and-variables.fm) there are markers of type #calc (which are all found and stored into an array.
  • Some of them are immediately followed by a variable (called temporary variable, because the names are built by date/time).
  • Before I insert the new variable, the old one should be found and removed.
  • The problem is that I do not find the old variable and hence can not remove it, before the new one is inserted. The inserting is OK, but it occurs independently of existing variables.
  • Line 49 always evaluates to false, even if there is a variable present.

How can I find (at first hand) any variable (Later I will need to check whether it is really a temprary variable) ?

#target framemaker
// Required doc: Markers-and-variables.fm:  aVariables = ["#DOCname", "#TEST", "2016-09-27T10:28:46.060Z"];  goCurrentDoc =  app.ActiveDoc;  giNCalcMarkers = CollectMarkers  (gaoCalcMarkers, "#calc");

for (j = 0; j < giNCalcMarkers; j++) {  goCurrentMarker = gaoCalcMarkers[j];            // find a marker  oFound = FindVariable (goCurrentDoc, goCurrentMarker);  if (oFound[0]) {                                // true, variable found    oFound[1].Delete();                           // remove temp. variable from document  }  oTextLoc = goCurrentMarker.TextLoc;  oTextLoc.offset = oTextLoc.offset + 1;          // insert temp variable behind marker  InsertVariable (goCurrentDoc, oTextLoc, "#TEST", "\+1.275×10<super>\+9" );
}
// ================= Routines to be tested ========================================================
function CollectMarkers (aMarkers, sMarkerName) { //=== Collect marker-objects, store in array ====
// In        aMarkers:    global array of markers to be filled
//           sMarkerName: type of marker to be collected
// Out       Return number of markers collected
var  oMarker, MarkerTI, nMarkers;  tsSave = goCurrentDoc.TextSelection;            // save current cursor location  oMarker = goCurrentDoc.FirstMarkerInDoc;  while (oMarker.ObjectValid()) {    MarkerTI = oMarker.MarkerTypeId;    if (MarkerTI.Name == sMarkerName) {      aMarkers.push(oMarker);                     // store the marker objects    }    oMarker = oMarker.NextMarkerInDoc;  }  goCurrentDoc.TextSelection = tsSave;            // Restore cursor location  nMarkers = aMarkers.length;  return nMarkers;                                // number of markers in array
} //--- end CollectMarkers 

function FindVariable (oDoc, oMarker) { //=== Find variable behind marker ========================
// In        oMarker: current marker
// Out       Function returns [true, found variable] or [false, loc behind the marker]
var tLoc1 = oMarker.TextLoc,    tLoc2 = oMarker.TextLoc,                      // should be just behind the marker    j, myTextRange, findParams, fRange, oTextItem, aVarsRange, nVars, thisVar;   tLoc1.offset = tLoc1.offset + 1;  tLoc2.offset = tLoc2.offset + 2;  myTextRange  = new TextRange(tLoc1,tLoc2);  oDoc.TextSelection = myTextRange;               // Does this hold a variable ?  findParams= GetFindParamsVariable ("");         // search for any variable  fRange = goCurrentDoc.Find  (tLoc1, findParams);// is a textrange  if (fRange.beg.obj.ObjectValid()) {    aVarsRange = goCurrentDoc.GetTextForRange (fRange, Constants.FTI_VarBegin);    nVars = aVarsRange.length;    for (j = 0; j < nVars; j++) {                   // loop should not be necessary      oTextItem = aVarsRange[j];                    // superfluous ?      thisVar = oTextItem.obj;                      // should contain only one variable      return [true, thisVar];    }  } else {    return [false, tLoc1];  }
} //--- end FindVariable 

function GetFindParamsVariable (sVarName) { //=== Set up parameters to Find variable ==============
// In        sVarName: variable type to be found
// Out       Returns parameters for the find function: no wrapping around ?
var findParams;  findParams = AllocatePropVals (2);   findParams[0].propIdent.num = Constants.FS_FindWrap ;   findParams[0].propVal.valType = Constants.FT_Integer;   findParams[0].propVal.ival = 0 ; // don't start at the beginning => seems to be 'nowrap'  findParams[1].propIdent.num = Constants.FS_FindNamedVariable;   findParams[1].propVal.valType = Constants.FT_String;   findParams[1].propVal.sval = sVarName;   return findParams; 
} //--- end GetFindParams

function InsertVariable (oDoc, oTextLoc, sVarName, sContent) { //=== Insert variable at location =====
// In        oTextLoc: where to insert the variable
//           sVarName: name of the variable
//           sContent: content of the variable
var oVar;   oVar = oDoc.NewAnchoredFormattedVar (sVarName, oTextLoc);   oVar.Fmt = sContent;
}

Get row and col nr of current cell

$
0
0

Dear all,

For absolute addressing a table cell out of the current cell I need to know where I am.

I have not found a proporty like CurrentRow or CellRowNum. CellRow is an object Row.

// CellNumbering.jsx
// have cursor in a table cell
#target framemaker  oDoc  = app.ActiveDoc;  oTbl  = oDoc.SelectedTbl;  oPgf  = oDoc.TextSelection.beg.obj;   oCell = oPgf.InTextObj; 
//jRow  = oCell.???;              // ???  jCol  = oCell.CellColNum;       // 0 ... n
$.writeln (oTbl.TblNumCols);      // 4
$.writeln (jCol);                 // 2

Is it necessary to loop through all rows and cells to find the currentselection => current location found?

Inserting a Date text into a document on several different pages

$
0
0

I need to put an ordinal date phrase in several positions in a document.  I have managed to be able to get it to put the phrase on the top of the first page where I then go along and cut and paste it where I need it.  But what I would like is to run the script and have it insert the text exactly where I want it to go in the document with out manually having to do it. Here is the script I am using which I basically got to work copying and fixing it so I could get an output.  I am running extendscript on Adobe FrameMaker v12

//  INSERTING THE VALUE OF A VARIABLE INTO A DOCUMENT THAT WAS CREATED IN SCRIPT

var m_names = new Array("January", "February", "March",

"April", "May", "June", "July", "August", "September",

"October", "November", "December");

 

 

var date = new Date();

//alert(date)  //shows system date

 

 

var curr_date = date.getDate();

//alert(curr_date)  //shows the day date

var sup = "";

if (curr_date == 1 || curr_date == 21 || curr_date ==31)

   {

   sup = "st";

   }

else if (curr_date == 2 || curr_date == 22)

   {

   sup = "nd";

   }

else if (curr_date == 3 || curr_date == 23)

   {

   sup = "rd";

   }

else

   {

   sup = "th";

   }

 

 

var curr_month = date.getMonth();

//alert(curr_month)  //shows the month

var curr_year = date.getFullYear();

//alert(sup)  //shows the suffix for the ordinal number of the day date

var NewordinalDate="the "+curr_date + sup + " day of "+m_names[curr_month] + ", " + curr_year

//alert(NewordinalDate)  // shows the date phrase of the ordinal day with the date.

//here is an example of the output "the 22nd day of August, 2016 "

var doc= app.ActiveDoc;

var mainflow =doc.MainFlowInDoc;

var tframe=mainflow.FirstTextFrameInFlow;mainflow.FirstTextFrameInFlow;

var pgf = tframe.FirstPgf;

var tLoc=new TextLoc();//Create the text location objet

tLoc.obj=pgf;  //make it a paragraph

tLoc.offset=25;   //insert at the start of the paragraphs

doc.AddText(tLoc,(NewordinalDate)); //insert the variable into the document look at the in parenthasse

//make sure paragraph marker is present on the target page or a lot of object references will be undifined.

 

In most of my documents I need to have a current date variable and this ordinal date phrase which I have to create using the parts of the two current date fields.  The result is I don't have a current date that will update. So I thought to create a script and run it just before printing or sending the documents. Most of these date phrases come in on the last page of the document which can be 15 to 16 pages long. As I have said at the moment this Script will write the phrase of the current system date at the left hand top of the document. Where I usually have a Header in bold so I have to drop that down and assign a normal paragraph tag to it before I run the script or I get Upper case in Bold underlined date phrase.  I really need to learn how to put the add text phrase or any other phrase where ever I want the result to go. In the script above I don't seem to get anything from the  tLoc.offset=    I don't believe this is executing I don't know why there is nothing from it. I have almost zero knowledge about how to script I am just fiddling with javascript premade scripts I have pulled off the internet and got them somehow to get results in Framemaker extend script.   I am amazed at how little there is on anything one actually needs to do Why this date phrase is not a built in variable in FrameMaker leaves me a bit weary.  Why framemaker Doesn't have a built in DBF connectivity is also a mystery I guess it is program created before ODBC

any insight or help with this would be immensely appreciated.

Find name of variable

$
0
0

Dear friends and experts, I'm again at the end of my knowledge:

  • A variable just behind a marker is found and the variable can be deleted in the text

MarkerWithVariableBehind.png

  • This variable should also be removed from the catalogue. I'ts name is not known, because the name is generated at the time of insertion (the current name is 2016-11-10T09:46:52.136Z).
  • Experiments with the text selection after finding the variable (line 31) did not reveal anything useful to get the name of the variable.
  • Do You have an idea?
#target framemaker
// Required doc: #calc Marker with text containing "C7 at the beginning
//               behind this marker the variable of unknown name is found
sMarkerText = '"C7';  oDoc =  app.ActiveDoc;  oMarker = oDoc.FirstMarkerInDoc;  while (oMarker.ObjectValid()) {    if (oMarker.MarkerTypeId.Name == "#calc") {      if (oMarker.MarkerText == sMarkerText) {        bFound = FindAndDeleteVariable (goCurrentDoc, goCurrentMarker); // remove already existing variable
// How to get the name of the variable to be able to remove it from the catalogue also?               oTextLoc = goCurrentMarker.TextLoc;        oTextLoc.offset = oTextLoc.offset + 1;        // insert temp variable behind marker        InsertVariable (goCurrentDoc, oTextLoc, "#TEST", "\+1.275×10<super>\+9" );      }    }  }

function FindAndDeleteVariable (oDoc, oMarker) { //=== Find variable behind marker and remove it ==
// In        oMarker: current marker
// Out       Function returns true for found+removed variable
var tLoc1 = oMarker.TextLoc,    tLoc2 = oMarker.TextLoc,                      // should be just behind the marker    iUnique1= oMarker.TextLoc.obj.Unique,         // ¶ of the marker    myTextRange, findParams, fRange;   tLoc2.offset = tLoc2.offset + 1;                // a - c are required!  myTextRange  = new TextRange(tLoc1,tLoc2);      // b  oDoc.TextSelection = myTextRange;               // c  findParams= GetFindParamsVariable ();           // search for any variable  fRange = oDoc.Find  (tLoc1, findParams);        // finds variable  if (fRange.beg.obj.ObjectValid()) {             // variable found ?    if (fRange.beg.obj.Unique == iUnique1) {      // same ¶ as the marker ?      if (fRange.beg.offset == tLoc1.offset+1) {  // TR =? variable behind marker        oDoc.DeleteText(fRange);                  // Delete the selected Variable        return true;      }    }  }  return false;                                   // there was'nt a variable
} //--- end FindAndDeleteVariable 

function GetFindParamsVariable () { //=== Set up parameters to Find a variable ====================
// Out       Returns parameters for the find function: no wrapping around ?
// Reference Klaus Göbel, https://forums.adobe.com/thread/2227993
//           FDK Function Reference, F_ApiFind()
var findParams = new PropVals() ;   propVal = new PropVal() ;  propVal.propIdent.num = Constants.FS_FindObject;   propVal.propVal.valType = Constants.FT_Integer;   propVal.propVal.ival = Constants.FV_FindAnyVariable ;   findParams.push(propVal);   return findParams; 
} //--- end GetFindParamsVariable

function InsertVariable (oDoc, oTextLoc, sVarName, sContent) { //=== Insert variable at location ==
// In        oTextLoc: where to insert the variable
//           sVarName: name of the variable
//           sContent: content of the variable
var oVar;   oVar = oDoc.NewAnchoredFormattedVar (sVarName, oTextLoc);   oVar.Fmt = sContent;
}

 

BTW the marker contains this text: "C7 ¶ after T2 TB" = @PI / 180.0; which is successfully evaluated and placed in the temporary variable - there is progress in my project¨.

Thank You very much for Your help!

Klaus

Keyboard shortcuts

$
0
0

Dear friends
FYI:   When working on "Customising FrameMaker 12/13" I was not succesful with keyboard shortcuts for a scipt.

In the meantime I discovered Russ Wards post on this forum and his script 100.02__ADVANCED_Create_formatting_shortcuts.
So I found the reason why my shortcuts did not work: For ESC sequences the backslash must be escaped!
Then I missed the key-label in the menu. I discovered that the menu entry can be appended by a tab and the label:

oMenus.MenuDocu = "Documentation\tESC,q,d";
 ...
FMcalcMenu.DefineAndAddCommand(1,"docFMcalcDocu", oMenus.MenuDocu, "\\!qd");

menu-shortcuts.png

Rick Quatro observed in the mentioned forum post that his CTRL + comma (^,) shortcut does not work. He argued that certain key combinations will not work: "I got some of the letter keys to work, but I couldn't use the punctuation keys. FrameScript still rules :-)".

 

I will update "Customising FrameMaker 12/13" accordingly…

Klaus

Can I do this with FrameMaker ExtendScripting?

$
0
0

Using FM 12.0

I'm a coder so coding is not the issue here. It's just my lack of familiarity with FM ExtendScript and the art of the possible.

 

I want to create a script that

 

  1. Inserts a marker of a custom type called Editorial Changes. We can safely assume that this marker type (Editorial Changes) exists already.
  2. Displays an advanced marker window: Please see the mock-up window below. Studying sample scripts such as SnpCreateCheckBoxRadioButtons.jsx, I know I can create something like that window, so that's not an issue.
  3. Once the user has finished filling the fields, I want to capture the data and store it inside the marker field, say as an XML snippet.
  4. Later on, when a user selects a created marker of type "Editorial Changes," I want my script to intercept that event, grab the XML content from the marker and display my custom window with all these fields.

 

Does the sequence outlined through steps 1-4 doable via an ExtendScript? If you've done something like that and have a script lying around, would you mind sharing?

 

Thanks!

 

Get focus back into document

$
0
0

Dear friends,

After opening a panel (wPalC) from the menu the focus is (of course) on the panel.
a) Before working in this panel, the user may want to open another panel wPalS (by means of a keyboard shortcut).

The focus should be back in the document for this.
b) If the user choses to work in the already open panel - no problem: Either he uses the immediate focus or as soon as he does anything there the focus is there. For example tool tips are displayed on hover, no click required.
But I have not found a method to get the focus into the document for case a).
I have this function which works fine in other circumstances:

function SetFocusToDoc (oDoc) {
var tRange = oDoc.TextSelection;  oDoc.ScrollToText (tRange);
} //--- end SetFocusToDoc

 

But whether I place the call to this routine at places 1), 2) or 3) - no success. The shortcut will not be executed (no "ping" though):

 

function Command (cmd) {  switch (cmd) {
//  ...     case 5:      HandleCalcMarkers();              // opens panel wPalC      wPalC.active = false;      SetFocusToDoc (goCurrentDoc);     // 1)      break;    case 6:      HandleSeriesMarkers();            // opens panel wPalS                                SetFocusToDoc (goCurrentDoc);     // 2)      break;    case 7:      HandleDocSettings();                                break;  }      SetFocusToDoc (goCurrentDoc);     // 3)
} //--- end Command
  1. I can get the focus in the document with the following method - not for the end-user:
  2. Run the script from ESTK with the menu setup replaced by an in-line selection list
  3. Invoke HandleCalcMarkers from this selection list. The panel is displayed and active
  4. From ESTK directly run (separate instance) SetFocusToDoc (app.ActiveDoc)
  5. In FrameMaker I see the focus in the document (blinking cursor).

How to get the focus back to the document in the script?

Any ideas welcome!

 

Even FM does not provide the focus in the document in all 'desired' cases, for example after Change Zoom level.

Setting up a character format

$
0
0

Dear friends,

 

It's quite easy to set up a new character format with 'all AsIs', but I have not found the necessary ingredients to set up one with particular properties:
a) name = superscript:     all AsIs, but superscript
b) name = highlight:         all AsIs, but a colour (from the standard set)
Hence I had the idea to call the Character Designer by means of F-codes.
Well - it opens, but I do not see how to set the dialogue to "All AsIs" - because the user normally has its cursor somewhere in the document and the really defined properties are only seen if the cursor is outside the document.
So far I'm here:

function DefineCharFmt (sName, oDoc, bProperty) {
var charFmt = 0, fcode = [],  msg;   msg = "Character format '" + sName + "' does not exist in catalogue\nShall it be created?";  charFmt = oDoc.GetNamedCharFmt (sName);   if (!charFmt.ObjectValid()) {                   // does not exist in catalogue    if (confirm (msg, false, "Confirm new character format")) {      charFmt = oDoc.NewNamedObject (Constants.FO_CharFmt, sName);      if (bProperty) {                          fcode[0] = FCodes.CHAR_DESIGN_CAT;       // Open Charactr designer to set the property
//      fcode[1] = FCodes.CHAR_DESIGNKIT_RESET;   // nothing to do with Set AsIs          Fcodes(fcode);      }      return true;    } else {      return false;name    }  }  return true;
} //--- end DefineCharFmt 


Maybe I need to put it the other way round:
Instruct the user that for the proper function of the script the xxx character formats must exist in the catalogue and be set up accordingly...
Or:
Createte the needed character formats in the catalogue - only "AsIs" and instruct the user to set them up properly to see the effect in the document.

 

Klaus


Display on/off quirks

$
0
0

Dear experts

(FM-13.0.5.547) I have discovered a strange behaviour:
In the following order the location is not restored after the actions. It seems that SetDisplay destroys it:

  SetDisplay (false);  savedTR = goCurrentDoc.TextSelection;
// Do a lot of things (loop) on various places in the document  RestoreTR (goCurrentDoc, savedTR);  SetDisplay (true);


In the following order things work as expected. Cursor location is restored.

  savedTR = goCurrentDoc.TextSelection;  SetDisplay (false);
// Do a lot of things (loop) on various places in the document  SetDisplay (true);  RestoreTR (goCurrentDoc, savedTR);

 

The two functions are

function RestoreTR (oTargetDoc, oSavedTR) {
// actions may have left us on a reference page
var bodyPage = oTargetDoc.FirstBodyPageInDoc;   oTargetDoc.CurrentPage = bodyPage;   oTargetDoc.TextSelection = oSavedTR;   oTargetDoc.ScrollToText(oSavedTR); 
} //--- end RestoreTR

function SetDisplay (bWanted) {
  if (bWanted) {                // switch ON    if (app.Displaying === 0) {      app.Displaying = 1;    }  } else {                      // switch OFF    if (app.Displaying === 1) {      app.Displaying = 0;    }  }
} //--- end SetDisplay

 

What may be the cause of this?

Special effects (mostly unwanted)

$
0
0

Dear friends,
We all know about special effects in the movies, but I can tell you: also ExtendScript can entertain us with such. It appears to be a conjurer of the good old style. It all happens on the stage of FM version 13.0.5.547.
Information for the uninitiated:

  • The script creates a menu with some entries
  • Two entries immediately open a panel to work with special markers
  • Other entries open the pdf documentation, open a panel for document settings or run functions through the document.
  • Debugging is not possible when functions are called via the menu. Hence for debugging I disable the set-up of the menu and present a selection list with the jumps to the functions.
  • I unregister the script each time before I start it again (either in ESTK or via script catalogue).

 

The Ghost

When opening one of the panels via menu it happens that in the top left corner a small selection list appears with contents from a previous call:

magic-ghost.png
I can create this illusion at will with the following sequence of magic tricks. No, it's not an illusion: Putting the cursor into the selection list the display can be changed with the arrow keys, so it's some sort of real...

  1. Leave all script activity (panels)
  2. Unregister the script
  3. Open a panel by the still 'active' menu in FM
  4. Voilà! The ghost appears in top left corner

 

The slave

From time to time (magic does not happen by schedule) the following effect can be seen:

  1. Starting the script before an FM document is open
  2. Invoking a script action via menu
  3. I do not see the panel - it is in the background
  4. Not certain about an error I bring the console window to the foreground
  5. Not seeing anything suspicious I dismiss the console window to get a fresh version for an error.
  6. At the same time the panel disappears, following 'his master' immediately to the nirvana.

Unfortunately I can not reproduce this at will... Hence I do not know whether an open ESTK (with nothing in there) has any influence.

 

The twins

I discovered this after a small update of my script and hence guessed the reason for it there - but my update was in a mathematical function, not in the area of the user interface:

magic-twins.png

  1. Open FM and then create a new document
  2. Invoke the script via catalogue and select a panel function from the menu
  3. The contents of the panel is duplicated
  4. Each 'content' is active independently of the other - see the different tabs in the screen shot.
  5. But I am not certain which one really performs the function in the document.
  6. Hence I dismiss these Siamese twins.
  7. Then I opened a document which behaved 'last time'
  8. Unregister script, start script again, open panel via menu
  9. Same effect
  10. Now I left FM and started afresh
  11. The magic did not appear any more (sorry folks!).

 

Big entertainment, isn't it? But frustrating when trying to get a good script...

What can we learn from these tricks?

What's the ExtendScript command for updating a FrameMaker book?

$
0
0

I have some scripts adapted from the FM_Outputs_CondText.jsx sample in FM10, but I just noticed today that the book is not getting updated. Seems like I need something in between these two commands:

 

FileSource = OpenBook(InputFile);

SavePdf(FileSource,InputFile.replace(/\.book$/i,"") + OutPutFiles[output_no]);

When is a script closed (time of unregistering)?

$
0
0

Dear friends and experts!
To avoid one (or more) of the special effects reported in this forum Klaus Göbel proposes to unregister the script when it is closed. But: when is the script closed?

I did not get a formal education in interactive programming, hence I have no real clue about the process: what is calling what. My programming experience is in procedural languages starting with Fortran in the 1960ies.

Please point me to a document describing all this - the Scripting Guide does not tell. And of course JavaScript books don't either.
The only sample script using Notify is FM_Suppress_Alerts.jsx and this is absolutely simplistic.
My understanding is this:

  • Starting the script registers it - 'purchases' a watch dog (IMHO not the same as registering an FDK client).
  • After starting the script it establishes the menu and configures the watchdog called Notification.
  • Within FM there is a nother watchdog barking at (the cat) Command when a menu item is selected.
  • Command calls the appropriate routine and then sleeps again (return tells the watch dog: have done!)
  • Notify is waked up on special events and calls appropriate routines (return tells the watch dog: have done!)
  • After a user has performed a menu selection and the the requested functions have been performed: where are we in the script? At the end of Command? At the end of main (that's really unreasonable).

The main structure of my script is this:

// --- Windows ID must be set outside the dialogue function to be available for Notify functions
var wPalC  = new Window("palette","FM-calc : Handle #calc Markers",    undefined);
//... also wPalS and wPalDS  main ();

function main () {
  SetUpGlobals ();                                // all global variables and constants  SetupFMcalc ();                                 // get inital data -- debug to be set explicitly  SetupNotifications ();                          // notification trigger 'Change document' etc.  // --- During development switch between the two following statements:  SetUpMenus(); // uncomment for real work  //DebugMenu (); // comment for real work - debugging does not work with menus
}
#include funGlobals.jsx
//... more includes
function SetUpMenus () {   //...
}
function Command (cmd) {   //...
}
function SetupNotifications () {   //...
}
function RemoveMyNotification() {   //...
}
function Notify (note, object, sparam, iparam) {   //...
}
//--- now follow the functions directly called from Command
function OpenHelpFile ()
function DoFMcalcInSelection()
function DoFMcalcInDoc () 
function DoFMcalcInBook () 
function HandleCalcMarkers()
function HandleSeriesMarkers()
function HandleDocSettings()
//...And all the others which I want to have in this module

In the past I had the call of RemoveMyNotification in the call-back functions for the Cancel/Exit buttons in the panels. But now I guess that the best place would be at the end of the Command function: After anything has been done.
But: SetUpNotifications is within the main function and will not be executed anymore after the script has been started the first time.

I need a better insight, sigh!

Selecting an unanchored frame

$
0
0

Beackground

I have a few old documents (~150) that are having issues. When opening these documents one graphic file cannot be found. I know this file was not checked into our source control system, therefore it's missing.

I can see the name of the missing file, for the moment I skip the dialog and continue.

I don't have the file (since it was not checked in) so I want to delete it from the document and insert a new one.

If I run a LOR/Imported Graphics I see file is located on page 42. If I navigate to that page I don't see the expected gray box to indicate the missing file.

I run the script below and I get that the file is located in an unanchored frame, that I cannot see.

 

Question:

Is there a way to select either the graphic or the unanchored frame in order to delete it? Thanks for any ideas...

 

var oDoc, oGraphic, oFrame;
oDoc = app.ActiveDoc;
oGraphic = oDoc.FirstGraphicInDoc;
if(oGraphic.ObjectValid()){    //good to go     while (oGraphic.ObjectValid()) {         //         if (oGraphic.type == Constants.FO_Inset){             oFrame = oGraphic.FrameParent;             alert(oGraphic.InsetFile + "\n" + oFrame.constructor.name);         }         oGraphic = oGraphic.NextGraphicInDoc;         }
}
Viewing all 888 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>