macro Full Description |
|
Syntaxmacro macro-name ( (arg argument-name delimiter) | (token argument-name delimiter?))* is macro-body macro-end Where:
argument-name
delimiter
macro-body
Purpose Defines a macro. Macros are used for two purposes -- to define constants and to extend the language. Defining constants is simple:
macro five is 5 macro-end macro mary is "Mary had a little lamb%n" macro-end macro tom tom is "Tom, Tom, the piper's son.%n" macro-end find mary local counter x initial {five} output "%d(x)%n" output tom tomNotice that a macro name can contain spaces, as in "tom tom" above. The sample above shows that a constant defined by a macro can be used either as a text or number replacement or as a pattern. You can also include patterns in a constant to form a new pattern. This is the simplest form of extending the language. Here the pattern for finding valid SGML names is encapsulated by a macro:
macro sgml-name is (letter [letter | digit | "-."]*) macro-endNote the parentheses around the pattern elements in the macro. These are not required to define the macro, but they are useful idea because they ensure that the new pattern will be treated as a single unit when the macro is expanded. Among other benefits, this ensures that sgml-name => name will work as you expect.
Extending the language becomes a little more complex if you need to provide parameters to your macros. One classic language extension is the "upto" macro which matches characters up to a specified pattern. It is defined:
macro upto (arg pat) is ((lookahead not (pat)) any)+ macro-end process submit "Mary had a little lamb" find "Mary" upto ("little") => found-stuff output found-stuff find any Apart from being extremely useful, this macro illustrates several important points about macros. First of all, the name of this macro is not actually "upto", but "upto (". The parentheses are not part of OmniMark's syntax for defining macros, they are actually part of the syntax of the macro being defined. So what about the closing parenthesis? It is the delimiter of the first (and, in this case, only) parameter, which is defined by the keyword find "xyz" upto ( "@" letter+ "$" ) If you define a macro with multiple parameters you can do it like this, using traditional parentheses and commas for delimiters:
macro sum ( arg n1, arg n2, arg n3) is n1 + n2 + n3 macro-end process local counter n set n to sum (1, 2, 3) But you can also define a macro using any delimiters you like, including ones that contain spaces:
macro sum > arg n1 big dog arg n2 / arg n3 ! is n1 + n2 + n3 macro-end process local counter n set n to sum >1 big dog 2/ 3! The above code works but its meaning is not very clear. There are ways to make your language extensions clearer by using appropriate words or punctuation as delimiters:
macro sum arg n1 and arg n2 and token n3 is (n1 + n2 + n3) macro-end process local counter n set n to sum 12 and 52 and 37This code introduces a new way to parameterize a macro -- the token keyword. When using "and" as a delimiter you obviously don't want a delimiter after the last parameter. To define a macro without a following delimiter, you can use token instead of arg .
As its name implies, a There is one other important difference between "arg" and "token" parameterization. Parameters declared with macro at-dollar is ("@" letter+ "$") macro-end find "xyz" upto ( at-dollar )But if "upto" were defined (less usefully) as taking a token argument, this would not work: macro upto token pat is ((lookahead not (pat)) any)+ macro-end macro at-dollar is "@" letter+ "$" macro-end find "xyz" upto at-dollar ;error! The following restrictions apply to macro use:
Where two macros have names which start with the same word or words, the longer name will always be matched if possible. Thus, given:
macro go ... macro sleep ... macro go to ... macro to sleep ... process go to sleep go sleepthe sequence go to sleep will invoke the "go to" macro, followed by the "sleep" macro, not "go" followed by "to sleep". The sequence go sleep will invoke the "go" macro followed by the "sleep" macro.
Macros cannot represent partial names. Consider a program that uses long counter names like macro chp is chapter macro-end macro num is number macro-end The name Macros cannot be redefined. Once a macro name has been defined, another macro cannot be defined with the same name in the same OmniMark program. Attention has been paid to this requirement when an Versions of OmniMark prior to V3 allowed you to use the back-quote character in macro names. If your program uses the back-quote character you must:
|