Copy link to clipboard
Copied
Hello,
I have a subchapter in a book where the subchapters are numbered. It starts at a subchapter, 5.1, with the paragraph style "Heading 1 Start, and the number properties as <$chapnum>.<n=1> :
Subsequent subchapters follow the "Heading 1 Continue" style and the number properies as <$chapnum>.<n+> , and it works just fine for 5.2 and 5.3, following the properties for Heading 1 Continue":
But then, when I try to start a new subchapter, 5.4, it only wants to be 5.1, despite having the exact same paragraph style and properties:
A couple of notes:
1. I have removed all overrides.
2. I am not a programmer. Unless you have text to copy and paste into the code, anything you say will go right over my head 😜.
Thank you.
Susan and I figured out the problem. There were two separate sets of paragraph formats without series labels (including the heading paragraphs) and they caused the numbers to restart. I showed her how to use series labels to keep numbering paragraphs independent of each other.
Also, I updated my script to ignore autonumbers without numbering building blocks; for example, bullets and text-only autonumbers. Here is the updated script.
/* CP-AutonumberReport.jsx Version 0.2b March 28, 2025
Copyri
...
Copy link to clipboard
Copied
It appears that you aren't using a Series Label for the numbering.
This might appear as the H: in a
Paragaph Format /Numbering\
Format: [ H:‹$chapnum›.‹n=1› ]
If the case, various stray numbered paras of other types might be resetting the default counter.
…which is one reason why the Series Label feature exists.
Also, check the Numbering properties from the Book menu for each chapter (it's a right-click option), plus within each chapter (Format🞃Document🞂Numbering…), esp. the chapter that's resetting to 1.
Copy link to clipboard
Copied
Hi Susan, You need to set the numbering at the book level instead of the document level. Click on one or more components in the book, right-click and choose Numbering. Set the desired numbering properties there and update the book. Dismiss any "Inconsistent numbering" dialog boxes and you should be all set.
Copy link to clipboard
Copied
You might find this series of short videos helpful to understand FrameMaker pagination and numbering:
Copy link to clipboard
Copied
Hi Frameexpert,
If I'm interpretting what you're saying correctly, I'm taking the following steps:
I select an element from the book (I assume that means chapter?). I'm choosing the one that's having the numerical problem:
And select "Numbering"
This is what appears:
The tab for "Chapter" is the tab selected. My chapter numbering is fine, so I'm going to select another tab, though I'm not sure which one. So I select "section," as it's a section within a chapter. This is what comes up:
All selections are grayed out, so I can't do anything. If I COULD select anything, I'd select "continue numbering from previous section in book" (though I don't know how that would affect the first section in the book, which I want to be the "start," not the "continue.").
I figured "Sub-section" might have selectable options:
This tab has nothing selectable either.
I haven't seen any "inconsistent numbering" dialog boxes, so I suspect I'm not looking in the right place?
What am I doing wrong? Maybe I'm using a different version of FrameMaker that you are? I'm using 2020.
Thank you.
Susy
Copy link to clipboard
Copied
Re: versions - should be the same; You're only using chapnum$ so the Chapter tab would be the only one that counts. Did you perform a book update?
Copy link to clipboard
Copied
Hi Susan, Sections and Subsections are grayed-out unless you have documents in folders or groups in the book (which you don't). You should only have to work with the Chapter tab. After you make your changes, update the book and see if the numbering updates.
Copy link to clipboard
Copied
I'm sorry but I'm a relative newbie and in my trainings, that has never been covered. I don't know you mean by "documents in folders." Should I take all of my book chapters and put them in folders? Or should I take all of them and group them into a folder?
This sounds really important and I can't believe that my trainer didn't cover this. We had about 8 1-hour sessions.
I'm going to take a stab in the dark here, as I really don't know what I'm doing.
I right-click on the FOLDER instead of the individual file, and select "Numbering" from the dropdown list:
This comes up, which I believe is the same menu that comes up when I do this with individual files:
"Section" and "Subsection" are still grayed out, which must mean that what I did with putting all of the files into a folder is NOT what needs to be done.
Can you tell me what you mean by "folders" and "groups?"
Sorry to be so obtuse. I've never had this problem before, and my trainer never covered this.
Thank you,
Susy
Copy link to clipboard
Copied
Can you meet via zoom or teams? I can show you how to increment your numbering quickly if I can see what you are doing. Folders and groups aren't necessary for what you want to do. There will be no cost for meeting. Thanks.
Copy link to clipboard
Copied
That is very generous! I think we have met before, around a year or so ago, and you helped me with something.
I'm going to try the code that you've written, and see if that solves the problem. If it doesn't, perhaps we can meet sometime today. I'm in CA, and therefore on PDT. I'm about 30 miles from the Adobe headquarters, and yet they are still no help 😐!
Copy link to clipboard
Copied
lol - I'm 99.9% sure that there's nobody at Adobe HQ dealing with FM
Copy link to clipboard
Copied
:Huh. I saved your code to a plain text file, and when I went to File/Script/Run, it called up the window to select the script file with the "jsx" extension, and it didn't appear as an option to select, as though it didn't exist. That is odd.
What time can you meet?
Copy link to clipboard
Copied
Hi Susan, I can meet at 2:30 pm PDT. Contact me offlist and I will send a meeting link.
rick at frameexpert dot com
Copy link to clipboard
Copied
I'm trying to figure out audio. Apparently my mic has decided not to work today. You can stop the meeting and I can let you know when the problem is solved. Sorry.
Copy link to clipboard
Copied
That's OK. I will be available at 2:30 your time. We can use our phones and just use zoom for sharing the screen.
Copy link to clipboard
Copied
Oh that's true! Hopefully I can get into the conference room or an empty office. So 2:30 it is. Thank you.
Copy link to clipboard
Copied
(Zoom link deleted)
Copy link to clipboard
Copied
OK, I should have read your original post more closely; you are having problems with numbering WITHIN a chapter. I am sorry about that. Let's meet and I will quickly show you how to find the problem.
Copy link to clipboard
Copied
Here is a script I always wanted to write. It provides a report of all of your paragraphs that have autonumbering applied. It gives you the actual number (or text), followed by the building blocks. It should help troubleshoot instances where the numbers aren't correct.
To use the script, copy it into a plain text file and save it in a convenient location with a .jsx extension. Open your document or book and choose File > Script > Run and select the script. You should get the Book Error Log with all of your autonumber data. If you look at the entries above where the number resets to 5.1, you should discover the paragraph that is incorrectly resetting the number. If you have trouble figuring it out, save the log file or take a screenshot of the log above the 5.1 paragraph.
To save the Book Error Log, you must unlock it first. Press Esc F l k (l = lower-case L) in sequence to unlock the file. Then you can save it as a regular FrameMaker document.
/* CP-AutonumberReport.jsx Version 0.1b March 25, 2025
Copyright 2025, Carmen Publishing Inc. All rights reserved.
For information, call 585-729-6746 or email rick@frameexpert.com.
Not to be resold without permission.
Version 0.1b March 25, 2025: First release of the script.
*/
#target framemaker
var CP_ANR = CP_ANR || {};
CP_ANR.version = "Version 0.1b March 25, 2025";
CP_ANR.file = $.fileName;
CP_ANR.main = function () {
var book, doc, markerType, counter;
book = app.ActiveBook;
if (book.ObjectValid () === 1) {
CP_ANR.processBook (book);
}
else {
doc = app.ActiveDoc;
if (doc.ObjectValid () === 1) {
CP_ANR.processDoc (doc, 0);
}
}
};
CP_ANR.processDoc = function (doc, bookId) {
var pgf;
// Process all paragraphs in the main flow.
pgf = doc.MainFlowInDoc.FirstTextFrameInFlow.FirstPgf;
while (pgf.ObjectValid () === 1) {
CP_ANR.processPgf (pgf, doc, bookId);
pgf = pgf.NextPgfInFlow;
}
};
CP_ANR.processBook = function (book) {
var bookComp, doc, regex;
// Regular expression for standard FrameMaker documents.
regex = /\.fm$/i;
// Loop through all of the components in the book.
bookComp = book.FirstComponentInBook;
while (bookComp.ObjectValid () === 1) {
if (bookComp.ExcludeBookComponent === 0) {
if (regex.test (bookComp.Name) === true) {
// Skip generated files.
if (bookComp.BookComponentType === Constants.FV_BK_NOT_GENERATABLE) {
// Get the document returned in a JavaScript object.
doc = CP_ANR.getDocument (bookComp.Name, undefined, false);
if ((doc) && (doc.ObjectValid () === 1)) {
book.StatusLine = "Processing " + new File (bookComp.Name).displayName;
// Call the function to get the document's autonumber data.
CP_ANR.processDoc (doc, book.id)
// If the document was opened by the script, save it and close it.
if (doc.openedByScript === true) {
//doc.SimpleSave (bookComp.Name, false);
doc.Close (true);
}
}
}
}
}
bookComp = bookComp.NextBookComponentInDFSOrder;
}
// Reset the book status line.
book.StatusLine = "";
};
CP_ANR.processPgf = function (pgf, doc, bookId) {
var textList, count, i, msg;
if (pgf.PgfIsAutoNum === 1) {
msg = pgf.PgfNumber + " " + pgf.AutoNumString;
msg = CP_ANR.writeBookErrorLog (pgf.id, doc.id, bookId, msg);
}
// Get any tables in the paragraph.
textList = pgf.GetText (Constants.FTI_TblAnchor);
count = textList.length;
for (i = 0; i < count; i += 1) {
// Process the table.
CP_ANR.processTbl (textList[i].obj, doc, bookId);
}
};
CP_ANR.writeBookErrorLog = function (objId, docId, bookId, msg) {
/// msg = CP_ANR.writeBookErrorLog (objId, docId, bookId, msg);
msg = 'log -b=' + bookId + ' -d=' + docId + ' -o=' + objId + ' --' + msg;
CallClient ('BookErrorLog', msg);
return msg; // Return for troubleshooting.
};
CP_ANR.processTbl = function (tbl, doc, bookId) {
var pgf, cell;
// If the title is at the top, process it first.
if (tbl.TblTitlePosition === Constants.FV_TBL_TITLE_ABOVE) {
pgf = tbl.FirstPgf;
while (pgf.ObjectValid () === 1) {
if (pgf.PgfIsAutoNum === 1) {
CP_ANR.processPgf (pgf, doc, bookId);
}
pgf = pgf.NextPgfInFlow;
}
}
// Process each cell and its paragraphs.
cell = tbl.FirstRowInTbl.FirstCellInRow;
while (cell.ObjectValid () === 1) {
if (cell.CellIsStraddled === 0) {
pgf = cell.FirstPgf;
while (pgf.ObjectValid () === 1) {
if (pgf.PgfIsAutoNum === 1) {
CP_ANR.processPgf (pgf, doc, bookId);
}
pgf = pgf.NextPgfInFlow;
}
}
cell = cell.NextCellInTbl;
}
// IF the title is at the bottom, process it last.
if (tbl.TblTitlePosition === Constants.FV_TBL_TITLE_BELOW) {
while (pgf.ObjectValid () === 1) {
if (pgf.PgfIsAutoNum === 1) {
CP_ANR.processPgf (pgf, doc, bookId);
}
pgf = pgf.NextPgfInFlow;
}
}
};
CP_ANR.getDocument = function (filename, structuredApplication, visible) {
var doc;
// See if the document is already open.
doc = CP_ANR.docIsOpen (filename);
if ((doc) && (doc.ObjectValid () === 1)) {
return doc;
}
else {
// The document is not already open, so open it.
return CP_ANR.openDocOrBook (filename, structuredApplication, visible);
}
};
CP_ANR.docIsOpen = function (filename) {
var file, name, doc;
// Make a File object from the file name.
file = new File (filename);
// Uppercase the filename for easy comparison.
name = file.fullName.toUpperCase ();
// Loop through the open documents in the session.
doc = app.FirstOpenDoc;
while (doc.ObjectValid () === 1) {
// Compare the document’s name with the one we are looking for.
if (new File (doc.Name).fullName.toUpperCase () === name) {
// The document we are looking for is open.
doc.openedByScript = false;
return doc;
}
doc = doc.NextOpenDocInSession;
}
};
CP_ANR.openDocOrBook = function (filename, structuredApplication, visible) {
var i = 0, docOrBook = 0, openProps, returnProps;
// Get default property list for opening documents.
openProps = GetOpenDefaultParams ();
// Get a property list to return any error messages.
returnProps = new PropVals ();
// Set specific open property values to open the document.
i = GetPropIndex (openProps,Constants.FS_AlertUserAboutFailure);
openProps[i].propVal.ival=false;
i = GetPropIndex (openProps,Constants.FS_MakeVisible);
openProps[i].propVal.ival=visible;
i = GetPropIndex (openProps,Constants.FS_FileIsOldVersion);
openProps[i].propVal.ival=Constants.FV_DoOK;
i = GetPropIndex (openProps,Constants.FS_FileIsInUse);
openProps[i].propVal.ival=Constants.FV_ResetLockAndContinue;
i = GetPropIndex (openProps,Constants.FS_FontChangedMetric);
openProps[i].propVal.ival=Constants.FV_DoOK;
i = GetPropIndex (openProps,Constants.FS_FontNotFoundInCatalog);
openProps[i].propVal.ival=Constants.FV_DoOK;
i = GetPropIndex (openProps,Constants.FS_FontNotFoundInDoc);
openProps[i].propVal.ival=Constants.FV_DoOK;
i = GetPropIndex (openProps,Constants.FS_RefFileNotFound);
openProps[i].propVal.ival=Constants.FV_AllowAllRefFilesUnFindable;
i = GetPropIndex (openProps,Constants.FS_UseRecoverFile);
openProps[i].propVal.ival=Constants.FV_DoNo;
if (structuredApplication !== undefined) {
i = GetPropIndex (openProps,Constants.FS_StructuredOpenApplication);
openProps[i].propVal.sval=structuredApplication;
}
// Attempt to open the document.
docOrBook = Open (filename,openProps,returnProps);
if (docOrBook.ObjectValid () === 1) {
// Add a property to the document or book, indicating that the script opened it.
docOrBook.openedByScript = true;
}
else {
// If the document can't be open, print the errors to the Console.
PrintOpenStatus (returnProps);
Console ("\r" + filename);
}
return docOrBook; // Return the document or book object.
};
CP_ANR.main ();
Copy link to clipboard
Copied
Susan and I figured out the problem. There were two separate sets of paragraph formats without series labels (including the heading paragraphs) and they caused the numbers to restart. I showed her how to use series labels to keep numbering paragraphs independent of each other.
Also, I updated my script to ignore autonumbers without numbering building blocks; for example, bullets and text-only autonumbers. Here is the updated script.
/* CP-AutonumberReport.jsx Version 0.2b March 28, 2025
Copyright 2025, Carmen Publishing Inc. All rights reserved.
For information, call 585-729-6746 or email rick@frameexpert.com.
Not to be resold without permission.
Version 0.2b March 28, 2025: Non-numbered autonumbered paragraphs are skipped.
Version 0.1b March 25, 2025: First release of the script.
*/
#target framemaker
var CP_ANR = CP_ANR || {};
CP_ANR.version = "Version 0.2b March 28, 2025";
CP_ANR.file = $.fileName;
CP_ANR.main = function () {
var book, doc;
book = app.ActiveBook;
if (book.ObjectValid () === 1) {
CP_ANR.processBook (book);
}
else {
doc = app.ActiveDoc;
if (doc.ObjectValid () === 1) {
CP_ANR.processDoc (doc, 0);
}
}
};
CP_ANR.processDoc = function (doc, bookId) {
var pgf;
// Process all paragraphs in the main flow.
pgf = doc.MainFlowInDoc.FirstTextFrameInFlow.FirstPgf;
while (pgf.ObjectValid () === 1) {
CP_ANR.processPgf (pgf, doc, bookId);
pgf = pgf.NextPgfInFlow;
}
};
CP_ANR.processBook = function (book) {
var bookComp, doc, regex;
// Regular expression for standard FrameMaker documents.
regex = /\.fm$/i;
// Loop through all of the components in the book.
bookComp = book.FirstComponentInBook;
while (bookComp.ObjectValid () === 1) {
if (bookComp.ExcludeBookComponent === 0) {
if (regex.test (bookComp.Name) === true) {
// Skip generated files.
if (bookComp.BookComponentType === Constants.FV_BK_NOT_GENERATABLE) {
// Get the document returned in a JavaScript object.
doc = CP_ANR.getDocument (bookComp.Name, undefined, false);
if ((doc) && (doc.ObjectValid () === 1)) {
book.StatusLine = "Processing " + new File (bookComp.Name).displayName;
// Call the function to get the document's autonumber data.
CP_ANR.processDoc (doc, book.id)
// If the document was opened by the script, save it and close it.
if (doc.openedByScript === true) {
//doc.SimpleSave (bookComp.Name, false);
doc.Close (true);
}
}
}
}
}
bookComp = bookComp.NextBookComponentInDFSOrder;
}
// Reset the book status line.
book.StatusLine = "";
};
CP_ANR.processPgf = function (pgf, doc, bookId) {
var textList, count, i, msg;
if (pgf.PgfIsAutoNum === 1) {
// Make sure there are actual building blocks (skip bullets, text-only, etc.).
if (/</.test (pgf.AutoNumString) === true) {
msg = pgf.PgfNumber + " " + pgf.AutoNumString + " [" + pgf.Name + "]";
msg = CP_ANR.writeBookErrorLog (pgf.id, doc.id, bookId, msg);
}
}
// Get any tables in the paragraph.
textList = pgf.GetText (Constants.FTI_TblAnchor);
count = textList.length;
for (i = 0; i < count; i += 1) {
// Process the table.
CP_ANR.processTbl (textList[i].obj, doc, bookId);
}
};
CP_ANR.writeBookErrorLog = function (objId, docId, bookId, msg) {
/// msg = CP_ANR.writeBookErrorLog (objId, docId, bookId, msg);
msg = 'log -b=' + bookId + ' -d=' + docId + ' -o=' + objId + ' --' + msg;
CallClient ('BookErrorLog', msg);
return msg; // Return for troubleshooting.
};
CP_ANR.processTbl = function (tbl, doc, bookId) {
var pgf, cell;
// If the title is at the top, process it first.
if (tbl.TblTitlePosition === Constants.FV_TBL_TITLE_ABOVE) {
pgf = tbl.FirstPgf;
while (pgf.ObjectValid () === 1) {
if (pgf.PgfIsAutoNum === 1) {
CP_ANR.processPgf (pgf, doc, bookId);
}
pgf = pgf.NextPgfInFlow;
}
}
// Process each cell and its paragraphs.
cell = tbl.FirstRowInTbl.FirstCellInRow;
while (cell.ObjectValid () === 1) {
if (cell.CellIsStraddled === 0) {
pgf = cell.FirstPgf;
while (pgf.ObjectValid () === 1) {
if (pgf.PgfIsAutoNum === 1) {
CP_ANR.processPgf (pgf, doc, bookId);
}
pgf = pgf.NextPgfInFlow;
}
}
cell = cell.NextCellInTbl;
}
// IF the title is at the bottom, process it last.
if (tbl.TblTitlePosition === Constants.FV_TBL_TITLE_BELOW) {
while (pgf.ObjectValid () === 1) {
if (pgf.PgfIsAutoNum === 1) {
CP_ANR.processPgf (pgf, doc, bookId);
}
pgf = pgf.NextPgfInFlow;
}
}
};
CP_ANR.getDocument = function (filename, structuredApplication, visible) {
var doc;
// See if the document is already open.
doc = CP_ANR.docIsOpen (filename);
if ((doc) && (doc.ObjectValid () === 1)) {
return doc;
}
else {
// The document is not already open, so open it.
return CP_ANR.openDocOrBook (filename, structuredApplication, visible);
}
};
CP_ANR.docIsOpen = function (filename) {
var file, name, doc;
// Make a File object from the file name.
file = new File (filename);
// Uppercase the filename for easy comparison.
name = file.fullName.toUpperCase ();
// Loop through the open documents in the session.
doc = app.FirstOpenDoc;
while (doc.ObjectValid () === 1) {
// Compare the document’s name with the one we are looking for.
if (new File (doc.Name).fullName.toUpperCase () === name) {
// The document we are looking for is open.
doc.openedByScript = false;
return doc;
}
doc = doc.NextOpenDocInSession;
}
};
CP_ANR.openDocOrBook = function (filename, structuredApplication, visible) {
var i = 0, docOrBook = 0, openProps, returnProps;
// Get default property list for opening documents.
openProps = GetOpenDefaultParams ();
// Get a property list to return any error messages.
returnProps = new PropVals ();
// Set specific open property values to open the document.
i = GetPropIndex (openProps,Constants.FS_AlertUserAboutFailure);
openProps[i].propVal.ival=false;
i = GetPropIndex (openProps,Constants.FS_MakeVisible);
openProps[i].propVal.ival=visible;
i = GetPropIndex (openProps,Constants.FS_FileIsOldVersion);
openProps[i].propVal.ival=Constants.FV_DoOK;
i = GetPropIndex (openProps,Constants.FS_FileIsInUse);
openProps[i].propVal.ival=Constants.FV_ResetLockAndContinue;
i = GetPropIndex (openProps,Constants.FS_FontChangedMetric);
openProps[i].propVal.ival=Constants.FV_DoOK;
i = GetPropIndex (openProps,Constants.FS_FontNotFoundInCatalog);
openProps[i].propVal.ival=Constants.FV_DoOK;
i = GetPropIndex (openProps,Constants.FS_FontNotFoundInDoc);
openProps[i].propVal.ival=Constants.FV_DoOK;
i = GetPropIndex (openProps,Constants.FS_RefFileNotFound);
openProps[i].propVal.ival=Constants.FV_AllowAllRefFilesUnFindable;
i = GetPropIndex (openProps,Constants.FS_UseRecoverFile);
openProps[i].propVal.ival=Constants.FV_DoNo;
if (structuredApplication !== undefined) {
i = GetPropIndex (openProps,Constants.FS_StructuredOpenApplication);
openProps[i].propVal.sval=structuredApplication;
}
// Attempt to open the document.
docOrBook = Open (filename,openProps,returnProps);
if (docOrBook.ObjectValid () === 1) {
// Add a property to the document or book, indicating that the script opened it.
docOrBook.openedByScript = true;
}
else {
// If the document can't be open, print the errors to the Console.
PrintOpenStatus (returnProps);
Console ("\r" + filename);
}
return docOrBook; // Return the document or book object.
};
CP_ANR.main ();
Copy link to clipboard
Copied
I dug out a couple of still-relevant autonumber videos from 2016:
Rick Quatro
http://give.roswellpark.org/goto/rick-quatro