groff: Identifiers

 
 5.5 Identifiers
 ===============
 
 An "identifier" labels a GNU 'troff' datum such as a register, name
 (macro, string, or diversion), typeface, color, special character,
 character class, environment, or stream.  Valid identifiers consist of
 one or more ordinary characters.  An ordinary character is an input
 character that is not the escape character, a leader, tab, newline, or
 invalid as GNU 'troff' input.
 
    Invalid input characters are a subset of control characters (from the
 sets "C0 Controls" and "C1 Controls" as Unicode describes them).  When
 GNU 'troff' encounters one in an identifier, it produces a warning in
 category 'input' (⇒Warnings).  They are removed during
 interpretation: an identifier 'foo', followed by an invalid character
 and then 'bar', is processed as 'foobar'.
 
    On a machine using the ISO 646, 8859, or 10646 character encodings,
 invalid input characters are '0x00', '0x08', '0x0B', '0x0D'-'0x1F', and
 '0x80'-'0x9F'.  On an EBCDIC host, they are '0x00'-'0x01', '0x08',
 '0x09', '0x0B', '0x0D'-'0x14', '0x17'-'0x1F', and '0x30'-'0x3F'.(1)
 (⇒Identifiers-Footnote-1) Some of these code points are used by
 GNU 'troff' internally, making it non-trivial to extend the program to
 accept UTF-8 or other encodings that use characters from these
 ranges.(2)  (⇒Identifiers-Footnote-2)
 
    Thus, the identifiers 'br', 'PP', 'end-list', 'ref*normal-print',
 '|', '@_', and '!"#$%'()*+,-./' are all valid.  Discretion should be
 exercised to prevent confusion.  Identifiers starting with '(' or '['
 require care.
 
      .nr x 9
      .nr y 1
      .nr (x 2
      .nr [y 3
      .nr sum1 (\n(x + \n[y])
          error-> a space character is not allowed in an escape
          error->   sequence parameter
      A:2+3=\n[sum1]
      .nr sum2 (\n((x + \n[[y])
      B:2+3=\n[sum2]
      .nr sum3 (\n[(x] + \n([y)
      C:2+3=\n[sum3]
          => A:2+3=1 B:2+3=5 C:2+3=5
 
 An identifier with a closing bracket (']') in its name can't be accessed
 with bracket-form escape sequences that expect an identifier as a
 parameter.  For example, '\[foo]]' accesses the glyph 'foo', followed by
 ']' in whatever the surrounding context is, whereas '\C'foo]'' formats a
 glyph named 'foo]'.  Similarly, the identifier '(' can't be interpolated
 _except_ with bracket forms.
 
    If you begin a macro, string, or diversion name with either of the
 characters '[' or ']', you foreclose use of the 'grefer' preprocessor,
 which recognizes '.[' and '.]' as bibliographic reference delimiters.
 
  -- Escape sequence: \A'anything'
      Interpolate 1 if ANYTHING is a valid identifier, and 0 otherwise.
      The delimiter need not be a neutral apostrophe; see ⇒
      Delimiters.  Because invalid input characters are removed (see
      above), invalid identifiers are empty or contain spaces, tabs, or
      newlines.
 
      You can employ '\A' to validate a macro argument before using it to
      construct another escape sequence or identifier.
 
           .\" usage: .init-coordinate-pair name val1 val2
           .\" Create a coordinate pair where name!x=val1 and
           .\" name!y=val2.
           .de init-coordinate-pair
           .  if \A'\\$1' \{\
           .    if \B'\\$2' .nr \\$1!x \\$2
           .    if \B'\\$3' .nr \\$1!y \\$3
           .  \}
           ..
           .init-coordinate-pair center 5 10
           The center is at (\n[center!x], \n[center!y]).
           .init-coordinate-pair "poi->nt" trash garbage \" ignored
           .init-coordinate-pair point trash garbage \" ignored
               => The center is at (5, 10).
 
      In this example, we also validated the numeric arguments; the
      registers 'point!x' and 'point!y' remain undefined.  ⇒Numeric
      Expressions for the '\B' escape sequence.
 
    How GNU 'troff' handles the interpretation of an undefined identifier
 depends on the context.  There is no way to invoke an undefined request;
 such syntax is interpreted as a macro call instead.  If the identifier
 is interpreted as a string, macro, or diversion, GNU 'troff' emits a
 warning in category 'mac', defines it as empty, and interpolates
 nothing.  If the identifier is interpreted as a register, GNU 'troff'
 emits a warning in category 'reg', initializes it to zero, and
DONTPRINTYET  interpolates that value.  ⇒Warnings, *noteInterpolating
DONTPRINTYET  interpolates that value.  ⇒Warnings, ⇒Interpolating

 Registers, and ⇒Strings.  Attempting to use an undefined
 typeface, special character, color, character class, environment, or
 stream generally provokes an error diagnostic.
 
    Identifiers for requests, macros, strings, and diversions share one
 name space; special characters and character classes another.  No other
 object types do.
 
      .de xxx
      .  nop foo
      ..
      .di xxx
      bar
      .br
      .di
      .
      .xxx
          => bar
 
 The foregoing example shows that GNU 'troff' reuses the identifier
 'xxx', changing it from a macro to a diversion.  No warning is emitted,
 and the previous contents of 'xxx' are lost.