Skip to main content
PrintHouse
Inspiring
June 26, 2024
Answered

Creating keyword based TOC

  • June 26, 2024
  • 3 replies
  • 452 views

Hello,

 

I was wondering what would be the best way to create a keword based table of contents or index including headings with page numbers, like so:

 

KEYWORD1

  PageNo  Heading on that page

  PageNo  Heading on that page

  PageNo  Heading on that page

KEYWORD2

  PageNo  Heading on that page

  PageNo  Heading on that page

  PageNo  Heading on that page

 

And so on.

 

Please note I don't want index letters (A, B, C...) at all, just styled keywords/topics BUT I need page heading included with a page number underneath. Is this possible using InDesign's tools or is this a job for a script (which might already exist somewhere)?

 

Thank you.

This topic has been closed for replies.
Correct answer PrintHouse

Thank you all for the suggestions. I decided to write a short script (with a little help from AI, no less!) to just get all indexed topics and build a custom TOC/index.

 

Here it is – hopefully will help someone:

 

#target indesign

// Define the paragraph styles
var indexHeadingStyle = "Index Heading";
var indexStyle = "Index";
var titleStyle = "Title";

// Get the active document
var doc = app.activeDocument;

// Prompt the user to select the text frame for the custom table of contents
if (app.selection.length == 1 && app.selection[0].constructor.name == "TextFrame") {
	var tocTextFrame = app.selection[0];
} else {
	alert("Please select a single text frame for the custom table of contents.");
	exit();
}

// Add the title at the beginning with the Title style
tocTextFrame.contents = "Ingredient Index\r";
tocTextFrame.paragraphs[-1].appliedParagraphStyle = doc.paragraphStyles.item(titleStyle);

// Get all index topics
var indexTopics = doc.indexes[0].allTopics;

for (var i = 0; i < indexTopics.length; i++) {
	var topic = indexTopics[i];

	// Add the index topic with the Index Heading style
	tocTextFrame.insertionPoints[-1].contents = topic.name + "\r";
	tocTextFrame.paragraphs[-1].appliedParagraphStyle = doc.paragraphStyles.item(indexHeadingStyle);

	// Get all page references for the topic
	var pageReferences = topic.pageReferences;

	for (var j = 0; j < pageReferences.length; j++) {
		var pageReference = pageReferences[j];
		var page = pageReference.sourceText.parentTextFrames[0].parentPage;

		// Find the first occurrence of the Title style on the page
		var titleText = null;
		var textFrames = page.textFrames;
		for (var k = 0; k < textFrames.length; k++) {
			var textFrame = textFrames[k];
			var paragraphs = textFrame.paragraphs;
			for (var l = 0; l < paragraphs.length; l++) {
				var paragraph = paragraphs[l];
				if (paragraph.appliedParagraphStyle.name == titleStyle) {
					titleText = paragraph.contents.replace(/[\r\n]+/g, ""); // Remove newlines from titleText
					break;
				}
			}
			if (titleText != null) {
				break;
			}
		}

		// If a title was found, add it with the page number in a new line and apply the Index style
		if (titleText != null) {
			var pageEntry = tocTextFrame.insertionPoints[-1].contents = titleText + "\t" + page.name + "\r";
			tocTextFrame.paragraphs[-1].appliedParagraphStyle = doc.paragraphStyles.item(indexStyle);
		}
	}
}

alert("Custom Index created successfully!");

  

3 replies

Barb Binder
Community Expert
Community Expert
June 26, 2024

Hi @PrintHouse:

 

If this appears in alphabetical order you could set this up as a two-level index, with Keywords as level 1, and Headings as level 2. You can disable Include Index Section Headings to eliminate the A, B, C section heads in the dialog box.

 

The only issue I see is that the page numbers will appear after both levels, but you could create and save two GREP find/change queries: the first to remove the page numbers on the keywords, and the second to put the page numbers in front of the heads. We can help you write those. You could even save them as a Find/ChangeByList script that will run both with one command.

 

~Barb

~Barb at Rocky Mountain Training
PrintHouse
PrintHouseAuthorCorrect answer
Inspiring
June 27, 2024

Thank you all for the suggestions. I decided to write a short script (with a little help from AI, no less!) to just get all indexed topics and build a custom TOC/index.

 

Here it is – hopefully will help someone:

 

#target indesign

// Define the paragraph styles
var indexHeadingStyle = "Index Heading";
var indexStyle = "Index";
var titleStyle = "Title";

// Get the active document
var doc = app.activeDocument;

// Prompt the user to select the text frame for the custom table of contents
if (app.selection.length == 1 && app.selection[0].constructor.name == "TextFrame") {
	var tocTextFrame = app.selection[0];
} else {
	alert("Please select a single text frame for the custom table of contents.");
	exit();
}

// Add the title at the beginning with the Title style
tocTextFrame.contents = "Ingredient Index\r";
tocTextFrame.paragraphs[-1].appliedParagraphStyle = doc.paragraphStyles.item(titleStyle);

// Get all index topics
var indexTopics = doc.indexes[0].allTopics;

for (var i = 0; i < indexTopics.length; i++) {
	var topic = indexTopics[i];

	// Add the index topic with the Index Heading style
	tocTextFrame.insertionPoints[-1].contents = topic.name + "\r";
	tocTextFrame.paragraphs[-1].appliedParagraphStyle = doc.paragraphStyles.item(indexHeadingStyle);

	// Get all page references for the topic
	var pageReferences = topic.pageReferences;

	for (var j = 0; j < pageReferences.length; j++) {
		var pageReference = pageReferences[j];
		var page = pageReference.sourceText.parentTextFrames[0].parentPage;

		// Find the first occurrence of the Title style on the page
		var titleText = null;
		var textFrames = page.textFrames;
		for (var k = 0; k < textFrames.length; k++) {
			var textFrame = textFrames[k];
			var paragraphs = textFrame.paragraphs;
			for (var l = 0; l < paragraphs.length; l++) {
				var paragraph = paragraphs[l];
				if (paragraph.appliedParagraphStyle.name == titleStyle) {
					titleText = paragraph.contents.replace(/[\r\n]+/g, ""); // Remove newlines from titleText
					break;
				}
			}
			if (titleText != null) {
				break;
			}
		}

		// If a title was found, add it with the page number in a new line and apply the Index style
		if (titleText != null) {
			var pageEntry = tocTextFrame.insertionPoints[-1].contents = titleText + "\t" + page.name + "\r";
			tocTextFrame.paragraphs[-1].appliedParagraphStyle = doc.paragraphStyles.item(indexStyle);
		}
	}
}

alert("Custom Index created successfully!");

  

Robert at ID-Tasker
Legend
June 26, 2024

@PrintHouse

 

Do you have everything styled - Char and ParaStyles?

 

Do you have a list of keywords? 

 

I have a tool that should be able to do it - but it's PC only... 

 

James Gifford—NitroPress
Legend
June 26, 2024

I don't think InDesign's TOC feature can do this; it's very flexible and configurable, but focused on doing a standard TOC of heading paragraphs in a hierarchy, and pushing it outside that model is difficult.

 

However, the Cross-References feature does a similiar job without any rigid structure and could be adapted to a content list such as you need. It's too complex to try and explain in a forum post, but just knowing the right tool/feature should be a help, and here's a good starting poing :https://helpx.adobe.com/indesign/using/cross-references.html

 

If you soak up the basics and can't figure out how to create the links and structure for your needs, ask away.