======Macro Command====== The ''Macro'' command allows a template section, containing data and/or PTPScript code, to be defined as a macro. In this context, a macro is essentially a sub-template, and behaves very much like a [[PTPScript:Functions|function]]. By default, it has its own [[PTPScript:Variables|Variable]] "[[PTPScript:Commands:Macro#Scope|scope]]" - it cannot access Variables that are available in the main template ([[PTPScript:Commands:Macro#Scope|PTPScript 4.1 added the ability to define macro scope]]). Any Variables that are created or modified within the macro will only affect the data inside that macro, unless the scope is changed. When a ''Macro'' command is first encountered, the macro data is not displayed, but is instead stored for later use. Parameters can be defined, so that values can be passed to the macro. When required, the macro can be displayed by calling it in the same way as a function. This means that the output of a macro can be used in an expression in the same way as that of a function. There are two commands in the ''Macro'' family - ''Macro'' and ''EndMacro''. Each ''Macro'' command has to have a corresponding ''EndMacro'' command. The ''Macro'' command consists of the command, followed by the macro name, and then the names of any parameters, contained within parentheses and separated by commas. The scope can also be changed. The ''EndMacro'' command does not use an expression, and so will ignore any expression given. For example: { macro Greeting ( Name, MealOfTheDay ) }… Hi there, {Name}! Would you like {MealOfTheDay}? { endmacro }… { Greeting ("Jim", "fish and chips") } Hi there, Jim! Would you like fish and chips? ''Macro'' names are case-insensitive, just like functions. ''Macro'' definitions and calls can be nested indefinitely within other ''Macro'' definitions, and within other command structures, however each macro is fully enclosed and cannot detect or affect anything else unless its scope is altered. All ''Macro'' definitions are global in scope - that is, they can be called from anywhere, no matter where they were defined. However, if defined within a macro, the containing macro has to be called before the definition will be processed. Macros can be re-declared without error. The latest definition will apply for all code following it. ===Checking for macros=== Sometimes it may be necessary to check for a macro, and in such a situation, [[PTPScript:Operators:Type Checking|type checking]] should be used to determine whether the macro has been defined. For example: { if "Greeting" is a macro }… { Greeting ("Jim", "fish and chips") } { endif } ===Resolving ambiguity=== Because macros are called in the same way as functions, a macro could be declared with the same name as a function. In this case, the function will always be called, not the macro. ====Scope==== The scope of each macro can be set as desired, at declaration time. The "scope" is the behaviour of Variables present in the macro, relative to the environment outside the macro. There are three kinds of scope, with various keywords for each, to provide flexibility to cater for different tastes. ^ Scope Type Keywords ^^^^ Description ^ | ''shared'' | ''inherited'' | ''mutable'' | ''same'' | All Variables will be available to the macro, and changes will be reflected in the original environment | | ''clean'' | ''fresh'' | ''separate'' | ''new'' | The macro will not inherit any Variables from the original environment, and vice versa (default) | | ''clone'' | ''preserved'' | ''immutable'' | ''copy'' | The macro will inherit all Variables from the original environment, but changes will not affect the original environment | The scope of each macro can be set by using the syntax ''macro (parameters...) as scope''. For example: { Name = "Jim" } { macro Greeting ( MealOfTheDay ) as shared }… Hi there, {Name}! Would you like {MealOfTheDay}? { endmacro }… { Greeting ("fish and chips") } Scope type keywords are case-insensitive. Macro scope can only be changed from PTPScript 4.1 onwards. PTPScript 4.0 anly allows macros to have ''clean'' scope - the default in PTPScript 4.1. Note that templates compiled by PTPScript 4.0 are incompatible with PTPScript 4.1 if they contain macros, and vice-versa. This means that cached templates need to be cleared when moving between versions (this is advisable in any case). Note that when macro scope is set to ''shared'', the parameters passed to the macro will themselves become part of the global environment. This defeats the point of macros, in many ways, as one of the benefits of using macros is encapsulation. If shared variables are needed, using a [[PTPScript:Commands:Section|section]] may be more appropriate.