Search code examples
batch-filecmdjscript

Batch-Hybrid Special Character Fault?


As long as I know, some special characters can be displayed if you echo them using "". I'm simply stuck on the code, trying to figure out where I can change for this to work. I can't see the problem. Code from here. What i need is a special code that can do write animations for me, and then exit. Just like that. I've copied the code from there, modified so it could be called using typewriter.bat "text" "charsnum-1", like typewriter "Hello" 4. Though I don't really understand Batch Hybrids, and, even knowing how to interpret code, I can't see where the symbols are getting stuck at.

To reproduce my problem: typewriter.bat "Hello?" 5

Code:

@if (@CodeSection == @Batch) @then

@echo off
setlocal

color 70
set charnuu=%2

call :split chars %1

:begin
for %%i in (%chars%) do call :type "%%~i"
exit /b
goto begin

:split <var_to_set> <str>
setlocal enabledelayedexpansion
set "line="
set "str=%~2"
for /L %%I in (0,1,%charnuu%) do set line=!line! "!str:~%%I,1!"
endlocal & set "%~1=%line%"
goto :EOF

:type <char>
cscript /nologo /e:JScript "%~f0" "%~1"
goto :EOF

@end
// end batch / begin JScript chimera
function pause() { WSH.Sleep(Math.random() * 50 + 50); }
function odds(num) { return !(Math.round(Math.random() * num) % num) }


pause();

if (odds(300)) WSH.Echo('');
if (!odds(400)) WSH.StdOut.Write(WSH.Arguments(0));

This code isn't showing common symbols or even the basic ones, like ?. Maybe I am too tired to see it. Help me.


Solution

  • Question marks can't be processed by regular for loops, but you can get around that by not processing the individual letters with a loop at all and just iterating over the entire string as a whole:

    @echo off
    
    REM Just kinda honor-system the string length since this is proof of concept
    REM     but remember that string indices start at 0
    set "string=%~1"
    set "string_length=%~2"
    
    REM Generate a backspace character for later
    for /f %%A in ('"prompt $H&for %%B in (1) do rem"') do set "BS=%%A"
    
    REM The setlocal is down here instead of at the top like it usually is to handle
    REM     strings that contain exclamation points.
    REM There's a period followed by a backspace before the substring is printed in
    REM     case the current character happens to be a space (which otherwise
    REM     wouldn't get printed).
    REM The timeout /t 0 is because timeout is an external command that technically
    REM     needs a few milliseconds to start up, so setting the wait period to 0
    REM     seconds actually generates a pause shorter than 1 second.
    setlocal enabledelayedexpansion
    for /L %%A in (0,1,%string_length%) do (
        <nul set /p "=.%BS%!string:~%%A,1!"
        >nul timeout /t 0
    )