X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/mup/blobdiff_plain/cdb3c0882392596f814cf939cbfbd38adc6f2bfe..ddf6330b56bcfb657e0186b24b9b1422c51d3424:/mup/docs/uguide/macros.html diff --git a/mup/docs/uguide/macros.html b/mup/docs/uguide/macros.html new file mode 100644 index 0000000..4274b8d --- /dev/null +++ b/mup/docs/uguide/macros.html @@ -0,0 +1,211 @@ + +
+ <-- previous page + + Table of Contents next page --> +
+ +
+Macros can be defined to avoid retyping or to give mnemonic names to
+things. A macro is defined with the following syntax:
+
+define macro_name macro_text @ +
+The macro_name consists of one or more upper case letters, digits, +and underscores, with the first character being a letter. +The macro_text can be any text. It can be any length from empty +to many pages. The "@" terminates the macro. A literal "@" can be +placed in the macro_text by preceding it with a backslash. +If you want a literal backslash in the macro_text, it also must +be preceded by a backslash. +
++A macro is called by stating the macro_name in the input. The +macro_name is replaced by the macro_text. +A macro can be defined at any point in the input. It can be used as +often as desired any time after it has been defined. A given macro_name +can be redefined as many times as desired, with each new definition +overwriting the previous definition. +
+
+As an example, suppose you are printing an orchestral score, and the oboe
+part happens to be on staff 5. Rather than having to remember which staff
+it is, you could define a macro:
+
+define OBOE 5: @ +
+Another common use of macros might be if a musical motif occurs several
+times. You could define a macro for the motive:
+
+define SCALE 8c;d;e;f;g;a;b;c+; @ +
+OBOE SCALE +
+It is possible to remove the definition of a macro using the "undef"
+statement:
+
+undef OBOE +
+It is possible to have parts of the input skipped over depending on whether +certain macros are defined or not. This is done using +"ifdef," "else," and "endif." The keyword "ifdef" is followed by +a macro name. If a macro by that name is currently defined, +Mup will continue +reading and processing input normally. If it finds a matching "else," +it will skip over input until the matching "endif." +If the macro is not currently defined, Mup will skip over the input +until it finds a matching "else" or "endif." There is also +an "ifndef" command that uses the opposite logic: it will read the input +up to the "else" or "endif" only if the macro is NOT defined. +
+
+The ifdefs can be sprinkled between other items in the input;
+they need not be on separate lines. They can be nested. Examples:
+
+// make last c an octave higher if macro "FRED" is defined +1: c;e;g;c ifdef FRED + endif; + +ifdef PIANO + staff 1 visible=n +else + ifdef VIOLIN + staff 2 visible=n + staff 3 visible=n + endif +endif +
+Macros can also be set from the command line using the -D option. +Only ordinary macros can be defined using the -D option, +not macros with parameters. +
++Macros defined within Mup input can be defined to have "parameters." +This may be useful +when you have something that is repeated with small variations. +When defining a macro with parameters, the macro name must be followed +immediately by a ( with no space between the end of the name and the +parenthesis. The opening parenthesis is followed by one or more +parameter names, separated by commas, and ending with a close parenthesis. +Parameter names have the same rules as macro names: they consist of +upper case letters, numbers, and underscores, starting with an upper case +letter. The parameter names can then appear in the text of the macro +definition where you want a value to be substituted. +
+
+As an example, suppose you are doing a score with staffs 1 through 4
+for vocal parts, and staffs 5 and 6 for a piano accompaniment, and that
+you frequently want to mark a dymanics change at the same point in time
+below each of the vocal scores and between the two piano staffs.
+You could typically do this with something like:
+
+boldital below 1-4: 1 "ff"; +boldital between 5&6: 1 "ff"; +
+define DYN( COUNT, VOLUME ) +boldital below 1-4: COUNT VOLUME; +boldital between 5&6: COUNT VOLUME; +@ +
+DYN(1,"ff") +
+DYN(3.5,"mp") +
+When calling a macro with parameters, the values to give the parameters
+are given inside parentheses. The values are separated by commas.
+The values in the parentheses are copied exactly as they are,
+including any spaces, newlines, macro names, etc.
+There are only a few exceptions to this:
+you can include a comma, closing parenthesis, or backslash
+as part of a parameter value by preceding it with a backslash, and
+a backslash followed by a newline
+in a parameter value will be discarded. Thus a macro call of
+
+MAC(\\\,\)) +
+If in a macro definition a parameter is used inside backticks,
+as in `NAME`, the value of the parameter will be placed
+inside double quotes. Thus, another way to do the example above would be:
+
+define DYN( COUNT, VOLUME ) +boldital below 1-4: COUNT `VOLUME`; +boldital between 5&6: COUNT `VOLUME`; +@ + +DYN(1,ff) +DYN(3.5,mp) +
+Conceptually, when the macro is expanded, the backticks are replaced
+by double quote marks, but in addition,
+any double quote mark found in the value being passed to the parameter will
+have a backslash inserted before it, and any backslash that occurs
+within double quotes in the value will also have a backslash inserted
+before it. Thus, for example:
+
+// If we define a macro like this: +define QUOTED(X) `X` @ + +// then for input value passed is `X` would be which would print as + +print QUOTED(hello) hello "hello" hello +print QUOTED("hello") "hello" "\"hello\"" "hello" +print QUOTED(\\n) \n "\n" a literal newline +print QUOTED("\\n") "\n" "\"\\n\"" "\n" +
+Sometimes it can be a little tricky to get the number of backslashes right, +or other details like that. +The -E Mup command line option +shows how macros will expand, which may help you figure out what to do. +
+