transpec(5)

โœจ NAME โœจ

okay bestie, this is transpec(5) from the File Formats Manual. The transpec is literally the translation specification for instant. ๐Ÿ’–

transpec โ€” translation specification for instant


๐ŸŒธ SYNOPSIS ๐ŸŒธ

file.ts

๐Ÿ’ซ DESCRIPTION ๐Ÿ’ซ

so here's the tea โ˜•: the transpec file is what the instant program reads to translate an SGML document instance into a format that's suitable for a formatting application. โœจ

The convention is to name the file with the suffix .ts. (yes, .ts, not the other .ts, iykyk ๐Ÿ’…)

A transpec file is made up of a bunch of individual translation specs. Each translation spec (aka a transpec) is made up of a number of fields, one per line. ๐Ÿซถ

Translation specs are separated by a line with a leading dash. Anything after the dash? ignored, bestie. literally not read. ๐Ÿ’€

Fields are composed of two parts: a name and a value, separated by a colon. The colon must immediately follow the name. After the colon, any amount of whitespace โ€” blanks and tabs โ€” may be present between the colon and the value. โœจ

careful, bestie: values should not be quoted, and watch out for trailing spaces. a trailing space is considered part of the value. quotes, if they show up, are considered part of the value of the fields. no cap. ๐Ÿ˜ญ

Lines that begin with whitespace (blanks and tabs) are a continuation of the previous line; the leading space is ignored. This whole vibe is very similar to e-mail headers. ๐Ÿ“ง

Lines beginning with a # (number sign) are comments, and blank lines are ignored. periodt. ๐Ÿ’…

โœจ Field Descriptions โœจ

okay so some fields are for identifying criteria that determines if a particular spec matches an element in the instance. others specify what action is to take place when a match happens, like sending text to the output stream. ๐Ÿ’…


๐Ÿ” Criteria fields ๐Ÿ”

Criteria fields restrict the conditions under which a single translation spec will apply. If each field specified in a particular transpec matches an element under consideration in the document instance, then that translation spec is said to match. The appropriate actions, as specified in that spec, are then taken. The program, instant, searches the list of transpecs in the order given in the file. Therefore, the more restrictive specs (those with more criteria) should appear before less restrictive ones. ๐Ÿ‘‘

For quick reference, this is a brief summary of the possible criteria fields for translation. A complete discussion of each follows.

  • GI โ€” gi ... โ€” name of this GI
  • AttValue โ€” attname reg-expr โ€” current element has attribute with value
  • Content โ€” reg-expr โ€” is reg-expr in char content>
  • Context โ€” context โ€” element context, up the tree
  • NthChild โ€” number โ€” current element is Nth child of its parent
  • PAttSet โ€” attname (val) โ€” parent has this attribute set (optional to value val)
  • Relation โ€” relationship gi โ€” gi has relationship to current element
  • VarREValue โ€” var REvalue โ€” variable is set to regular expression value
  • VarValue โ€” var value โ€” variable is set to value

GI: gi [...]

gi is the name of the generic identifier, or element name, to consider. More than one GI may appear in this field. โœจ

AttValue: attname regular-expression

This is an attribute name-value pair, where attname is an attribute of the GI. The regular-expression is of the form accepted by the unix program egrep. This pair is compared to the corresponding attribute name-value pairs of the GI under consideration. To simply test if an attribute is set, use . (a dot) for regular-expression. There may be more than one of these lines for each transpec. ๐ŸŽ€

Content: regular-expression

This specifies that the character content of GI contains a string matching the regular-expression.

Context: context

This specifies the context in which to apply this translation spec. It is either a list of generic identifiers or a regular expression describing a list of generic identifiers, looking up the hierarchy. The first is the parent of the GI.

NthChild: number

This specifies that the GI is the numberth child element of its parent. Children are numbered starting with 1. Negative numbers may be used to indicate order counting backwards. For example, -1 denotes the last child.

PAttSet: attname

This specifies that the parent has this attribute, attname, set to any value (not IMPLIED). A value to match may optionally be specified after attname.

Relation: relationship gi

This specifies that the current element has the relationship to the named gi. The acceptable relationships are: ancestor (anywhere up the tree), child (immediate child), descendant (anywhere down the tree), parent (immediate ancestor), sibling (share same parent element), sibling+ (any later sibling), sibling+1 (the immediately following sibling), sibling- (any earlier sibling), sibling-1 (the immediately following sibling). ๐Ÿ’€

VarREValue: varname REvalue

This specifies that the global variable varname has the value REvalue, where REvalue is a regular expression (see the VarValue statement).

VarValue: varname value

This specifies that the global variable varname has the (literal) value value (see the VarREValue statement).

There are two special GIs. If specified, _Start and _End are processed as if they were GIs in the instance at the start and end of the translation, respectively. Their criteria are never checked. Only their actions are performed. ๐ŸŒŸ


๐ŸŽฌ Action fields ๐ŸŽฌ

For quick reference, this is a brief summary of the action fields for translation. They are only performed if all the criteria are satisfied. A complete discussion of each follows.

  • Action โ€” spec-id โ€” use transpec whose spec ID is spec-id
  • EndText โ€” text โ€” text for end of element
  • Increment โ€” name โ€” increment variable name
  • Ignore โ€” key โ€” flag for ignoring element's children and/or data
  • Message โ€” text โ€” text to send to stderr
  • Quit โ€” text โ€” print text and quit program
  • Replace โ€” text โ€” replace this subtree with text
  • Set โ€” name value โ€” set variable name to value
  • SpecID โ€” spec-id โ€” unique Spec ID (int) of this spec
  • StartText โ€” text โ€” text for start of element

Action: spec-id

Use the actions of the spec identified by the SpecID with matching identifier spec-id.

EndText: text

This specifies text to be output when the end tag is processed.

Ignore: key

This specifies that the data or children for this element are to be ignored. Set key to all to ignore the element (data and child elements), to data to ignore the immediate character data content (child elements are still descended into), and to children to process the immediate character data content but not descended into child elements. Other actions specified in this transpec are still performed, however.

Increment: name

This is used to increment a variable whose value is a number. If the variable is not a number, no action will be taken. The variable must have been previously defined. This action is done immediately before EndText. There may be more than one of these lines for each transpec.

Message: text

This specifies a string to be printed to the standard error when the matching element is processed. It is intended for informing the user of the progress of the translation. It is also used for validation of instances (see the -v flag of instant(1)); a spec would be written to recognize a construct that is not allowed. This action is done immediately after StartText. Messages are also useful for debugging spec files; one is able to easily tell when a matching spec is processed, without looking at the actual output of the translation. Note that the spec writer is responsible for putting newlines (\n) in the message text.

Replace: text

This specifies text to replace the current subtree with. This is equivalent to StartText and Ignore.

Quit: text

This specifies text to be printed to the standard error. The program then terminates with exit status 1. This is intended for bailing out when an undesirable instance is encountered (such as when it is known that the formatting application can never handle a class of components, like tables).

Set: name value

This is used to set a variable whose name is name and value is value. Names that would be valid for GIs in the document instance are valid for variable names. value is the rest of the line and may be any string. This action is done immediately before EndText. There may be more than one of these lines for each transpec. See the discussion on variables below.

SpecID: spec-id

This names the spec with the number spec-id. Other specs may refer to this one by this number by an Action field or an _action special variable. This is used for cases where several specs to perform the exact same action.

StartText: text

This specifies text to be output when the start tag is processed.


๐ŸŒˆ Other Fields ๐ŸŒˆ

These fields may appear anywhere. The action occurs when the translation spec file is read, before any elements are translated. These are independent of any element processing.

Var: name value

This is used to define a variable whose name is name and value is value. It is similar to Set, but it may occur anywhere in the file and takes effect when the spec file is read.


๐Ÿ’– Text Strings ๐Ÿ’–

The text referred to in the StartText, EndText, Replace, and Message actions is more than simple character strings. Special sequences allow more complex output.

One type of special sequence is for C-style string processing. Most special characters are escaped with a \ (backslash). Like in C or shell programs, to print a \ (backslash), you must escape it with another backslash. These special character strings are:

  • \n (backslash-n) โ€” This specifies that a newline character is to be printed to the output stream.
  • \r (backslash-r) โ€” This specifies that a carriage return character is to be printed to the output stream.
  • \t (backslash-t) โ€” This specifies that a tab character is to be printed to the output stream.
  • \s (backslash-s) โ€” This specifies that a space is to be printed to the output stream. This is useful for the end of a transpec line, where it can be difficult to tell if a blank is present at the end.
  • \007 (backslash-007) โ€” This specifies that the character whose octal value is 007 is to be printed to the output stream. This works for any octal character value.
  • ^ (caret) โ€” This specifies that position in the string will be at the start of a line in the output stream.

If the first token of the text string is #include, then the second token is taken to be a file name and that file is included. If the file is not found, the library directory, as mentioned above, is searched. If the text string starts with a ! (exclamation point), the rest of the line is taken to be a command and the output of that command is inserted.

An element's attributes may also be used in the text of output fields. To use an attribute value, precede its name with a ${ (dollar sign-left curly bracket) and follow it with a } (right curly bracket). (This style is followed by the Bourne shell.) For example, ${TYPE}. If the attribute is not set (not IMPLIED), nothing will be printed to the output stream. To specify a value to use if the attribute is not set, place the value after the attribute name, separated by a space. To return the attribute value in lower-case, add a colon followed by lower-case l (${TYPE:l}).

๐Ÿฆ‹ Variables ๐Ÿฆ‹

okay bestie, so variables in instant are lowkey exactly like the ones you already know from sh and awk. you set them with Var: name value and Set: name value. values can be set and reset to literally any string you want, no cap.

and here's the fun part: in a Var line, if the value starts with a !, then the rest of the line gets executed as a command and its output becomes the value. โœจ chef's kiss.

referencing a variable's value looks exactly like referencing an attribute's value: ${name}. if that variable was never defined, you just get null back. but if you want a default instead of a sad little null, use the form ${name default} and you're saved. ๐Ÿซถ

variables can be used anywhere attributes can be used โ€” so, in any of the text strings we talked about above. and actually, when an attribute name gets referenced but isn't set for a given element, instant goes looking for a variable with the same name. boom, global defaults, iconic behaviour. if you want to be sure you're grabbing a local variable value and not an attribute value, use lower or mixed case names, because attribute names (as handed over by onsgmls) are always in upper case. ๐Ÿ’…

you can have any number of Var actions in the spec file. those set the variable values before any translation happens. the Set actions inside transpecs, though, happen when that spec gets processed โ€” i.e. when an element matches the given criteria.


๐ŸŽ€ Preset Variables ๐ŸŽ€

instant presets a few variables for you the moment the program starts. you can override their values in transpec files or right on the command line. main character energy fr fr.

  • date โ€” the date and time the program started. the format is: Tue 10 Aug 1993, 16:52.
  • host โ€” the name of the host where the program is run. it's whatever the gethostname library call returns.
  • transpec โ€” the translation spec filename.
  • user โ€” the login name of the user running the program.

โœจ Special Variables โœจ

there's a whole little collection called special variables, and you spot them because their names start with a _ (underscore). here's the summary, and then the full deep-dive on each one follows. ๐Ÿงš

quick thing before we go: spec-id refers to a number specified in a SpecID field. when it shows up in a special variable, it means "perform the action in that translation spec."

ngl this bit matters: when a spec-id is given in a special variable, the default behaviour is to perform the translation spec named by the spec-id while ignoring any criteria statements found there. for most special variables that use a spec-id, postpending a t to the spec-id (no spaces between them, e.g. "${_followrel child TITLE 15t}") will cause the criteria statements in the named translation spec to evaluate successfully before that translation spec gets processed. noted bestie ๐Ÿ’–
  • _action spec-id โ€” do spec with id spec-id
  • _allatts โ€” print all attribute/value pairs
  • _attval att [value] spec-id โ€” use spec-id if attribute matches
  • _chasetogi gi spec-id โ€” follow IDREFs until gi found
  • _eachatt att spec-id [spec-id] โ€” do spec-id for each word of attribute value
  • _eachcon spec-id [spec-id] โ€” do spec-id for each word of content
  • _env env-variable โ€” return value of env variable
  • _filename โ€” filename of notation
  • _find rel gi spec-id โ€” find gi based on relationship
  • _followlink [attname] spec-id โ€” follow IDREFs [attname] and use spec-id
  • _followrel rel gi spec-id โ€” do spec-id on rel if it matches
  • _gi [M|L|U] โ€” return GI name; M, L, U case
  • _id id [spec-id] โ€” find element with ID and use spec-id
  • _include filename โ€” insert file here
  • _infile [line] โ€” instance filename [and line number]
  • _insertnode S|E spec-id โ€” do spec-id when element is traversed
  • _isset var [value] spec-id โ€” do spec-id if variable matches
  • _location โ€” print location of current element
  • _namelist spec-id [spec-id] โ€” content is namelist, do spec-id for each
  • _nchild [gi] โ€” number of child elements [named attname]
  • _osftable format [flag] โ€” print table format specification
  • _path โ€” print path to current element
  • _pattr attname โ€” value of parent's attribute
  • _pfind args ... โ€” same as _find, but start at parent
  • _relation rel gi spec-id [spec-id] โ€” do spec-id if relation matches
  • _set var value โ€” set variable to value
  • _!command โ€” command to run

  • _action spec-id โ€” use the actions of the spec identified by the SpecID with matching identifier spec-id. this behaves similarly to the Action action, except it's in addition to the present translation spec. stacking, we love to see it. ๐Ÿ”ฅ
  • _allatts โ€” prints all attribute name-value pairs of the current element to the output stream. the name and value are separated by a = (equals sign), and the value is surrounded by quotes. super useful for creating a normalized version of the instance. periodt.
  • _attval attname [value] spec-id โ€” if the current element has an attribute named attname โ€” optionally whose value matches value โ€” then use the actions of the transpec identified by spec-id.
  • _chasetogi gi spec-id โ€” follows IDREF attributes until it finds an element whose GI is gi, or which has a child element with that GI. then it applies the transpec spec-id to that element. by default, instant assumes the attributes named LINKEND, LINKENDS, and IDREF are of type IDREF or IDREFS. (this corresponds with the OSF DTDs.) you can change that by setting the variable link_atts to a space-separated list of attribute names. ๐ŸŒˆ
  • _eachatt att spec-id [spec-id2] โ€” the transpec named by spec-id gets invoked once per each word found in the value of the attribute att. inside the target transpec, the current word being processed is available in the variable named each_A (${each_A}). if spec-id2 is specified, it'll use spec-id for the first word in the attribute and spec-id2 for the others.
  • _eachcon spec-id [spec-id2] โ€” the transpec named by spec-id gets invoked once per each word found in the content of the current element. inside the target transpec, the current word being processed is available in the variable named each_C (${each_C}). if spec-id2 is specified, it'll use spec-id for the first word in the content and spec-id2 for the others.
  • _env env-variable โ€” prints the value of the environment variable env-variable to the output stream.
  • _filename โ€” prints the filename of the notation associated with this element, if any. this is how you get the filename of an external notation entity reference. for example, to print the filename in the latex macro from the epsf macro package, use \epsfboxi{${_filename}}. ๐ŸŽ€
  • _find [top] relationship args ... spec-id โ€” descends the document hierarchy finding elements that match one of several criteria. when one is found, the action specified by spec-id is performed. if top is specified, the search starts at the top of the document hierarchy instead of at the current element. the possible values for relationship are gi, gi-parent, parent, and attr, and they take different arguments. honestly, explanations land best by example:
    • _find gi CHAPTER 123 โ€” find elements whose GI is CHAPTER, and perform action 123.
    • _find gi-parent TITLE CHAPTER 124 โ€” find elements whose GI is TITLE and whose parent is CHAPTER, and perform action 124.
    • _find parent BODY 125 โ€” find elements whose parent's GI is BODY, and perform action 125.
    • _find attr TYPE UGLY 125 โ€” find elements whose attribute named TYPE is set to UGLY, and perform action 126.
  • _followlink [attname] spec-id โ€” when processing an element, instant will follow the IDREF attributes until it finds an element with no IDREF attributes. it will then apply the transpec specified by spec-id to that element. if specified, it will follow the link pointed to by attname. by default, instant assumes the attributes named LINKEND and LINKENDS are of type IDREF or IDREFS. you can change this by setting the variable link_atts to a space-separated list of attribute names.
  • _followrel relationship gi spec-id โ€” if the gi has the specified relationship to the current element, perform the action specified by spec-id on the related element. go look at the discussion of the criteria field Relation for the acceptable relationship names. ๐Ÿ‘‘
  • _gi [M|L|U] โ€” prints the name of the current GI to the output stream. if specified, M, L, or U will make sure the GI name is printed in mixed, lower, or upper case, respectively.
  • _id id [spec-id] โ€” find the element with id and use spec-id, if set. if it's not set, use the spec for that element's context.
  • _include filename โ€” inserts the file filename into the output stream.
  • _infile [line] โ€” prints the name of the sgml instance file to the output stream. if line is specified, it also prints the line number. this depends on onsgmls being called with the -l option. don't forget it or you get nothing bestie ๐Ÿ˜ญ
  • _insertnode S|E spec-id โ€” do spec-id when the current element is traversed at a later pass. you can think of it as inserting a node, without content, into the hierarchy. this is only useful if it's done to elements before they're processed. typically _chasetogi or _followlink is specified early in an instance's processing, so that when the elements found by one of these actions are processed in their turn, the added actions get performed. _insertnode would be specified as the action of a spec-id pointed to in a _chasetogi or _followlink usage. ๐Ÿงš
  • _location โ€” the location of the current element is printed to the output stream in several ways: the path to the element (see _path), a position hint, which is the nearest title, the line number (if the ESIS โ€” that's the output from onsgmls โ€” contains line numbers), and the ID of the element, if it has one. this is especially useful when you're using the Message action to validate an instance. ๐Ÿ’…
  • _namelist spec-id [spec-id2] โ€” bestie, this one assumes the content of the current element is a namelist (aka a list of element IDs) and then applies the action for spec-id to every element that list points at. Add spec-id2 and it's giving โœจsplit energyโœจ: spec-id handles the first ID in the namelist and spec-id2 takes care of all the others. ๐Ÿ’…
  • _nchild [gi] โ€” prints the number of child elements of the element straight into the output stream. Pass a gi and it counts only the child elements with that name instead. lowkey the easiest headcount ever ๐Ÿงฎ
  • _osftable tex|tbl|check [flag] โ€” prints table markup into the output stream, and the format depends on whether you said tex or tbl. The flag may be one of cellstart, cellend, rowstart, rowend, top, or bottom, and that value determines what markup or text gets generated. Say cellstart and you get the correct markup for the beginning of a cell. Say top, bottom, or rowend and the correct markup for the end of the appropriate position is printed to the output stream. Say check and the attributes and child elements get checked for errors and consistency. ๐Ÿฉท
  • _path โ€” prints the path to the current GI into the output stream. A path is each element, going down the tree from the topmost element, and the number in parentheses after each element name shows which child element the next one is in the order of children for that element. Ordering starts at 0. For example: OSF-BOOK(3) BODY(0) CHAPTER(4) SECTION. Decode that and it says the path is <OSF-BOOK>'s third child, <BODY>'s zeroth, and <CHAPTER>'s fourth, which is named <SECTION>. it's giving ancestry.com ๐ŸŒณ
  • _pattr name โ€” prints the value of the parent's attribute whose name is name to the output stream.
  • _pfind rel gi spec-id โ€” literally exactly the same as _find except that the search starts at the current element's parent. same vibe, different starting point ๐Ÿซถ
  • _relation relationship gi spec-id [spec-id2] โ€” if the gi has the specified relationship to the current element, it performs the action specified by spec-id on the current element. If the relationship test fails and spec-id2 is specified, it performs that action instead. Peep the discussion of the criteria field Relation for the acceptable relationship names. ๐Ÿ‘€
  • _set varname value โ€” sets the value of the variable varname to value.
  • _isset varname [value] spec-id โ€” if the value of the variable varname is set to value, then it performs the action referred to by spec-id. Leave value out and the action gets performed if varname is set to any value at all. ๐ŸŽ€
  • _! command โ€” runs the command command, directing its standard output into the output stream. yes bestie we're shelling out ๐Ÿš

โœจ Immediate Variables โœจ

Immediate variables are like special variables, except for the timing โ€” and the timing is the whole plot twist. Immediate variables get expanded when the transpec is originally processed, while special variables are processed later, near when the final output is being generated. The general syntax of immediate variables is:

${+immediate_variable ...}

There is currently only one immediate variable defined:

  • +content โ€” this special variable is replaced by the data content of the current element. ๐ŸŒธ

๐ŸŽ€ Examples ๐ŸŽ€

The following will output the given string for elements whose generic identifier is P (for paragraph). At the start of processing this element, the program ensures that the output starts on a new line, the troff macro <.P> is output, then a newline. At the end of this element processing, the program ensures that the output starts on a new line.

GI:             P
StartText:      ^.P^
EndText:        ^
-

The following will output the given string for elements whose generic identifier is CMD-ARGUMENT and which have an attribute PRESENCE set to the value OPTIONAL.

GI:             CMD-ARGUMENT
AttValue:       PRESENCE OPTIONAL
StartText:      $\\[
EndText:        $\\]
-

The following prints the section number, title, and page number of the target of a cross reference. Assume the cross reference points to a section element, which contains a title element. The criteria for this spec to match is that the attribute OSFROLE is set to the value getfull. The action is to replace the content of the <XREF> element with the given string. When processing the string, instant will follow the IDREF attributes of <XREF> until an element with no IDREF attributes is found. It will then apply the transpec numbered 87 to that element, which will print the name of the GI in mixed case into the output stream. It will then print the LaTeX reference instruction with the value of the LINKEND attribute as an argument. (This will become the section number after processing by LaTeX.) It will then follow IDREFs until it finds an element whose GI is TITLE or which has a child element with that GI. It will apply the transpec numbered 1 to that element, which copies the title into the output stream where the cross reference occurs. Finally, it will print the word page followed by the LaTeX instruction to obtain the page number of a reference. ๐Ÿ˜ค iconic behavior, honestly

GI:             XREF
AttValue:       OSFROLE getfull
Replace:        ${_followlink 87} \\ref{${LINKEND}},\s
                {\\bf ${_chasetogi TITLE 1}}, page \\pageref{${LINKEND}}
-
# Print GI name, in mixed case
GI:             _pr_gi_name
SpecID:         87
Ignore:         1
EndText:        ${_gi M}
-
GI:             _pass-text
SpecID:         1
-

and that's a wrap, bestie!! ๐ŸŽ€โœจ this whole page is filed under the file format section as transpec(5) โ€” go forth and transform, you absolute icon ๐Ÿ’…๐Ÿ‘‘

๐Ÿ“ฆ where this page comes from