  The Kaptain Handbook
  Terk Zsolt tz124@hszk.bme.hu
  Version 0.6 , Wed Mar 28 2001

  This Handbook describes Kaptain Version 0.6
  ______________________________________________________________________

  Table of Contents


  1. Introduction

     1.1 Changes
        1.1.1 Changes 0.51 {[rarr  ]} 0.6
        1.1.2 Changes 0.5 {[rarr  ]} 0.51
        1.1.3 Changes 0.4 {[rarr  ]} 0.5
        1.1.4 Changes 0.3 {[rarr  ]} 0.4
        1.1.5 Changes 0.2 {[rarr  ]} 0.3
        1.1.6 Changes 0.1 {[rarr  ]} 0.2
        1.1.7 Changes 0.1
        1.1.8 Updating old grammars for 0.2 -> 0.3 changes

  2. Installation

     2.1 How to obtain Kaptain
     2.2 Requirements
     2.3 Compilation and installation
     2.4 Bugs

  3. Usage

     3.1 General Usage

  4. Kaptain grammars

     4.1 About grammar rules
     4.2 Quoted strings
     4.3 Specials
     4.4 How the dialog is built
     4.5 Modifiers
     4.6 Text appearing in the dialog
     4.7 Dirty tricks
        4.7.1 Multiple nonterminals
        4.7.2 Grammatical constraints
     4.8 Example grammars
        4.8.1 Sound recording
        4.8.2 Creating archives
        4.8.3 Calling perl

  5. Questions and Answers

  6. Copyright



  ______________________________________________________________________

  11..  IInnttrroodduuccttiioonn

  Kaptain is a universal graphical front-end based on context-free
  grammars.  The program kaptain reads a file containing grammatical
  rules for generating text.  It builds a dialog from the grammar and
  generates the text according to the user's settings.



  11..11..  CChhaannggeess


  11..11..11..  CChhaannggeess 00..5511 {{[[rraarrrr  ]]}} 00..66


  +o  :reverse works with :tabbed

  +o  string initial value for list- and comboboxes


  11..11..22..  CChhaannggeess 00..55 {{[[rraarrrr  ]]}} 00..5511


  +o  bug in Makefiles corrected

  +o  directroy structure fixed: now /usr/bin is default, grammars go to
     /usr/share/grammars


  11..11..33..  CChhaannggeess 00..44 {{[[rraarrrr  ]]}} 00..55


  +o  some new special symbols

  +o  new modifier :tree to create Control Center like front-ends - very
     interesting

  +o  Kaptain has moved to sourceforge.net


  11..11..44..  CChhaannggeess 00..33 {{[[rraarrrr  ]]}} 00..44


  +o  compiles if only Qt2 is present

  +o  bug fixes

  +o  many extensions

  +o  grammatical constraints

  See file NEWS for detailed description

  11..11..55..  CChhaannggeess 00..22 {{[[rraarrrr  ]]}} 00..33


  +o  based on Qt 2.1 and KDE 2

  +o  flexible grammar rules

  +o  new widgets

  +o  the ability of fetching other programs' output for quoed text (like
     backquotes in the shell)

  +o  better layout management, multitab dialogs and subdialogs

  +o  tooltip and whatsthis support

  +o  utf-8 encoding for unicode support

  +o  small changes in grammar syntax

  +o  the ability to execute different commands from the same dialogs

  +o  ...

  11..11..66..  CChhaannggeess 00..11 {{[[rraarrrr  ]]}} 00..22


  +o  grammar interpreter completely rewritten with Lex {[amp   ]} Yacc

  +o  QLayout usage for widget arrangement


  11..11..77..  CChhaannggeess 00..11

  This was the first version:

  +o  grammar interpreter with Lex

  +o  heuristic widget arrangement


  11..11..88..  UUppddaattiinngg oolldd ggrraammmmaarrss ffoorr 00..22 -->> 00..33 cchhaannggeess

  The syntax of grammars changed a bit, sorry for that. It's very easy
  to update your old grammars.

  +o  Change {[lcub  ]} and {[rcub  ]} braces to double quotes
     everywhere.

  +o  Replace .. to ,

  +o  Extend the start rule to create the Ok and Cancel buttons:

     start "Title" -> command buttonbar ;
     buttonbar :horizontal -> @action(command)="Ok" @close="Cancel;

     command -> <the old start rule> ;
     ...




  22..  IInnssttaallllaattiioonn


  22..11..  HHooww ttoo oobbttaaiinn KKaappttaaiinn

  The primary web site for Kaptain is {urlnam}
  <http://kaptain.sourceforge.net>.  You can download the latest
  version, documentation and Kaptain grammars there.



  22..22..  RReeqquuiirreemmeennttss

  Kaptain is based on Qt 2.1 and KDE 2. However, it can be compiled
  without the KDE libraries.


  22..33..  CCoommppiillaattiioonn aanndd iinnssttaallllaattiioonn


  In order to compile and install Kaptain on your system, type the
  following in the base directory of the Kaptain distribution:




  % ./configure
  % make
  % make install





  If you don't have kdelibs installed, run ./configure --disable-kde.
  This should work if the QTDIR variable points to the base Qt
  directory. (or specify qt directory for the configure script by adding
  the parameter --with-qt-dir=/usr/lib/qt2 or wherever you installed
  qt2)


  Since Kaptain uses

  autoconf


  compiling it.  Should you run into problems please report them to the
  the author Terk Zsolt


  22..44..  BBuuggss

  Something's wrong with :wizard. Fixed; it was because MOC doesn't care
  about preprocessor directives.



  33..  UUssaaggee


  33..11..  GGeenneerraall UUssaaggee

  Kaptain must read the grammar to show up the dialog.  You can either
  specify the file containing grammatical rules or write it to the
  standard input.  For example



       % kaptain example.kaptain





  On the other hand, if the Kaptain grammar example contains the comment


       #!/usr/bin/kaptain




  on the first line, and is executable, you simply type example at the
  prompt.


  If the first parameter is --test or -t,the program won't execute the
  generated command, just write it to the standard output. It is useful
  for test purpuses for grammar writers.

  Another flag is --verbose or -V, and it makes kaptain print out every
  rule it reads. You can check where the parser failed, if the grammar
  contains errors.

  If no input files are specified, Kaptain reads the grammar from the
  standard input.


  An other way to use kaptain is to start /usr/bin/kaptainshell, which
  shows up the grammars located in /usr/share/grammars and the user can
  choose from that list. Kaptainshell itself is a simple kaptain grammar
  script (in 241 bytes).


  44..  KKaappttaaiinn ggrraammmmaarrss

  Kaptain reads the file which contains the specification of a context
  free grammar.  The text generated by the grammar can be an executable
  command (or anything you can type at the shell prompt - pipes,
  scripts, ... - even multiline ones).  This grammar describes the
  format of the command line and Kaptain creates the graphical dialog
  from that grammar, and then generates the command according to the
  user's manipulation on the dialog.



  44..11..  AAbboouutt ggrraammmmaarr rruulleess

  Each grammar rule may contain tokens of the following types:

     nnoonntteerrmmiinnaallss
        Nonterminal symbol, which stands for a complex text. It must
        start with a letter, and may contain numbers inside.


     tteerrmmiinnaallss

        qquuoottaattiioonnss
           A quoted string which is fix text.

        ssppeecciiaallss
           Some special element for user input: always begin with @, for
           example @integer, @string, ...  These will be substituted the
           value the user sets in the dialog.


  Each rule describes the meaning of a nonterminal:


       start -> "My name is " name "." ;
       name -> @string ;




  Rules have a nonterminal on the left side, something on the right side
  of an arrow (->), and are followed by a semicolon (;)

  The start symbol is the top level nonterminal, it must be present.
  The way texts are generated is beggining with start, and substituting
  all nonterminals with the appropriate sequence of symbols. When there
  are no nonterminals, the specials are substituted according to the
  user input, and the generated text is ready.


  Rules may be non-deterministic:


  start -> "It is " weather " today. The temperature is " temp "." ;
  weather -> "sunny" | "raining" | how " cold." ;
  how -> "a little" | "very" | @ ;
  temp -> @integer ;




  That veritcal bar symbol ({[verbar]}) means one and only one of the
  separated partitions should generate the text. In this case, the user
  will choose whether it is raining or it is sunny, or just cold, and if
  cold then how. It can be "very cold","a little cold", or simply
  "cold".  So @ is an abbreviation for nothing :). He/she should also
  specify the temperature - @integer orders Kaptain to place a little
  spin box in the dialog. This symbol evaluates to the content of the
  spin box.


  Kaptain grammars mustn't contain recursive definitions. Implicit
  recursion is also forbidden, thus


       a -> b ;
       b -> c ;
       c -> a ;




  is invalid. (The reason is that these cannot form dialog elements the
  way Kaptain works.)


  44..22..  QQuuootteedd ssttrriinnggss

  Kaptain accepts quotations very similar to Perl.

        Escape sequences may be included: {[bsol  ]}n, {[bsol  ]}t,
        {[bsol  ]}{[quot  ]}, {[bsol  ]}{[bsol  ]} {[bsol  ]}$.  Shell
        environmental variables are substituted ( $ONLYCHARS and ${[lcub
        ]}any text in braces{[rcub  ]} ).

     'single'
        Literal string, cannot contain '

     q{[percnt]}text{[percnt]}
        ({[percnt]} can be replaced by any character except letters,
        numbers, underscore, hyphen and semicolon.) Literal string, no
        way to have the bounding character inside.

     `back quotes`
        A command, which is executed and the string is the standard
        output of that command. May not contain a backquote.

     x{[percnt]}command{[percnt]}
        ({[percnt]} can be replaced by any character except letters,
        numbers, underscore, hyphen and semicolon.) Literal string, no
        way to have the bounding character inside. The value is the
        output of the command.


  To make multi line quotations easy, captain accepts the following form




  ... <<ANYLABEL
  the
  literal
  text
  ANYLABEL






  44..33..  SSppeecciiaallss

  The format of a special is


       @name(param1, param2, ...)=initvalue




  where param1, param2, ... and initvalue can be either nonterminals,
  quoted strings or integer values.


  The following specials are available in the current release

     @integer
        An integer input from the user; you can specify valid range and
        inintial value if you like: @integer(-2,100)=4 means an integer
        between -2 and 100, initially 4. Either range or initial value
        can be omitted.


     @float
        Guess what it can be... Note that the initial value must be
        quoted! Ex.: @float="1.13".


     @string
        A text input field from the user; maximum length and initial
        value is optional: @string(15)="Hi, there!"


     @infile
        Input file.  A text input field and a button from the user; a
        FFiillee OOppeenn dialog will appear if the button is pressed.  Filter
        string and initial value are optional
        @infile("*.txt")="myfile.txt"


     @outfile
        The same as @infile, just with a SSaavvee aass dialog.


     @directory
        The same as above, just for choosing directory. No filter string
        is accepted, only initial value.  @directory="/home/joe"


     @list, @combo, @combow
        A simple listbox or combo box with elements from which the user
        should choose. @combow is read-write combo box, the others are
        read-only elements from the user's view.  The returned value is
        the selected string.  For example
        @list("cat","dog","lion","tiger").
        If any of the given strings is multiline (it contains newline
        character), it is split to form different elements in the list.
        Thus @list(`ls`); would execute the command ls which gives the
        list of files, each on a different line, and the list box will
        contain the name of the files in the current directory.

        The initial value, if it is integer _n, makes the _nth element to
        be selected. From 0.6 initial string value can be given. (Thanks
        to Luca Montecchiani {[lsqb  ]}m.luca@iname.com])


     @regexp
        A text input field controlled by a regular expression:
        @string("{[circ  ]}[ab]*$") only allows to type a and b letters
        in the field.


     @button
        A pushbutton which creates a new dialog when pressed. It accepts
        a nonterminal symbol as a parameter, which will form the dialog.
        The initial value is the text on the button.
        Ex.:@button(newdialog)="Settings...".  @button is deprecated,
        use :dialog modifier instead. The argument is that it doesn't
        express the relation between grammatical symbols correctly.


     @close
        A button to close the current dialog. Closing the main dialog
        means exiting kaptain.

     @action
        A button for executing a command. If only a nonterminal is given
        as a parameter, it is evaluated and passed to the shell for
        execution. If several parameters are given (either quoted
        strings and nonterminals), the first one is considered to be a
        program and the others the parameters. For example
        @action(start) would evaluate the start symbol and execute it
        through the shell (usually bash). It is equivalent to
        @action("bash","-c",start). Another possibility is to use
        @action("perl","-e",start) to execute perl. In this case the
        text generated by the symbol start is meant to be perl code.

        During the command is executed, the push button is disabled.
        When child process finishes, it is enabled again.  To make
        Kaptain dialog disappear before executing command, use @exec.


     @exec
        Same as @action, but Kaptain quits immediately after starting
        the command.


     @container
        Accepts a nonterminal symbol as a parameter. It consists of a
        listbox and two buttons, Add and Remove. When Add is pressed, it
        evaluates the nonterminal and puts the text into the listbox.
        Remove removes the selected element from the listbox. It is
        useful when any number of arguments of the same type can be
        accepted (usually file names)


     @icon
        Given a file name parameter, it loads the graphic and shows it
        in the dialog. Has no effect in the generated text.  If Kaptain
        was compiled with kde support, it looks for the file in the kde
        standard icon directories. Otherwise, full paths have to be
        specified.

     @text
        Information for the user slightly sunken in a frame. The
        parameter can be multiline text. Has no effect in the generated
        text.

     @echo
        Similar to @action, but it just prints the text to the standard
        output, never executes it. Useful when Kaptain is part of a
        pipe.


           New features in 0.5:

     @execclose
        Behaves like @exec or @action but closes only the current
        subdialog (or the application, if it's about a top level
        dialog).

     @fork
        Similar to @exec or @action but Kaptain just forks and is going
        on.

     @dump
        Just like @echo but then quits.

     @execbuffer
        Parameters and initial value are like those of @action. Places a
        button which executes the given command and catches the standard
        output of the execution. After that, when it comes to text
        generation, it evaluates to the standard output of the command
        which has been executed when the button was pressed the last
        time.

     @password
        Similar to @string, but shows only *'s

     @preview
        A button which creates a subdialog. That contains the text
        generated from the nonterminal given as a parameter.  For
        example pressing the button made by @preview(start), you will
        see the generated text according to the current settings.

     @fill
        Inserts stretchable space.

  This list may improve in the future.




  44..44..  HHooww tthhee ddiiaalloogg iiss bbuuiilltt

  The fact is that the grammar itself contains enough information to
  build a user friendly dialog.  Each nonterminal is connected to an
  area in the window.


  For a conjunctive rule, like this


       start -> first second third ;



  the areas generated for first, second, third will be placed top-down.
  If you want them to be placed left to right, use the modifier :hori-
  zontal like this:


       start :horizontal -> first second third ;




  See next section for detailed information about modifiers.


  For a disjunctive rule, Kaptain places radio buttons for choosing from
  several possibilities. That is for


       start -> first | second | ! third | @;




  either first, second, third will appear in the dialog with a radio
  button, and user can choose exactly one.  That exclamation mark
  selects the default one. Modifiers are also avaiable just like above.

  Sometimes its better to have check boxes if two or three possibilities
  are avalable (tristate check boxes also exist).  Here


       a -> "yes" | "no" ;
       b -> "yes" | "maybe" | "no"




  either a and b represents a check box.

  Kaptain creates a standard check box if:

  +o  there are 2 possibilities

  +o  at least one of them is simple. That means it's epsilon (@), quoted
     string, or if a nonterminal, it evaluates to @ or quoation and it
     doesn't have a title.

     So to force Kaptain creating radio buttons for a double
     disjunction, write


       a -> yes | no;
       yes "Yes" -> "yes";
       no "No" -> "no";





  Kaptain creates a standard check box if:

  +o  there are 3 possibilities

  +o  the second and the third choice is simple

  Avoiding tristate check boxes can be done the with the same trick like
  above.
  If you place a ! to one of the choices, the check box will be selected
  according to it.



  44..55..  MMooddiiffiieerrss

  Modifiers always begin with a colon and are related to the nonterminal
  after which they appear.  For example:


       start :framed :horizontal -> a b c ;




  means that a, b and c are placed horizontally one by one, and each is
  in a frame.

  Modifiers usually have effect on the appearence of the dialog.

     :framed
        Makes the child widgets to appear in a frame.

     :tabbed
        Makes the child widgets to appear on different tabs.

     :horizontal
        Makes the child widgets to appear horizontal one by one, instead
        of the default vertical arrangement.

     :reverse
        Makes the child widgets to appear in reverse order. That is down
        to top if :horizontal is not present, otherwise right to left.

     :noeval
        The nonterminal will evaluate to an empty string. It is useful
        when you use a @string input field by a @container, and you want
        to have only those items which were inserted into the container.

     :double
        Place child elements in two rows or columns. It is useful when
        you have many radio buttons.

     :beside
        Place child elements immediately to the right of the label of
        this rule (if it's a radio button or check box), not below as by
        default.  Use it in the similar situations as this:  number
        :beside "Number" -> @integer {[verbar]} @ ;

     :dialog
        Create a pushbutton, which if pressed, makes a subdialog to
        appear with the right side of the rule.

     :wizard
        Create a pushbutton, which stands for a subdialog, having all
        the nonterminals from the right side as pages in a so called
        "Wizard" dialog ( with "Next", "Back", "Cancel" and "Finish"
        buttons). Must be a conjunctive rule.

  New modifiers in 0.5:

     :tree
        Places all children in a QListView object. If the children are
        also marked with :tree, they will appear on the secind level in
        the tree. Look at the example grammar for indent. This is a very
        good way to place a great amount of structured information in
        the dialog. Checkboxes and radio buttons can appear in the tree,
        but if other things are present, they will be placed under or
        beside the QListView object. Use it with :beside if you want to
        create things like KControlCenter.  If the label of the tree
        item is like "{[lcub  ]}icons/my.gif{[rcub  ]}Text", then the
        picture mentioned between the braces will be placed beside the
        Text - this can be very attractive.

     :detailed
        Together with :tree, it makes a second column appear in the
        TreeView where the tooltip information is placed.

  Notice that modifier :framed won't make the same nonterminal be in a
  frame, but all its children.  Look at the example grammars to see what
  I'm talking about.


  44..66..  TTeexxtt aappppeeaarriinngg iinn tthhee ddiiaalloogg

  The user won't see the names of the nonterminals or the text the
  grammar generates.  You must specify some comment for every
  nonterminal which would be on the screen.  The syntax is:


       start "The title" -> a | b | c ;
       a "Choice A" -> "--a";
       b "Choice B" -> "--b";
       c "Choice C" -> "--c";




  In this case the title of the dialog is "The title" and the radio but-
  tons have the labels "Choice A", "Choice B" and "Choice C". Without
  quotes, of course.


  To include more information, you can use tooltips and whatsthis.


       a "Choice A" "This is choice A" "When you choose A, ..." -> "--a";




  So the rule syntax is:


       <nonterminal> [<modifiers>] [<title> [<tooltip> [<whatsthis>]]]
         -> {<nonterminal> | <terminal> | <vertical bar> | @ | ! }* ;




  I'm in trouble when I try to describe some kind of grammar rules with
  grammar rules :-) Look at the examples.


  You can assign title, tooltip and whatsthis text to a nonterminal in a
  different place it is defined. If you had a rule


       nonterm -> a b c;


  insert the following anywhere below the rule:


       nonterm :horizontal = "Title" "ToolTip" "This is WhatsThis" ;




  This is useful because the grammar definition is separated from the
  description. You can also have multi line whatsthis:


       nonterm = "" "ToolTip" <<THEEND
       This is whatsthis.
       You can read many things here.

       Have a nice day!
       THEEND




  In this case, the title was empty, so if the nonterminal had a title,
  this would not overwrite it.


  44..77..  DDiirrttyy ttrriicckkss


  44..77..11..  MMuullttiippllee nnoonntteerrmmiinnaallss

  If a nonterminal symbol appears in the grammar several times on the
  right side, it is shown just for the first time.  This helps you to
  achive different placement in the dialog to the generated text. For
  example:


       start -> a b c d @exec(command)="OK" ;
       command -> b a d c ;
       a -> ...




  Thus command is executed, which combines the dialog elements in a dif-
  ferent order.

  Similarly, if symbol a appears twice on the same right side,


       start -> x " and " x ;
       x -> @integer=19;




  only one input field will be shown in the dialog, but the generated
  text will be 19 and 19.


  44..77..22..  GGrraammmmaattiiccaall ccoonnssttrraaiinnttss

  Suppose we have some text to generate, which might be enclosed in some
  kind of parentheses:


  start -> open "any text" close ;
  open -> "(" | "[" | "{" | "<" ;
  close -> ")" | "]" | "}" | ">" ;




  This leads to a dialog where you have to choose the opening and clos-
  ing symbol. This allows the user to generate strange things like (any
  text{[rcub  ]}. Kaptain makes it easy to avoid this: after the rules
  just say


       close <- open ;




  which is a constraint for two disjunctive rules with the same number
  of choices on the right. This means the choice for close depends on
  the choice of open. If the _n_t_h possibility is choosen for open, then
  close will also evaluate to the _n_t_h disjunction. Thus only one radio
  button group is needed.


  _T_h_i_s _f_e_a_t_u_r_e _a_l_l_o_w_s _t_h_e _g_r_a_m_m_a_r _t_o _e_f_f_e_c_t _o_n _d_i_f_f_e_r_e_n_t _p_a_r_t_s _o_f _t_h_e
  _g_e_n_e_r_a_t_e_d _t_e_x_t_. _I_t _s_o_m_e_h_o_w _m_e_a_n_s _m_u_c_h _p_o_w_e_r _t_h_a_n _t_h_a_t _o_f _c_o_n_t_e_x_t_-_f_r_e_e
  _g_r_a_m_m_a_r_s_.






  44..88..  EExxaammppllee ggrraammmmaarrss

  _I_f _y_o_u _w_r_i_t_e _y_o_u_r _o_w_n _g_r_a_m_m_a_r_s_, _a_n_d _y_o_u _t_h_i_n_k _t_h_e_y _m_i_g_h_t _b_e _u_s_e_f_u_l _f_o_r
  _o_t_h_e_r_s_, _p_l_e_a_s_e _s_e_n_d _t_h_e_m _t_o _m_e _t_z_1_2_4_@_h_s_z_k_._b_m_e_._h_u_, _I _w_i_l_l _p_u_t _t_h_e_m _t_o
  _t_h_e _m_a_i_n _K_a_p_t_a_i_n _s_i_t_e_.


  44..88..11..  SSoouunndd rreeccoorrddiinngg

  Let's record from the microphone connected to the computer. The
  executable command is


       % dd count=5 bs=8 < /dev/audio > myfile.au




  It would be better to see a beautiful dialog. The grammar


       #!/usr/local/bin/kaptain
       start:framed -> "dd count=" count " bs=" size "k <" input " > " output ;
       count "Number of blocks" -> @integer=5 ;
       size "Size of blocks (k)" -> @integer=8 ;
       input "Input device" -> audio | dsp ;
       audio "Audio" -> "/dev/audio" ;
       dsp "DSP" -> "/dev/dsp" ;
       output "Output file" -> @outfile("*.au");



  44..88..22..  CCrreeaattiinngg aarrcchhiivveess

  Here is a simple grammar, just witten in 5 minutes (may contain
  errors, check before you try to use it!)


       #!/usr/bin/kaptn

       start "Tar" -> tar buttons;

       tar -> "tar " choice " " opt archive " " files;
       opt:framed :horizontal  -> extropt createopt ;

       createopt "Write options" -> dump remove verb comp;
       extropt "Read options" -> noerr keep same abs;

       dump "Dump files, not just symlinks" -> "--dereference " | @;

       noerr"Ignore failed read" -> "--ignore-failed-read " | @;

       keep "Keep existing files" -> "-k " | @;

       same "Extract all protection information" -> "-p " | @;

       abs "Absolute path names" -> "-P " | @;

       remove "Remove files after adding to archive" -> "--remove-files " | @;

       verb "Verbosely list files proceeded" -> "-v " | @;

       comp -> compress | @;
       compress "Compression" -> gzip | bzip;
       gzip "gzip" -> "-z ";
       bzip "bzip2" -> "--use-compress-program bzip2 ";

       choice:framed  -> work;
       work "Main choice" -> concat | ! create | diff | del | append | list | update | extract;
       concat "Append to archive" -> "A";
       create "Create archive" -> "c";
       diff "Find differences between archive and file system" -> "d";
       del "Delete from archive" -> "-delete";
       append "Append to the end of an archive" -> "r";
       list "List contents" -> "t";
       update "Update archive" -> "u";
       extract "Extract from archive" -> "x";

       archive "Archive name" -> @infile;

       files "Files to work with" -> @string ;

       buttons :horizontal -> @action(tar)="OK" @close="Cancel";















  44..88..33..  CCaalllliinngg ppeerrll

  Kaptain can generate various texts, such as complicated pipes or a
  piece of perl code.  To create your encrpyted password, use the perl
  command:


       print crypt('passwd','sa')."{[bsol  ]}n";




  Let's make the grammar:



       #!/usr/local/bin/kaptain
       start "Password encrypter" -> code @action("perl","-e",code)="Crypt";
       code:framed -> "print crypt('" passw "','" sa q%')."{[bsol  ]}n"% ;
       passw "Password" -> @string="notsimple";
       sa "Random chars(2)" -> @string(2)="y4";





  Notice that the @action has three parameters; the perl compiler is
  called without the shell, having two parameters: "-e" and the
  evaluated text of code;










  A complete example can be found here: {urlnam} <enscript.html>



  55..  QQuueessttiioonnss aanndd AAnnsswweerrss

  QQ:: I get "parse error". What to do?

  AA:: That means the grammar is syntactically not correct. The most
  frequent mistake is that semicolon is missing at the end of the rules.
  Try to run kaptain with --verbose switch, it will print out the parsed
  rules.  The last rule printed out is just before the rule containing
  the error.

  That means the next rule contains errors. Check if it is finished with
  a semicolon and for other syntaxical problems.  QQ:: How can I use
  recursive rules.

  AA:: Kaptain doesn't enable recursion in grammar. You can create
  repetition with the @container special symbol.



  66..  CCooppyyrriigghhtt



  Kaptain Copyright 2000 Terk Zsolt , tz124@hszk.bme.hu


  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or (at
  your option) any later version.

  This program is distributed in the hope that it will be useful, but
  WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.


















































