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

How to get full paragraph number as displayed on the page in ExtendScript

Participant ,
Jun 29, 2020 Jun 29, 2020

Copy link to clipboard

Copied

I need to add page headers to a long and complex book. The book is hierarchically structured into numeric paragraphs and subparagraphs, and the page headers must reflect the first and last paragraph numbers on each page; e.g., if §5.14 starts at the top of page 109 and §5.17.2 starts at the bottom of the same page, the page header should say “§5.14 – 5.17.2”.

 

The numbered paragraphs are all in a numbered list, so the numbers are automatic.

 

Since, very annoyingly, auto-numbers like these cannot be extracted into text variables, making the headers is proving to be a bit of a headache. Manually doing it is not an option. The best way I’ve come up with (based on this StackExchange post) is to make a script that:

 

  1. Iterates through all paragraphs in the document
  2. If the paragraph has a numbered heading style applied, insert an anchored text frame (with a specific object style applied, which is non-printing and applies the paragraph style the page header text variables are based on)
  3. Populate the text frame with the number of the paragraph (note: the full number, e.g., “5.17.2” – not just “2”)

 

The two first were fairly easy, but I’m stumped for the third. I can easily retrieve the current paragraph’s individual number (“2”) or the formatting applied to the numbering (e.g., “^1.^2.^#^t”), but how to I get the numbers from any previous level? How to I get the full, formatted string “5.17.2”?

 

I suppose I could use Paragraph.convertBulletsAndNumberingToText(), then use GREP replace to delete everything after the numbering, but that seems extremely hacky for something so rather fundamental to a nested list as accessing the fully qualified number. Moreover, convertBulletsAndNumberingToText() can only be applied to an existing Paragraph object and has the bizarre and counterintuitive behaviour of returning undefined, rather than returning the converted string as you’d expect. I’m not sure I’d even be able to duplicate the paragraph into the anchored text frame and textify the numbering at all – the act of duplicating the paragraph might just increase the numbering so I’d end up with “5.17.3” as the text, rather than “5.17.2” …

 

Is there really no simple, sane function to extract this?

TOPICS
Scripting

Views

1.1K

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

Participant , Jun 30, 2020 Jun 30, 2020

Okay, so it seems I was looking through the properties of the Paragraph class too narrowly – I was looking under N for numberingXXX, and it turns out there is a property called Paragraph.bulletsAndNumberingResultText which gives me exactly what I’m looking for (well, nearly – that property also includes the tab that follows the numbering marker, but that should be easy to get rid of).

 

So simple, and yet it took me hours to locate. 😕

Votes

Translate

Translate
Participant ,
Jun 30, 2020 Jun 30, 2020

Copy link to clipboard

Copied

Okay, so it seems I was looking through the properties of the Paragraph class too narrowly – I was looking under N for numberingXXX, and it turns out there is a property called Paragraph.bulletsAndNumberingResultText which gives me exactly what I’m looking for (well, nearly – that property also includes the tab that follows the numbering marker, but that should be easy to get rid of).

 

So simple, and yet it took me hours to locate. 😕

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 ,
Jun 30, 2020 Jun 30, 2020

Copy link to clipboard

Copied

Did you try retrieving the bulletsAndNumberingResultText property of your paragraph? (See https://www.indesignjs.de/extendscriptAPI/indesign-latest/#Paragraph.html)

 

(Hm. There is no (longer?) the option to simply delete my answer. I see you found it while I was testing it out and searching the right page on Gregor's site ...)

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
New Here ,
Feb 25, 2022 Feb 25, 2022

Copy link to clipboard

Copied

Would you share your script for extracting the paragraph numbers so they can be used in a running header? I understand your description of how you worked around this ridiculous inDesign shortcoming. But I do not have scripting experience and don't know how to implement a similar solution.

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
Participant ,
Feb 26, 2022 Feb 26, 2022

Copy link to clipboard

Copied

Sure thing. It’s quite a simple script and not thoroughly tested (I just left it alone when it worked), but it should work in most documents, as far as I can guess.

 

Note the bit at the top where you will have to insert values to match your InDesign document: what you want your EditUndo menu to say after running the script, what paragraph styles have the numbers you want to extract, what space delimiter you have between the numbers and the contents of the paragraph, and what you’ve called the object style that is to hold the ‘hidden’ paragraph numbers. You have to have set up your paragraph styles and this object style before running the script.

 

You can copy-paste the script below into a new file (plain text only, so don’t use Word or anything like that), call it something like “Add hidden paragraph numbers.jsx” (whatever you want, just use the extension .jsx), add the script to your Scripts menu and then you can run it.

 

Alternatively, you can download the attached file and put it into the Scripts folder (as described in the article linked to above). Note: Unfortunately, we can’t upload .jsx files here, so if you choose this option, you have to change the downloaded file’s extension from .txt to .jsx before running the script.

 

The script:

 

/** VARIABLE NAMES THAT MUST BE SPECIFIED BEFORE USING THE SCRIPT
 *  Each variable is preceded by a comment that describes what the variable is used for
**/


// [string] scriptUndoName: The name that will appear in your “File” → “Undo” menu after running the script
var scriptUndoName = "Add hidden paragraph numbering for running headers";

// [array] paragraphStyleNames: An array of names of the paragraph styles in your document that contain numbering and should have the hidden numbers added
var paragraphStyleNames = ['Heading 1', 'Heading 2', 'Heading 3', 'Heading 4'];

// [string] hiddenNumbersObjectStyleName: The name of the object style you have set up for the text frames that contain your hidden paragraph numbers; should be set to non-printing
var hiddenNumbersObjectStyleName = 'Headernummer';

// [string] paragraphNumberingDelimiter: Whatever character you have set in your Bullets and Numbering section between the numbering and the content – usually an em space, a tab, etc.
// NOTE: Has to be a JavaScript notation of the character, not the InDesign code for it; so a tab is either "	" (a literal tab) or "\t", but not "^t" as in InDesign
var paragraphNumberingDelimiter = "\t";


/*** END VARIABLES - LEAVE THE REST OF THE FILE ALONE ***/





Array.prototype.indexOf = function (item) {
	var index = 0, length = this.length;

	for (; index < length; index++) {
		if (this[index] === item) return index;
	}

	return -1;
};



app.doScript(init, void 0, void 0, UndoModes.ENTIRE_SCRIPT, scriptUndoName);




function init() {
	var doc = app.activeDocument;
	var stories = doc.stories;
	var styles = doc.paragraphStyles;
	var paras, p, s, frame, ip, txt;

	for (var i = 0; i < stories.length; i++) {
		paras = stories[i].paragraphs;

		for (var j = 0; j < paras.length; j++) {
			p = paras[j];
			s = p.appliedParagraphStyle;

			if (paragraphStyleNames.indexOf(s.name) !== -1) {
				ip = p.insertionPoints.previousItem(p.insertionPoints.lastItem());
				txt = p.bulletsAndNumberingResultText.replace(paragraphNumberingDelimiter, '');

				frame = ip.textFrames.add({
					appliedObjectStyle: doc.objectStyles.item(hiddenNumbersObjectStyleName),
					contents: txt
				});
			}
		}
	}
}

 

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
New Here ,
Mar 14, 2022 Mar 14, 2022

Copy link to clipboard

Copied

LATEST

Thank you! Very helpful.

 

 

 

Brandy

 

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