Item ::= ReLabel | Menu ReLabel ::= 'ReLabel' '[' SpecificMenu Old New ']' | 'ReLabel' '[' Old New ']' SpecificMenu ::= Identifier Old ::= Identifier New ::= Identifier Menu ::= '[' MenuName MenuParms* Entry* ']' MenuName ::= Identifier MenuParms ::= 'breakBefore' ':' Bool | 'breakAfter' ':' Bool | 'beginsActive' ':' Bool | 'notifyProc' ':' Proc Entry ::= '[' EntryName EntryParms* '=>' WhatToDoWhenHit ']' EntryName ::= Identifier EntryParms ::= 'guarded' ':' Bool | 'display' ':' StringOrProc WhatToDoWhenHit ::= NotifyProcData | TriggerAndResults* TriggerAndResults ::= '[' ( SimpleTrigger | TriggerList ) TriggerParms* '=>' NotifyProcData ']' TriggerList ::= '[' SimpleTrigger* ']' SimpleTrigger ::= 'notrigger' | 'all' | 'leftup' | 'middleup' | 'rightup' | 'shiftleftup' | 'shiftmiddleup' | 'shiftrightup' | 'allnonshifts' | 'allshifts' | 'allleft' | 'allmiddle' | 'allright' TriggerParms :== 'popUpDoc' ':' String | 'guardResponse' ':' StringOrProc | 'makeActive' ':' String | 'makeInActive' ':' String | 'toggle' ':' String Identifier ::= whatever CedarScanner thinks is an Identifier NotifyProcData ::= ListOfRefAny -- this stuff gets passed to your notify proc Proc ::= '{' ModuleName '.' ProcedureName ListOfRefAny '}' StringOrProc ::= String | Proc ModuleName ::= String ProcedureName ::= String String ::= a quoted String that CedarScanner gets for me Bool ::= 'true' | 'false' ListOfRefAny ::= list of things until I hit a ']' or '}' Examples: The following description is for a simple menu with four entries, each of which sends a single atom when the button is pressed: [HouseCleaningMenu [Dust => $Dust] [Sweep => $UseBroom] [Vacuum => $Vacuum] [Mop => $MopFloors] ] The next example provides the same functionality, but with only two menu entries. It does this by "overloading" the second entry. This means the entry will cause different things to happen depending on whether it is invoked with the left, middle, or right mouse button. [HouseCleaningMenu [Dust => $Dust] [CleanFloors => [allleft => $UseBroom ] [allmiddle => $Vacuum ] [allright => $MopFloors ] ] ] The next example provides the same functionality in yet a third way: The second menu entry is used to "bring up" a secondary menu for the user to click at. The secondary menu is designed to provide three buttons, each of which will cause the menu to disappear after one of the options is invoked. [HouseCleaningMenu [Dust => $Dust] [Places => [all toggle: "FloorCleaningMenu" => ] ] -- note that nothing follows the '=>' ] [FloorCleaningMenu [Sweep => [all makeInActive: "FloorCleaningMenu" => $UseBroom ] ] [Vacuum => [all makeInActive: "FloorCleaningMenu" => $Vacuum ] ] [Mop => [all makeInActive: "FloorCleaningMenu" => $MopFloors ] ] ]  MenuBNF.tioga, written by R. Pausch NOTE: examples can be found at the bottom of the file, below the BNF This in an informal BNF description of the Syntax of Cedar Viewer Menus, as parsed by Menus.ParseDescription. BNF notation: anything in single quotes (also shown in BOLD) means I need that exact String, although I don't care about the case of the characters. Parens (), OR bars | and stars * are part of the BNF notation. NOTE: You may find this thing easier to read if you use one very wide viewer. Last Edited by: Pausch, August 26, 1983 7:17 pm three String are MenuName, oldentryname, newentryname  using only two strings implies that ALL entries in all menus that have first String as their name should be ReLabel with the second String. Note that this doesn't change the 'name' field of the data structure, rather, it changes the 'displayData' field (which is why it is called 'ReLabel', not 'Rename') complexity: if an Entry is to have different functionality for different triggers, i.e. left-clicking does something different than right-clicking, it is harder to specify. To wit, EACH trigger or combination of triggers must have things specified for it. Ê­˜Jšœ#™#J™EJšœ’™’Jšœ/™/Jšœ˜J˜š œ Ïb œœœ œœ ˜OJšœé™éJšœ˜Jšœ˜Jšœ˜—J˜šœ œ˜,Jšœ˜—J˜Jšœ œœ œœœœ œœ˜oJ˜šœ œœ˜J˜Jšœ7˜7J˜šœœ/œ˜_Jšœ‚™‚J˜—Jšœœ˜&J˜Jšœ œœœ œ œ œœœœ œ œ œ ˜ÂJ˜Jšœ œœ œœ œœ œœ œœ˜–J˜Jšœ<˜