This is Info file edb.info, produced by Makeinfo-1.63 from the input file edb.texi.  File: edb.info, Node: How to specify delimited file layouts, Next: Resolving ambiguities, Prev: Delimited file layout, Up: Delimited file layout How to specify delimited file layouts ------------------------------------- In a database stored in delimited file layout, records and fields can be separated by particular strings, by regular expressions, by context-sensitive regular expressions, or by arbitrary functions. The sepinfo structure holds this information for use when reading the database from disk (and writing it back). The sepinfos used when reading a database are stored in its `record-sepinfo' and `field-sepinfo' slots (for more details about the database structure, *note The database structure::.). When reading, if a separation function is specified, it is used; otherwise, if a regular expression is specified, it is used; otherwise, a string must be specified. It is converted into a regular expression, the regular expression slots of the sepinfo are filled in, and reading proceeds as if you had specified a regular expression. (To have a regular expression recomputed when it is next needed, set it to `nil' when setting the corresponding string value.) When a sepinfo is used for writing, it must specify literal string separators. (The sepinfo may have its separation function or regular expressions set as well, for reading, but those slots are ignored when writing.) * Menu: * The sepinfo structure:: The sepinfo structure * Sepinfo examples:: Record and field separator examples  File: edb.info, Node: The sepinfo structure, Next: Sepinfo examples, Prev: How to specify delimited file layouts, Up: How to specify delimited file layouts The sepinfo structure ..................... The sepinfo structure contains the information required to decide where records or fields start and end (actually, to determine where the record or field separators start and end; "sepinfo" is short for "separator information"). The slots of this structure may be accessed by using the macro `sepinfo-'SLOTNAME. The slots may be set using the macro `sepinfo-set-'SLOTNAME, whose second argument is the value to be stored in the slot. The `pre-first-' slots describe text that precedes the first item of interest. In a record sepinfo they describe the file header, which precedes the first record. In a field sepinfo they describe any information that preceded the first field of every record, after the record separator. The `post-last-' slots are similar, but are used to inform EDB of text following the last information-carrying text. In a record sepinfo, they describe the file trailer, which follows the last record in the file. A field sepinfo's `post-last-' slots tell about information following the last field of a record but preceding the record separator. The `-submatch' integers describe which submatch of a regexp match is the actual separator, as opposed to surrounding text used to help make the match unambiguous. This specification of the submatch permits context-sensitive matching that you might otherwise expect could not be done with regular expressions alone. For instance, suppose a database has records with a variable number of fields separated by newlines, that records are also separated by newlines, and that the first field of each record has some special form different from all other fields (say, it is a number with a decimal part). The following code would permit separation of the records without writing a special function to do so and without including the decimal number in the separating text: (sepinfo-set-sep-regexp (database-record-sepinfo database) "\\(\n\\)[0-9]+\\.[0-9]+") (sepinfo-set-sep-regexp-submatch (database-record-sepinfo database) 1) When you set the slots of the sepinfo, be careful to use a correct value. For instance, if your record separator is a form feed on a line by itself, you probably want to set the `sep-string' slot of the database's `record-sepinfo' to `"\f\n"', or possibly `"\n\f\n"', rather than just `"\f"', lest the newlines be considered to be part of the records rather than part of the separator. The slots of the sepinfo are listed below but are not described in detail; see the preceding description for details of their use. `pre-first-string' Setting the slot to `nil' (or not setting it) is equivalent to setting it to the empty string. `pre-first-regexp' `pre-first-regexp-submatch' `sep-string' `sep-regexp' `sep-regexp-submatch' `sep-function' A function that takes a buffer position, the end of the previous separator (that is, the start of the current record or field), as its argument and returns a pair of two buffer positions bracketing the next separator. That is, the returned values are the end of the current record or field and the beginning of the next one (or nil if there are no more). When the function is called, point is at the beginning of an item and the buffer is narrowed to the list being currently processed. The use of a separation function is useful when the separation criteria cannot be expressed as a combination of context-sensitive regular expressions. The `pre-first-' and `post-last-' slots are still used even if a function is specified. `post-last-string' Setting the slot to `nil' (or not setting it) is equivalent to setting it to the empty string. `post-last-regexp' `post-last-regexp-submatch'  File: edb.info, Node: Sepinfo examples, Prev: The sepinfo structure, Up: How to specify delimited file layouts Record and field separator examples ................................... [[[Put examples here.]]] [[[ For instance, to parse "[Mary, John,Jack, and Jill]" and to write it back out as "[Mary, John, Jack, Jill]", the following specification would suffice: pre-first-string "[" sep-string ", " sep-regexp ", +\\(and +\\)?" sep-regexp-submatch 0 post-last-string "]" ]]] [[[ The -string slots are used for writing; but what if you only have a regexp for the leading or trailing junk, but you want that restored exactly? You can set pre-first-string *after* the database file has been found. For instance, in db-before-read-hooks, use a function such as (defun btxdb:read-comments () (save-excursion (set-buffer db-buffer) (goto-char (point-min)) (if (search-forward "@" nil t) (sepinfo-set-pre-first-string (database-record-sepinfo database) (buffer-substring (point-min) (point)))))) or even put (sepinfo-set-post-last-string (database-record-sepinfo database) (save-excursion (set-buffer db-buffer) (goto-char (point-min)) (re-search-forward "\n\C-l\n") (buffer-substring (match-beginning 0) (point-max)))) as is in your auxiliary file. ]]] [[[ If all records have the same number of lines on disk, use the following function to return an appropriate sep-function. This is useful when, for instance, both the field separator and the record separator are the newline character. `make-n-line-sep-function' Return a sep-function useful when all records have exactly N lines on disk. ]]]  File: edb.info, Node: Resolving ambiguities, Next: Problems with end-of-file newlines, Prev: How to specify delimited file layouts, Up: Delimited file layout Resolving ambiguities --------------------- Substitution is a mechanism for dealing with the problem of distinguishing field and record separators from the contents of database records. For instance, if the newline character (actually, a string consisting of only the newline character) is used as a record separator, and records may contain multiline text fields (or other fields whose storage representation contains a newline), then how would EDB know, when reading the database back in, which newlines are record separators and which are part of fields? There are several ways to avoid this ambiguity. * Disallow the use in record fields of the character or string causing the ambiguity. For instance, in the example above, you might change the record field type of all of the string fields to one-line-string. * Change the separator(s) to strings that do not appear in the storage representation of any field. For instance, Unix password files are stored in delimited file layout with a colon as the field delimiter (and colons are prohibited from appearing in the field text). (sepinfo-set-sep-string (database-field-sepinfo database) ":") Strings containing non-printing characters are another good bet, but this method relies on luck and the hope that the chosen separators will never appear in data. * Change the representation of the ambiguous string, when it appears in data; this guarantees that whenever the string does appear in a database file, it stands for a separator. This scheme is called substitution, because another string is substituted for the ambiguous one when it appears in data. This is similar to the previous workaround, which changed the separators rather than the data-bearing instances of the string. Ambiguities are still possible, if the substituted text happens to appear elsewhere in data. Specifying a substitution is described below. * The simplest solution is to use EDB's internal file layout (*note Internal file layout::.). Ambiguities can only occur when the field data and the separators are both text to be interpreted by EDB. EDB's internal file layout uses Emacs Lisp's mechanisms (a built-in form of quoting) to ensure that what is read in is identical to what was written out. The database designer need not worry further about the problem. Substitution is the replacement of potentially ambiguous strings by other ones. For instance, when writing tab-separated text, each occurrence of the newline character in a field could be replaced by control-k when the database is written. Then, when the file is read in, every newline can be safely assumed to be a record separator. The final step is converting the control-k characters back into newlines. This approach is taken by some marketed databases; for instance, I believe that FileMaker does just this. The problem with this approach is that if there were any control-k characters in the text, then when the database is read back in, they will be (incorrectly) converted to newlines. EDB warns when the database is being written out if this problem could occur; you may choose a different substitution or abort the database write operation. It is usually possible to find a substitution--a character or sequence of characters that doesn't appear in the data. The database's substitutions slot is an association list of data strings and their file representations. To make control-k in the database file stand for newline in the data, put eval: (database-set-substitutions database '(("\n" . "\C-k"))) in the "Local Variables" section of your format file, or put the form without `eval:' in the auxiliary file.  File: edb.info, Node: Problems with end-of-file newlines, Prev: Resolving ambiguities, Up: Delimited file layout Problems with end-of-file newlines ---------------------------------- Suppose you want to get rid of every newline at the end of the database file, but you don't know how many there are. (sepinfo-set-post-last-regexp (database-record-sepinfo database) "\n*\\'") (sepinfo-set-post-last-regexp-submatch (database-record-sepinfo database) 0) does not work, because the post-last-record regexp is searched for backward from the end of the buffer, and (because of the way that `regexp-search-backward' is implemented) the backwards regexp match for `\n*' is always the empty string! The proper way to write this is (sepinfo-set-post-last-regexp (database-record-sepinfo database) "[^\n]\\(\n*\\'\\)") (sepinfo-set-post-last-regexp-submatch (database-record-sepinfo database) 1)  File: edb.info, Node: Tagged file layout, Next: Nonregular file layout, Prev: Delimited file layout, Up: Database file layout Tagged file layout ================== Another popular file layout supported by EDB is that of field values preceded by the fieldname. For instance, a record might be represented in the file by Where:Here When: Now What: This! which indicates a record in which the `where', `when', and `here' fields have the specified values. Tagged files are a special case of files in nonregular layout; support for them is implemented through the mechanisms described in *Note Nonregular file layout::. To read a database file in tagged format, call the function `db-tagged-setup' in the database's format or auxiliary file. Its argument specifies the names of the fields and the tags that precede them in the database file. `db-tagged-setup' Ready the database to read files in tagged format. Creates database local variables and sets database slots. Argument TAGGED-FIELD-SPECS is a list of tagged-field specifications, one for each field in a database record. Each tagged-field specification is a three-element list of the field name (a symbol), the tag used to identify it in the file (a string), and a brief help string. Instead of a symbol, the tagged-field name may be a cons of the field name and its type. To indicate that a field is never found in the input file (typically because it is computed on the fly), use `nil' for its tag. This function should be called first in an auxiliary or format file, so that the defaults it chooses can be overridden. `database-set-fieldnames-to-list' should not be called if this function is. Calling `db-tagged-setup' sets the database's field names and installs appropriate functions for reading and writing the database. It also creates some database-local variables (*note Local variables::.) which can be modified (by use of the `database-set-local' function) in order to customize the behavior of the parsing and output functions with respect to what characters can appear in a tag, what the separator between tag and value looks like, and how continuation lines are handled. By default, records are separated by blank lines, tags are separated from field values by `:', white space around the separator is not significant on input, the separator is followed by one tab on output, and continuation lines start with whitespace. `db-tagged-tag-chars' The characters that are allowed in field tags, in a form suitable for placing inside [] in a regular expression. `db-tagged-separator' The string that separates field names from values. Used only if `db-tagged-separator-regexp' or `db-tagged-separator-output' is `nil' (depending on whether the record is being read or written). `db-tagged-separator-regexp' A regexp for the separator between field names and values when parsing. `db-tagged-separator-output' The separator between field names and values on output. `db-tagged-continuation' The string that marks (the beginning of) a continuation line. Used only if `db-tagged-continuation-regexp' or `db-tagged-continuation-output' is `nil' (depending on whether the record is being read or written). `db-tagged-continuation-regexp' A regexp for a continuation line in a value when parsing. `db-tagged-continuation-output' The fixed string to use (before) continuing values on output. Other hooks permit arbitrary manipulations of records; for instance, if a database nearly conforms to the tagged file model, these can be used to customize the behavior of the existing tagged code. One way to do this is to have a function in `db-tagged-rrfr-hooks' remove the field from the file representation before the record is parsed, then have `db-tagged-wrfr-after-hooks' modify the automatically generated tagged file representation for that field. These functions can also be used for simpler tasks, of course. `db-tagged-rrfr-hooks' Hooks run on each database record before tagged parse. `db-tagged-wrfr-before-hooks' Hooks run before each tagged write of a database record. The record is bound to the dynamic variable record, and point is where the record will be inserted in the buffer. `db-tagged-wrfr-after-hooks' Hooks run after each tagged write of a database record. The record is bound to the dynamic variable record, and point is immediately after the file representation of the record.  File: edb.info, Node: Nonregular file layout, Next: Reading from disk, Prev: Tagged file layout, Up: Database file layout Nonregular file layout ====================== Unlike most databases, EDB can work with data stored in any file layout whatever--so long as you specify how the information is to be extracted. If the file layout is too complicated to be described by regular expressions describing the record and field separators and their context (*note Delimited file layout::.), then you may write Emacs Lisp code which extracts the information from the database file. The great advantage of this mechanism is that it permits you to maintain your current files, in exactly their current file layouts, and to keep the same tools and habits you've accumulated, but also to manipulate them in a structured way with EDB. For instance, you might wish to maintain the database file in a file format easy for people to read all the time, rather than having to create a report for that purpose. Three pieces of information must be provided: how to find the extent of a file record, how to read a file record, and how to write a file record. The third may be omitted if the database is only being read in the custom file layout (and will be saved in some more tractable file format). If the second is provided (that is, the `read-record-from-region' database slot is set), then the file will be assumed to be in a nonregular file layout and the value of that slot is used to read the database, no matter what other information is provided. Information about how to separate one record from another within the file is found in the `record-sepinfo' slot of the database, as usual. In many cases, even if the file layout of the data is nonregular, it is easiest to describe the record separator with a string or a regexp. For more details, see *Note Delimited file layout::. You may also set the sepinfo's `sep-function' slot to a function. The function should take one argument, the end of the previous record (`nil' the first time it's called), and return a pair whose car is the end of the current record and whose cdr is the start of the next record (`nil' if there is no next record in the file). The `read-record-from-region' slot of the database contains a function of no arguments which, when called with the current buffer narrowed to a single file record (that is, narrowed to the representation of a single database record), returns a record in the database's internal file layout. The variable `database' is dynamically bound to the current database, and so the right way to create the record to be returned is via `(make-record database)'. Its fields can then be set with `record-set-field'. The `write-region-from-record' slot of the database optionally contains a function which takes a database record as its argument and inserts the file representation of that record in the current buffer; the variable `database' is dynamically bound to the current database. If this slot is not specified (and slot `internal-file-layout-p' is `nil'), then the fieldsep and recordsep information, if present, is used to write the record (*note Delimited file layout::.). This permits the use of a simple, delimited output file layout with a more flexible input file layout. Tagged format is a special case of nonregular file layout for which EDB provides support; see the implementation of support for tagged database files in `db-tagged.el' and *Note Tagged file layout::. Another example is given below. * Menu: * Nonregular database example:: Example of database in nonregular file layout  File: edb.info, Node: Nonregular database example, Prev: Nonregular file layout, Up: Nonregular file layout Example of database in nonregular file layout --------------------------------------------- Here is a simple example of a database in a nonregular file layout; this does not mean that the file representation of each record is vastly different from the others (it may be, but is not in this instance), but that there is no regular rule for extracting field values from the record. Suppose we had a database with fields `place', `time', and `purpose', whose database file was: Dentist's Office at Never! for Root canal Home at Midnight for Sleep Other places at Other times for Other things In order to read and write this database, place the following code in the auxiliary file (*note Reading from disk::.): (database-set-read-record-from-region database 'arb-demo-rrfr) (database-set-write-region-from-record database 'arb-demo-wrfr) (defun arb-demo-rrfr () (goto-char (point-min)) (if (re-search-forward "\\(.*\\)\s-+at\\s-+\\(.*\\)\s-+for\\s-+\\(.*\\)") (let ((result-record (make-record database))) (record-set-field result-record 'place (db-match-string 1) database) (record-set-field result-record 'time (db-match-string 2) database) (record-set-field result-record 'purpose (db-match-string 3) database) result-record) (error "This didn't look right to me."))) (defun arb-demo-wrfr (record) (insert (record-field record 'place database) " at " (record-field record 'time database) " for " (record-field record 'purpose database))) The auxiliary file would also specify the database's fieldnames: (database-set-fieldnames-to-list database '(place time purpose)) as well as possibly other information such as the summary format or the name of the default format file. See the example database auxiliary file `arb-demo.dba' for a concrete example of this. All this Emacs Lisp code may be placed in "Local Variables" section of the format file instead of in the auxiliary file, if desired. For more information about the "Local Variables" section of a file, *Note Variables: (emacs)File Variables. This particular example is simple enough that a special function for reading isn't strictly necessary. Reading can be done under the control of regular expressions; for instance, each field separator would be `"\\s-+\\(at\\|for\\)\\s-+"'. See the example database auxiliary file `arb-demo-regexp.dba' for a concrete example of this. You would still need to specify a special record-writing function. Here is another example, which has no field separators; in the data file, the fields abut one another. While it, too, could be read and written under the control of regular expressions, the use of functions is a bit clearer. The data file is: Einsteinbirthday03141879 Botswanaindepend09301966 The auxiliary file contains the following: (database-set-print-name database "Historic Dates") (database-set-fieldnames-to-list database '(name occasion month day year)) (sepinfo-set-sep-string (database-record-sepinfo database) "\n") (database-set-read-record-from-region database 'sized-field-rrfr) (database-set-write-region-from-record database 'sized-field-wrfr) (defvar sized-field-alist '((name . 8) (occasion . 8) (month . 2) (day . 2) (year . 4))) (defun sized-field-rrfr () (goto-char (point-min)) (let ((result-record (make-record database)) (field-begin (point))) (mapcar (function (lambda (this-size-cons) (forward-char (cdr this-size-cons)) (record-set-field result-record (car this-size-cons) (buffer-substring field-begin (point)) database) (setq field-begin (point)))) sized-field-alist) (if (not (eobp)) (error "Found extra characters in this record.")) result-record)) (defun sized-field-wrfr (record) (mapcar (function (lambda (this-size-cons) (let ((this-field-value (record-field record (car this-size-cons) database))) (if (not (= (length this-field-value) (cdr this-size-cons))) (error "Field %s value \"%s\" should have length %d, not %d." this-field-value (car this-size-cons) (cdr this-size-cons) (length this-field-value))) (insert this-field-value)))) sized-field-alist)) This example is actually a bit too simple. Some of the fields could be made non-strings, field constraints should keep the fields the right length, and `sized-field-alist' should be a database-local variable.  File: edb.info, Node: Reading from disk, Prev: Nonregular file layout, Up: Database file layout What happens when a database is read in from disk ================================================= In brief, the following happens after you execute `db-find-file': 1. If the database is already read in and its buffer has not been killed, the buffer is simply selected. No other work is done. 2. Otherwise, the database file is inserted in a special buffer of its own. If the database is in EDB internal file layout (that is, if an identifying header is found), it is read in immediately. Otherwise, a new, empty database is created. In either case the dynamic variable `database' is bound; this makes it possible to refer to the database in the auxiliary and format files (even before it has been read in, if it is not in EDB internal file layout). 3. The format file is found (*note Auxiliary files::.), and the data display buffer is created. 4. The function `db-setup-data-display-buffer' is called; it performs the rest of the work necessary for setting up the data display buffer (everything up to the running of `db-before-read-hooks'). Its first action is to insert the format file's contents into the data display buffer. 5. The auxiliary file, if any, is loaded. This happens in the data display buffer, and the dynamic variable `database' and the buffer-local variable `dbc-database' are bound to the current database. For more information about how the auxiliary file is found and what it can do, see *Note Auxiliary files::. The auxiliary file is not read every time `db-setup-data-display-buffer' is called, only when a database's primary display format is read. (The primary display format is the one initially selected when a database is first read in.) 6. The "Local Variables" section, if any, of the format file is executed; this may set variables and execute Emacs Lisp code, exactly analogously to the auxiliary file. EDB ignores the value of `inhibit-local-variables' when evaluating this code. This section is then deleted from the working copy of the file, so that it does not appear in the data display buffer when you view database records. For more information about the "Local Variables" section of a file, see *Note Variables: (emacs)File Variables. 7. Database information is propagated; for instance, the names of the database fields are known by now, and various other database slots are filled in depending on this information, if they haven't been set yet. 8. The format file is parsed, and literal text and formatting directives are distinguished from one another. This work is done by the `db-setup-format-parse-displayspecs' function. When that function is done, `db-setup-data-display-buffer' returns the database data display buffer as its result. 9. The hooks in `db-before-read-hooks' are run in the data display buffer. 10. If the database had already been read because it was stored in internal file layout, it is massaged a bit to get it into its final form; for instance, the backward links are added between adjacent records. Otherwise, the database is finally read; the values of the `recordsep' and `fieldsep' slots of the database determine whether the layout is delimited or nonregular and direct the parsing. The `substitutions' slot directs replacement of characters that could not be written into the file, and the `stored->actual' slot of each recordfieldspec completes the translation to the data's internal format from its file layout. 11. The hooks in `db-after-read-hooks' are run in the data display buffer. 12. The database has now been read and is in its final form. The first record of the database is displayed in the data display buffer, which is then placed in view mode and selected (made visible).  File: edb.info, Node: How information is displayed, Next: Customization, Prev: Database file layout, Up: Top How information is displayed **************************** The display of information, both on the screen (whether in the data display buffer, the summary buffer, or elsewhere) and in other output (such as reports), is controlled by formatting commands. We will discuss a data display buffer by way of example; the formatting specifications are the same for summary buffers and reports as well. Display types should not be confused with record field types; a display type is used to specify how a particular value is shown on the screen, but a record field type constrains the information actually contained in the record field. This chapter does not discuss record field specifications, which specify everything about a record field type except how it is displayed and parsed in output intended for humans to read. For more information about that, and about the distinction between record field types and displaytypes (the latter of which is described in this chapter), *note Record field types::.. A "display format" gives all of the information necessary to create a data display buffer; it consists of literal text that is displayed as is (and may not be edited by a user of the database) and of "display specification"s that instruct EDB how to display a particular field's contents. The display specifications do not appear in the data display buffer; they are replaced by fields' values, which may or may not be editable. An example of a display specification is `\name,width=16', which indicates that the `name' field of the database should be displayed (after being padded or truncated to exactly 16 characters). When a format is first specified, it is parsed and the formatting information specified in the display specification strings is used to create a displayspec structure. Users should never have to manipulate displayspecs directly. * Menu: * Display specifications:: Display specifications * Predefined displaytypes:: Predefined displaytypes * Enumeration displaytypes:: Enumeration types * Defining new displaytypes:: Defining new displaytypes * Display specification optional parameters:: Display specification optional parameters * Display specification abbreviations:: Display specification abbreviations  File: edb.info, Node: Display specifications, Next: Predefined displaytypes, Prev: How information is displayed, Up: How information is displayed Display specifications ====================== A "display specification" describes how a particular database record field appears in the data display buffer. An display specification consists of a backslash followed by a field name, plus perhaps some optional type and formatting information, plus optionally a backslash followed by a space. The items of extra formatting information must be separated from the field name and from each other by commas. No spaces or tabs may occur in a display specification. To specify a backslash which does not begin a display specification, but should appear in the data display buffer verbatim, precede it by another backslash. Here is a (quite complicated) example display format: \name,one-line-string,actual->display=upcase\ , \occupation' Pay: \\\salary,min-width=4: too much! Address: \address,indent is home sweet home This display format is valid if the database contains fields called `name', `occupation', `salary', and `address'; any other fields are not displayed. Some typical records would be displayed like this: JOHN DOE, butcher Pay: \ 22: too much! Address: 123 Main St. Anyplace, USA is home sweet home JANE ROE, baker Pay: \4444444: too much! Address: 675 Massachusetts Avenue is home sweet home The optional information includes the type of this display field and formatting directives for it; if the type is present, then it must come first among the displayspec's optional specifications. Each optional parameter is preceded by a comma to separate it from the preceding one (or from the fieldname, for the first optional parameter). The optional information is typically of the form `SLOTNAME=VALUE', which sets the specified slot to the given value, or `SLOTSETTER', which sets some slot to a particular value. Explicitly specified formatting information overrides any defaults. For a list of slotnames and slotsetters, *note Display specification optional parameters::.. The display type can be specified by writing a typename (such as `string' or `integer') as the first optional parameter. A type abbreviation may be used instead of a typename; the defined type abbreviations are `#' for integer, `$' for number, `"' for string, and `'' for one-line-string. The display type specifies default values for the display specification (actually for the displayspec structure, which is derived from the display specification). It is rarely necessary even to specify the displaytype--most display specifications consist of simply a backslash and a fieldname--since if the displaytype is omitted then a displaytype with the same name as the record field type (actually the `type' slot of the recordfieldspec) is used. This works because typically displaytypes and recordfieldtypes with the same names and complementary definitions are declared at the same time. The displaytype must be compatible with the record field type; it is an error to specify a displaytype of `integer' when the data is actually a string. `database-set-fieldnames-to-list' to specify recordfieldtypes; *note The database structure::.. A display specification abbreviation, which consists of an abbreviation name preceded by a backslash (and so looks like a simple display specification in which no optional information is specified), can be used instead of a standard display specification; *Note Display specification abbreviations::.  File: edb.info, Node: Predefined displaytypes, Next: Enumeration displaytypes, Prev: Display specifications, Up: How information is displayed Predefined displaytypes ======================= The file `db-types.el' defines the following displaytypes, corresponding recordfieldtypes, and some useful associated functions. You can also define displaytypes of your own; see *Note Defining new displaytypes::. integer Ordinary integers. integer-or-nil Integers or `nil', the empty value; `nil' is formatted as the empty string. number Ordinary numbers. A number is an integer or a floating-point number. number-or-nil Numbers or `nil', the empty value; `nil' is formatted as the empty string. yes-no This displayspec corresponds to the boolean recordfieldtype. The field is three characters long and contains "Yes" or "No ". string Ordinary strings. By default there is no maximum or minimum width or height, and subsequent lines are indented relative to the first character of the first line. one-line-string Strings which may not contain newlines. string-or-nil Either a string or the value `nil', which is displayed as the empty string. nil-or-string Either a string or the value `nil'. When you enter the empty string as the field value, or when a new record is created, the value `nil' is used in preference to the empty string. one-line-string-or-nil Either the value `nil' or a string which may not contain newlines. date A date which specifies zero or more of the year, month, and day. The date is formatted by `format-date' and parsed by `parse-date-string'; for details, *note Date displaytype::.. time A time which specifies zero or more of the hour, minute, and second. The time is formatted by `format-time' and parsed by `parse-time-string'; for details, *note Time displaytype::.. * Menu: * Date displaytype:: Date displaytype * Time displaytype:: Time displaytype  File: edb.info, Node: Date displaytype, Next: Time displaytype, Prev: Predefined displaytypes, Up: Predefined displaytypes Date displaytype ---------------- EDB defines a date abstraction and a variety of useful operations upon it; the best way to learn about these features is to read `db-time.el' This section provides more detail about the date displaytype. A date specifies a year, month, and day (all integers); any or all of these components may be hidden. Dates are created by the constructor `make-date' and a date's components are retrieved using the selectors `date-year', `date-month', and `date-day'. `make-date' Make an EDB date object with arguments YEAR MONTH DAY. [[[Document parse-date-string, format-date, simple-format-date, def-xxx-type.]]] [[[ I added several useful (to me, anyway) displayspecs for various date types. These are meant to be used in a display spec, like: \datefield,date-mmddyy The displayspecs are implemented with similarly named formatting functions, which I also implemented. All of the new formatting functions are named format-date-XXX, where XXX are the various styles. ]]]  File: edb.info, Node: Time displaytype, Prev: Date displaytype, Up: Predefined displaytypes Time displaytype ---------------- [[[Similarly to the above, for times.]]]  File: edb.info, Node: Enumeration displaytypes, Next: Defining new displaytypes, Prev: Predefined displaytypes, Up: How information is displayed Enumeration types ================= An enumeration displaytype is used for fields whose values are one of a fixed set of alternatives. Each alternative may be a single character (say, `M' or `F' for gender) or specifiable by a single character (for example, if the first letters of the alternatives are unique); you need only type a single character in order to select one of the alternatives. Another possibility is that each alternative consists of an entire string entered with completion. (The string may consist of only a single character if desired, but you must still type RET after entering the string.) The internal representation of the data--its recordtype--need have nothing to do with the way that the alternatives are specified. The next two sections describe the two types of enumeration displaytypes, which are nicknamed "one-char-enum" and (for the multicharacter alternative type) "enum". * Menu: * One-character enumeration displaytypes:: One-character enumeration displaytypes * Multi-character enumeration displaytypes:: Multi-character enumeration displaytypes  File: edb.info, Node: One-character enumeration displaytypes, Next: Multi-character enumeration displaytypes, Prev: Enumeration displaytypes, Up: Enumeration displaytypes One-character enumeration displaytypes -------------------------------------- One-character enumeration displaytypes are not yet implemented.  File: edb.info, Node: Multi-character enumeration displaytypes, Prev: One-character enumeration displaytypes, Up: Enumeration displaytypes Multi-character enumeration displaytypes ---------------------------------------- Multi-character enumeration displaytypes require you to enter an entire string in order to specify one of the alternatives. This typing may be done with completion in the minibuffer, which means that keys such as TAB and ? complete a partly-entered choice or list the remaining possibilities. (For more about completion, see *Note Completion: (emacs)Completion.) The internal, input, display, and file storage representations of the value may all be different. Multi-character enumeration displaytypes (also known as enum displaytypes) are created by calling the following function, which also creates a corresponding recordfieldtype. `define-enum-type' Make TYPENAME (a symbol or string) an enumerated type. Both a displaytype and a recordfieldtype are created. ALTERNATIVES is a list. Each alternative is a list of up to four components: the internal representation, any constant Lisp object, often a string; the input representation typed by the user to specify this alternative, a string or list of strings (for multiple input representations); the display representation, a string; and the file storage representation, a string. If the input representation is omitted and the internal representation is a string, that string is used. If the display representation is omitted, it defaults to the first input representation. The display representation is automatically also a valid input representation. If the file storage representation is omitted, it defaults to the display representation. If all the other components are omitted, the internal representation string may be used in place of a one-element list containing just it. Optional argument OPTSTRING is a displayspec option string. When a record field's type is an enum type, both EDB and code written by the database designer may assume that the value in the record field is one of the valid representations. (Similarly, when a field's type is string, EDB can assume that the field content is actually a string.) This means that the empty string, `nil', and other special values must be specifically mentioned when the enumeration type is defined. Here is a way to define an enumeration type which is either a day of the week or the empty string: (define-enum-type 'workday '("Monday" "Tuesday" "Wednesday" "Thursday" "Friday" "")) If it is possible for the field value to be `nil' (but not the empty string) after reading the database, and `nil' should be displayed as `Unknown' (and that string parsed into a value of `nil'), the following definition suffices: (define-enum-type 'workday '("Monday" "Tuesday" "Wednesday" "Thursday" "Friday" (nil "Unknown")))  File: edb.info, Node: Defining new displaytypes, Next: Display specification optional parameters, Prev: Enumeration displaytypes, Up: How information is displayed Defining new displaytypes ========================= When you are about to type a complicated display specification--or a simple one more than once--consider defining and using a displaytype instead. Displaytypes are more concise (and so less cumbersome and less error-prone), easier to change (since a change to the displaytype can affect every display specification that uses it), and clearer (since a descriptive typename makes immediately clear what the intention is). Furthermore, displaytypes can be built up incrementally, with each one making a few changes to those from which it inherits defaults. There are two ways to define a new displaytype; each requires specifying the name of the displaytype and some formatting information to be associated with that displaytype. The first method permits a displaytype to be specified by the optional part of a display specification, which is a string consisting of comma-delimited optional parameters. The first optional parameter may be a type, in which case the defaults for values not explicitly set in the other parameters are taken from that type. `define-displaytype-from-optstring' Define a displaytype named TYPENAME according to OPTSTRING. TYPENAME is a symbol or string and OPTSTRING is the optional parameters part of a display specification string. The second method is more useful for complicated displaytypes; it is also somewhat more efficient, which is why the file `db-types.el' uses it to define the standard predefined types. This method is to create a displayspec or copy an existing one, then modify it as desired using the structure slot modifiers (i.e., `displayspec-set-'SLOTNAME; see *Note Display specification optional parameters::, for a list of slotnames), and then associate a typename with the displayspec. In fact, this is precisely what `define-displaytype-from-optstring' does. `make-displayspec' Not documented. `displaytype->displayspec' Return a copy of the displayspec corresponding to string or symbol DISPLAYTYPE. Return `nil' if there's no corresponding displayspec. `define-displaytype-from-displayspec' Define a displaytype named TYPENAME (a symbol) with the default DISPLAYSPEC. DISPLAYSPEC may also be a typename symbol itself.