Page 1 of 1

help with multilinea macro in not delayed

Posted: 22 Sep 2024 06:06
by einstein1969
unfortunately with macros and the various /escape/ etc substitutions I have never been able to.

I am making a "Lite" version of the "automacro" program that Terry T3rror made viewtopic.php?f=3&t=11339. This is because I need to keep the macros also in the form of subprocedures callable with call: (I don't know if I will succeed).

I have reached a point where it seems impossible to cross the endlocal tunnel/barrier on a ready-made macro that contains LF. I have prepared a small example of the point that I cannot overcome.

Basically the automacro version of T3rror wants Delayed enabled. I am trying to enable it inside the automacroLite sub and therefore I have to overcome the barrier. I managed to overcome the barrier without LF and now I am in non-delayed mode.

And I wanted to know if it was possible to do the final part of the character substitution in non-delayed mode. The first substitution that I am trying is that of the LF. I am not succeeding and perhaps it is not possible as I was told.

But never say never....

Code: Select all

@echo on

setlocal disabledelayedexpansion

echo 1.

rem simple one line macro
set "macro1=set/a a=a+1"

set a=1

echo a=%a%

%macro1%

echo a=%a%

pause

echo 2.

rem multilinea macro
set "macro2=set/a a=a+1 [LF] set/a b=b+1 "

rem define \n 
(Set LF=^
%= this line required =%
)

rem is it possible to replace the [LF] with the var LF and have a multiline macro in not delayed mode?

rem set macro2=%macro2:[LF]=.....%

rem use macro in delayed/not delayed , is it possible?

%macro2%

rem OR

setlocal enabledelayedexpansion
%macro2%


pause

is it possible to replace the [LF] with the var LF and have a multiline macro in not delayed mode?

Francesco Poscetti aka esintein1969

Re: help with multilinea macro in not delayed

Posted: 22 Sep 2024 09:36
by jeb
Hi einstein1969,

I don't see the relation between delayed expansion and line feeds here.

Using of line feeds in macros just depends on code blocks.
It is essential to use the parenthesis in the macro.

Code: Select all

rem define a line feed for using in macro definitions
(Set $\n=^^^
%= this line is required =%
)

set macro2=(set/a a=a+1 %$\n%
set/a b=b+1 %$\n%
)

echo on
%macro2%
Only the parenthesis allows a simple way to embed and use line feeds, because without, a single line feed stops the parsing of a line

Re: help with multilinea macro in not delayed

Posted: 22 Sep 2024 14:52
by einstein1969
I explained myself badly.

I expanded the code hoping that you can understand where I'm having difficulty

I have a code that reads a file and prepares the macro in this format: set macro=<code>[LF]<code>[LF]<etc>

Code: Select all

@echo off
setlocal enabledelayedexpansion

rem From Honguito98 idea
call :AutomacroLite "%~f0" f1

%f1%

echo !a! !b!

pause

goto :eof

:AutomacroLite param
If not "!!" == "" (
  1>&2 Echo %0 requires delayed expansion enabled prior to calling.
  Pause
  Exit /b 1
)

rem version 0.2 contributions by T3RRY on 20/9/2024
rem version 0.1 by Einst on 19/9/2024

rem Here is a piece of code that reads a file and creates the macro in the following format: example

set "%~2=for /L %%l in (1,1,5) do set/a a=a+1[LF]set/a b=555[LF]"


set "%~2=(!%~2!)"

rem define \n 
(Set LF=^
%= this line required =%
)

 set ^"%~2=!%~2:[LF]=^%LF%%LF%!"
 set "%~2=!%~2:%%%%=%%!"

goto :eof
this code works, but I would like to do the setlocal enabledelayedexpansion in the procedure and then pass the tunnel/barrier endmacro if possible.

Like this:

Code: Select all

@echo off
rem setlocal enabledelayedexpansion

rem From Honguito98 idea
call :AutomacroLite "%~f0" f1

%f1%

echo !a! !b!

pause

goto :eof


:AutomacroLite param

setlocal enabledelayedexpansion

If not "!!" == "" (
  1>&2 Echo %0 rewuires delayed expansion enabled prior to calling.
  Pause
  Exit /b 1
)

rem version 0.2 contributions by T3RRY on 20/9/2024
rem version 0.1 by Einst on 19/9/2024

rem Here is a piece of code that reads a file and creates the macro in the following format: example

set "%~2=for /L %%l in (1,1,5) do set/a a=a+1[LF]set/a b=555[LF]"


set "%~2=(!%~2!)"

rem define \n 
(Set LF=^
%= this line required =%
)

 set ^"%~2=!%~2:[LF]=^%LF%%LF%!"
 set "%~2=!%~2:%%%%=%%!"

endlocal ....

pause

goto :eof
is it possible to exit endlocal and return the macro to main? what should i do?

another question: why do you use 3 caret ^ for the definition of LF?

Code: Select all

(Set $\n=^^^
%= this line is required =%
)
another question 2 :

Code: Select all

   set ^"%~2=!%~2:[LF]=^%LF%%LF%!" 
why does honguito use this to make the substitution, can you explain to me why it is double %LF% and the caret ^ in those positions?

honguito98 automacro : https://ss64.org/viewtopic.php?t=65

Re: help with multilinea macro in not delayed

Posted: 11 Oct 2024 05:11
by einstein1969
basically the question is this.

Is it possible to bypass the endlocal barrier/tunnel inside a call of variables that have LF or in any case the code to create multiline macros?

I enter the procedure with the value of the delayed variables or active or inactive, then I activate it if necessary, I do some work and in the end I have to do endlocal.

If it is not possible is there an alternative way that I can use?

Re: help with multilinea macro in not delayed

Posted: 16 Oct 2024 10:06
by jeb
einstein1969 wrote:
11 Oct 2024 05:11
Is it possible to bypass the endlocal barrier/tunnel inside a call of variables that have LF or in any case the code to create multiline macros?
Yes. You can even make it so that it's possible to return the macro to whatever mode it was in before.

The :lineReturnTest test enables delayed expansion and returns the variable "resu", that's the "line" variable where all "\n" are replaced by real new lines.

Small example

Code: Select all

@echo off
setlocal DisableDelayedExpansion

for /F "delims=" %%L in ("^ < > & ! %%") DO (
    set "line=%%L \n Line2 \n"%%L"\nLine4"
)

set "line"
call :lineReturnTest
echo(----------------------
setlocal EnableDelayedExpansion
call :lineReturnTest
exit /b

:lineReturnTest
for /F %%E in (^""^!^!"^") do (
    setlocal EnableDelayedExpansion
    set "exclam=%%~E"
    set "_tmp=!line!"

(set \n=^
%=empty line=%
)

    FOR %%L in ("!\n!") DO (
        set "_tmp=!_tmp:%%=%%2!"
        set "_tmp=!_tmp:\n=%%~1!"
        set "_tmp=!_tmp:^=%%4!"
        set ^"_tmp=!_tmp:"=%%5!"
        call set "_tmp=%%_tmp:^!=\E%%"
        set "_tmp=!_tmp:\E=%%3!"
    )
)
(
    if defined exclam (
        set "exclam=^!"
        set "caret=^"
    ) ELSE (
        set "exclam=^^^!"
        set "caret=^^"
    )
    set "_tmp"
    FOR %%1 in ("!\n!") DO for /F "tokens=1-9" %%2 in (^"%% !exclam! !caret! "") do (
        endlocal
        echo 2P=%%2, 3E=%%3, 4C=%%4, 5Q=%%5
        set "resu=%_tmp%" !
    )
)
set "resu"
exit /b

For this to work, you need a variable that does contains no real new lines until the last step.
But this should be easy, because inside the enabled delayed block you could replace real new lines with "\n"