home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.lang.perl
- Path: cis.ohio-state.edu!zaphod.mps.ohio-state.edu!qt.cs.utexas.edu!cs.utexas.edu!uunet!snorkelwacker.mit.edu!bloom-picayune.mit.edu!math.mit.edu!drw
- From: drw@kronecker.mit.edu (Dale R. Worley)
- Subject: Forms-oriented input system, documentation
- Message-ID: <DRW.92Apr14115354@kronecker.mit.edu>
- Sender: news@athena.mit.edu (News system)
- Nntp-Posting-Host: kronecker.mit.edu
- Organization: MIT Dept. of Tetrapilotomy, Cambridge, MA, USA
- Date: Tue, 14 Apr 1992 16:53:54 GMT
- Lines: 578
-
- Forms system
- version 1.0
- Design
-
- 1. Form
-
- A "form" consists of a sequence of "fields". Each field contains the
- information necessary to display and input one value.
-
- 2. Input commands
-
- At any time, form input is either editing the value of a particular field
- ("in a field"), or it is transitting between fields ("out of a field").
- Entry into a field is done only when a command is executed which would change
- the value of the field; bringing the cursor to rest on a particular field is
- not sufficient to enter the field. Conversely, exiting a field is done only
- when some command is executed which would transit to another field, or exit
- the form entirely. However, exiting a field causes its value to be checked
- for validity, and if the validity check fails, the command that caused exiting
- of the field is not performed.
-
- The commands which are executed out of a field are:
-
- LFD accept contents of form
- (also C-j)
- C-c abort the form
- (exits the current field, if any, with C-y, and thus never
- fails)
- RET go to next field
- TAB go to previous field
-
- The commands which are executed in a field are:
-
- C-y restore previous value of the field and exit from field
- (bypasses validity check on previous value)
- C-v perform validity check on field
- C-v C-v exit from field, if it is valid
-
- C-u clear field
- C-k clear to end of field
- C-r clear to beginning of field
-
- C-a go to beginning of field
- C-e go to end of field
-
- C-b go back one character
- C-f go forward one character
-
- C-d delete next character
- DEL delete previous character
- (also C-h)
-
- The help commands are:
-
- C-p give help on current field
- C-p C-p show help screen describing all commands
-
- The help command (C-p) gives help on the field the cursor is in
- (whether or not it has been entered) by displaying its help_message
- attribute value in the field named MSG. However, if there is no such
- attribute or no field named MSG, or if there is no current field
- (because no visible field is writeable), it behaves like C-p C-p.
-
- In addition, all printing characters (SPC through ~) are commands to insert
- the character into the field value. Note, however, that the exact meaning
- of the in-field commands is determined by the field definition.
-
- The function keys can also be used as commands. See the section
- titled "function keys".
-
- 3. Attributes
-
- Each field is described by a set of "attributes". A form is stored in
- an associative array, and the attributes of the fields are stored in
- elements of the associative array: The value of the attribute $attr of
- field $field in form $form is stored in $form{$field,$attr}. Certain
- attributes are used by the forms system as a whole, and are stored with
- the null string as field name.
-
- The forms system reserves the package name "forms" for its data and
- subroutines. In addition, the package "forms_user" is used for storing
- code and data used by user-written routines. Names of the form
- "forms_generated_0000" are generated by the forms system, and so should
- be avoided, both in the two packages and as field names.
-
- 4. Values
-
- A value is represented in three distinct ways. While this may seem
- excessively complicated, it appears to be the only general framework
- that handles the myriad possible ways of displaying and inputting field
- values in a reasonably extensible way. The forms of a value are:
-
- Attribute "value": The actual value of the field, considered the output
- of the form when it is successfully executed, and the input, when the
- fields are pre-loaded before the form is executed. This value can be
- any Perl value that can be stored in a scalar.
-
- Attribute "displayed_value": The field, interpreted as a set of
- characters. For example, if the value is to be a number, the displayed
- value may be a character representation of the number. In addition, if,
- say, -1 is a special value of the number, the displayed value may code
- it as a particular character string, say, "Unknown".
-
- Attribute "displayed_field": The field, as displayed on the screen.
- This attribute is always exactly as long as the field length (attribute
- "field"length"), and is what is displayed on the screen.
-
- The translation between these forms is as follows:
-
- The translation value -> displayed_value is done by the function stored
- in attribute construct_displayed_value. It is called with two
- arguments, the field name and the value, and returns the displayed
- value.
-
- The translation displayed_value -> displayed_field is done by the
- function stored in attribute initialize_displayed_field. It is called
- with two arguments, the field name and the displayed value, and
- returns the displayed_field. In addition, it sets the variable
- $forms'cursor_location to the correct initial location of the cursor.
- (Cursor locations are relative to the beginning of the field, which is
- location 0.) This function is always called upon entry to a field,
- thus it may set additional attributes for the field for the user of
- the editing functions for the field.
-
- The displayed value and displayed field are both edited by the
- function stored in attributes "edit" and "insert". They are called
- with two arguments, the field name and the character typed. The
- character is either a printing character (in which case "insert" is
- called) or a non-printing character that is not one of the out-field
- input command characters listed above (in which case "edit" is
- called). The functions are responsible for updating the displayed
- value, the displayed field, and $forms'cursor_location appropriately,
- and must also report erroneous input characters.
-
- When the field is exited, two further attribute functions are called:
- The attribute "validate_displayed_value" is called with two arguments,
- the field name and the displayed value. It returns true if the value of
- the field is considered valid, and false if it is not. If it returns
- false, exit from the field is blocked. If it returns true, the function
- stored in attribute "interpret_displayed_value" is called with the field
- name and the displayed value as arguments. It returns the value. Since
- interpret_displayed_value is always called immediately after a
- successful call to validate_displayed_value, the latter may set global
- variables for the former. (This is the only circumstance where user
- functions can safely set its own global variables.)
-
- 5. Formatting attributes
-
- Attribute "label": The text of the label to be applied to the field.
-
- Attribute "label_location": Two numbers, seperated by commas, giving the
- location of the first character of the label. (Locations are always given
- in the order "row,column", both of which are 0-origin, with the 0 row being
- the top row and the 0 column the leftmost column.)
-
- Attribute "field_length": The number of characters to be allocated to
- the field. If this attribute is undefined or 0, the field has no
- input area, and only its label is relevant.
-
- Attribute "field_location": The location of the field.
-
- Attribute "read_only": If true, the field may not be entered in. The
- RET and TAB commands skip over the field.
-
- Attribute "invisible": If true, the field and its label are not displayed
- and cannot be altered.
-
- Attribute "initially_invisible": Set from attribute "invisible" when
- the form array is constructed, and used to restore attribute "invisible".
-
- Attribute "canonicalize": If true, when the field is exited, the value
- that was created is used to re-calculate the displayed value and the
- displayed field.
-
- Attribute "help_message": Displayed by the C-p command when the cursor
- is in the field.
-
- In addition, there are several attributes that apply to the form as a whole:
-
- Attribute "fields": A comma-separated list of the field names, in
- their natural order. A field's position in the natural order is
- determined by the location in which it was first given an attribute.
- RET cycles through the fields in the natural order, and TAB cycles
- through them in the reverse of the natural order.
-
- Attribute "initialize": A function to be executed once the form is set up
- but before any forms processing is performed.
-
- Attribute "finalize": A function to be executed when the form is accepted
- with LFD. If it returns false, the accept is rejected.
-
- Attribute "forms_version": This attribute declares that the form
- structure conforms to a particular version of the forms package, and
- all upward-compatible extensions of it. If provided, the forms system
- checks that it is capable of processing the given version of the forms
- structure. This document describes version 1.0.
-
- The field MSG is used to display help messages for fields (via the C-p
- command and the help_message attribute) and other messages (via the
- report_error and report_message functions). If it is not present,
- these messages are not displayed.
-
- 6. Manipulating other fields
-
- The edit_field function or other functions of a field may need to alter
- the value or visibility of a field. If it does so, it should call the
- appropriate function:
-
- $forms'changed_value($field) is used to signal that the value attribute of
- the given field has been changed, and the displayed value and displayed
- field should be updated.
-
- $forms'changed_visibility($field) is used to signal that the invisible
- attribute of the given field has been changed, and the screen should
- be updated appropriately. (It should not be called if the invisible
- attribute has not been changed, unless the user makes sure that no
- overlapping fields are visible.) The user is responsible for making
- sure that the fields that are visible at a given moment do not
- overlap. If a field that is being made invisible and a field that is
- being made visible overlap, the user should be sure to make the one
- field invisible before making the other field visible.
-
- 7. Input representation
-
- A form can be represented as a sequence of lines of text, or more
- exactly, as an array of strings. (Ending linefeeds on the strings are
- ignored.) The representation gives the values of the attributes in a
- straightforward way:
-
- field.attribute = value
-
- Whitespace around the field and attribute names and the "=" are ignored;
- leading and trailing whitespace around the value is also ignored.
- Lines that are entirely whitespace, or whose first non-whitespace character
- is "#" are ignored.
-
- Attributes of the form as a whole are set in the expected manner:
-
- .attribute = value
-
- A line of the form
-
- field:
-
- is used to provide a default field name for succeeding attributes. The
- default field name is invoked by omitting the "field." part of the
- attribute setting line:
-
- user_name:
- field_location = 2,5
- field_length = 8
-
- A line of the form
-
- :
-
- provides a generated field name as the default field name. It is most often
- used for fields that have labels but no value.
-
- Values are usually interpreted as character strings. However, certain
- values are interpreted differently:
-
- &name
-
- This value is interpreted as "*forms_user'name", which is the correct
- way to represent functions as attributes.
-
- &package'name
-
- This value is interpreted as "*package'name".
-
- @name
-
- This value is interpreted as "*forms'name". (More exactly, the three
- above forms are evaluated directly, after replacing the first
- character with "*". If the first character is "&", it is evaluated in
- package forms_user; if it is "@", it is evaluated in package forms.
- Thus, "&" is used for functions defined by the user, and "@" is used
- for functions supplied by forms.
-
- * expression
-
- This value is interpreted by evaluating "expression", in the package
- forms_user.
-
- "text"
-
- This value is interpreted as "text", allowing characters that would
- otherwise be interpreted specially.
-
- field.attribute = {
- text
- };
-
- This value is used to construct a subroutine in the forms_user package.
- The value itself is interpreted as "*forms_user'<subroutine_name>".
- The text of the subroutine is terminated by a line consisting of "};",
- possibly with leading and trailing whitespace.
-
- Interspersed with the attribute values can be sets of lines with the format
-
- sub name {
- text
- };
-
- These forms are used to define subroutines. They are evaluated in the
- forms_user package.
-
- In addition, there can be lines with the format
-
- * expression
-
- The expression is evaluated in the package forms_user.
-
- Note that "* expression" constructions and subroutines defined in the
- forms description are evaluated in the order that they are in the
- forms description, at the time that the representation is processed by
- &forms'process_representation.
-
- The input representation of a form is transformed into an array with
- the function:
-
- &forms'process_representation(*array, @representation)
-
- where the form attributes will be stored in the associative array %array,
- and the representation is taken from @representation. The function returns
- true if no error is found and false if an error was found. The error message
- is stored in $forms'error.
-
- The function can be used to process input representations from files:
-
- &forms'process_representation(*array, <FILE>);
-
- and from here-documents:
-
- &forms'process_representation(*array, split(/\n/, <<'EOF'))
- text...
- EOF
-
- If the input representation is in a file, a more convenient form can be used:
-
- &forms'process_representation_from_file(*array, $file_name, $inc)
-
- This function reads the representation from the given file and processes it.
- In addition, if $inc is true, @INC is searched for $file_name, just as require
- does. If the file does not exist, the function aborts execution.
-
- These functions set certain attributes in addition to those that are mentioned
- in the input representation: "initially_invisible" is set from "invisible",
- and "fields" is set to be the list of fields in the form.
-
- 8. Processing forms
-
- Several functions are used to process forms:
-
- &forms'clear_values(*array)
-
- This function clears (sets to undef) all of the value attributes of the given
- form. It is used to clear a form in preparation for further input.
-
- &forms'clear_values_and_redisplay
-
- This function is used during forms input to clear all of the value
- attributes and force redisplay of all the fields (via
- &forms'changed_value).
-
- &forms'reset_visibility(*array)
-
- This function sets the invisible attributes from the initially_invisible
- attributes.
-
- &forms'process_form(*array)
-
- This form displays the given form and gets the user's input. Initially
- displayed values are obtained from the value attributes of the form, and
- the returned values are returned in the value attributes. The function
- returns true if the form as accepted and false if it was aborted. During
- execution of the form, %forms'form is aliased to %array. &forms'process_form
- is not intended to be executed recursively.
-
- &forms'dump_form(*array, filehandle)
-
- Prints out all of the attributes in a form. If filehandle is omitted,
- STDOUT is used.
-
- 9. Service routines
-
- &forms'report_message(text)
-
- is used to display a message in the field named MSG (if there is one).
-
- &forms'report_error(text)
-
- is used to display an error message in the MSG field. (It performs a
- report_message and then rings the bell.)
-
- 10. Function keys
-
- The function keys can be used as commands if they are defined by a
- form. Function keys are typed as:
-
- ESC
- single optional 'O' or '['
- zero or more characters in the range '!' to '?'
- one character '@' or greater
-
- (This should probably be changed to a more flexible system.) They are
- translated into function key identifications (F1 through F10) by the
- table %forms'function_key. The function key identifications for F1 to
- F9 are loaded from the 'k1' through 'k9' capabilities from the termcap
- entry, and the F10 identification is taken from the 'k;' capability
- (or if it is not present, the 'k0' capability). In addition, several
- standard function key codes are loaded:
-
- Key Sun Sun VT100 Manual typing Termcap
-
- F1 \e[224z \e[11~ \eOP \e1f \e1F k1
- F2 \e[225z \e[12~ \eOQ \e2f \e2F k2
- F3 \e[226z \e[13~ \eOR \e3f \e3F k3
- F4 \e[227z \e[14~ \eOS \e4f \e4F k4
- F5 \e[228z \e[15~ \e5f \e5F k5
- F6 \e[229z \e[17~ \e6f \e6F k6
- F7 \e[230z \e[18~ \e7f \e7F k7
- F8 \e[231z \e[19~ \e8f \e8F k8
- F9 \e[232z \e[20~ \e9f \e9F k9
- F10 \e[-1z \e[21~ \e0f \e0F k; or k0
- \e10f \e10F
-
- A function key is considered "local" if the cursor is sitting in a
- field and that field has an attribute "F1" (or whatever). A function
- key is considered "global" if it is not local and there is a global
- attribute "F1" (or whatever). Escape sequences that are neither local
- nor global produce an error message. If a local function key is
- given, the field is enterd (if it has not been) and the function named
- by the attribute is executed. If a global function key is given, the
- field is exited (if it has not been) and the function named by the
- attribute is executed.
-
- 11. Problem with curseperl
-
- Curseperl has an ugly problem. The following program does not do what
- is expected (clear the screen) when $ARGV[0] is true:
-
- $ENV{'TERM'} = 'vt100';
- &initscr;
- if ($ARGV[0]) {
- &getcap('k1');
- &getcap('k2');
- &getcap('k3');
- &getcap('k4');
- }
-
- &clear;
- &refresh;
- &getch;
-
- (This is using BSD curseperl on a Sun4 with SunOS 4.1.1)
-
- getcap is just a wrapper for termcap's tgetstr, *using a fixed
- internal buffer to collect the results from tgetstr*. It appears that
- this internal buffer has a finite size, and each successive return
- value is written after the previous one, so if you do a few too many
- getcap's, you write off the end of the buffer...
-
- A solution which appears to work is to change the interface for
- &getcap to call tgetstr directly, but to supply a new buffer each
- time. The patch for this is follows. It is necessary to install this
- patch, because forms.pl uses getcap() when it is loaded. If this
- patch can't be installed, you have to comment out the calls to
- &'getcap in subroutine load_function_keys. This may disable the
- function keys defined in the termcap entry for the user's terminal.
-
- *** bsdcurses.mus.old Thu Apr 9 16:40:41 1992
- --- bsdcurses.mus Thu Apr 9 16:41:18 1992
- ***************
- *** 476,484 ****
- CASE int erasechar
- END
-
- ! CASE char* getcap
- ! I char* str
- ! END
-
- case US_getyx:
- if (items != 3)
- --- 476,493 ----
- CASE int erasechar
- END
-
- ! case US_getcap:
- ! if (items != 1)
- ! fatal("Usage: &getcap($str)");
- ! else {
- ! char* retval;
- ! char* str = (char*) str_get(st[1]);
- ! char output[50], *outputp = output;
- !
- ! retval = tgetstr(str, &outputp);
- ! str_set(st[0], (char*) retval);
- ! }
- ! return sp;
-
- case US_getyx:
- if (items != 3)
-
- 12. Standard field types
-
- The forms system contains routines for inputting various standard
- field types.
-
- - Ordinary text fields
-
- Ordinary text fields can be implemented with the attributes:
-
- construct_displayed_value = @char_field
- initialize_displayed_field = @id_cursor_after
- validate_displayed_value = @true
- interpret_displayed_value = @trim_trailing_space
- insert = @text_insert
- edit = @text_edit
-
- When the field is entered, the cursor is placed after the first
- non-blank character of the value. When the field is exited, the
- contents of the field have trailing spaces removed, and the remainder
- is the field vbalue.
-
- - Hidden text fields
-
- Hidden text fields are just like ordinary text fields, except that the
- field value is not displayed -- the characters of the value (up to the
- last non-blank character) are displayed as periods ("."). Hidden text
- fields are good for inputting passwords and similar things. They can
- be implemented with the attributes:
-
- construct_displayed_value = @char_field
- initialize_displayed_field = @id_cursor_after_hidden
- validate_displayed_value = @true
- interpret_displayed_value = @trim_trailing_space
- insert = @text_insert_hidden
- edit = @text_edit_hidden
-
- - Enumerated fields
-
- Enumerated fields allow one of a set of values to be selected. Each
- value is represented by one of a set of "representations", which are
- what is displayed to the user and what the user types in the field to
- specify a value. The set of permissible values and their
- representations are specified by the attribute "translate_table",
- which is a list of items of the form "representation=value", separated
- by backslashes ("\"). The representations and values are searched for
- in translate_table, so they may not contain backslashes or equal
- signs. In addition, representations are recognized
- case-insensitively, while values are represented case-sensitively.
- When a value is translated to a representation, the first
- representation listed is chosen. A value that does not have a
- representation should not be present. A representation that does not
- have a value will be rejected as invalid. An example of an enumerated
- field with the translation table
-
- Value Representation
- 1 Yes (preferred representation)
- 1 Y
- 0 No (preferred representation)
- 0 N
-
- is constructed by:
-
- construct_displayed_value = @enum_field
- initialize_displayed_field = @id_cursor_after
- validate_displayed_value = @enum_validate
- interpret_displayed_value = @enum_interpret
- translate_table = Yes=1\Y=1\No=0\N=0\=0
- insert = @text_insert
- edit = @text_edit
- canonicalize = 1
-
- In this case, "canonicalize" is set, so that upon field exit the
- value is displayed in the preferred representation.
-
-