Meb - Menu Builder

Versions 0.4 and up can be found at

Older versions can be found at

  • Stu 2022-08-22 Version 0.5
  • Stu 2018-05-25 Version 0.4
  • Stu 2015-05-28 Version 0.3
  • Stu 2015-05-20 Version 0.2

Jeff Smith 2022-08-27 : Below is an online demo using CloudTk. This demo runs "Meb" in an Alpine Linux Docker Container. It is a 50.6MB image which is made up of Alpine Linux + tclkit + Meb-0.5.kit + libx11 + libxft + fontconfig + ttf-dejavu + i3wm. It is run under a user account in the Container. The Container is restrictive with permissions for "Other" removed for "execute" and "read" for certain directories.

Stu 2012-06-17 Meb 0.1
Meb is a menu builder that employs the same philosophy as Gub:

  • Require learning the least amount of new syntax as possible.
  • Leverage Tk options.
  • Take care of the drudgery part of gui building.
  • Generate Tcl code.


  • Generates Tcl code to create menus.
  • Takes care of the less important aspects of menu creation.
  • Simple layout, one item per line.
  • Indent determines level, one space per level.
  • Tk options start at first '-' after label text.
  • Auto underline using '&'.
  • Cascades determined my indent (level).
  • Checkbuttons,radiobuttons determined by -variable option.
  • Auto command.
  • Namespace for commands and variables.
  • Separator is any string of '-' and/or '='
  • MebTool, a command-line and gui utility.

Release notes

Summer 2022 - Version 0.5

Now generates Ruby code
GUI partly redone with Guhb
Participate in and use of Central
New examples in all supported langs

Spring 2018 - Version 0.4

Light tidying
Tcl 8.6 required
Tk menu options with #rrggbb colours
no longer interfere with comments.

Spring 2015 - Version 0.3

Meb 0.3:
Better ampersand underlining

Mebtool 0.3:
Consolidate help -> program info

Spring 2015 - Version 0.2

Source code generation for: Tcl, Lua, Python, Perl

The non-Tcl languages don't have full functionality
but they basically work.

New exported procs:
mebLangs - List available languages
mebUA - Underline Ampersand

Updated spite.conf for newer SPITE

The returned dict member 'script'
has been replaced by '$lang src'
where $lang is one of tcl, lua, python or perl

Now requires Gub
Added source tab

Spring 2012 - Version 0.1

Example usage

$ cat example3.mob             

# Meb example 3 - simple


$ mebtool example3.mob  

menu .m -tearoff 0
.m add cascade -label File -underline 0 -menu [menu .m.m0 -tearoff 0]
.m.m0 add command -label Load -underline 0 -command ::fileLoad
.m.m0 add command -label Save -underline 0 -command ::fileSave
.m.m0 add command -label New -underline 0 -command ::fileNew
.m.m0 add separator
.m.m0 add command -label Exit -underline 1 -command ::fileExit
.m add cascade -label Help -underline 0 -menu [menu .m.m1 -tearoff 0]
.m.m1 add command -label About -underline 0 -command ::helpAbout
.m.m1 add command -label Readme -underline 0 -command ::helpReadme
$ cat example1.mob                                                                                         

# Meb example 1

&Command        # Comments start at the first # on a line
 &Sing          # and continue to the end of the line
 &Jump          # These lines become commands
 -              # This is a separator
 &Shampoo       +menuoptions {-bg tan}  # Set menu (cascade) options with meb option
  &Lather       -value soapy            # The -value option makes this become a radiobutton
  R&inse        -command {puts rinse!}  # Leading { prevents namespace prefixing
 =              # This is a separator
 E&xplode       # Commands become prefixed with a namespace

# Blank lines and comments are ignored
# Separators can be any combination of - and =
# Meb options are {n v} and start with +
# The default namespace is ::

&Radio          # These are good
 &Lettuce       -variable veg -command ::myns::hello    # Leading :: prevents namespace prefixing
 &Carrot        -variable veg
 &Radish        -variable veg           # These become radiobuttons
 &Potato        -variable veg           # because they share a common -variable
 =-=-=-=-=-=                            # This is a separator
 &Healthy       # These are better
  &Beer         -variable yum           # Submenus (cascades) are made by
  &Chips        -variable yum           # indenting one space from their parent
  Piz&za        -variable yum
  &Lard         -variable yum           # Variables become prefixed with a namespace

 &Extra Cheese  -variable cheese        # These become checkbuttons because they
 &No Singing    -variable sing          # are the only items to use a particular -variable
  &Verbose      +type radiobutton -variable verbose     # Override type with meb option
  &Whisper      -variable whisper
$ mebtool -names -namespace myns -nomenu -menuname .z example1.mob

.z add cascade -label Command -underline 0 -menu [menu .z.mCommand -tearoff 0]
.z.mCommand add command -label Sing -underline 0 -command ::myns::commandSing
.z.mCommand add command -label Dance -underline 0 -command ::myns::commandDance
.z.mCommand add command -label Jump -underline 0 -command ::myns::commandJump
.z.mCommand add separator
.z.mCommand add cascade -label Shampoo -underline 0 -menu [menu .z.mCommand.mShampoo -bg tan -tearoff 0]
.z.mCommand.mShampoo add radiobutton -label Lather -underline 0 -value soapy
.z.mCommand.mShampoo add command -label Rinse -underline 1 -command {puts rinse!}
.z.mCommand.mShampoo add command -label Repeat -underline 0 -command ::myns::commandShampooRepeat
.z.mCommand add separator
.z.mCommand add command -label Explode -underline 1 -command ::myns::commandExplode
.z add cascade -label Radio -underline 0 -menu [menu .z.mRadio -tearoff 0]
.z.mRadio add radiobutton -label Lettuce -underline 0 -variable ::myns::veg -command ::myns::hello
.z.mRadio add radiobutton -label Carrot -underline 0 -variable ::myns::veg
.z.mRadio add radiobutton -label Radish -underline 0 -variable ::myns::veg
.z.mRadio add radiobutton -label Potato -underline 0 -variable ::myns::veg
.z.mRadio add separator
.z.mRadio add cascade -label Healthy -underline 0 -menu [menu .z.mRadio.mHealthy -tearoff 0]
.z.mRadio.mHealthy add radiobutton -label Beer -underline 0 -variable ::myns::yum
.z.mRadio.mHealthy add radiobutton -label Chips -underline 0 -variable ::myns::yum
.z.mRadio.mHealthy add radiobutton -label Pizza -underline 3 -variable ::myns::yum
.z.mRadio.mHealthy add radiobutton -label Lard -underline 0 -variable ::myns::yum
.z add cascade -label Checkbutton -underline 0 -menu [menu .z.mCheckbutton -tearoff 0]
.z.mCheckbutton add checkbutton -label {Extra Cheese} -underline 0 -variable ::myns::cheese
.z.mCheckbutton add checkbutton -label {No Singing} -underline 0 -variable ::myns::sing
.z.mCheckbutton add cascade -label Other -underline 0 -menu [menu .z.mCheckbutton.mOther -tearoff 0]
.z.mCheckbutton.mOther add radiobutton -label Verbose -underline 0 -variable ::myns::verbose
.z.mCheckbutton.mOther add checkbutton -label Whisper -underline 0 -variable ::myns::whisper