Version 8 of ampersand magic

Updated 2002-07-10 08:55:43

All underline handling in Tk standard dialogs is now done with "magic ampersands".

[As of which version?]

The experts in this are A/AK and DKF. The latter has explained, "'Ampersand magic' is a way of encoding the character to underline in a button, label, menu etc. in the string. It is easiest to see how it works by looking at an example:

  If the string to show is 'Save As...' and the letter to underline is the 'A'
  in 'As...' then the ampersand-magic-ed string is 'Save &As...'

  If the string to show is 'Quit' and the letter to underline is 'Q', then the
  ampersand-magic-ed string is '&Quit'.

IIRC, this sort of thing came originally from Windows, and it is rather a good idea because it makes it much easier to set up underlines for labels (where real ampersands tend to be fairly rare), particularly compared with counting characters to get to the right spot. I don't remember the exact details of Tk's implementation but I think it is done through extra procedures and is just used for strings for Tk's standard dialogs coming from the message catalog."


[Bring Anton's example code from "msgcat and shortcut keys" here.]


[But Perl/Tk uses '^' in place of '&'? What's going on?]


RS thought the TCT had decided to use the Unicode "non-spacing underline" for this function? The advantage would have been that the hot key could be easily parsed out, while such a string would not have to be modified at all to display the underline - self fulfilling data prophecy...


Ro coughs up some code:

  # ::whatUnderlined --
  #
  #
  # Description
  #
  #   Finds out what character index to underline from a given label.
  #   The character after the "&" is the one to be underlined.
  #   The first character has index 0.
  #   Only one character can be underlined.
  #
  #   e.g.:  Given "Forma&t" it will return {5 Format}
  #          Given "Edit"    it will return {0 Edit}
  #
  #   Note: If the "&" character is missing, 0 is the index returned.
  #
  #
  # Arguments
  #
  #   s          The label to parse for single character underlining.
  #   
  #
  # Results
  #
  #   Returns two elements in list format, the first is the index of the 
  #   character to be underlined, the other is the label to be displayed.
  #
  #   If no character is to be underlined, the character index 
  #   returned is 0, and the label returned is the original given label.
  #
  #
  # Side Effects
  #
  #   none
  #
  #
  proc ::whatUnderlined {s} {

    #
    # Get the index of the "&" character.
    #
    set i [string first & $s]

    #
    # If there is no "&" character in the label, then return the
    # index 0 and the original given label.
    #
    if {[string equal "-1" $i]} {
      return [list 0 $s]
    } 

    #
    # If there is a "&" character, then return the index of the
    # explicitely determined character to underline and the display
    # formatted label.
    #  
    set s [string replace $s $i $i]
    return [list $i $s]

  }