Advertisement
T3RRYT3RR0R

MenuMacro

Jan 21st, 2024 (edited)
1,185
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Batch 8.11 KB | Software | 0 0
  1. @Echo off
  2.     REM Setlocal EnableDelayedExpansion
  3.  
  4. ======================================================================================
  5.     REM Modular menu macro by T3RRY T3RR0R
  6.         REM https://pastebin.com/K3LpJXh5
  7.         REM to discuss batch macro techniques Join https://discord.gg/HCSEC829F9
  8.  
  9.     ================================================ REM = Menu macro Definition BEGIN
  10.     REM IMPORTANT - Defines the following Variables:    \n Console_Width Menu*
  11.         REM         Reserved Variable Prefix:           Menu
  12.         REM          - Do not define other variables with the leading name 'Menu' in your
  13.         REM         script to prevent any possibility of variable contamination.
  14.  
  15.     REM Version Update 24/01/2024
  16.         REM Incorporate ADS redirection + More command to handle cases where
  17.         REM Menu output exceeds the consoles height and scrolling is disabled.
  18.  
  19.     REM Version Update 21/01/2024
  20.         REM Variable Structure reworked to minimize variable reservations required by
  21.         REM constraining all internal variables to a single  prefix: menu*
  22.         REM Macro help and usage now embeded in the Macro.
  23.         REM Expanding the macro without arguments will now display the help output.
  24.         REM return variables are now named:
  25.         REM                                 Menu{String}
  26.         REM                                 Menu{Key}
  27.         REM                                 Menu{Number}
  28.  
  29.     REM Macro definition and expansion environment trickery pioneered by Jeb
  30.         REM Recommended Learning resources:
  31.         REM https://www.dostips.com/forum/viewtopic.php?t=9265#p60294
  32.         REM https://www.dostips.com/forum/viewtopic.php?f=3&t=10983&sid=f6937e02068d93bc5a97ef63d4e5319e
  33.         REM Macros with arguments learning resource:
  34.         REM https://www.dostips.com/forum/viewtopic.php?f=3&t=1827
  35.  
  36. (Set \n=^^^
  37.  
  38. %= Newline var \n for multi-line macro definition - Do not modify This codeblock. =%)
  39.  
  40. REM - use REM / remove REM on the below line to enable / disable menu dividing line
  41.     REM Goto :NoDividingLine
  42.  
  43.     REM Enable DE environment to perform variable concatenation within a for loop
  44.         Setlocal EnableDelayedExpansion
  45.  
  46.     REM Get console width for dividing line
  47.     For /f "usebackq tokens=2* delims=: " %%W in (`mode con ^| %__APPDIR__%findstr.exe /LIC:"Columns"`) do Set /A Console_Width=%%W
  48.         Set "Menu_Div=" & For /L %%i in (1 1 %Console_Width%)Do Set "Menu_Div=!Menu_Div!-"
  49.         Endlocal & Set "Menu_Div=%Menu_Div%"
  50.  
  51. :NoDividingLine
  52.     REM Menu internal variables
  53.     REM keymap. translates literal keypress to the numeric position of the item in the menu list
  54.         Set /a Menu@0=36,Menu@1=1,Menu@2=2,Menu@3=3,Menu@4=4,Menu@5=5,Menu@6=6,Menu@7=7,Menu@8=8,Menu@9=9,Menu@a=10,Menu@b=11,Menu@c=12,Menu@d=13,Menu@e=14,Menu@f=15,Menu@g=16,Menu@h=17,Menu@i=18,Menu@j=19,Menu@k=20,Menu@l=21,Menu@m=22,Menu@n=23,Menu@o=24,Menu@p=25,Menu@q=26,Menu@r=27,Menu@s=28,Menu@t=29,Menu@u=30,Menu@v=31,Menu@w=32,Menu@x=33,Menu@y=34,Menu@z=35
  55.     REM Valid choice characters
  56.         Set "Menu.Keys=123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0"
  57.         Set "Menu.Hash=Header"
  58.  
  59. REM Menu macro Usage: %Menu% "quoted" "list of" "options"
  60. %= Outer for loop allows environment independant definition =% For /f %%! in ("! ^! ^^^!") Do ^
  61. %= IMPORTANT - No whitespace permitted here =%Set ^"Menu=For %%n in (1 2)Do if %%n==2 (%\n%
  62.     If defined Menu{Args} (%\n%
  63.         %= Switch control via !! Expansion outcome  =%  for /f "tokens=2" %%? in ("%%!%%! 1 0") do (%\n%
  64.         %= Switch - Setlocal / NOP                  =%    If %%~? EQU 1 SetLocal EnableDelayedExpansion%\n%
  65.         %= Output Dividing Line                     =%    ^>"%~f0:MenuMacro:$Data" (%\n%
  66.         %= If Header Substitute Output substitution =%    If not "Header" == "%%!Menu.Hash%%!" (%\n%
  67.                                     If Defined Menu_Div Echo(%%!Menu_Div%%!%\n%
  68.                                     Echo(Header%\n%
  69.                                   )%\n%
  70.                                   If Defined Menu_Div Echo(%%!Menu_Div%%!%\n%
  71.         %= Reset Menu.# index for Menu.Item[#]      =%    Set "Menu.#=0"%\n%
  72.         %= Undefine choice command key list         =%    Set "Menu.Chars="%\n%
  73.         %!! Each in List =%    For %%G in (%%!Menu{Args}%%!)Do (%\n%
  74.         %= For Menu.Item Index value                =%      For %%i in (%%!Menu.#%%!)Do If not %%i GTR 35 (%\n%
  75.         %= Build the Choice key list                =%        Set "Menu.Chars=%%!Menu.Chars%%!%%!Menu.Keys:~%%i,1%%!"%\n%
  76.         %= Define Menu.Item array                   =%        Set "Menu.Item[%%!Menu.Keys:~%%i,1%%!]=%%~G"%\n%
  77.         %= Assign String for safe output            =%        Set "Menu.Output=%%~G"%\n%
  78.         %= Display as [key] Option String           =%        Echo([%%!Menu.Keys:~%%i,1%%!] %%!Menu.Output%%!%\n%
  79.         %= Increment Menu.# Index var               =%        Set /A "Menu.#+=1"%\n%
  80.         %= Close Menu.# expansion loop              =%      )%\n%
  81.         %= Close Menu{Args} String loop             =%    )) %\n%
  82.         %= Read output in from ADS to permit More   =%    More ^< "%~f0:MenuMacro:$Data"%\n%
  83.         %= Output Dividing Line                     =%    If Defined Menu_Div Echo(%%!Menu_Div%%!%\n%
  84.         %= Select option by character index         =%    For /f "delims=" %%o in ('%__APPDIR__%Choice.exe /N /C:%%!Menu.Chars%%!')Do For /f "tokens=1,2 delims=;" %%V in ("%%!Menu.Item[%%o]%%!;%%!Menu@%%o%%!")Do (%\n%
  85.         %= Switch - Endlocal / NOP ; returnVars     =%      ( If %%~? EQU 1 EndLocal ) ^& (%\n%
  86.         %= exit [sub]script w/out modifying option  =%        If /I "%%V" == "Exit" Exit /B 2%\n%
  87.         %= Assign 'Menu{String}' w/literal string   =%        Set "Menu{String}=%%V"%\n%
  88.         %= Assign 'Menu{key}' with key pressed      =%        Set "Menu{Key}=%%o"%\n%
  89.         %= Assign 'Menu{Number} with list position  =%        Set "Menu{Number}=%%~W"%\n%
  90.         %= Reset Menu Argument variable             =%        Set "Menu{Args}="%\n%
  91.         %= Set errorlevel to match Menu{Number}     =%        CMD /C Exit %%~W%\n%
  92.         %= Close Menu macro processing loops        =%  )  )  )%\n%
  93.     )Else (%\n: Show Macro Help if no arguments supplied - will not display if expanded menu variable has trailing whitespace =%
  94.         CLS%\n%
  95.         Echo(Usage:%\n%
  96.         Echo(%\n%
  97.         Echo(%%Menu%%%\n%
  98.         Echo(       Output this help info, Set Errorlevel 0%\n%
  99.         Echo(%\n%
  100.         Echo(%%Menu%% "DoubleQuoted List" "Of Options"%\n%
  101.         Echo(       Output the Menu list, Take input%\n%
  102.         Echo(%\n%
  103.         Echo(%%Menu:Header=Your Custom Header%% "DoubleQuoted List" "Of Options"%\n%
  104.         Echo(       Outputs substituted Header, Output Menu list; Take input%\n%
  105.         Echo(%\n%
  106.         Echo(Return Variables:%\n%
  107.         Echo(       Menu{String}    : The literal String%\n%
  108.         Echo(       Menu{Key}   : The Key Pressed%\n%
  109.         Echo(       Menu{Number}    : The list position of the option as an Integer%\n%
  110.         Echo(                 IE:   Option 1 = 1, Option A = 10%\n%
  111.         Echo(                 Note: The Errorlevel is also set to this value%\n%
  112.         Echo(%\n%
  113.         Echo(  Note:      The number of options available is limited to 36.%\n%
  114.         Echo(%\n%
  115.         Echo(  Important: The following variable prefix is reserved: Menu%\n%
  116.         Echo(%\n%
  117.         Pause%\n%
  118.         CLS%\n%
  119.         %= If Menu expanded without Args Set Errorlevel 0 =%(Call )%\n%
  120.     )%\n%
  121. %= Capture Macro input - Options List       =%)Else Set Menu{Args}=^"
  122. ========================================== REM = Menu Macro Definition END
  123.  
  124. REM Below lines Not required if macro definition is pasted within another script
  125.     REM Load macro from a calling script using any arg within the Findstr Search strings below; Return to caller
  126.     If Not "%~1" == "" Echo(%*|%SystemRoot%\System32\findstr.exe /LI "/D Def Menu Load Menu Get" 2>&1 > nul && Exit /b 0
  127.  
  128. REM Below lines Are Demo Only.
  129.     REM Everything from this line and below is example usage only.
  130.     REM demonstrates retention of last option variables upon selection of exit
  131.     REM Call:DemoMenu
  132.     REM Echo(You last chose %Menu{String}% by pressing %Menu{Key}% at index %Menu{Number}%
  133.     REM Exit /b 0
  134.  
  135.     REM view macro usage by expanding without arguments
  136.     %Menu%
  137.  
  138.     REM Apply Header using substring when expanding macro
  139.     %Menu:Header=This is a demo Header% "See next demo" "Close after seeing this demo's output"
  140.     Echo(You Pressed %Menu{key}% to Choose '%Menu{String}%'; option number = %Menu{Number}%
  141.     If %Menu{Number}% EQU 2 Exit /b 0
  142.     Pause
  143.  
  144. :DemoMenu
  145.     CLS
  146.  
  147.     %Menu% List of your Options here. "Double qoute" "Delimited Strings" filler to extend option count. caps at 36 \ / \ / \ / \ / \ / \ / \ / \ / \ / \ . Exit \ .
  148.     Echo(You Pressed %Menu{key}% to Choose '%Menu{String}%'; option number = %Errorlevel%
  149.     Pause
  150.     Goto:DemoMenu
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement