Help on DeskLib format messages files
=====================================

A Msgs file is a sequence of lines which may be blank, a comment, or a
message.

A comment is started with a # character at the START of a line

A Msgs message is of the form:
group.msg: message

i.e.
quit.menu:     Quit
quit.help:     This menu option allows you to quit the application
quit.notsaved: Some files are not saved. Are you sure you want to quit?
quit.yes:      QUIT
quit.no:       No

info.menu:     Info
info.help:     Follow the arrow to display information about this program

etc.



"group" and "msg" tags are text strings (leading blanks (newlines, spaces,
tabs) are ignored) of up to 8 characters. (8 because I can then do a very
quick word-word comparison to compare tags instead of up to 8 character
comparisons, and because more than 8 characters simply encourages slight
memory wastage and inefficiency). They can contain any characters except "."
(for group) and ":" (for msg).

The message following the ":" is of the following format:
  Leading blanks are ignored
  The message is all characters from then on until the next newline
   (character 10 - LF) character. (there is no need for a newline character
   at the end of the file)

  The normal string will be fetched using Msgs_Lookup.
  It can contain any of the following controls:
      <group.msg>   insert the message with the given tag
                    (note: no default string can be specified here)
      <>            can be used to insert a single "<" character

    e.g.
      quit.text: Quit
      quit.Menu: <quit.text>
      quit.help: The <quit.text> option allows you to quit the application

    would allow us to change quit.text to "Finish" without changing the
    other messages in the file.
    The main use for this is to do stuff like:

      error.file: File not found <msg.space>
      error.open: File is open <msg.space>
      msg.space:  - Press space or click mouse to continue

    so that repeated parts of messages may be defined seperately, or:

      data.type: bytes
      mess.1: File counted, %d <data.type>

    where in some situations you might like to change the term "bytes" to
    read "octets" or "samples" without having to edit hundreds of messages
    in your messages files

    The string can also contain all the normal controls that you can put
    into an sprintf format string.
    This is used with Msgs_printf, which is identical to sprintf except
    that you pass in a message tag, and the message produced is then used
    in an sprintf command as the format string.
    e.g.
    the messages:

      data.type: bytes
      msg.count: File counted: %d <data.type>.

    used with:

      Msgs_printf(outputstring, "msg.count", bytecount);

    will give the equivalent of

      sprintf(outputstring, "File counted: %d bytes.", bytecount);

    resulting in (bytecount == 37)

      outputstring == "File counted, 37 bytes."
   
ALL substitutions are carried out when the message is fetched (NOT when
messages are loaded). This has a slight speed disadvantage, but the main
reason for message including was to allow inclusion of long strings that are
used repeatedly, in order to reduce memory usage.

As you can see, this is much nicer, and in some ways more powerful than
msgtrans' simpler "tag: message" format, and also requires less processor
work to find things (as things are grouped, so you don't have to search the
whole file, only one subgroup) (note: this may be slower than msgtrans - I
don't claim it's faster, just IMHO nicer - if you prefer msgtrans, then use
msgtrans)


Using Msgs
==========

To retrieve a message, simply pass in the group and msg tags to the
appropriate function, as in the following:
"group.msg"              (The message indicated)
"group.msg:default"      (If the message can't be found, use default instead)

Msgs_Lookup() is similar to Acorn's msgs_lookup(), but it returns a
TRUE/FALSE result to indicate whether you have ended up with a valid string
to print (either the found message, or the default string you supplied)


WildCards
=========

the last powerful function that Msgs_ provides is the ability to *terminate*
a message tag (in the messages file, or in calls to Msgs functions) with a
"*", which matches any character or character sequence.

The comparison process (in Msgs_Lookup) is done as a two-pass process, first
it attempts to match the tags with wildcards disabled - if this fails, then
a second pass is made with wildcards enabled. Thus, you can mix wildcards
and normal tags without odd effects.

Messages are read in and added to the front of a linked-list, so any
wildcarded messages in the messages file should appear EARLIER in the file
than any other similar wildcarded messages, as in:

  win*.*: This is any general icon in the window
  window.3: Icon 3 allows you to clear the picture
  window.10: Icon 10 is the "OK" icon. Click it to finish editing
  window.*: This is another generalised message
  window.7: Icon 7 beeps if you click it

This will attempt to match any message with "window.7", then "window.10"
then "window.3", and if no match is found, it will try to match "window.*"
and then "win*.*" (so "window.9" will match "window.*", but "winston.churchill"
will match "win*.*".

That is, the most generalised messages should go first, and more specific
messages follow on. The most commonly used messages (if you know which ones
they are) should be put towards the end of the group/file in order to
increase efficiency in fetching them.

  --This would be used for situations such as Help_'s automatic help in a
  window, where a help message is generated by using the window's
  template-name (window), and appending the icon number, so if the mouse
  pointer is over icon 12, the tag "window.12" is generated, which does not
  match window.7 (checked first), window.10, or window.3, but does match
  window.*
  This means that if help is not specifically available for a given icon, the
  help will default back to a general "window" help message.
  Only the first matching message is returned.

Wildcards can be used in the messages file as above, and can also be used
when fetching messages - using the above example, the tag "window.*" would
match window.7, returning "Icon 7 beeps if you click it" (window.7 is the
last matching message defined in the file, which means it will be checked
FIRST)

the tag "window.1*" will not match window.7, so will continue to window.10,
at which point the match is found, etc.

Note: Wildcards are only implemented simply: A wildcard essentially means
the end of the tag, as it matches ALL characters from that point on -
characters following the wildcard are ignored.

i.e. matching
  window.icon45     

will return TRUE for all the following cases:
  window.icon45
  window.i*
  window.i*45
  window.i*zot
  window.icon*
  w*.ic*
i.e. ONLY use the wildcard at the END of a tag.
(and remember that the group and msg tags are treated as SEPERATE tags
here, so w*.zot will NOT match the above)


Extra notes
===========

a blank group tag or msg tag can be used (though it's not recommended), but
the delimiters must still be present, as in:

.:Message for blank group and blank name
quit.:Quit's blank-message-tag message
.quit:No group for the quit message!

You can also use the same group/tag name (e.g. a blank name) for all
messages, but this is silly, as the only effect is to reduce the speed with
which messages can be found.
