我有一个基本上看起来像这样的宏:
#macro( surround $x )
surround:$x
$bodyContent
/surround:$x
#end
调用#@surround("A")bunch o' stuff#end
按预期产生“环绕:一堆东西/环绕:A”。调用#@surround("A")#@surround("B")more stuff#end#end
产生环绕:A环绕:B更多的东西/环绕:B /环绕:A这正是我想要的。
但现在我想用另一个宏向上构建
#macro( annotated-surround $x $y )
#@surround( $x )
annotate:$y
$bodyContent
#end
#end
的预期扩展#annotated-surround( "C" "note" ) stuff #end
是环绕:C annotate:note stuff /surround:C
...但这不起作用;我得到了带注释的环绕体内容的可怕的半无限扩展。
我已经阅读了Velocity 模板宏中的 Closure的答案,但仍然不太清楚我想做的事情是否可行。
我愿意在#surround
and
的定义中做任意棘手的事情#annotated-surround
,但我不希望这些宏的用户看到任何复杂性。整个想法是简化他们的生活。
只要我有你的耳朵:设置macro.provide.scope.control=true
应该是“宏中的本地命名空间”。这是什么意思?提供的命名空间是否独立于默认上下文,但在所有宏的所有调用之间共享一个这样的空间?或者是否为每个宏调用提供了单独的上下文,甚至是递归的?它必须是后者,因为$macro.parent
,对吧?
还有一个问题。考虑以下宏:
#macro( recursive $x )
#if($x == 0)
zero
#else
$x before . . .
#set($xMinusOne = $x - 1)
#recursive($xMinusOne)
. . . $x after
#end
#end
#recursive( 4 )
产量:
4 之前。. . 3 之前。. . 2 之前。. . 1 之前。. . 零 。. . 0 之后。. . 0 之后。. . 0 之后。. . 4 后
现在我明白了所有那些“0”的出现:只有一个全局 $x,所以在递归调用中分配给它会破坏它并且它不会被恢复。但是最后的“4”到底是从哪里来的呢?就此而言,我的第一个“环绕”宏是如何工作到任意深度的?为什么它的最终 $x 不会在内部调用中被破坏?
很抱歉这么冗长,但我一直无法在这件事上找到明确的文件。