T3RRYT3RR0R

PRO Cursor color and output control Macro

Jan 22nd, 2021 (edited)
729
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ::: Cout cursor Macro. Author: T3RRY ::: Filename: Cout.bat
  2. ::: OS requirement: Windows 10
  3. ::: Purpose: Facilitate advanced console display output with the easy use of Virtual terminal codes
  4. ::: Uses a macro function to effect display without users needing to memorise or learn specific
  5. ::: virtual terminal sequences.
  6. ::: Enables output of text in 255 bit color at absolute or relative Y;X positions.
  7. ::: Allows cursor to be hidden or shown during and after text output. See help for more info.
  8.  
  9. @Echo off & Setlocal EnableExtensions
  10. ============================================== :# Usage
  11.  If not "%~1" == "" Echo/%~1.|findstr /LIC:"/?" > nul && (
  12.   If "%~2" == "" (Cls &  Mode 1000,50 & Color 30)
  13.   If "%~2" == "Usage" ( Color 04 & ( Echo/n|choice /n /C:o 2> nul ) & timeout /T 5 > nul )
  14.   If "%~2" == "DE" ( Color 04 & Echo/                      --- Delayed expansion detected^^^! Must not be enabled prior to calling %~n0 ---&( Echo/n|choice /n /C:o 2> nul ))
  15.   If not Exist "%TEMP%\%~n0helpfile.~tmp" (For /F "Delims=" %%G in ('Findstr.exe /BLIC:":::" "%~f0" 2^> nul ')Do (
  16.    For /F "Tokens=2* Delims=[]" %%v in ("%%G")Do Echo(^|%%v^|
  17.   ))>"%TEMP%\%~n0helpfile.~tmp"
  18.   Type "%TEMP%\%~n0helpfile.~tmp" | More
  19.   timeout /T 60 > nul
  20.   Color 07
  21.   Exit /B 1
  22.  )
  23.  If "!![" == "[" Call "%~f0" "/?" "DE"
  24.  If Errorlevel 1 Exit /B 1
  25. :::[=====================================================================================================================]
  26. :::[ cout /?                                                                                                             ]
  27. :::[ * Valid Args for COUT: {/Y:Argvalue} {/X:Argvalue} {/S:Argvalue} {/C:Argvalue}                                      ]
  28. :::[       - Args Must be encased in curly braces. Arg order does not matter ; Each Arg is optional.                     ]
  29. :::[ * Valid Switches for COUT: /Save /Alt /Main                                                                         ]
  30. :::[ /Save - Stores the Y and X position at the start of the current expansion to .lY and .lX variables                  ]
  31. :::[ /Alt  - Switch console to alternate screen Buffer. Persists until /Main switch is used.                             ]
  32. :::[ /Main - Restore console to main screen Buffer. Console default is the main buffer.                                  ]
  33. :::[                                                                                                                     ]
  34. :::[   USAGE:                                                                                                            ]
  35. :::[ * ArgValue Options ; '#' is an integer:                                                                             ]
  36. :::[   {/Y:up|down|#} {/Y:up#|down#|#} {/Y:#up|#down|#} {/X:left|right|#} {/X:left#|right#|#} {/X:#left|#right|#}        ]
  37. :::[  * note: {/Y:option} {/X:option} - 1 option only per Arg.                                                           ]
  38. :::[        - directions: 'up' 'down' 'left' 'right' are relative to the cursors last position.                          ]
  39. :::[         - /Y and /X options - #direction or direction#:                                                             ]
  40. :::[           Positions the cursor a number of cells from the current position in the given direction.                  ]
  41. :::[           Example; To move the cursor 5 rows up in the same column, without displaying any new text:                ]
  42. :::[            %COUT%{/Y:5up}                                                                                           ]
  43. :::[        - '#' (Absolute position) is the column number {/X:#} or row number {/Y:#} the cursor                        ]
  44. :::[         * Integers for absolute positions contained in variables must be Expanded: {/Y:%varname%}                   ]
  45. :::[           is to be positioned at, allowing cursor position to be set on single or multiple axis.                    ]
  46. :::[         * Absolute Y and X positions capped at line and column maximum of the console display.                      ]
  47. :::[         * Exceeding the maximum Y positions the cursor at the start of the last line in the console display.        ]
  48. :::[         * Exceeding the maximum X positions the cursor at the start of the next line                                ]
  49. :::[                                                                                                                     ]
  50. :::[   {/S:Output String}                                                                                                ]
  51. :::[    /S Sub-Args: (-) (+) (K) (.#.)                                                                                   ]
  52. :::[   {/S:(-)Output String} * Hides the Cursor during output of the string.                                             ]
  53. :::[   {/S:Output String(+)} * Shows the Cursor after output of the string.                                              ]
  54. :::[   {/S:Output String(K)} * Clears the row of text from the position (K) occurs.                                      ]
  55. :::[   {/S:(.#.)}            * Delete # of characters from the current row to the right of the curser:                   ]
  56. :::[   {/C:VTcode} {/C:VTcode-VTcode} {/C:VTcode-VTcode-VTcode}                                                          ]
  57. :::[  * note: Chain multiple graphics rendition codes using '-'                                                          ]
  58. :::[  See:      https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences#text-formatting      ]
  59. :::[  See also: https://www.rapidtables.com/web/color/RGB_Color.html                                                     ]
  60. :::[=====================================================================================================================]
  61.  
  62. ============================================== :# PreScript variable definitions
  63.  
  64. rem /* generate Virtual Terminal Escape Control .Character */
  65.  For /F %%a in ( 'Echo prompt $E ^| cmd' )Do Set "\E=%%a"
  66. rem /* https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences */
  67. (Set \n=^^^
  68.  
  69. %= Newline variable for macro definitions. DO NOT MODIFY this line or above 2 lines. =%)
  70.  
  71. ================== :# Screen Dimensions [Customise columns,lines using the mode command.]
  72.  Mode 160,38 & Cls
  73. rem /* Get screen dimensions [lines] [columns]. Must be done before delayed expansion is enabled. */
  74.  For /F "tokens=1,2 Delims=:" %%G in ('Mode')Do For %%b in (%%H)Do For %%a in (%%G)Do Set "%%a=%%b"
  75.  
  76. rem /* NON ENGLISH VERSION USERS: You will need to manually set Columns and lines for their desired console size */
  77.  If not defined columns (Set "columns=100"& Set "lines=30")
  78.  
  79. rem /* Cursor position codes - https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences#simple-cursor-positioning */
  80.  Set "left=D"&Set "right=C"&Set "up=A"&set "down=B"
  81.  For /L %%n in (1 1 %lines%)Do (Set "%%ndown=[%%nB"&Set "down%%n=[%%nB"& set "%%nup=[%%nA"&Set "up%%n=[%%nA")
  82.  For /L %%n in (1 1 %columns%)Do (Set "%%nleft=[%%nD"&Set "left%%n=[%%nD"&set "%%nright=[%%nC"&set "right%%n=[%%nC")
  83.  
  84. %= Catch Args        =%Set COUT=For %%n in (1 2)Do If %%n==2 ( %\n%
  85. %= Test No Args       =%If "!Args!" == "" (CLS^&Echo/Usage Error. Args Required. ^& Call "%~f0" "/?" "Usage" ^|^| Exit /B 1) %\n%
  86. %= Test Braces Used   =%If "!Args:}=!" == "!Args!" (CLS^&Echo/Usage Error. Args must be enclosed in curly braces ^& Call "%~f0" "/?" "Usage" ^|^| Exit /B 1) %\n%
  87. %= Reset macro        =%Set ".Y=" ^& Set ".X=" ^& Set ".Str=" ^& Set ".C=" %\n%
  88. %=  internal vars     =%Set "Arg1=" ^& Set "Arg2=" ^& Set "Arg3=" ^& Set "Arg4=" %\n%
  89. %= Split Args.        =%For /F "Tokens=1,2,3,4 Delims={}" %%1 in ("!Args!")Do ( %\n%
  90. %= Substring           =%Set "Arg1=%%~1" %\n%
  91. %=  modification       =%Set "Arg2=%%~2" %\n%
  92. %=  identifies Args    =%Set "Arg3=%%~3" %\n%
  93. %=  during handling.   =%Set "Arg4=%%~4" %\n%
  94. %=                    =%) %\n%
  95. %= Check /Save switch =%If not "!Args:/Save=!" == "!Args!" (%\n%
  96. %= Reset Cursor Save   =%Set ".Cpos=" ^&Set ".Char="%\n%
  97. %!!%For /L %%l in (2 1 12)Do (%\n%
  98. %= until R returned     =%If not "!.Char!" == "R" (%\n%
  99. %= from esc[6n          =%^<nul set /p "=%\E%[6n" %\n%
  100. %= Redirects to          =%FOR /L %%z in (1 1 %%l) DO pause ^< CON ^> NUL%\n%
  101. %= prevent blocking      =%Set ".Char=;"%\n%
  102. %= script execution      =%for /F "tokens=1 skip=1 delims=*" %%C in ('"REPLACE /W ? . < con"') DO (Set ".Char=%%C")%\n%
  103. %= Append string w.out R =%If "!.Cpos!" == "" (Set ".Cpos=!.Char!")Else (set ".Cpos=!.Cpos!!.Char:R=!") %\n%
  104. %=                      =%)%\n%
  105. %=                     =%)%\n%
  106. %= Split Captured Pos  =%For /F "tokens=1,2 Delims=;" %%X in ("!.Cpos!")Do Set ".lY=%%X" ^& Set ".LX=%%Y" %\n%
  107. %= End of Pos /Save   =%)%\n%
  108. %= Begin Arg          =%For %%i in (1 2 3 4)Do For %%S in (Y X C S)Do If not "!Arg%%i!" == "" ( %\n%
  109. %= Processing. 4 Args   =%If not "!Arg%%i:/%%S:=!" == "!Arg%%i!" ( %\n%
  110. %= Flagged with Y X C S  =%Set "Arg%%i=!Arg%%i:/%%S:=!" %\n%
  111. %= Strip /Flag In Arg#   =%For %%v in ("!Arg%%i!")Do ( %\n%
  112. %= /Y Lines Arg handling  =%If "%%S" == "Y" ( %\n%
  113. %= Test if arg is variable =%If Not "!%%~v!" == "" ( %\n%
  114. %= assign down / up value   =%Set ".Y=%\E%!%%~v!" %\n%
  115. %= -OR-                    =%)Else ( %\n%
  116. %= assign using operation   =%Set /A ".Y=!Arg%%i!" %\n%
  117. %!!%If !.Y! GEQ !Lines! (Set /A ".Y=Lines-1") %\n%
  118. %= constrained to console   =%Set ".Y=%\E%[!.Y!d" %\n%
  119. %= maximum lines.         =%)) %\n%
  120. %= /X Cols Arg handling   =%If "%%S" == "X" ( %\n%
  121. %= processing follows same =%If Not "!%%~v!" == "" ( %\n%
  122. %!!%Set ".X=%\E%!%%~v!" %\n%
  123. %= except if Columns     =%)Else ( %\n%
  124. %= exceed console max     =%Set /A ".X=!Arg%%i!" %\n%
  125. %= columns line wrapping   =%If !.X! GEQ !Columns! (Set ".X=1"^& Set ".Y=%\E%!Down!") %\n%
  126. %= is effected.            =%Set ".X=%\E%[!.X!G" %\n%
  127. %=                       =%)) %\n%
  128. %= /C Color Arg Handling. %If "%%S" == "C" ( %\n%
  129. %= Substituition          =%Set ".C=%\E%[!Arg%%i!" %\n%
  130. %= replaces '-' with VT   =%Set ".C=!.C:-=m%\E%[!" %\n%
  131. %= chain - m\E[           =%Set ".C=!.C!m" %\n%
  132. %=                       =%) %\n%
  133. %= /S String Arg Handle  =%If "%%S" == "S" ( %\n%
  134. %=  Substitute Sub-Args   =%Set ".Str=!Arg%%i!" %\n%
  135. %=  (-) hide cursor        =%Set ".Str=!.Str:(-)=%\E%[?25l!" %\n%
  136. %=  (+) show cursor        =%Set ".Str=!.Str:(+)=%\E%[?25h!" %\n%
  137. %=  (K) clear line         =%Set ".Str=!.Str:(K)=%\E%[K!" %\n%
  138. %=  (.#.) delete # of      =%Set ".Str=!.Str:(.=%\E%[!" %\n%
  139. %=  characters             =%Set ".Str=!.Str:.)=P!" %\n%
  140. %=                       =%) %\n%
  141. %= End Arg Handling   =%))) %\n%
  142. %= /Main /Alt Switch  =%If not "!Args:/Main=!" == "!Args!" ( %\n%
  143. %= handling for       =%^< nul Set /P "=%\E%[?1049l!.Y!!.X!!.C!!.Str!%\E%[0m" %\n%
  144. %= switching console  =%)Else If not "!Args:/Alt=!" == "!Args!" ( %\n%
  145. %= buffers. No Switch =%^< nul Set /P "=%\E%[?1049h!.Y!!.X!!.C!!.Str!%\E%[0m" %\n%
  146. %= outputs to current =%)Else ( ^< nul Set /P "=!.Y!!.X!!.C!!.Str!%\E%[0m" ) %\n%
  147. %= buffer.           =%)Else Set Args=
  148.  
  149. rem /* Simple subsecond delay macro. Uses call to a non existentent label # number of times to delay script execution. */
  150.  For /F "tokens=1,2 delims==" %%G in ('wmic cpu get maxclockspeed /format:value')Do Set /A "%%G=%%H/15" 2> nul
  151.  If not defined Maxclockspeed Set "Maxclockspeed=200"
  152.  Set "Hash=#"& Set "delay=(If "!Hash!" == "#" (Set /A "Delay.len=Maxclockspeed")Else Set "Delay.len=#")& For /L %%i in (1 1 !Delay.Len!)Do call :[_false-label_] 2> Nul"
  153.  
  154. ============================================== :# Script Body [Demo]
  155. rem /* Enable Delayed Expansion after macro definiton in order to expand macro. */
  156.  Setlocal EnableDelayedExpansion & CD "%TEMP%"
  157. rem /* Usage examples */
  158.  %COUT%{/X:10}{/Y:5}{/C:34}{"/S:(-)hello there^^^!"}
  159.  %Delay%
  160. rem /* Example use of mixed foreground / background color and other graphics rendition properties */
  161.  %COUT%{"/C:31-1-4-48;2;0;80;130"}{/S:Bye for now.}{/Y:down}
  162.  %Delay%
  163.  %COUT%{/Y:up}{/C:35}{/S:again}{/X:16}
  164.  %Delay%
  165.  %COUT%{"/S:(K)^_^"}{/X:right}{/C:32}{/Y:down} /Save
  166.  %Delay%
  167. rem /* Switch to Alternate screen buffer: /Alt */
  168.  %COUT%{"/S:(-)(K)o_o"}{/X:.lX+1}{/Y:6}{/C:33}{/Y:down} /Alt
  169.  %Delay%
  170.  %COUT%{"/S:Don't worry, they'll be back"}{/Y:down}{/X:15left}{/C:7-31}
  171. rem /* Cursor position is tied to the active console buffer. The contents of the Alternate buffer are discarded when reverting to the Main buffer. */
  172.  %Delay%
  173. rem /* Return to Main screen buffer: /Main */
  174.  %COUT%{/X:3left}{/Y:5up}{"/S:That's all folks."} /Save /Main
  175. rem /* Cursor position is tied to the active console buffer. */
  176.  %Delay%
  177. rem /* restore cursor position from /Save .lX value with -7 offset ; Overwrite all and delete 6 following characters:(.6.) ; restore cursor: (+) */
  178.      %COUT%{/X:.lx-9}{/S:How(.6.)(+)}{/C:32}
  179. rem /* The same as the above line using VT codes manually. */
  180. ::: <nul Set /P "=%\E%[10D%\E%[32mHow%\E%[6P%\E%[?25l"
  181.  %Delay%
  182.  %COUT%{/Y:100}
  183.  Endlocal
  184.  Goto :eof
  185.  
RAW Paste Data