HOME | COMPANY | SOFTWARE | DOCUMENTATION | EDUCATION & TRAINING | SALES & SERVICE | |
"The Official Guide to Programming with OmniMark" |
|
International Edition |
Previous chapter is Chapter 4, "Processing SGML Documents".
Next chapter is Chapter 6, "OmniMark Data Types".
OmniMark allows rules to be grouped together under group names. These groups can then be "turned on" or "turned off", so that rules in "turned off" groups are not available for processing. The groups "turned on" at any point in processing are called the active groups. The ability to activate different sets of groups allows different sets of rules to apply to processing different parts of the input, and avoids the need to make a set of tests for each rule performed. Groups act as "guards" on the rules. Note that groups have an effect on rules but not declarations.
GROUP group-name (& group-name)* rule*
The GROUP declaration indicates that the following rules are members of the named groups. For example, the following defines the first ELEMENT rule to be part of the section group, and the second to be part of both the chapter and annex groups:
GROUP section ELEMENT title OUTPUT "\section-title{%c}%n" . . . GROUP chapter & annex ELEMENT title OUTPUT "\title{%c}%n" . . .
Declarations are not affected by groups. The selection of an error rule (like PROLOG-IN-ERROR or SGML-ERROR) is likewise not affected by which groups are active.
Groups are a convenient way of bundling related rules together. Rules that fall in a given group can be triggered only when at least one of their named groups is active. In the above example, the first ELEMENT title rule is triggered only when the section group is active. The second is triggered only when the chapter and/or the annex group is active. It is the responsibility of the OmniMark programmer to ensure that both rules couldn't be triggered; this would violate the requirement that any encountered ELEMENT can trigger exactly one ELEMENT rule.
More than one GROUP declaration can name the same group: the rules following every GROUP declaration for a given name are members of the named group.
The following syntactic variations are permitted:
GROUP main-document AND table-processing
Example A
GROUP (main-document AND table-processing)
Example B
GROUP (main-document & table-processing)
"GROUP #IMPLIED" is a special group that is always active. It is the only group that is active when an OmniMark program starts.
All rules before the first explicit GROUP declaration are considered part of the #IMPLIED group, as are all rules in programs containing no explicit GROUP declaration.
The following example places the first ELEMENT rule in the section group and the second rule in "GROUP #IMPLIED".
GROUP section ELEMENT title ... GROUP #IMPLIED ELEMENT title ...
The #IMPLIED group cannot be combined with other groups in GROUP declarations because it essentially "includes" all groups. Once a rule is in the #IMPLIED group, it is always active.
It is often useful to place only the first rule in the program (a DOCUMENT-START, FIND-START, or PROCESS-START rule) in the #IMPLIED group, and immediately change to a specific group. Thereafter, the active rules can be controlled by "NEXT GROUP IS" and "USING GROUP".
There are two ways to change the currently active groups:
Only the groups of the current domain can be changed. For example, if the currently active groups of the input processor are changed, the currently active groups of the output processor are unaffected.
NEXT GROUP IS group-name (& group-name)*
The "NEXT GROUP IS" action changes the currently active groups. It makes the named group or groups active. All other groups (except the #IMPLIED group) are no longer active.
NEXT GROUP IS section & syntax
This action activates the section and syntax groups. A "NEXT GROUP IS" action always deactivates all groups not named in the action (except for the #IMPLIED group which is always active).
As well, the next group action can activate more than one group at a time:
NEXT GROUP IS section & annex
If the only group named in the "NEXT GROUP IS" action is the #IMPLIED group, then all other groups are deactivated. The #IMPLIED group cannot be combined with other groups in "NEXT GROUP IS" actions because it would have no effect. The #IMPLIED group is always active.
The following syntactic variations are permitted:
NEXT GROUP IS main-processing AND count-newlines
Example A
NEXT GROUP IS (main-processing AND count-newlines)
Example B
NEXT GROUP IS (main-processing & count-newlines)
USING GROUP group-name (& group-name)* action
The groups used can also be changed "temporarily" by the "USING GROUP" prefix. The new groups are only in effect during the action that follows. After the action ends the previous groups are reinstated.
The "USING GROUP" prefix is especially useful in conjunction with the SUBMIT action when a FIND rule that applies to the submitted text is different from those that normally apply. For example:
FIND "\table{" [any except "}"]+ => file-name "}" USING GROUP table-processing SUBMIT FILE file-name
If the group is changed by "NEXT GROUP IS" while within the action prefixed by "USING GROUP", the groups activated by the "NEXT GROUP IS" action are only effective until the end of the action prefixed by "USING GROUP".
The #IMPLIED group cannot be combined with other groups in "USING GROUP" prefixes, because it would have no effect. The rules in the #IMPLIED group are always active, whether they are mentioned or not. "USING GROUP #IMPLIED" is just a way of deactivating all of the programmer-defined groups in the program.
The following syntactic variations are permitted:
FIND "\table{" [any except "}"]+ => file-name "}" USING GROUP table-processing AND main-processing SUBMIT FILE file-name
Example A
FIND "\table{" [any except "}"]+ => file-name "}" USING GROUP (table-processing AND main-processing) SUBMIT FILE file-name
Example B
FIND "\table{" [any except "}"]+ => file-name "}" USING GROUP (table-processing & main-processing) SUBMIT FILE file-name
If new groups are to be added to the currently active groups instead of replacing them, the keyword #GROUP can be used in place of explicitly naming all of the currently specified groups.
The following example shows how to add the group process-part-number to the currently active groups:
DOWN-TRANSLATE ... ELEMENT part-no USING GROUP #GROUP & process-part-number OUTPUT "%c" ...
SAVE GROUPS
At the start of a rule, together with the other LOCAL declarations, and SAVE declarations, a "SAVE GROUPS" declaration can be used to save the groups currently active. When the rule ends they will be restored, no matter what changes to groups are made while the rule is processing. The "SAVE GROUPS" declaration is like the SAVE declaration except that it applies to groups rather than OmniMark shelves.
The "SAVE GROUPS" declaration must appear before any actions.
OmniMark allows "NEXT GROUP IS" to be used in a function. It is possible that such a function is called in the header of a rule. For example:
DOWN-TRANSLATE DEFINE SWITCH FUNCTION change-group AS NEXT GROUP IS table-processing RETURN TRUE ELEMENT row WHEN change-group ...
Programming in this style is unwise and can cause the program to behave unpredictably. Essentially, the only guarantees that OmniMark makes in this situation are:
Otherwise, the behaviour of the program is unpredictable. More importantly, such behaviour may be different for different releases, reflecting improved optimization techniques.
Programmers are cautioned that they should never depend on side effects within a function called from a rule header.
Each domain has its own set of active groups. A "NEXT GROUP IS" action or "USING GROUP" prefix in an output processor rule only affects the selection of output processor rules. Likewise, a current group change in an input processor rule affects only the selection of input processor rules.
Line-breaking rules use the active groups of the domain in which the stream was opened, regardless of which domain the PUT or OUTPUT action occurred in. Streams which do not belong to either domain use line breaking rules in the active output processor groups.
An error rule cannot contain a "NEXT GROUP IS" action or a "USING GROUP" prefix.
FIND rules can be combined with GROUP declarations to build powerful finite state machines:
The experienced programmer will find that this is an extremely powerful technique for certain tasks.
Next chapter is Chapter 6, "OmniMark Data Types".
Copyright © OmniMark Technologies Corporation, 1988-1997. All rights reserved.
EUM27, release 2, 1997/04/11.