Copy link to clipboard
Copied
Friends, Romans, Countrymen, I wanted to create a list of commands with this (now stripped down) script:
// ListCommands2.jsx ====== UTF-8 ======================================
//@target framemaker
var KLD_Z = KLD_Z || {}; // global script object
KLD_Z.main = function () { // <><><><><><><><><><><><><><><><><><><><><>
$.bp(true);
var j=0, line, cmd = app.FirstCommandInSession;
while (cmd.ObjectValid()) {
line = cmd.Name + "\t" + cmd.Label+ "\t" + cmd.Fcodes + "\t" + cmd.KeyboardShortcuts;
// $.writeln (j, " ", line);
j += 1;
cmd = cmd.NextCommandInSession;
}
$.writeln ("Finito ", j-1, " ", line);
} //--- end main -------------------------------------------------------
KLD_Z.main ();
In ESTK the script run for a while - visually not recognisable, because the initial breakpoint is highlighted and the round indicator spins. If you have the $.witeln active, then after a while the log shows much output, but stops amids the list, which later is continued to (in my case) line 1383 which is (found by other means) really the last valid command.
After this the script is spinning and nothing happens any more. Terminating the script yields the status message «Execution halted: Adobe FrameMaker 2019 (15.0) did not respond.». FM must be killed.
By other means (looping to command 1380 and then stepping) I found that at this point
cmd.NextCommandInSession is null. The while can not handle this ????
{With acitvated $.writeln you get only the last portion of the list, not the full list. In the real script i pushed the lines into an array which I later wanted to copy to a file}
Klaus, it seems you jumped to the wrong conclusion. I experimented with the code a bit and found that the Fcodes property may cause the problem. Here is my - working - function:
ListCommands = function( )
{
var oFile = File( 'C:\\Temp\\FM_Commands.txt' );
oFile.encoding = 'UTF-8';
if( !oFile.open( 'w' ) ) return false;
var i = 0;
var n;
var oCmd = app.FirstCommandInSession;
while( oCmd.ObjectValid( ) )
{
i++;
oFile.writeln( oCmd.Name + '\t' + oCmd.Label + '\t' + oCmd.Fcode + '\t' +
...
Copy link to clipboard
Copied
You could try this:
while ((cmd) && (cmd.ObjectValid()))
Copy link to clipboard
Copied
I have renamed the topic to what i have found with various time consuming experiments.
For the tests I use an empty document which I probe in my standard FM-15.0.8 setup (some plug-ins, some own scripts in StartupFolder), Windows and FM restarted after every hang of ETSK and FM.
Before the final tests I modified the initial script (see above) with various while conditions (wlc means: Welcome Screen, doc: the before mentioned document):
while (cmd && cmd.ObjectValid()) { // wlc: last is 1384, not terminating
while (cmd !== null) { // wlc: last is 1383, not terminating
while (cmd !== null) { // doc: last is 1384, not terminating
"not terminating" means: ESTK spins its indicator in the status line endlessly. I need to kill ESTK and then also FM.
The following script terminates as expected - watch the number of commands found.
// ListCommands4.jsx ====== UTF-8 ==============================================
//@target framemaker
var KLD_Z = KLD_Z || {}; // global script object
// file is E:\_DDDprojects\FM-JsxLib\Docu\z-empty.fm (lastg is 1802)
KLD_Z.main = function () { // <><><><><><><><><><><><><><><><><><><><><><><><><>
var j=0, line, cmd = app.FirstCommandInSession;
while (cmd.ObjectValid()) {
line = cmd.Name + "\t«" + cmd.NextCommandInSession.Name + "»";
if (j > 1790) {$.writeln (j, " ", line);}
$.bp(j==1800);
j += 1;
cmd = cmd.NextCommandInSession;
}
$.writeln ("Finito by ObjectValid, j=", j-1);
} //--- end main ---------------------------------------------------------------
KLD_Z.main ();
This is logged:
--- 2022-02-28 14:09 after Win reboot
1791 Sep2 «iFrameCandidatesSep»
1792 iFrameCandidatesSep «null»
Finito by ObjectValid, j=1792
--- 2022-02-28 14:22 after Win reboot
same happening
So ObjectValid() works as expected. From various experiments with the cmd object I know that ESTK does not indicate the next-to-final item as invalid. ESTK reports most properties as 0 and the Name as string "null"...
So I went back to my intial approach to collect the data in an array and write this then to a file:
// ListCommands5.jsx ====== UTF-8 ==============================================
//@target framemaker
var KLD_Z = KLD_Z || {}; // global script object
// file is E:\_DDDprojects\FM-JsxLib\Docu\z-empty.fm (lastg is 1802)
KLD_Z.main = function () { // <><><><><><><><><><><><><><><><><><><><><><><><><>
var j=0, line, aLines = [], cmd = app.FirstCommandInSession, sFilePath;
sFilePath = "E:/_DDDprojects/FM-JsxLib/FMjsxLib/Functions/Demos/ListCommands.txt";
aLines.push ("Name \tLabel \tFcodes \tKeyboardShortcuts");
while (cmd.ObjectValid()) {
$.bp(j==1390);
if (j > 1380) {$.writeln (j, " ", cmd.Name, " «", cmd.NextCommandInSession.Name, "»");}
line = cmd.Name + "\t" + cmd.Label+ "\t" + cmd.Fcodes + "\t" + cmd.KeyboardShortcuts;
aLines.push (line);
j += 1;
cmd = cmd.NextCommandInSession;
}
$.writeln ("Number of commands in array: ", aLines.length);
KLD_Z.WriteLineArray (sFilePath, aLines);
} //--- end main ---------------------------------------------------------------
KLD_Z.main ();
Note that I have set here the breakpoint to a much smaller value of j (1390 vs 1790 in the previous script). Nevertheless the result is frustrating:
--- 2022-02-28 14:13
1381 ETBCutTableRows «ETBCutTableCols»
1382 ETBCutTableCols «ETBGoToMasterPage»
1383 ETBGoToMasterPage «ETBGoToRefPage»
1384 ETBGoToRefPage «ToolBar_gfx»
1385 ToolBar_gfx «ToolBar_Separator_0»
ESTK spinning, killed, FM to be killed
--- 2022-02-28 14:20 after Win reboot
same happening
My personal conclusion on this:
The list of commands is very flaky and with cmd.NextCommandInSession it is not possible to build a reliable list. Maybe Klaus Müller had the same experience until he decided to build the itl-FrameScript "Report FM Commands" by another method.
Copy link to clipboard
Copied
Klaus, it seems you jumped to the wrong conclusion. I experimented with the code a bit and found that the Fcodes property may cause the problem. Here is my - working - function:
ListCommands = function( )
{
var oFile = File( 'C:\\Temp\\FM_Commands.txt' );
oFile.encoding = 'UTF-8';
if( !oFile.open( 'w' ) ) return false;
var i = 0;
var n;
var oCmd = app.FirstCommandInSession;
while( oCmd.ObjectValid( ) )
{
i++;
oFile.writeln( oCmd.Name + '\t' + oCmd.Label + '\t' + oCmd.Fcode + '\t' + oCmd.KeyboardShortcuts );
oCmd = oCmd.NextCommandInSession;
}
oFile.close( );
alert( 'There are ' + i + ' commands' );
return true;
}
This gives me 1545 commands in my current session and it takes less than a second to generate the file. When I change oCmd.Fcode to oCmd.Fcodes the process hangs at command number 1250 - always the same one. It might be that the sequence of Fcodes is not compatible with characters that can be written to a file. This might happen when an End-Of-File code happens to be also inside an FCodes array - or some other problem might disrupt the write buffer and thereby get FM to hang.
Kind regards
Jang
Copy link to clipboard
Copied
Hi Jang,
Cudos for your effort!
In further tests I found this:
In my case the culprit is the 1386th command. Stopping at the 1385th command ($.bp(j == 1385)) and trying to inspect property oCmd.NextCommandInSession lets ESTK wheel:
The very strange thing is this - even not using the property Fcodes in the script creates problems:
With breakpoint:
So there must be something the ES engine in FM can not handle...
→ I'll stop my curiosity now and do something more productive...
Copy link to clipboard
Copied
There may also be an output buffer overrun. Try adding some pause in the loop after incrementing the i variable:
if( i % 1000 == 0 )
{
var n = 0;
while( n < 1000 ) n++;
}
In my first attempts, writing only the command number did not cause any issues. Adding more properties started to cause issues at some point. Then introducing the wait cycle after every 1000 commands allowed the script to terminate correctly. I have seen output buffer overruns in other scripts in the past, so this is something to be aware of when creating massive output flows.