Macro for Dummies
Posted: 10 Feb 2024 00:27
As requested by @miskox at viewtopic.php?f=3&t=10983#p69429
As remarked within the code, this template is intended to make it easy to create macro's that take arguments
The template does nothing with the arguments other than splitting them and returning them in an array.
Features:
- Basic error handling
- Flag if expanded in envirronment without EDE
- Output Usage if expanded without Arguments
- Support for a large number of arguments - 750 innately, but the true determining factor will be the input length of the argument string
- Custom Variable name for the $Return Array via sting substitution when expanded.
- Template specifies:
- where you need to add in your custom proccessing of the arg
- where to insert help specific to your macro
CTRL + H may be used to replace $Macro.Template with your own macro name.
Edits: Fixed Typo's
As remarked within the code, this template is intended to make it easy to create macro's that take arguments
The template does nothing with the arguments other than splitting them and returning them in an array.
Features:
- Basic error handling
- Flag if expanded in envirronment without EDE
- Output Usage if expanded without Arguments
- Support for a large number of arguments - 750 innately, but the true determining factor will be the input length of the argument string
- Custom Variable name for the $Return Array via sting substitution when expanded.
- Template specifies:
- where you need to add in your custom proccessing of the arg
- where to insert help specific to your macro
CTRL + H may be used to replace $Macro.Template with your own macro name.
Code: Select all
@Echo off & Setlocal EnableExtensions & CLS
REM Author: T3RR0R, aka T3RRY. 10/02/2024
REM Discuss with author at https://discord.gg/HCSEC829F9
REM
REM - A template for the creation of macros with arguments
REM Macros may be defined in either Delayed enabled or disabled environments, but will require
REM Delayed expansion to be enabled in order for them to be expanded.
REM
REM EXPLAINER
REM - Macro's offer superior performance to CALLed :functions, however involve an
REM increased degree of complexity in their definition and use.
REM This template aims to reduce the learning curve required and make macro's more accessible
REM As such, no processing of the Arguments provided to the Macro is performed
REM
REM Any Macro specific processing is to be defined by You, the user, where the template notes
REM to insert such processing.
REM
REM The DEFAULT behavior is to split the arguments into an Array defined to $Return[#], where
REM # is the current index of the Array (1 indexed).
REM The size of the Array is returned in $Return[i]
REM $Return may be substituted using Substring Modification with a custom variable name at the
REM time of expansion.
REM
REM Use the search and replace tool of your script editor to replace $Macro.Template with the
REM intended name of your Macro
REM Recommended Learning resources:
REM [1] https://www.dostips.com/forum/viewtopic.php?t=9265#p60294
REM [2] https://www.dostips.com/forum/viewtopic.php?f=3&t=10983&sid=f6937e02068d93bc5a97ef63d4e5319e
REM - Macros with arguments:
REM [3] https://www.dostips.com/forum/viewtopic.php?f=3&t=1827
REM - CMD parsing behaviour:
REM [4] https://stackoverflow.com/questions/4094699/how-does-the-windows-command-interpreter-cmd-exe-parse-scripts
REM String length method is a modified version originally produced by JEB
REM See link at resource [2] above.
(Set $\n=^^^
%= DO NOT MODIFY $\n newline variable for multi-line macro definition =%)
REM - Each internal line of multiline macro's must be terminated with the escaped linefeed variable:
REM %$\n%
REM - EnableDelayedExpansion Aka EDE required to %expand% macro/s
REM May be placed before or after Macro definiton.
Setlocal EnableDelayedExpansion
For /f %%! in ("! ^! ^^^!") Do %= This outer loop allows DDE or EDE environment independant definition =%^
%= IMPORTANT - No whitespace permitted here =%Set $Macro.Template=For %%n in (1 2)Do if %%n == 2 (%$\n%
If "%%!%%!" == "" (%$\n: Error Check - DDE or EDE state. If Delayed expansion [EDE] is enabled; enact macro =%
If not "%%!$Macro.Template.Args%%!" == "" (%$\n: Arg Validation; If Macro expanded with args enact arg processing =%
If "%%!$Macro.Template.Args:~0,1%%!" == " " Set "$Macro.Template.Args=%%!$Macro.Template.Args:~1%%!"%$\n%
Set "$Macro.Template.Args=%%!$Macro.Template.Args:" "=","%%!"%$\n%
For /l %%i in (1 1 750)Do If defined $Macro.Template.Args For /f "tokens=1 Delims=," %%? in ("%%!$Macro.Template.Args%%!")Do If not %%? == "" (%$\n: Split Args =%
Set "$Macro.Template.ThisArg=%%~?"%$\n%
(Set^^ "$_=%%~?")%$\n%
If Defined $_ (%$\n: Get Arg Len to Shift Arg =%
Set "$Macro.Template.ThisArg.Len=1"%$\n%
For %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1)Do (%$\n%
If "%%!$_:~%%P,1%%!" NEQ "" (%$\n%
Set /a "$Macro.Template.ThisArg.Len+=%%P"%$\n%
Set "$_=%%!$_:~%%P%%!"%$\n%
)%$\n%
)%$\n%
)Else set "$Macro.Template.ThisArg.Len=0"%$\n%
Set /a "$Macro.Template.ThisArg.Len+=3"%$\n%
For /F "delims=" %%i in ("%%!$Macro.Template.ThisArg.Len%%!")Do Set "$Macro.Template.Args=%%!$Macro.Template.Args:~%%i%%!"%$\n: Shift Arg =%
%$\n: INSERT CUSTMIZED PROCESSING OF ARGUMENT HERE; TERMINATE EACH LINE WITH $\n VARIABLE =%
Set "$Return[%%i]=%%!$Macro.Template.ThisArg%%!"%$\n%
Set "$Return[i]=%%i"%$\n%
)%$\n%
)Else (%$\n: ARS INVALIDATED; OUTPUT USAGE =%
Echo(%$\n%
Echo(Usage:%$\n%
Echo( %%$Macro.Template%% "arg string" "arg string" "arg String"%$\n%
Echo( - Or -%$\n%
Echo( %%$Macro.Template%% "arg string","arg string","arg String"%$\n%
Echo(%$\n%
Echo( %%$Macro.Template:$Return=ReturnName%% "arg string","arg string","arg String"%$\n%
Echo( Use Substitution to provide a custom return variable name by replacing $Return%$\n%
Echo(%$\n%
Echo( - Arguments must be double quoted: "argument"%$\n%
Echo( - Arguments must not contain ',' characters.%$\n%
Echo( Comma: ',' is used internally to seperate arguments.%$\n%
Echo( - Arguments may be seperated by either whitespace: " " or Comma: ","%$\n%
Echo(%$\n%
%$\n: INSERT CUSTOMIZED MACRO HELP HERE; TERMINATE EACH LINE WITH $\n VARIABLE =%
)%$\n%
)Else (%$\n: NO EDE - Notify Environment requirement =%
Echo(%$\n%
Echo( %%! Delayed Expansion is currently Disabled.%$\n%
Echo( To successfully expand %%$Macro.Template%%, the command:%$\n%
Echo(%$\n%
Echo(Setlocal EnableDelayedExpansion%$\n%
Echo(%$\n%
Echo( is required *before* this macro command.%$\n%
Echo(%$\n%
)%$\n%
)Else Set $Macro.Template.Args=%= Capture macro Args =%
Echo(Example:
Echo(%%$Macro.Template:$Return=My Array%% "Arg one" "Arg two" "<a=b>" "this=?" "and*" "Hello World^^^!"
%$Macro.Template:$Return=My Array% "Arg one" "Arg two" "<a=b>" "this=?" "and*" "Hello World^^^!"
Set "My Array"
REM Usage displayed if expanded with no args
%$Macro.Template%
Setlocal DisableDelayedExpansion
%$Macro.Template% "Demo Macro Error output in Environment Without EnableDelayedExpansion"
(
Endlocal & Endlocal & Endlocal
Pause
)