The EMDL (Easy Menu
Definition
Language)
Language Definition and
EMDL to UMENU Converter (GNU/GPL)
Copyright (C) 2002-2004 by Steve Litt
NO WARRANTY!
There is no warranty for anything contained in the
EMDL distribution or documentation or its web pages, to the extent
permitted by applicable law. Except when otherwise stated in
writing
the copyright holders and/or other parties provide the program,
documentation
and web pages "as is" without warranty of any kind, either expressed or
implied, including, but not limited to, the implied warranties of
merchantability
and fitness for a particular purpose. The entire risk as to the
quality
and performance of the program is with you. Should the program,
documentation
or web pages prove defective, you assume the cost of all necessary
servicing,
repair or correction.
EMDL is a language to quickly and
easily
define an entire menu system. The emdlparser.pl program
converts
an EMDL file to a tree of UMENU .mnu files.
Project Charter
The purpose of the EMDL language is to facilitate fast and easy
manipulation
of large menu systems using a standard text editor capable of automatic
indentation (the ability to indent to the same level as the preceding
line,
plus ways to cut, paste, indent and exdent multiple lines). The Vim
editor
is one such editor. VimOutliner is ideally suited for EMDL authoring
because
of its ability to collapse and expand trees.
Priorities of the EMDL initiative are:
- Quick and easy creating and editing of large menu systems
- Cut and paste
- Promotion and demotion
- Assignment of commands, directories, prepaths, and other
parameters to
choices
- Authoring can be done with a text editor
- Readability
- Use of a text outliner to define menu hierarchies
And the following are not design priorities at all:
- Ease of parsing
- Run time efficiency
- Gui environments
- Inclusion of every last possible feature of every possible menu
system
Priorities #1, 3 and 4 preclude anything with end tags, and suggest
that
the language should be line based. So it is. #3 suggests use of an
outline
to simulate the hierarchy of a menu system, with its tree of menus and
each menu's selection of choices, many of which have multiple
parameters.
EMDL is so productive you can create a substantial personal custom
"start
menu" in an hour or so. It's featureful enough to create fairly complex
menus, although it lacks a generic facility for prompted argument
substitution.
However, if the destination menu supports prompted argument
substitution
in its commands, then the prompted argument substitution tags can be
placed
in an EMDL command parameter. This is why EMDL supports UMENU prompted
argument substitution. It's anticipated that version 2 of the EMDL
language
specification will support prompted argument substitution natively.
EMDL language version 1.1 has two very nice new features:
- Support for multiple command parameters
- Support for environment variable parameters
The first program to use EMDL is emdlparser.pl, which performs
the function
suggested by its name. It's a GNU GPL licensed program that runs on any
Linux computer with a standard Perl 5 installation, and will likely run
on any UNIX, UNIX workalike, or BSD computer. It hasn't been tested
with
Windows, but making it run on Windows would likely require only the
most
trivial changes.
emdlparser.pl is a
complete rewrite of the older emdl2umenu.pl.
Regression testing has proven that for a given input file, emdlparser.pl outputs identical
.mnu files as emdl2umenu.pl. However, the
newer program is an order of magnitude simpler, and it runs about 7
times faster. This efficiency in terms of speed and simplicity is
achieved by use of the Node.pm
tool.
Unlike its more complex predecessor, the emdlparser.pl program consists
of a single source file (which uses Node.pm). The newer program is
less object oriented, although all data structures are now based on
trees of Node objects. The new program has a simple main program
calling several fairly simple subroutines. The subroutines, in turn,
use Walker objects to traverse Node trees issuing callback routines for
each Node. The callback routines are all methods of the Callbacks object, which also
has variables for the number of errors and the number of warnings.
Having this program output a different kind of menu would essentially
involve only creating a new callback routine to output that new menu.
The intended audience of EMDL are those who possess all of the
following
traits:
- Have, or can create, a tool to convert EMDL to their menuing
system of
choice
- Willing to edit and create menus
Willing to use an editor instead of a "drag and drop environment"
Maintainer's Guide
All current and future maintainers of EMDL and various EMDL parsers
should
be very cognizant of the project's priorities. EMDL must be easy for
the
human creating or maintaining the menu system, even if this ease means
very complex parsing algorithms. Nothing slows a user like needing to
type
tags. Nor is a GUI "drag and drop" an appropriate solution, because
invariably
such software is slower than an editor for an experienced user.
Project Specifications
The project spec consists of:
- EMDL version 1.1 language definition
- emdlparser.pl
program
specifications
EMDL version 1.1 Language Definition
Before defining the language, an example is in order:
E:::Example Menu Mouse Speedup param C: xset C: m 3 2 Office ::: Office Menu Abiword param C: abiword & Lyx param C: lyx & D: /data/lyxdocs ^Quit Information ::: Information Menu Ifconfig param C: ifconfig P: /sbin S: 1 Top param C: top ^Quit
^eXit
|
The main menu is called "Example Menu" and contains three choices,
four
choices: Mouse Speedup, Office, Information, and eXit. Note that the
middle
two choices are submenus, as shown by the triple colon separating their
choice text from their menu titles. The Abiword choice runs the
following command:
abiword &
Any parameter beginning with C: is a command. As shown in the
Ifconfig
choice of the Information Menu, a parameter with P: is one or
more directory to prepend to the path, and S: signifies that
execution
stops after the command, and the user must press a key to get back to
the
menu. This is necessary to read output from commands that print to
stdout.
As shown on the Lyx choice on the Office Menu, any parameter
beginning
with D: signifies a directory to switch to before executing
the
command.
The Mouse Speedup choice runs
the following command:
xset m 3 2
What has happened is there are multiple C: lines. They are concatenated
with a single space in between them, to create a single command. This
enables you to place a small script inside a menu definition file.
Because these lines are strung together, each separate command must end
in a semicolon.
The preceding paragraph is actually a little misleading because in
fact, the separate C:
lines are passed individually to the menu program. It's the menu
program that concatenates them. This behavior might be configurable in
later EMDL parser programs.
Notice the Quit and eXit commands are preceded by
carats
(^). That's EMDL shorthand for saying "this choice takes you up one
level".
The violet item is the starting menu
letter
and menu title for the main menu. Each green item
is a menu choice. Each red item is a
submenu,
and of course a submenu is both a choice on its containing menu and a
menu
header for a new submenu, so it parses like this:
(Choice text ::: Submenu Title)
The Seven Line Types
EMDL is line oriented. Each line defines something. Lines cannot
be arbitrarily split. It is also indentation dependent, because the
menu
hierarchy is represented by a tab indented outline. There are seven
types
of lines in EMDL.:
Line type |
Definition |
Use |
Examples |
First Menu Line |
The first line containing ::: |
Defines title of main menu and letter string of main menu |
E:::Example Menu
|
COMMENT |
1st non-whitespace character is # |
Ignored and not transferred to output |
|
BLANK |
Empty line or whitespace only line |
Ignored and not transferred to output |
|
MENU |
Line containing ::: |
Used as a choice on its containing menu and as a header for a
new submenu |
Office ::: Office Software Menu Development:::Development Menu
|
PARAMHEAD |
Any line whose only non-whitespace is the string "param" or
"params",
and such line is immediately subservient to a CHOICE line. |
Used to identify subsequent parameters for the parent CHOICE
line. |
param
|
PARAMETER |
Any line subservient to a PARAMHEAD line. |
Used to add information about the parent CHOICE line. |
C: abiword D: /data/documents
|
CHOICE |
A line that isn't one of the preceding. It contains a single
letter,
follow |
Denotes a choice on a menu |
Abiword
|
Choice Lines
Choice lines contain the text of the choice, and via various tricks
also
contain the letter that activates them, as following
- The first character of the line, unless...
- The first upper case character in the line overrides the
preceding,
unless...
- The first & followed by a non-whitespace, in which case the
non-whitespace
is the activation letter, overrides all the preceding, unless...
- If the line starts with _LX_, where X stands for any letter, that
letter
is the activation letter and overrides all the preceding.
In practice, making the first upper case letter the activation letter
is
the best technique, because it's the most readable by the user of the
menu.
The other techniques provide options when that isn't the best
representation.
A special case is a choice that begins with a carat (^). In such a
case,
that choice escapes to the next higher level menu. Note that this could
also be done by giving that choice a command parameter line whose
command
is the carat character.
Parameters
Choices contain the text to be displayed and the activation letter, and
in the case of choices that escape to a higher level menu, the choice's
command. All other information about a command must be specified in its
parameters. Parameter lines are key/value pairs, where the key is
represented
by a single upper case letter, and the value is represented by a
string.
A colon and optional whitespace separate the key from the value.
Key |
Meaning |
Example
line
|
Comments |
C |
Command |
C: su -c "/sbin/halt"
|
Multiple commands for a single line append in the order
encountered.
|
D |
Current directory |
D: /documents/hillproject
|
Directory to switch to before running the command |
P |
Prepath |
P: /usr/local/myapp
|
1 or more directories, separated by path separators (colon in
UNIX),
which are prepended to the existing path before running the command |
S |
Stop |
S: 1
|
Signifies a stop after running the command, so that the user
can read
the output of the command. The user then presses a key to return to the
menu. |
V |
Drive |
V: C:\
|
Drive letter or NFS drive or the like. Unimplemented in EMDL
version1,
but reserved. |
E |
Environment var |
E: MENU=UMENU
|
The specification states there can be multiple environment
variables
in a choice, each which must be set before running the command. This is
not implemented in the current emdlparser.pl. |
I
|
Icon
|
I: /usr/share/icons/gvim.png
|
Not currently implemented in
UMENU, but included in EMDL to accommodate GUI menus.
|
Note that:
^Quit
is shorthand for:
Quit
param
C: ^
The former is preferred because it's more readable and requires much
less
typing.
Common EMDL Errors
Errors
- A choice or menu indented under the preceding choice
- A choice or menu doubly indented under the precding menu
- A PARAMHEAD line that's not indented exactly one tab farther than
the
preceding choice line
- A parameter line that's indented more than 1 tab below the
preceding
PARAMHEAD
line
- A parameter not starting with a capital letter, followed by a
colon
(which
may be surrounded by whitespace on either side)
- The most common example is forgetting the C: before the command
parameter
Warnings
- A menu without a Quit is usually a bad thing
- A menu sporting multiple choices with the same menu letter is an
error
in some menu programs (including UMENU).
- A choice without a command is useless and should generate a
warning
- A menu with no choices should generate a warning, because it's
useless
Prompted Argument Substitution
EMDL version 1.1 doesn't directly support prompted argument
substitution.
If it were to, it would probably use a special parameter syntax with a
parameter line for each argument.
Menu systems implementing prompted argument substitution entirely
within
their commands can obtain their prompted argument specifications
from
the command defined in the EDML file, as shown in the following UMENU
compatible
fragment:
T_Grep for text in files param C: find %b%Starting directory%% -type f | xargs grep -l %a%Text to look for%% | less
|
The preceding first prompts for the text to look for, and then for
the
starting directory, after which it finds any files in the starting
directory
tree containing the sought text.
Future Enhancements to the EMDL Spec
Parameters for menus and parameter mapping are two likely candidates
for
an upcoming version of the EMDL spec.
Parameters for Menus
The EMDL 1.1 specification neither specifies nor prohibits parameters
for
menus. It will probably be specified in an upcoming EMDL version.
Currently,
the menu line itself specifies the menu title. Properties such as the
initial
choice on a menu whose order is not top to bottom would need to be
coded
as parameters subservient to a menu.
Parameter Mapping
The parameter letter designations in EMDL 1.1 (C, P, D, S, E, I and V)
were
taken directly from UMENU (except for I), and might not be ideal for
users of other menus.
Future versions of EMDL will specify a letter to parameter type file,
so
that an organization can code parameters in a manner most obvious to
them.
Such a mapping file will also provide for more accurate parameter
checking,
and might open the door for multi character parameter keys.
emdlparser.pl Program Specification
The emdlparser.pl program
parses an EMDL file in a fairly compliant way. It's
completely compliant with the following:
- Menus and submenus
- Directories
- Prepaths
- Commands
- Stops
And the following EMDL features are inadequately supported or
unsupported
in emdlparser.pl:
- Drives (incompletely supported by UMENU)
- Same-lettered choices on a menu (not supported by UMENU)
The emdlparser.pl program
is comprised of a main routine calling simple subroutines, which
perform their work using Node walkers (see Node.pm) and associated
callback routines. All callback routines are methods of the Callbacks object, which also
contains variables to keep count of errors and warnings.
Creating an output mechanism for a new type of menu is pretty
much as simple as creating a callback routine for that menu type, and
then calling that callback with a Node Walker.
Validation
There are two types of validation -- parse validation and menu
validation.
Parse validation checks that the EMDL code is a well formed outline,
with no double indents. Menu validation means that the outline
represents a valid outline, including:
- One paramhead per command choice
- Command choice has one child -- a paramhead
- Paramheads =~ m/^\s*params?\s*/i;
- Paramheads have only parameters as children
- Parameters have a paramhead as a parent
- Parameters have no children
- Menu choices have three colons
- Menu choices have a menu as a parent, or no parent at all
- Menu choices have menu choices and/or command choices as children
- Command choices have only a menu choice as a parent
- Command choices have only a single paramhead as a parent
Validation is done by callback routines.
All detected errors and warnings are written to stdout.
Downloads
- Current downloads (0.7.0)
- Previous versions
Maintainers List
Needed Programming and Documentation Tasks
- Specification for EMDL native prompted argument substitution.
- Writer callback for Icewm menus
- Writer callback for KDE menus
- Port to Windows and various Unices
How to Participate
Email Steve Litt if you'd
like to participate. I'll work with you as much or as little as you
want.
Mailing List
There's no mailing list yet. For now, communicate directly with Steve
Litt. Once there are several participants, I'll make a mailing
list.
FAQ (Frequently Asked Questions) list
None exists. The project is too new to really know what to put in it.
HTMLized versions of the project
documentation
README.html covers most of
what you need to install, configure
and use EMDL.
Links to related projects.
Dedication: We Stand On Their Shoulders
- Richard Stallman and the Free
Software
Foundation:
Without them I shudder to think what the software world would be like
today.
- Linus Torvalds and the various Linux projects: Without Linux, I
wouldn't
need EMDL or UMENU -- I'd just need a lot more money to purchase
proprietary
software and a lot more patience to deal with Blue Screens of Death and
resulting data loss.
- Greater Orlando Linux User Group
(GoLUG): The peer to peer brain network of which
I'm a small part.
- The VimOutliner Project.
These guys
keep making VimOutliner better and better. VimOutliner was my original
reason for creating Node.pm, which so greatly enhanced this version
of EMDL.
-
David Billsbrough, my UMENU co-conspirator who has given me many of my
ideas for specifications.
Progress
- On 3/5/2002,
the first distribution of the EMDL project was released as
version 0.5.0. This is alpha code. It seems to work perfectly on my
box,
and I tested it hard.
- On 5/24/2004,
the second distribution of the EMDL project was released as
version 0.7.0. Much simpler and robust than the original, this can be
considered beta rather than alpha. It also is 7 times faster,
implements more
features, and is simple enough to reasonably allow output to menu
systems
other than UMENU.
Top of Page