Add script to context menu on paragraph or character styles panel?
Copy link to clipboard
Copied
Does anybody know, if there is a chance, to add a script to the context menu, when selecting a paragraph or character style with the right button of the mouse? And then work with the selected style inside the script?
Thanks
Tobias
Copy link to clipboard
Copied
Hi
app.menus.everyItem().name.join('\n').match(/[^\n]+Context Menu/g).join('\n')
Will give you a list of the context menus which I thing is what you are after.
app.menus.itemByName('Text Style List Context Menu').menuItems.everyItem().name.join('\n')
Gives
Edit "Paragraph Style 1"...
Duplicate Style...
Delete Style
Redefine Style
Apply "Paragraph Style 1"
Apply "Paragraph Style 2", Clear Overrides
Apply "^1", Clear Character Styles
Apply "^1", Clear All
Apply "^1" then Next Style
Apply "^1" then Next Style, Clear Overrides
Apply "^1" then Next Style, Clear Character Styles
Apply "^1" then Next Style, Clear All
Convert "Paragraph Style 1" Bullets and Numbering to Text
New Paragraph Style...
Style Group Options...
Duplicate Group
Delete Group...
Copy to Group...
New Group from Styles...
This is obviously dynamically generated and further filtered so you probably would have I tough time messing around with it.
In German etc. you will need to do a bit of translating.
Have fun.
Trevor
P.s. I'm not sure that this is the correct menu but it's a possible starting point
Copy link to clipboard
Copied
Wow – thanks, Trevor! This is a very good starting point ...
Thanks
Tobias
Copy link to clipboard
Copied
Peter Kahrel has some really good information on his site about this, and the links in the article are quite helpful as well:
Show InDesign's menu actions | Peter Kahrel
Perhaps have a look at some startup scripts in the public domain, like the addpathoperationstolayoutmenu by Ole Kvern: InDesign Scripting: Baby Steps (it's at the end of his article which is also a great read too).
Copy link to clipboard
Copied
Trevor×… wrote:
…
app.menus.itemByName('Text Style List Context Menu')
…
P.s. I'm not sure that this is the correct menu but it's a possible starting point
Hi Trevor,
this one is the right one.
It's un-localized menu name is "$ID/RtMenuStyleListItem".
@Tobias,
you could add an event listener to that menu looking for: "beforeDisplay".
Just tested that. And if needed also event listeners to the associatedMenuActions of every menuItem looking for "beforeInvoke" or "afterInvoke".
Regards,
Uwe
Copy link to clipboard
Copied
Hi Tobias,
I'm not sure what exact context menu you are looking for.
Is it this one:
Or is it that one:
Or something else entirely?
To get the selected paragraph style in the Paragraph Style panel when no text is selected by the user, just add a new text frame to the document and see what paragraph style is applied to the first insertion point of its parent story.
Regards,
Uwe
Copy link to clipboard
Copied
Hej Uwe,
It's the latter one: $ID/ParaStyleControlPanelPopup
I had in mind to get the paragraph style, which I right click on. That's not necessarily the one, which is selected:
Hm. I now think this can't be done with scripting ...
Thanks
Tobias
Copy link to clipboard
Copied
Ah yes, I see now what you are looking for. If the menu is really "$ID/ParaStyleControlPanelPopup" you can get access to all the menuElements of the popup and retrieve the name of the paragraph style. But I'm in doubt if "$ID/ParaStyleControlPanelPopup" is the right one.
If I run the script below in a situation I am showing here:
I do not get "[Einf. Abs.]" bearbeiten… and so on. So I think, we still have to search for the right menu.
See result below:
var menuName = "$ID/ParaStyleControlPanelPopup";
var menuElements = app.menus.itemByName(menuName).menuElements.everyItem().getElements();
for( var n=0; n<menuElements.length; n++ )
{
if(menuElements[n].constructor.name == "MenuSeparator"){ continue };
$.writeln( n+"\t"+menuElements[n].title );
};
/*
0 Neues Absatzformat...
1 Format duplizieren...
2 Format löschen...
4 Format neu definieren
6 Formatoptionen...
8 Abweichungen löschen
9 Aufzählungszeichen und Nummerierung von "[Einf. Abs.]" in Text konvertieren
10 Verknüpfung mit Format aufheben
12 Absatzformate laden...
13 Alle Textformate laden...
*/
Regards,
Uwe
REPLY EDITED: Had to edit this post because the script code was not transferred to the new forum without errors.
Copy link to clipboard
Copied
Just checked a few things.
I think, you are after menu: "$ID/RtMenuStyleListItem". At least it's closer to what you want:
Note: This is not exactly the context menu you are looking for, but it is showing one or more of the right menu elements you are looking for. Then there you have the chance to retrieve the paragraph style name that is associated with the context menu.
The problem with "$ID/RtMenuStyleListItem":
You cannot tell if the user opened the context menu for a style group.
If that is the case menu "$ID/RtMenuStyleListItem" is still showing menu elements for the last paragraph style in the style's list where the context menu was invoked for.
The other problem:
What will you do if two or more styles share the same name?
That's possible if they are stored in different style groups.
Some code you could run from the ESTK if you are using the context menu with different paragraph styles in the Paragraph Styles panel:
var menuElements = app.menus.itemByName("$ID/RtMenuStyleListItem").menuElements.everyItem().getElements();
for( var n=0; n<menuElements.length; n++ )
{
if( menuElements[n].constructor.name == "MenuSeparator"){ continue };
$.writeln( n +"\t"+ menuElements[n].title );
};
Here my invoked context menu:
Here the result from the JavaScript Console when running the script above:
/*
0 "Absatzformat 2" bearbeiten...
1 Format duplizieren...
2 Format löschen
3 Format neu definieren
5 "Absatzformat 2" anwenden
6 "^1" anwenden, Abweichungen löschen
7 "^1" anwenden, Zeichenformate löschen
8 "^1" anwenden, Alle löschen
10 "^1" und dann Nächstes Format anwenden
11 "^1" und dann Nächstes Format anwenden, Abweichungen löschen
12 "^1" und dann Nächstes Format anwenden, Zeichenformate löschen
13 "^1" und dann Nächstes Format anwenden, Alle löschen
15 Aufzählungszeichen und Nummerierung von "Absatzformat 2" in Text konvertieren
16 Neues Absatzformat...
18 Formatgruppenoptionen...
19 Formatgruppe duplizieren
20 Formatgruppe löschen
22 In Gruppe kopieren...
23 Neue Gruppe aus Formaten...
*/
Hm… Still hope you'll find the right context menu where in a situation like this is showing the right menu elements:
Regards,
Uwe
REPLY EDITED: Had to edit this post because the script code was not transferred to the new forum without errors.
Copy link to clipboard
Copied
Uwe, thanks for your investigation. $ID/RtMenuStyleListItem seems to me the right menuElement. It's »Textformatliste-Kontextmenü« in German – Jesus!
I think, that your script snippet shows all possible options for this context menu. The UI hides all options, which are not applicable in the given context.
It's fascinating, that Adobe seems to use the same thing for both paragraph styles and character styles! A right click on a style group has no effect on the returned value.
That's a brilliant starting point for me! I'll test a bit and try to implement some function that does some simple name-changing to get into it.
Many thanks!
Tobias
Copy link to clipboard
Copied
tobias.wantzen wrote
… I think, that your script snippet shows all possible options for this context menu. The UI hides all options, which are not applicable in the given context.…
A brave hypothesis, Tobias!
I would check again all menu titles with app.findKeyString( menu.title ) if there are other candidates where a substring like "$ID/RtMenu" or even "$ID/Rt" is used.
Regards,
Uwe
Copy link to clipboard
Copied
Of course, I hope you are right with that:
tobias.wantzen wrote
… The UI hides all options, which are not applicable in the given context. …
Best,
Uwe
Copy link to clipboard
Copied
Uwe, I know, this thread is quite old, but I still haven’t found a better solution to this. I just want to document my findings on this topic – maybe they are of some help for others, maybe someone get’s the clou and has a better solution for this.
`$ID/RtMenuStyleListItem` is in my eyes the only valid menu item, which reflects the context menu, if I right-click on a paragraph style or character style. It seems, that this menu item is for both: paragraph and character styles.
The first sub-item in this menu holds the name of the last selected paragraph or character style.
$.writeln( app.menus.itemByName('$ID/RtMenuStyleListItem').menuItems.firstItem().name );
But sadly I couldn’t get the style object id (or something similar), but it’s only the style name embedded in »"paragraphStyleName" bearbeiten...« (as it is given back in the German localization).
So if this style name is unique, I could search for it in `app.activeDocument.allParagraphStyles` and get the desired paragraph style object. If there are many styles with the same name in different style groups, I couldn’t find out, which one is selected, because I get no information, in which style group the selected style is in. So I have to present the user a list of possible choices.
It’s a bit around the corner, but seems to work. Here is a (quick and maybe a bit dirty) proof of concept—still lacking the handling of multiple styles with the same name:
#targetengine "session"
app.scriptPreferences.userInteractionLevel = UserInteractionLevels.INTERACT_WITH_ALL;
main();
function main(){
var theRtMenuStyleListItem = app.menus.item("$ID/RtMenuStyleListItem"),
theMenuName = "UPGRADE FONT SIZE";
// Remove any previous versions of the menu item and actions.
if( theRtMenuStyleListItem.menuItems.itemByName( theMenuName ).isValid ) { theRtMenuStyleListItem.menuItems.itemByName( theMenuName ).remove(); }
if( app.scriptMenuActions.itemByName( theMenuName ).isValid ) { app.scriptMenuActions.itemByName( theMenuName ).remove(); }
// Create the menu action, menu item, and event listener.
var theScriptMenuAction = app.scriptMenuActions.add( theMenuName );
var theScriptMenuItem = theRtMenuStyleListItem.menuItems.add( theScriptMenuAction, LocationOptions.AFTER, theRtMenuStyleListItem.menuItems.item(-1) );
var theScriptEventListener = theScriptMenuAction.eventListeners.add( "onInvoke", theScriptHandler );
}
function theScriptHandler () {
// Collect paragraph style name from context menu
var selectedStyle = app.menus.itemByName('$ID/RtMenuStyleListItem').menuItems.firstItem().name.replace(/"([^"]+)".+/g, "$1");
// Search for corresponding style name in allParagraphStyles
var allStyles = app.activeDocument.allParagraphStyles;
var foundStyles = [];
for ( var i = 0; i < allStyles.length; i++ ) {
if ( allStyles[i].name == selectedStyle ) {
foundStyles.push( allStyles[i] );
}
}
// Handle and process found styles
if ( foundStyles.length == 1 ) {
processStyle( foundStyles[0] );
} else if ( foundStyles.length > 1 ) {
// further handling: user selection of the right style
}
function processStyle ( theStyle ) {
theStyle.pointSize += 20;
}
}
Please let me know, if you can think of a better solution for this!
Best regards,
Tobias
Copy link to clipboard
Copied
Hi Tobias,
that may help you:
If just one sigle paragraph style is selected in the Paragraph Styles Panel adding a temp text frame to the document with some contents will reveal what exactly is selected. The same goes for a selected character style.
But this is not as much unique as you might think.
If a paragraph style group is selected the temp frame's text will reflect the last selected style.
The same goes with the situation where the user did not select a style or a style group.
Regards,
Uwe Laubender
( ACP )
Copy link to clipboard
Copied
Hi Tobias,
after some more tests I find that the context menu "$ID/RtMenuStyleListItem" ("Textformatliste-Kontextmenü") is not updated as often as it should be. Rerunning the same code several times when different documents were active did not update the results when I tried to read out the different menuItems and their names or titles.
Hope, that "$ID/ParaStyleControlPanelPopup" ("Absatzformat-Steuerungsbedienfeldmenü") is more reliable.
Maybe we have the chance to detect with menuItems named "$ID/Duplicate Style..." and "$ID/Duplicate Styles" if only one style is selected, if two or more styles are selected or if actually no style is selected.
One could exploit properties isValid and enabled of both menuItems.
Regards,
Uwe Laubender
( ACP )
Copy link to clipboard
Copied
Thanks Uwe for your suggestions!
The deeper we get into this, the more it comes out, that there is no satisfiable solution for my use case via scripting. I think, I have to quit this try.
Thanks, Tobias
Copy link to clipboard
Copied
Hi Tobias,
right! Did further tests and came to the conclusion that often the update of the menu items is OK and right in time.
But sometimes the update is only done when I open the context menu. Unfortunately this cannot be simulated or done by DOM scripting. So in the end I think you have to drop the idea altogether.
FWIW: Something similar was discussed over at hilfdirselbst.ch:
In Absatzformatpalette ausgewählte Absatzformate ermitteln
Martin Fischer, 13. Dez 2019
https://www.hilfdirselbst.ch/gforum/gforum.cgi?post=573264#573264
I came to the same conclusion there:
There is no reliable way to read out actual data from the context menu of the Paragraph Panel.
Regards,
Uwe Laubender
( ACP )

