=pod
 $Id: dml.pod,v 1.17 2003/08/23 14:19:20 malekith Exp $
=cut

=head1 NAME

dml - shell dialogs with HTML-like syntax

=head1 SYNOPSIS

dml [B<-pec>] [B<-f> I<input_file>] [B<-o> I<output_file>] 
    [B<-C> I<config_file>] [B<-t> I<title_string>] [I<program...>]


=head1 DESCRIPTION

DML is a cmdline tool which can be used to create interactive
shell scripts. It is somewhat similar to B<dialog(1)> tool,
but is much more powerful.

DML is shorthand for Dialog Markup Language. As name suggests
it uses several markups to donate specific widgets. DML
program is much like HTML page with form. However there are
several differences:

* tabs and newlines are generally ignored

* spaces are not, so if you write S<'foo    bar'> you will
get S<'foo    bar'> not S<'foo bar'>

* input is not automagicly wrapped. you need explicit <br>
tags (except inside <text> </text>)

* there is no <p> tag (use <br><br>)

There are three ways of passing programs to DML. First is to specify
program in command line, like this

 $ dml 'Hello world<br><button>'

second is to specify file with program with B<-f> option, and third
is to pass program to dml's stdin. I found 3rd method most
convenient, using here doc, like this:

 $ dml <<EOF
 > <input id=a>
 > <br>
 > <button>
 > EOF

Tags are specified inside <>. Tags which are not recognized are left
untouched, this is useful when you're debugging scripts. Most of tags
can have attributes in form name=value. If B<value> contains spaces
it should be specified in single or double quote. All tags which
produce input widgets can get B<id=> attribute. It's used to
identify given widget. After dialog is executed DML dumps
id_of_widget="state_or_caption_of_widget" pairs to stdout
(unless overridden with B<-o> option). This can be used in shell, like
this

 eval `dml <<EOF
 Name: <input id=name caption="Franek">
 <br>
 <button res=1 caption="_Ok"> <button res=2 caption="Oo_ps">
 EOF`

After this 3 variables are set: B<res> to 1 or 2 depending on
whatever user pressed. B<name> to whatever was entered in input box.
And B<undef> since there was no id given for some widgets (two buttons).
If you're wondering about "_Ok" then B<O> is highlighted, and some day
there will be some shortcut available to use it ;^)

I found useful to define function for it (backticks quoting problems etc.)
like this:

 dial()
 {
         eval `dml -t '_Some title' "$@"`
 }

And then use it like this:

 dial <<EOF
 Hello world
 EOF

=head1 OPTIONS

=over

=item * B<-e> reopen from stdErr

When dml is started it may need to read program from its STDIN and
then write output to its STDOUT. But it also has to read and
write console. STDERR is assumed to be connected with terminal, and
is used for this purpose in case we cannot use STD{IN,OUT}. 
That's why you should never do 'dml 2> anything'. This option
can be used to always use STDERR.

=item * B<-c> clobber output file

If file specified as output already exists dml won't overwrite it,
this option may change this.

=item * B<-p> poor man frames

Use +, - and | characters for frames, instead of vt100 semigraphics. 
Sometimes needed for bogus fonts.

=item * B<-C> I<config_file>

Use alternate configuration file instead of I</etc/dml.conf>.

=item * B<-t> I<title_string>

This string is displayed in top-left corner of screen, it can contain
'_'s which highlight next character.

=item * B<-f> I<input_file>

Read program from file.

=item * B<-o> I<output_file>

Send output to file. It's not overwritten unless B<-c>.

=back

=head1 TAGS REFERENCE

All attributes are optional. Some default are assumed.
B<id> always defaults to "undef". B<width> and B<height>
are computed. B<caption> has synonymous B<text> in most
cases.

=over

=item * <B<meta>>

set some meta-information for form.
Attributes: B<title> -- set title displayed in top of form.
B<res> -- set modal result on start, this defaults to 0, and is
useful to display some information like 'Scanning...' and then
scan. If you set it, dml call won't block - it will just display
dialog and return. B<width>, B<height> -- can be used to set
fixed size window. B<active> -- can be used to set which widget
should initially have focus. Note that you *have to* use it
before you define actual widget.

=item * <B<br>>

breaks line. No attributes (yet ;).

=item * <B<input>>

display one line input box. Attributes: B<id>, B<width> -- defaults to 30,
B<caption>, B<res>, B<pass=1> -- don't display caption, just single 'x',
B<pass=2> -- mask input characters with '*'s. There
is few more attributes for file selector inputs, see 
B<FILESELECTOR> section for details. It is also possible to provide
user with optional list of choices in the input box, see B<POPUP MENUS>
for details.

Since 0.1.1 you can prevent user from changing value of input box with
B<ghosted=1>. It is mainly useful with popup menu.

=item * <B<button>>

display button that can be selected and pressed. Attributes: B<id>,
B<width>, B<caption>, B<res> -- modal result, if set to 0 (not useful),
pressing this button won't close the window, sets shell variable I<res>
to this modal result, dml command returns with status I<res> - 1.
Button sets I<id> to 'yes' or 'no' depending on whatever it was pressed
when closing dialog, I<res> is more convenient anyway. I<text_res>
attribute can also be used. It takes string as argument, this string
is placed in output variable text_res.

=item * <B<check>>

display checkbox ([X] or [ ]). Text describing it has to be entered
outside (like this: '<check id=foo> Set foo').  Attributes: B<id>,
B<checked=1> -- if you want it to be marked per default. Sets I<id> to
'yes' or 'no'.

=item * <B<text>> ... </B<text>>

textarea, multiline widget that can be scrolled. Text inside it can
contain <B<br>>'s, and two font tags: <B<i>> ... </B<i>> and <B<b>>
... </B<b>>, first being italics (blue ;) and second bold (yellow). Text
is wrapped.  Attributes: B<width> which defaults to 40, B<height> which
defaults to 8.

=item * <B<menu>> ... </B<menu>>

multiline menu of options.
It contains <B<item>> tags. <B<item>> can have only one attribute
B<id>, followed by actual menu item caption, like this:

 <menu id=m>
 <item id=del>_Remove the file
 <item id=mv>_Move the file away
 </menu>

I<id> of menu should not be confused with I<id> of items. After dialog
is done I<id> of menu contains I<id> of item. So after executing our
example in shell variable I<$m> there is either 'del' or 'mv'.

'R' and 'M' characters are highlighted. They will be used for shortcuts
in future.

In 0.0.4 support for multiple selection menus has been added.
They are done using I<checked> attribute to menu. It can be B<0>
or B<1>. If it is not passed -- given menu item is normal (i.e. doesn't
have [B<X>]). You can safely mix items with and without checked
tag within the same menu. If there is at least single item with 
I<checked> attribute, return value of menu is special. In normal
case it contains id's of checked items. However, when menu has B<res>
set and you press enter on item without I<checked> attribute,
result of menu is id of selected item. There is also additional
attribute for <B<menu>>: I<checked> - it contains whitespace separated
list of items that should be selected. When item is listed there
it is marked as checked, if it's not, and has checked=1 -- it's
checked nevertheless.

I<group> attribute can be used along with I<checked> to make 
radio-button group. When item belonging to named group is checked
all other items in that group are unchecked.

When I<ghosted> attribute is set to B<1>, item cannot be selected.
When I<nohl> attribute is set to B<1>, _ sequences are not interpreted.

Attributes: B<id>, B<width> -- defaults to widest entry, B<height> --
defaults to 8 or number of entries, whichever is smaller, B<res> --
menus can be assigned modal results, just like buttons, window is closed
when Enter is pressed inside the menu, B<selected> -- id of preselected
item, by default first one is selected.

=back

=head1 FILESELECTORS

If you need user to enter some path, it's nice to allow him
to choose from whatever she has on his disk. So you add additional
attribute to your <B<input>> tag: B<fs>. It should be set to
string of letters, which describe which types of files can be selected.

=over

=item * B<d> -- directories

=item * B<b> -- broken (non-existing) files

=item * B<r> -- regular files

=item * B<v> -- devices

=item * B<o> -- other files (fifos, sockets etc)

=item * B<a> -- all files, equivalent to 'B<dbrvo>'

=back

You can also pass B<title> attribute to <B<input>> tag to specify
title of fileselector window, and B<label> to set caption
of button (which defaults to '_...'). Example:

 <input id=dir title='Choose dir' fs=d label='_Search'>

=head1 POPUP MENUS

Similarly to file selectors, since 0.0.17 it is possible to provide
list of predefined strings for input box, and present it in form
of menu. To do that you need to add B<menu> attribute to <B<input ...>>.
Its value should be B<id> of some menu with B<hidden> attribute set
to 1. B<title> and B<label> has the same meaning as with file selectors.

=head1 NLS

There is no NLS support in dml anymore. You can use $(gettext ...).

=head1 FILES

=over

=item /etc/dml.conf 

Color definitions overriding default colors

Example:

    pi_color_window white red
    pi_color_button cyan black

For full list of available options and colors, refer to source code
(file slang.c)


=head1 BUGS

Well, possibly lot of undetected...

While '_' highlights next character in button caption and menus, 
it has no practical meaning -- it should be used for shortcuts.

=head1 LICENSE

This program is distributed under the terms of GNU General Public 
License, version 2.

=head1 AUTHOR

Michal Moskal <malekith@pld-linux.org>

=head1 CONTACT

Please send comments, bug reports, etc to the author.

=head1 SEE ALSO

B<sh(1)>, B<dialog(1)>

=cut
