Copy link to clipboard
Copied
Hi All Scripting Gurus!
I am doing a telephone/business directory. The data is imported from an Excel spreadsheet. Some businesses/organizations have multiple entries. I would like to be able to group them under a common heading. Please see attached files. A semi-automatic script, say, highlight a selection manually, then execute the script working only on this selection, would do the trick. A fully automatic one processing the whole document would be fantastic!
Thank you!
More compact! …
// by FRIdNGE, Michel Allio [24/03/2023]
// Place The Cursor in The Text To Be Treated!
var myToc = app.selection[0].parentStory;
var NoIndent = 0, Indent = 10;
// 1
app.findGrepPreferences = app.changeGrepPreferences = null;
app.findGrepPreferences.findWhat = "(~\\r\\K.)|(~\\h)";
app.changeGrepPreferences.leftIndent = Indent;
myToc.changeGrep();
// 2A
app.findGrepPreferences.findWhat = "(^.+~\\r).+\\r\\K(?=\\1)";
myFound = myToc.findGrep();
for ( var f = myFound.length-1; f >=
...
Copy link to clipboard
Copied
Hi @nickg86903597, could you please post a sample .indd file with a page or two so we can see actual details, like line break chars etc? It shouldn't be hard to script this.
- Mark
Copy link to clipboard
Copied
I would work with a second level headline. Normally I have additional columns in Excel to sort, order and put to level all entries. They can be deleted or otherwise become invisible at the end, but during formatting they are very helpful and fastforward.
Copy link to clipboard
Copied
Why can't you do it in the Excel first?
Copy link to clipboard
Copied
Just wanted to endorse what both @Willi Adelberger and @Robert at ID-Tasker are saying: it's better to organise your *data* (in Excel) that to organise your presentation (in Indesign). That way if you (or client) makes changes to the data, you won't have to do this again each time. A database would be even better, because you can have a "company" entity with multiple addresses/phone numbers.
That said, I am assuming at this point that making the adjustments in Indesign is makes sense, in your particular case.
- Mark
Copy link to clipboard
Copied
Hi @nickg86903597, this probably won't work straight away, because I don't know all the parameters around what characters your text is using, but here is a starting point. See script below.
I have made a couple of assumptions:
1. That single entity, non-duplicated entries use linefeeds, not carriage returns (see ATM Batteries & Tyres).
2. That you will use a paragraph style that indents subsequent lines.
I've set up a paragraph style here that shows the entity name in bold.:
/**
* Clean up Duplicated Company Details
* @author m1b
* @version 2023-03-23
* @discussion https://community.adobe.com/t5/indesign-discussions/script-for-grouping-paragraphs-under-common-heading/m-p/13669481
*/
function main() {
// this regex parses the first line,
// eg. 'Company Name ~ 123 Sample Street'
// into array with company name as element 1
// and address/phone details as element 2.
var lineParser = /^([^~]+)\s?~\s*\n?(.+)/,
doc = app.activeDocument,
cleaner = /(^\s+|[\s\n]+$)/g,
text = doc.selection[0];
if (
text == undefined
|| !text.hasOwnProperty('paragraphs')
|| text.paragraphs.length < 2
) {
alert('Please select multiple paragraphs and try again.');
return;
}
var paras = text.paragraphs,
currentPara,
currentMatch,
// the company/person name
contentsName,
// the address/phone details
contentsDetails;
for (var i = paras.length - 1; i > 0; i--) {
currentPara = paras[i];
currentMatch = currentPara.contents.match(lineParser);
if (currentMatch == null)
continue;
if (currentMatch.length >= 1) {
contentsName = currentMatch[1].replace(cleaner, '');
if (currentMatch.length >= 2)
contentsDetails = currentMatch[2].replace(cleaner, '');
else
contentsDetails = '';
}
var p, matchCount = 0;
matchPreviousLines:
while (p = paras[i - 1].contents.match(lineParser)) {
var matchedContents = p[1].replace(cleaner, '');
if (matchedContents == contentsName) {
// matched
contentsDetails = p[2].replace(cleaner, '') + '\u000A' + contentsDetails;
i--;
matchCount++;
continue matchPreviousLines;
}
else {
// no match
break matchPreviousLines;
}
}
if (matchCount > 1) {
// combine the paragraphs
currentPara.contents = contentsName + ' ~\u000A' + contentsDetails + '\u000D';
while (matchCount--)
paras[i + matchCount].remove();
}
}
}
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Clean up Duplicated Company Details');
Copy link to clipboard
Copied
Simplistically, a funny game for Grep! …
Before/After:
// by FRIdNGE, Michel Allio [24/03/2023]
// Place The Cursor in The Text To Be Treated!
var myToc = app.selection[0].parentStory;
var NoIndent = 0, Indent = 10;
// 1a
app.findGrepPreferences = app.changeGrepPreferences = null;
app.findGrepPreferences.findWhat = "~\\r\\K.";
app.changeGrepPreferences.leftIndent = Indent;
myToc.changeGrep();
// 1b
app.findGrepPreferences.findWhat = "(^.+~\\r).+\\r\\K(?=\\1)";
myFound = myToc.findGrep();
for ( var f = myFound.length-1; f >= 0; f-- ) myFound[f].paragraphs[0].remove();
// 2a
app.findGrepPreferences.findWhat = "~\\h";
app.changeGrepPreferences.leftIndent = Indent;
myToc.changeGrep();
// 2b
app.findGrepPreferences.findWhat = "(^.+~\\h).+\\r\\K(?=\\1)";
myFound = myToc.findGrep();
app.findGrepPreferences = app.changeGrepPreferences = null;
for ( var f = myFound.length-1; f >= 0; f-- ) {
app.findGrepPreferences.findWhat = "^.+~\\h";
app.changeGrepPreferences.changeTo = "";
myFound[f].paragraphs[0].changeGrep();
}
// 2c
app.findGrepPreferences.findWhat = "~\\K\\h";
app.changeGrepPreferences.changeTo = "\r";
myToc.changeGrep();
// 2d
app.findGrepPreferences.findWhat = "(.)\\h~$";
app.changeGrepPreferences.changeTo = "$1";
app.changeGrepPreferences.leftIndent = NoIndent;
myToc.changeGrep();
app.findGrepPreferences = app.changeGrepPreferences = null;
alert("Youpi! …")
(^/) The Jedi
Copy link to clipboard
Copied
More compact! …
// by FRIdNGE, Michel Allio [24/03/2023]
// Place The Cursor in The Text To Be Treated!
var myToc = app.selection[0].parentStory;
var NoIndent = 0, Indent = 10;
// 1
app.findGrepPreferences = app.changeGrepPreferences = null;
app.findGrepPreferences.findWhat = "(~\\r\\K.)|(~\\h)";
app.changeGrepPreferences.leftIndent = Indent;
myToc.changeGrep();
// 2A
app.findGrepPreferences.findWhat = "(^.+~\\r).+\\r\\K(?=\\1)";
myFound = myToc.findGrep();
for ( var f = myFound.length-1; f >= 0; f-- ) myFound[f].paragraphs[0].remove();
// 2B
app.findGrepPreferences.findWhat = "(^.+~\\h).+\\r\\K(?=\\1)";
myFound = myToc.findGrep();
app.findGrepPreferences = app.changeGrepPreferences = null;
for ( var f = myFound.length-1; f >= 0; f-- ) {
app.findGrepPreferences.findWhat = "^.+~\\h";
app.changeGrepPreferences.changeTo = "";
myFound[f].paragraphs[0].changeGrep();
}
app.findGrepPreferences.findWhat = "~\\K\\h";
app.changeGrepPreferences.changeTo = "\r";
myToc.changeGrep();
app.findGrepPreferences.findWhat = "(.)\\h~$";
app.changeGrepPreferences.changeTo = "$1";
app.changeGrepPreferences.leftIndent = NoIndent;
myToc.changeGrep();
app.findGrepPreferences = app.changeGrepPreferences = null;
alert("Youpi! …")
(^/)