diff --git a/v3/bootstrap/Doc/Macros.md b/v3/bootstrap/Doc/Macros.md
index bb5a5c9..607b92f 100755
--- a/v3/bootstrap/Doc/Macros.md
+++ b/v3/bootstrap/Doc/Macros.md
@@ -7,6 +7,8 @@ Any macro can be used in any of the two forms, either _inline_ or _HTML-like_.
Inline:
```
@macro-name(value)
+
+@macro-name(value text=" ...text... ")
```
HTML-style:
@@ -27,6 +29,28 @@ The two forms exist to fill two distinct functions:
- html-like: element-like, simpler when dealing with html
+### Positional and keyword attributes
+
+Attributes (arguments) can be set sequentially by value, as they are
+defined or by name in any order.
+
+The following are equivalent:
+```
+
+
+
+```
+
+Keyword attributes are special attributes that are given by name rather
+than by value by default and if no value is set explicitly it defaults
+to `true` if passed, and to false if omitted.
+
+The following are equivalent:
+```
+
+
+```
+
### Special attributes
Two special attributes are handled differently: `text` and `body`, these
@@ -108,6 +132,7 @@ This will enable writing documents (mainly in _markdown_) that are usable
bot from within pWiki as well as outside.
+
## Macros
### now ()
@@ -132,33 +157,56 @@ use.
-### slot ( shown|hidden)
+### slot ( shown|hidden) / content
```
-\@slot()
-\@slot( )
-\@slot( hidden)
-\@slot( shown)
+@slot()
+@slot( )
+@slot( hidden)
+@slot( shown)
+
+ ...>
+ ...
+
+ ...
+
```
Define or fill a slot.
First occurrence of a slot `name` will _define_ a slot and set its value
(fill it) with `text` if given.
-Each new occurrence of a name will override slot content.
+Each new occurrence of a slot with the same name will override slot content.
Only the first occurance of the `name` slot macro is displayed by default.
Slot display can be explicitly controlled via the `hidden` and `shown`
-keywords, if both are given `hidden` has precedence.
+keywords, if both are given `hidden` has precedence. All _shown_ slots of
+the same name will display the same value.
Nested slots are processed in order of occurrence, i.e. a nested slot can
override it's parent's value.
+
+**Example:**
```
- some text
+
+ some text
+
+
```
Will resolve to: `new text`
+`` / `@content()` if encountered will be replaced with previous
+slot value.
+
+**Example:**
+```
+
+
+[[ ]]
+```
+Will resolve to `[[ some text ]]`
+
**Example:**
@@ -182,7 +230,7 @@ Will resolve to: `new text`
-
+---
### filter (name)
diff --git a/v3/pwiki/parser.js b/v3/pwiki/parser.js
index c006e56..fbae6eb 100644
--- a/v3/pwiki/parser.js
+++ b/v3/pwiki/parser.js
@@ -1309,6 +1309,13 @@ module.parser = {
// ...
//
//
+ // Wrap previous value of slot
+ // >
+ // ...
+ //
+ // ...
+ //
+ //
// Force show a slot...
//
//
@@ -1325,12 +1332,9 @@ module.parser = {
// all other slots with will replace its content, unless
// explicit shown/hidden arguments are given.
// NOTE: hidden has precedence over shown if both are given.
- // XXX revise...
//
- // XXX do we need to be able to insert previous slot value???
- // ...this was implemented via , but the naming
- // was not obvious, should be something like
- // or ...
+ // XXX can there be a situation where not all elements
+ // are cleared???
// XXX revise the use of hidden/shown use mechanic and if it's
// needed...
slot: Macro(
@@ -1358,34 +1362,43 @@ module.parser = {
// set slot value...
//
- // NOTE: the slots are filled sequentially, in
- // order of opening elements, rather than
- // topologically, i.e. filled on the way down
- // the tree vs. up.
var slot = slots[name] ??= []
// NOTE: the placeholder is a stand-in for our
- // current value that is still to be generated.
- var placeholder = [...(0 in slot ? slot : [])]
+ // current value that is still to be generated...
+ var placeholder = [...slot]
slot.splice(0, slot.length, placeholder)
- // expand slot body...
+ // expand body...
body = body ?
parser.expand(this, body ?? [], state)
: body
// if slot not overriden, write our value...
if(slot[0] === placeholder){
- slot.splice(0, 1,
+ slot.splice(0, slot.length,
...(body != null ?
[body]
- : placeholder)) }
+ : placeholder))
+ // placeholder ->
+ body = placeholder }
+ // -- handle slot's original value...
+ slot[0] =
+ body.flat().length > 0
+ && slot[0] instanceof Array ?
+ slot[0]
+ .map(function(e){
+ if(e && e.name == 'content'){
+ return body }
+ return e })
+ : slot[0]
return hidden ?
''
: Object.assign(
// stage II: place the latest slot value...
function(st){
- return ((st ?? state).slots ?? {})[name]
- ?? body },
+ return ((st ?? state).slots ?? {})[name] },
{slot: name}) }) })),
+ // XXX do not like this name...
+ content: ['slot'],
//
diff --git a/v3/pwiki/test/parser.js b/v3/pwiki/test/parser.js
index a5d71ce..5b8098e 100755
--- a/v3/pwiki/test/parser.js
+++ b/v3/pwiki/test/parser.js
@@ -56,7 +56,7 @@ test.Setups({
...ins.map(function(e){
return e + 'third' }),
'third' ]} },
-
+ // nested...
slot_nested: function(assert){
return {code: [
'[[ ]]@slot(slot.content value)',
@@ -65,8 +65,7 @@ test.Setups({
return {code: [
'[[ ]]@slot(slot value)',
'value' ]} },
-
- // recursion...
+ // nested-self...
slot_nested_nested: function(assert){
return {code: [
'[[ ]]',
@@ -76,6 +75,32 @@ test.Setups({
return {code: [
'[[ ]]',
'[[ ]]' ]} },
+ // slot content...
+ slot_content: function(assert){
+ return {code: [
+ '[[ ]]',
+ '[[ ]]' ]} },
+ slot_content_multi: function(assert){
+ return {code: [
+ '[[ ]]',
+ '[[ moo moo moo ]]' ]} },
+ slot_content_filled: function(assert){
+ var ins = this.slot_content(assert).code.slice(0, -1)
+ return {code: [
+ ...ins.map(function(e){
+ return '' + e }),
+ '[[ content ]]' ]} },
+ slot_content_content_filled: function(assert){
+ var ins = this.slot_content_filled(assert).code
+ var res = ins.pop()
+ return {code: [
+ ...ins.map(function(e){
+ return e +'(( ))' }),
+ '(( '+ res +' ))' ]} },
+ slot_content_nested: function(assert){
+ return {code: [
+ 'moo[[ ]]',
+ '[[ moo ]]' ]} },
/* XXX SHOWN_HIDDEN
// XXX these need to be revised...
@@ -125,6 +150,24 @@ test.Modifiers({
string: 'string',
}
return state },
+ slot: function(assert, state){
+ state.code = [
+ ...state.code
+ .slice(0, -1)
+ .map(function(e){
+ return `[[ ${e} ]]` }),
+ `[[ ${state.code.at(-1)} ]]`,
+ ]
+ return state },
+ slot_expand: function(assert, state){
+ state.code = [
+ ...state.code
+ .slice(0, -1)
+ .map(function(e){
+ return `[[ ]]${e}` }),
+ `[[ ${state.code.at(-1)} ]]`,
+ ]
+ return state },
})