CDSoft / pp

PP - Generic preprocessor (with pandoc in mind) - macros, literate programming, diagrams, scripts...
http://cdelord.fr/pp
GNU General Public License v3.0
252 stars 21 forks source link

Add macro for assigning the expansion of some text to a symbol #53

Open bpj opened 6 years ago

bpj commented 6 years ago

This is sort of a follow-up on #29.

To be able to specify a required argument in code block format I recently wrote a macro where the first argument is optional, handled by checking the definedness of what would be the last argument if the optional argument is present:

!foo[(OPTIONAL)](REQUIRED_A)(REQUIRED_B)
~~~~~~~~~~~~~~~~~~~~~~~~
REQUIRED_C
~~~~~~~~~~~~~~~~~~~~~~~~

However inside the definition of !foo I have to repeatedly say !ifdef(4)(!2)(!1) etc. when referring to any of the arguments. What I would like to be able to do is to assign the text of a parameter to a symbol, however !def(__req_a)(!ifdef[4][!2][!1]) doesn't work because inside a definition the number symbols must refer to the arguments of the macro being defined. The solution would be a macro !assign(SYMBOL)(TEXT) which makes !SYMBOL expand to the expansion of TEXT when !assign was called. Then one could say things like !assign(__foo)(!ifeq[3][yes][!1][!2]) and thereafter use !__foo instead of !ifeq(3)(yes)(!1)(!2), which hopefully makes the code more readable and more maintainable.

CDSoft commented 6 years ago

The problem will be the same with assign. It's due to the parser. Arguments always refer to the arguments of the current macro, not the caller. To make this work we would have to change the parser. Maybe we could add a new argument syntax to skip one (or n) frame in the call stack or maybe a macro arg that takes the argument number and the number of frames to skip, the default value could be 1.

!def(__req_a)(!ifdef[!arg(4)][!arg(2)][!arg(1)])
dfolio commented 5 years ago

I guess I have a similar issue. Indeed, I would like to define nested macros with reference to arguments from the caller, that is something like:

!def(my_macro)(my_macro takes arg1 as a name and arg2 as a description)
``````
!def(!1)(here I want to put a description from arg2 !!2 of the caller not !2)
!def(!1_a)(an other macro defined from arg1 !1 of the caller )(**!!1**)
``````
!my_macro(test)(some description of the test)
!test(foo2)(foo2)
!test_a

that return:

here I want to put a description from arg2 !foo2 of the caller not foo2
**!**

as stated the issue is how to refer to the arguments of the caller in nested macros...

If someone have some tips to deal with such issue... while waiting an update of the parser

NB: to show the parser issue, in !def(!1_a) '!!2' does not returned value from the caller, but '!1' in the doc render the caller arg1:

test_a
        an other macro defined from arg1 test of the caller
CDSoft commented 6 months ago

Sorry for the late reply... Please keep in mind that pp is not supported anymore, it's hard to deploy. For new projects I suggest ypp which is is based on a Lua interpreter and way easier to compile and install and binaries are easier to produce (thanks to zig) and deploy (see hey).

ypp uses a Lua interpreter. I guess what you want is way easier with Lua functions with tables as arguments.