Copy link to clipboard
Copied
Hi,
I'm wondering if there's a way (or a script out there) to automate finding the last item of a bulletted list and apply a paragraph style? I'm dealing with multiple, hundred-page documents with tons of bulletted lists, and currently I'm applying a paragraph style to each of these in order to increase the space below the list and the top of the next paragraph.
Suggestions?
It’s not clear to me, if the bullets are formatted at this time or how you indentify them.
But try the following:
...app.findGrepPreferences = app.changeGrepPreferences = null;
app.findGrepPreferences.properties = { bulletsAndNumberingListType: ListType.BULLET_LIST };
var allFounds = app.findGrep();
for ( var i = 0; i < allFounds.length; i++ ) {
var curFound = allFounds;
var allParas = curFound.paragraphs;
var nParas = allParas.length;
allParas[nParas-1].appliedParagraphStyle = "
Copy link to clipboard
Copied
It’s not clear to me, if the bullets are formatted at this time or how you indentify them.
But try the following:
app.findGrepPreferences = app.changeGrepPreferences = null;
app.findGrepPreferences.properties = { bulletsAndNumberingListType: ListType.BULLET_LIST };
var allFounds = app.findGrep();
for ( var i = 0; i < allFounds.length; i++ ) {
var curFound = allFounds;
var allParas = curFound.paragraphs;
var nParas = allParas.length;
allParas[nParas-1].appliedParagraphStyle = "bulletLast";
}
app.findGrepPreferences = app.changeGrepPreferences = null;
–Kai
Copy link to clipboard
Copied
YES! Kai you are awesome, this is perfect and will save so many hours!!
Thank you!!!!
Copy link to clipboard
Copied
Hi Kai,
I do it with a little grep search.
Copy link to clipboard
Copied
Hi Obi-wan, your way with grep ist clever. I did it in the past in a similiar way. The benefit of the script is, that it could also style the other parts of the bulleted list (all bullets, only the first bullet, the first and last bullet) or could be part of a larger script, that do some other styling or clean up.
–Kai
Copy link to clipboard
Copied
To show also a screen: If the body style has no space after, there are sometimes 3 styles for the list needed.
var bulletStyle = "allBullets",
bulletFirst = "firstBullet",
lastBullet = "lastBullet";
app.findGrepPreferences = app.changeGrepPreferences = null;
app.findGrepPreferences.properties = { bulletsAndNumberingListType: ListType.BULLET_LIST };
var allFounds = app.findGrep();
for ( var i = 0; i < allFounds.length; i++ ) {
var curFound = allFounds;
var allParas = curFound.paragraphs;
// whole list
allParas.everyItem().appliedParagraphStyle = "allBullets";
// first bullet
allParas[0].appliedParagraphStyle = "firstBullet";
// last bullet
allParas[allParas.length-1].appliedParagraphStyle = "bulletLast";
}
app.findGrepPreferences = app.changeGrepPreferences = null;
Copy link to clipboard
Copied
Hi Kai,
This last [JS] is perfect and more interesting (does what your first script does!) [works fine with ID CC 2014]. I really like it and I put it in my ID scripts panel.
Many thanks.
A little error on line 17, fixed:
allParas[allParas.length-1].appliedParagraphStyle = "lastBullet";
A good idea to add: an UI that allows the user to choose the three para styles to be treated.
Copy link to clipboard
Copied
Ah, this writing for the styles was not intended, since I saved the names already in the variables at the beginning of the script.
Limitation: This will not work with paragraph styles in groups at the moment and: What if there is no list instead there are typed bullets followed by a tab. So a little GREP-search could be included. Your idea with the UI sounds interesting. Since I have no idea how to do this and since I never built a UI before, this could be my little first one 😉 In the meantime the corrected version.
var bulletStyle = "allBullets",
firstBulletStyle = "firstBullet",
lastBulletStyle = "lastBullet";
app.findGrepPreferences = app.changeGrepPreferences = null;
app.findGrepPreferences.properties = { bulletsAndNumberingListType: ListType.BULLET_LIST };
var allFounds = app.findGrep();
for ( var i = 0; i < allFounds.length; i++ ) {
var curFound = allFounds;
var allParas = curFound.paragraphs;
// whole list
allParas.everyItem().appliedParagraphStyle = bulletStyle;
// first bullet
allParas[0].appliedParagraphStyle = firstBulletStyle;
// last bullet
allParas[allParas.length-1].appliedParagraphStyle = lastBulletStyle;
}
app.findGrepPreferences = app.changeGrepPreferences = null;
Copy link to clipboard
Copied
CC 2018 not working : is it possible update Thanks
Copy link to clipboard
Copied
It really, really, REALLY would be helpful if you tell anything more than "not working".
Copy link to clipboard
Copied
Hi idjev ,
you replied to answer #7 by Kai.
There is nothing in the script's code there that is not compatible with CC 2018.
Maybe you found a new case where the script is not running?
Other limitations than Kai already mentioned there?
And btw.: "Not working" is a statement that is too vague.
Did you get an error message?
Can you post the document so that Kai or someone else can look into it?
( Upload it to Dropbox or a similar service and post a download link here )
Regards,
Uwe
Copy link to clipboard
Copied
Hi Obi-wan,
here it is, with some lines more 😉 Try also the editField: E.g. if you have no list already, you could search for '•\t' or '-\x20{2}' or '-\s+'. Notice, that this will also remove those characters too.
And: If you start the script a second time, your first choice will be overwritten. The script should also work with paragraph styles in groups.
// ApplyStylesToBulletedLists.jsx
// Kai Rübsamen, www.ruebiarts.de
// DESCRIPTION: Search for bullets and apply styles
if ( app.scriptPreferences.version >= 6 ) {
app.doScript( main, ScriptLanguage.JAVASCRIPT , [], UndoModes.ENTIRE_SCRIPT, "Search and style bulleted lists" );
}
else {
main();
}
function main() {
// make certain that user interaction (display of dialogs, etc.) is turned on
app.scriptPreferences.userInteractionLevel = UserInteractionLevels.interactWithAll;
if ( app.documents.length == 0 ) {
alert ( "Open a document!" );
exit();
}
var curDoc = app.activeDocument;
// COLLECT ALL STYLES IN THE DOCUMENT
// ---
// Create a list of names and paragraph styles
var allParaStyleNamesList = [];
var allParaStylesList = [];
// all styles outside of groups
for ( var i = 0; i < curDoc.paragraphStyles.length; i++ ) {
var curParaStyle = curDoc.paragraphStyles;
allParaStyleNamesList.push( curParaStyle.name );
allParaStylesList.push( curParaStyle );
}
// all styles inside of groups
for ( var i = 0; i < curDoc.paragraphStyleGroups.length; i++ ) {
var curStyleGroup = curDoc.paragraphStyleGroups;
for ( var j = 0; j < curStyleGroup.paragraphStyles.length; j++ ) {
allParaStyleNamesList.push( curStyleGroup.paragraphStyles
.name + " ( " + curStyleGroup.name + " )" ); allParaStylesList.push( curStyleGroup.paragraphStyles
); }
}
// the slice() method returns a copy of the array into a new array object
var displayNames = allParaStyleNamesList.slice(2);
// insert a new element at the beginning
displayNames.unshift( "Choose a style" );
// CREATE THE DIALOG
// ---
var dlg = app.dialogs.add({ name: "Style bulleted list" }); // the dialog container
var min_width_left = 110;
var min_width_right = 230;
with ( dlg.dialogColumns.add() ) { // at least one column
with ( dialogRows.add() ) { // row
staticTexts.add({ staticLabel: "Required:" });
}
with ( borderPanels.add() ) { // border
with (dialogColumns.add()) { // column
with ( dialogRows.add() ) { // row
staticTexts.add({ staticLabel: "Main bullet style:" , minWidth: min_width_left });
var mainStyle = dropdowns.add({ stringList: displayNames, selectedIndex: 0 , minWidth: min_width_right });
} // end dialogRows
} // end dialogCols
} // end borderPanels
with ( dialogRows.add() ) { // row
staticTexts.add({ staticLabel: "Optional:" });
}
with ( borderPanels.add() ) { // border
with (dialogColumns.add()) { // column
with ( dialogRows.add() ) { // row
staticTexts.add({ staticLabel: "First bullet style:" , minWidth: min_width_left });
var firstStyle = dropdowns.add({ stringList: displayNames, selectedIndex: 0 , minWidth: min_width_right });
}
with ( dialogRows.add() ) { // row
staticTexts.add({ staticLabel: "Last bullet style:" , minWidth: min_width_left });
var lastStyle = dropdowns.add({ stringList: displayNames, selectedIndex: 0 , minWidth: min_width_right });
} // end dialogRows
} // end dialogCols
} // end borderPanels
with ( dialogRows.add() ) {
staticTexts.add({ staticLabel: "I have no list so far and want to remove some garbage too!" });
}
with ( borderPanels.add() ) { // border
with ( dialogColumns.add() ) { // column
with (dialogRows.add() ) { // row
staticTexts.add({ staticLabel: "Search for:", minWidth: min_width_left });
var text_edit_box = textEditboxes.add({ minWidth: min_width_right });
} // end dialogRows
} // end dialogCols
} // end borderPanels
} // end dialogCols
// show the dialog and save users choice
if( dlg.show() ){
var mainParaIndex = mainStyle.selectedIndex;
var firstParaIndex = firstStyle.selectedIndex;
var lastParaIndex = lastStyle.selectedIndex;
var dlgStr = text_edit_box.editContents;
dlg.destroy();
}
else {
dlg.destroy();
exit();
}
// test the choice for the main style
if ( mainParaIndex != 0 ) {
var mainBulletStyle = allParaStylesList[mainParaIndex+1];
}
else {
alert ( "Choose at least the main style for all bullets!" );
exit();
}
// SEARCH AND STYLE THE BULLETS
// ---
app.findGrepPreferences = app.changeGrepPreferences = null;
if ( dlgStr != "" ) {
app.findGrepPreferences.findWhat = dlgStr + "(.)";
app.changeGrepPreferences.changeTo = "$1";
app.changeGrepPreferences.properties = { bulletsAndNumberingListType: ListType.BULLET_LIST };
app.changeGrep();
}
app.findGrepPreferences = app.changeGrepPreferences = null;
app.findGrepPreferences.properties = { bulletsAndNumberingListType: ListType.BULLET_LIST };
var allFounds = app.findGrep();
for ( var i = 0; i < allFounds.length; i++ ) {
var curFound = allFounds;
var allParas = curFound.paragraphs;
allParas.everyItem().appliedParagraphStyle = mainBulletStyle; // whole list
if ( firstParaIndex != 0 ) {
allParas[0].appliedParagraphStyle = allParaStylesList[firstParaIndex+1]; // first bullet
}
if ( lastParaIndex != 0 ) {
allParas[allParas.length-1].appliedParagraphStyle = allParaStylesList[lastParaIndex+1]; // last bullet
}
}
app.findGrepPreferences = app.changeGrepPreferences = null;
} // end main
Copy link to clipboard
Copied
Hi Kai,
I'll test it with pleasure. I'll let you know. Thanks!
Copy link to clipboard
Copied
Hi Kai,
Doing this with paras styles without auto-numbering could be a fine way!
Copy link to clipboard
Copied
I have no idea what that means? Everything is o.k.? Everything is o.k., but in the case of … ? It would be additional nice … ?
Copy link to clipboard
Copied
Kai,
What I mean is that the script is too limited.
The idea would be to treat any group of paragraphs predefined by "Style 0" style as follows: Style 1 for the first para, Style 2 for the following paras, Style 3 for the last para.
In my sample, the script does not work and stop on the code line 142.
Copy link to clipboard
Copied
Sorry to hear, that you got an error. I have no problems here. If you provide a sample-doc I will try to fix this.
The original intention of the script was not to find paragraphs with predefined styles and that’s also not, was the actual script does!
The script will search either for bulleted lists or for normal paragraphs that look like bulleted lists. In the last case, you must insert some grep code. Since we tested it here with two guys, I would think, it does what it should do.
Copy link to clipboard
Copied
Kai,
Don't be sorry! The script works very fine in the way you've written it.
It doesn't work in another case where I find interesting to make it work. That's what I show in my sample:
I have a group of paras styled with "Style 0" and I want to apply: Style 1 to the first para, Style 2 to the following and Style 3 to the last.
Here, I don't use (auto-numbering or manual) bullets.
So, I think "bullets" should not be an essential criterion for research.
For me, the good way is:
Search a paras group (in sequence) with the same style (no manual bullet used but possibly auto-numbering)
or
Search a paras group (in sequence) with the same manual bullet
or
Search a paras group (in sequence) with the same style and the same manual bullet.
Copy link to clipboard
Copied
My problem is, that I don’t know at the moment how single paragraphs with manual bullets can be treated at one list. This is easier, if there is already a list. You can check this, if you search for style 0 (all paragraphs are highlighted) or if you search with e.g. '•\t.+\r' (only one paragraph is highlighted).
edit: Ah, maybe '(•\t.+\r)+' this will work 😉
In the meantime. Something like that for your first need?
// Enter your style names
//
var paraStyle_0 = "style 0",
paraStyle_1 = "style 1",
paraStyle_2 = "style 2";
paraStyle_3 = "style 3";
app.findGrepPreferences = app.changeGrepPreferences = null;
app.findGrepPreferences.properties = { appliedParagraphStyle: paraStyle_0 };
var allFounds = app.findGrep();
for ( var i = 0; i < allFounds.length; i++ ) {
var curFound = allFounds;
var allParas = curFound.paragraphs;
// whole list
allParas.everyItem().appliedParagraphStyle = paraStyle_2;
// first bullet
allParas[0].appliedParagraphStyle = paraStyle_1;
// last bullet
allParas[allParas.length-1].appliedParagraphStyle = paraStyle_3;
}
app.findGrepPreferences = app.changeGrepPreferences = null;
Copy link to clipboard
Copied
Kai,
I've tested it. Cool!
If you include the UI and the Grep research, your script will be PERFECT !!
Copy link to clipboard
Copied
What could be a reason fo this one? "Search a paras group (in sequence) with the same style and the same manual bullet."
I would say, the script should cover 3 topics:
1. Search a paras group (in sequence) with the same style (no manual bullet used but possibly auto-numbering)
2. Search a paras group (in sequence) with the same manual bullet
3. Search a paras group (in sequence) that has already a local real bulleted list applied
I will try to figure that out, but give me some time
Copy link to clipboard
Copied
What I mean by:
Search a paras group (in sequence) with the same style and the same manual bullet
When we import a Word file, we can have several paras groups with the same bullet BUT, in the ID Layout, we can choose to use several different "Style 0" [Style 0a, Style 0b …] to format these paras, like in this sample:
Before script:
After script:
A good idea to be included too:
You search a para style "Style 0" with manual bullet and you apply the 3 para styles deleting the manual bullet replacing it by a object placed in a library. As:
In fact, when I imagine a script, I try to include in it things I can do with it. That always makes it more complex, but as I have ideas, I'm not satisfied!
That said, nothing forces you to continue! I have other extensions in mind such as nesting multiple levels of styles!
Copy link to clipboard
Copied
Hi,
I am not interested to script elements from a library at the moment, but I’m interested in playing with dialogs. Here is the next and maybe last version:
// ApplyStylesToLists.jsx
// Kai Rübsamen, www.ruebiarts.de
// Vers. 1.1
// DESCRIPTION: Search for lists and apply styles
if ( app.scriptPreferences.version >= 6 ) {
app.doScript( main, ScriptLanguage.JAVASCRIPT , [], UndoModes.ENTIRE_SCRIPT, "Search and style lists" );
}
else {
main();
}
function main() {
// make certain that user interaction (display of dialogs, etc.) is turned on
app.scriptPreferences.userInteractionLevel = UserInteractionLevels.interactWithAll;
if ( app.documents.length == 0 ) {
alert ( "Open a document!" );
exit();
}
var curDoc = app.activeDocument;
// COLLECT ALL STYLES IN THE DOCUMENT
// ---
// Create a list of names and paragraph styles
var allParaStyleNamesList = [];
var allParaStylesList = [];
// all styles outside of groups
for ( var i = 0; i < curDoc.paragraphStyles.length; i++ ) {
var curParaStyle = curDoc.paragraphStyles;
allParaStyleNamesList.push( curParaStyle.name );
allParaStylesList.push( curParaStyle );
}
// all styles inside of groups
for ( var i = 0; i < curDoc.paragraphStyleGroups.length; i++ ) {
var curStyleGroup = curDoc.paragraphStyleGroups;
for ( var j = 0; j < curStyleGroup.paragraphStyles.length; j++ ) {
allParaStyleNamesList.push( curStyleGroup.paragraphStyles
.name + " ( " + curStyleGroup.name + " )" ); allParaStylesList.push( curStyleGroup.paragraphStyles
); }
}
// the slice() method returns a copy of the array into a new array object
var displayNames = allParaStyleNamesList.slice(1);
// insert a new element at the beginning
displayNames.unshift( "Choose a style" );
// CREATE THE DIALOG
// ---
var dlg = app.dialogs.add({ name: "Style lists" }); // the dialog container
var min_width_left = 140;
var min_width_right = 210;
with ( dlg.dialogColumns.add() ) { // at least one column
with ( dialogRows.add() ) { // row
staticTexts.add({ staticLabel: "Find what:" });
}
with ( borderPanels.add() ) { // border
with (dialogColumns.add()) { // column
with ( dialogRows.add() ) { // row
staticTexts.add({ staticLabel: "Paragraph style:" , minWidth: min_width_left });
var search_style = dropdowns.add({ stringList: displayNames, selectedIndex: 0 , minWidth: min_width_right });
} // end dialogRows
with ( dialogRows.add() ) { // row
staticTexts.add( {staticLabel: "Real list:", minWidth: min_width_left} );
var cb_realList = checkboxControls.add({staticLabel: "", checkedState: false, minWidth: min_width_right});
} // end dialogRows
with (dialogRows.add() ) { // row
staticTexts.add({ staticLabel: "Manual bullets:", minWidth: min_width_left });
var text_edit_box = textEditboxes.add({ minWidth: min_width_right -120});
staticTexts.add( {staticLabel: "( E.g.: -\\s+ or •\\t )"} );
} // end dialogRows
} // end dialogCols
} // end borderPanels
with ( borderPanels.add() ) { // border
with (dialogColumns.add()) { // column
} // end dialogCols
} // end borderPanels
with ( dialogRows.add() ) { // row
staticTexts.add({ staticLabel: "Change to:" });
}
with ( borderPanels.add() ) { // border
with (dialogColumns.add()) { // column
with ( dialogRows.add() ) { // row
staticTexts.add({ staticLabel: "Main paragraph style:" , minWidth: min_width_left });
var main_style = dropdowns.add({ stringList: displayNames, selectedIndex: 0 , minWidth: min_width_right });
} // end dialogRows
with ( dialogRows.add() ) { // row
staticTexts.add({ staticLabel: "First paragraph style:" , minWidth: min_width_left });
var first_style = dropdowns.add({ stringList: displayNames, selectedIndex: 0 , minWidth: min_width_right });
}
with ( dialogRows.add() ) { // row
staticTexts.add({ staticLabel: "Last paragraph style:" , minWidth: min_width_left });
var last_style = dropdowns.add({ stringList: displayNames, selectedIndex: 0 , minWidth: min_width_right });
} // end dialogRows
with ( dialogRows.add() ) { // row
staticTexts.add( {staticLabel: "Remove bullets:", minWidth: min_width_left} );
var cb_removeBullets = checkboxControls.add({staticLabel: "", checkedState: false, minWidth: min_width_right});
} // end dialogRows
} // end dialogCols
} // end borderPanels
} // end dialogCols
// show the dialog and save users choice
if( dlg.show() ){
var searchParaIndex = search_style.selectedIndex;
var mainParaIndex = main_style.selectedIndex;
var firstParaIndex = first_style.selectedIndex;
var lastParaIndex = last_style.selectedIndex;
var dlgStr = text_edit_box.editContents;
var cbList = cb_realList.checkedState;
var cbRemove = cb_removeBullets.checkedState;
dlg.destroy();
}
else {
dlg.destroy();
exit();
}
// SEARCH AND STYLE THE PARAGRAPHS
// ---
// test the choice for find what
if ( searchParaIndex == 0 && cbList == false && dlgStr == "" ) {
alert("You must enter something!");
exit();
}
app.findGrepPreferences = app.changeGrepPreferences = null;
if ( searchParaIndex != 0 && cbList == false && dlgStr == "" ) { // style, no list
var searchStyle = allParaStylesList[searchParaIndex];
app.findGrepPreferences.properties = { appliedParagraphStyle: searchStyle };
}
else if ( searchParaIndex != 0 && cbList == true ) { // style and list
var searchStyle = allParaStylesList[searchParaIndex];
app.findGrepPreferences.properties = { appliedParagraphStyle: searchStyle, bulletsAndNumberingListType: ListType.BULLET_LIST };
}
else if ( searchParaIndex == 0 && cbList == true && dlgStr == "" ) { // only list
app.findGrepPreferences.properties = { bulletsAndNumberingListType: ListType.BULLET_LIST };
}
else if ( searchParaIndex != 0 && dlgStr != "" && cbList == false ) { // style and grep
var complGREP = "(" + dlgStr + "(.|\\n)+\\r)+";
alert ( complGREP );
app.findGrepPreferences.findWhat = complGREP ;
var searchStyle = allParaStylesList[searchParaIndex];
app.findGrepPreferences.properties = { appliedParagraphStyle: searchStyle };
}
else if ( dlgStr != "" && cbList == false ) { // only grep
var complGREP = "(" + dlgStr + "(.|\\n)+\\r)+";
alert ( "Notice:\r Your grep will be expanded to find the whole list\r" + complGREP );
app.findGrepPreferences.findWhat = complGREP ;
}
else if ( dlgStr != "" && cbList == true ) { // warning list or grep, not both
alert ( "Stop!\rYou can only search for manual bullets\rOR automatic lists, not both at the same time!" );
exit();
}
var allFounds = app.findGrep(true); // it’s important to search backwards if later manual bullets should be deleted !
// test the choice for change to
if ( mainParaIndex != 0 ) {
var mainStyle = allParaStylesList[mainParaIndex];
}
else {
alert ( "Choose at least the main style for all paragraphs!" );
exit();
}
for ( var i = 0; i < allFounds.length; i++ ) {
var curFound = allFounds;
var allParas = curFound.paragraphs;
allParas.everyItem().appliedParagraphStyle = mainStyle; // whole paragraphs
if ( firstParaIndex != 0 ) {
allParas[0].appliedParagraphStyle = allParaStylesList[firstParaIndex]; // first paragraph
}
if ( lastParaIndex != 0 ) {
allParas[allParas.length-1].appliedParagraphStyle = allParaStylesList[lastParaIndex]; // last paragraph
}
if ( dlgStr != "" && cbRemove == true ) {
app.findGrepPreferences.findWhat = dlgStr;
curFound.changeGrep();
}
}
app.findGrepPreferences = app.changeGrepPreferences = null;
} // end main
Copy link to clipboard
Copied
Kai,
I like it! Very clever! I appreciate the "undo".
Comment 1: Useful! As I insert in my own [JS], the choice on:
– the entire book
– all the document
– selected text
– the current story
– until the end on the story
– until the end on the document
– excluding locked layers
…
Comment 2: When we launch the script again, have the last settings definied.
Comment 3: The possibility to save settings, restore those who we want to use or reset the settings by default.
Copy link to clipboard
Copied
I thought about the scope before I posted the lines. Maybe I try it next week and put the new version on my website. If so, I will let you know.
To save or reset settings seems difficult or I have no idea how to do this.
– Kai