const PAGEBREAK_PREFIXES = ["Problem Statement (Japan", "Chapter"];
const SCRIPT_NAME_MULTI_PREFIX = 'Custom Page Break (Multi-Prefix Match)';
const SCRIPT_ERROR_MENU_NAME_MULTI_PREFIX = `${SCRIPT_NAME_MULTI_PREFIX} (Configuration Error)`;
function getValidPrefixes(prefixes) {
if (!Array.isArray(prefixes)) {
return [];
}
return prefixes.filter(prefix => typeof prefix === 'string' && prefix.trim().length > 0);
}
function onOpen_MultiPrefix() {
try {
const validPrefixes = getValidPrefixes(PAGEBREAK_PREFIXES);
if (validPrefixes.length === 0) {
Logger.log(`onOpen_MultiPrefix: No valid page break prefixes are set (${JSON.stringify(PAGEBREAK_PREFIXES)}). Displaying error menu.`);
showConfigurationErrorMenu_MultiPrefix("No valid page break prefixes are set");
return;
}
let menuItemText = `Page Break Before Prefixes (${validPrefixes.slice(0, 2).map(p => `"${p}"`).join(', ')}...)`;
if (validPrefixes.length === 1) {
menuItemText = `Page Break Before Prefix "${validPrefixes[0]}"`;
} else if (validPrefixes.length === 2) {
menuItemText = `Page Break Before Prefixes (${validPrefixes.map(p => `"${p}"`).join(', ')})`;
}
DocumentApp.getUi()
.createMenu(SCRIPT_NAME_MULTI_PREFIX)
.addItem(menuItemText, 'insertPageBreakAtPrefixMarkers')
.addToUi();
Logger.log(`onOpen_MultiPrefix: Menu added successfully (Valid target prefixes: ${JSON.stringify(validPrefixes)}).`);
} catch (e) {
Logger.log(`onOpen_MultiPrefix: Error while adding menu: ${e}\n${e.stack}`);
showConfigurationErrorMenu_MultiPrefix("Error adding menu");
}
}
function showConfigurationErrorMenu_MultiPrefix(reason) {
try {
DocumentApp.getUi()
.createMenu(SCRIPT_ERROR_MENU_NAME_MULTI_PREFIX)
.addItem(`Check Settings (${reason})`, 'showConfigurationError_MultiPrefix')
.addToUi();
} catch (e) {
Logger.log(`showConfigurationErrorMenu_MultiPrefix: Further error while displaying error menu: ${e}`);
}
}
function showConfigurationError_MultiPrefix() {
let currentSetting = "Undefined or inaccessible";
try {
currentSetting = typeof PAGEBREAK_PREFIXES !== 'undefined'
? (Array.isArray(PAGEBREAK_PREFIXES) ? JSON.stringify(PAGEBREAK_PREFIXES) : `Invalid setting value (${PAGEBREAK_PREFIXES})`)
: "Undefined";
} catch(e) {
currentSetting = "Error displaying setting value";
}
const message = `There is a problem with the script's settings.\n\n`
+ `Current setting value (PAGEBREAK_PREFIXES): ${currentSetting}\n\n`
+ `Please open the script editor, check and correct the "PAGEBREAK_PREFIXES" value at the top of the file, and **save the file**.\n\n`
+ `This value must be an **array** containing **at least one** **non-empty** prefix string to serve as a page break marker (e.g., ["PREFIX1", "PREFIX2"]).\n`
+ `Empty strings "" and strings with only whitespace " " are ignored.\n\n`
+ `(Example: const PAGEBREAK_PREFIXES = ["Chapter ", "Section ", "Figure-"];)`
DocumentApp.getUi().alert("Script Configuration Error", message, DocumentApp.getUi().ButtonSet.OK);
}
function insertPageBreakAtPrefixMarkers() {
const startTime = new Date();
let doc;
try {
doc = DocumentApp.getActiveDocument();
if (!doc) throw new Error("Could not get the active document.");
doc.getName();
} catch (e) {
handleExecutionError_MultiPrefix("Document Access Error", e);
return;
}
const validPrefixes = getValidPrefixes(PAGEBREAK_PREFIXES);
if (validPrefixes.length === 0) {
Logger.log(`insertPageBreakAtPrefixMarkers: Check before processing revealed no valid page break prefixes are set.`);
showConfigurationError_MultiPrefix("No valid page break prefixes are set");
return;
}
Logger.log(`--- Starting Page Break Insertion (Multi-Prefix Match) ---`);
Logger.log(`Document: ${doc.getName()}`);
Logger.log(`Valid target prefixes (actually used for search): ${JSON.stringify(validPrefixes)}`);
const body = doc.getBody();
const numChildren = body.getNumChildren();
let pageBreakInsertedCount = 0;
let foundMarkersCount = 0;
Logger.log(`Number of elements: ${numChildren}. Traversing in reverse order...`);
for (let i = numChildren - 1; i >= 0; i--) {
const element = body.getChild(i);
if (element.getType() === DocumentApp.ElementType.PARAGRAPH) {
const paragraph = element.asParagraph();
let paragraphText;
try {
paragraphText = paragraph.getText();
if (validPrefixes.some(prefix => paragraphText.startsWith(prefix))) {
foundMarkersCount++;
if (i > 0 && body.getChild(i - 1).getType() !== DocumentApp.ElementType.PAGE_BREAK) {
try {
body.insertPageBreak(i);
pageBreakInsertedCount++;
} catch (insertError) {
Logger.log(`! Error while inserting page break at Index ${i}: ${insertError}`);
}
}
}
} catch (elementError) {
Logger.log(`! Error processing Index ${i} (Type: PARAGRAPH): ${elementError}. Skipping.`);
}
}
}
const endTime = new Date();
const duration = (endTime.getTime() - startTime.getTime()) / 1000;
Logger.log(`--- Traversal Complete ---`);
Logger.log(`Processing time: ${duration.toFixed(2)} seconds`);
Logger.log(`Paragraphs starting with specified prefixes (${JSON.stringify(validPrefixes)}) found: ${foundMarkersCount}`);
Logger.log(`Inserted page breaks: ${pageBreakInsertedCount}`);
const resultMessage = buildResultMessage_MultiPrefix(pageBreakInsertedCount, foundMarkersCount, validPrefixes, duration);
DocumentApp.getUi().alert("Processing Complete", resultMessage, DocumentApp.getUi().ButtonSet.OK);
Logger.log(`--- Page Break Insertion (Multi-Prefix Match) Complete ---`);
}
function handleExecutionError_MultiPrefix(context, error) {
Logger.log(`Runtime error (${context}): ${error}\n${error.stack}`);
let userMessage = `An error occurred while running the script.\n\nContext: ${context}`;
if (error.message) {
if (error.message.includes("Authorization required")) {
userMessage = "The necessary permissions to run the script have not been approved.\n\nPlease reload the document or run the script again, and grant permission on the authorization screen.";
} else {
userMessage += `\nDetails: ${error.message}`;
}
}
DocumentApp.getUi().alert("Script Error", userMessage, DocumentApp.getUi().ButtonSet.OK);
}
function buildResultMessage_MultiPrefix(insertedCount, foundCount, validPrefixes, duration) {
const displayPrefixes = validPrefixes.slice(0, 3).map(p => `"${p}"`);
const prefixDescription = `paragraphs starting with the specified prefixes (${displayPrefixes.join(', ')}${validPrefixes.length > 3 ? '...' : ''})`;
if (insertedCount > 0) {
return `Inserted page breaks before ${insertedCount} ${prefixDescription}.\n\nProcessing time: ${duration.toFixed(2)} seconds`;
} else if (foundCount > 0) {
return `${foundCount} ${prefixDescription.replace('paragraphs', 'paragraph(s)')} were found, but no page breaks were inserted.\n(This may be because the paragraph is at the beginning of the document or a page break already exists.)\n\nProcessing time: ${duration.toFixed(2)} seconds`;
} else {
return `No ${prefixDescription} were found.\n\nPlease check the following:\n`
+ `1. Are valid prefixes set in "PAGEBREAK_PREFIXES" at the top of the script? (Current valid settings: ${JSON.stringify(validPrefixes)})\n`
+ `2. Does the document contain any paragraphs that start with one of these prefixes? (The match is case-sensitive.)\n`
+ `3. Have the script permissions been approved?`;
}
}