How to preserve character styles when merging text via javascript
I'm using a script to merge multiple lines into one paragraph.
This is the start of a paragraph.
This line needs running back.
This line needs running back.
Result:
This is the start of a paragraph. This line needs running back. This line needs running back.
I have code to produce this and it works perfectly. However, when there are characters that are bold or use a bold character style, when merged the bold characters are not retained or preserved.
I am attempting to use a custom indexof function (as i know idnesign does not support indexof) to try and match the characters or words when they shift position from their line to a different one.
For whatever reason i just can't get this to work. Does anyone have any suggestions i can feed to chatgpt as im inexperienced with code.
Please see below code that im using. Just to note, the code only works within the defined paragraph styles CAUTION, WARNING or NOTE.
Thanks,
// Custom indexOf function for word searching
function customIndexOf(text, searchWord) {
var index = -1;
// Ensure text and searchWord are strings
if (typeof text !== "string" || typeof searchWord !== "string") {
throw new Error("Both text and searchWord must be strings");
}
var wordLength = searchWord.length;
// Iterate through the text to find exact match
for (var i = 0; i <= text.length - wordLength; i++) {
if (text.substr(i, wordLength) === searchWord) {
index = i; // Found exact match
break;
}
}
return index;
}
// Function to merge paragraphs
function mergeParagraphs(paragraphsToMerge) {
var firstParagraph = paragraphsToMerge[0];
var mergedText = firstParagraph.contents;
var boldedWords = [];
// Collect all bolded words within the paragraphs to be merged
for (var p = 1; p < paragraphsToMerge.length; p++) { // Start from 1 to avoid duplicating first paragraph
var paragraph = paragraphsToMerge[p];
var paragraphText = paragraph.contents;
var boldText = [];
for (var i = 0; i < paragraph.texts.length; i++) {
var text = paragraph.texts[i];
if (text.appliedCharacterStyle.name === "Bold Copy") {
boldText.push(text.contents); // Collect bold text
}
}
// Store the bold words and their position
boldedWords.push({
text: paragraphText,
bold: boldText
});
mergedText += " " + paragraphText;
paragraph.remove();
}
mergedText = mergedText.replace(/\s{2,}/g, ' '); // Remove excessive spaces
firstParagraph.contents = mergedText;
// Now we need to apply the bold text in the merged paragraph
for (var i = 0; i < boldedWords.length; i++) {
var boldedWord = boldedWords[i].bold;
for (var j = 0; j < boldedWord.length; j++) {
// Using customIndexOf to find the word in the merged paragraph
var index = customIndexOf(firstParagraph.contents, boldedWord[j]);
if (index !== -1) {
var charRange = firstParagraph.characters.itemByRange(index, index + boldedWord[j].length - 1);
charRange.appliedCharacterStyle = app.activeDocument.characterStyles.itemByName("Bold Copy");
}
}
}
// Preserve the paragraph style (the style of the first paragraph)
var firstParagraphStyle = paragraphsToMerge[0].appliedParagraphStyle;
firstParagraph.appliedParagraphStyle = firstParagraphStyle;
}
// Function to apply style and merge paragraphs based on target style
function applyStyleAndMerge(targetStyle, stopStyles) {
if (app.documents.length > 0) {
var doc = app.activeDocument;
if (app.selection.length > 0 && app.selection[0].constructor.name === "Text") {
var selectedText = app.selection[0];
var paragraphs = selectedText.paragraphs.everyItem().getElements();
var applyingStyle = false;
var rangeToMerge = [];
var lastTargetStyleIndex = -1;
function isInStopStyles(styleName) {
for (var i = 0; i < stopStyles.length; i++) {
if (stopStyles[i] === styleName) {
return true;
}
}
return false;
}
for (var p = 0; p < paragraphs.length; p++) {
if (paragraphs[p].appliedParagraphStyle.name === targetStyle) {
lastTargetStyleIndex = p;
}
}
for (var p = 0; p < paragraphs.length; p++) {
var paragraph = paragraphs[p];
var isStopStyle = isInStopStyles(paragraph.appliedParagraphStyle.name);
if (isStopStyle && applyingStyle) {
applyingStyle = false;
if (rangeToMerge.length > 1) {
mergeParagraphs(rangeToMerge);
}
rangeToMerge = [];
}
if (paragraph.appliedParagraphStyle.name === targetStyle) {
applyingStyle = true;
rangeToMerge.push(paragraph);
} else if (applyingStyle && !isStopStyle) {
rangeToMerge.push(paragraph);
}
if (p === lastTargetStyleIndex && applyingStyle) {
applyingStyle = false;
if (rangeToMerge.length > 1) {
mergeParagraphs(rangeToMerge);
}
rangeToMerge = [];
}
}
if (rangeToMerge.length > 1) {
mergeParagraphs(rangeToMerge);
}
}
}
}
var cautionStopStyles = ["WARNING", "NOTE", "Body Header", "Body Copy Bullet", "Safety Header", "Body Header CAPS", "Body Copy"];
applyStyleAndMerge("CAUTION", cautionStopStyles);
var warningStopStyles = ["CAUTION", "NOTE", "Body Header", "Body Copy Bullet", "Safety Header", "Body Header CAPS", "Body Copy"];
applyStyleAndMerge("WARNING", warningStopStyles);
var noteStopStyles = ["CAUTION", "WARNING", "Body Header", "Body Copy Bullet", "Safety Header", "Body Header CAPS", "Body Copy"];
applyStyleAndMerge("NOTE", noteStopStyles);
