macro now mostly works + added quote macro...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2022-05-02 16:56:43 +03:00
parent e07e0165bc
commit a47aa54587

View File

@ -752,6 +752,11 @@ module.BaseParser = {
lex = typeof(lex) == 'string' ? lex = typeof(lex) == 'string' ?
this.lex(page, lex) this.lex(page, lex)
: lex : lex
var quoting = to
&& page.QUOTING_MACROS.includes(to)
&& []
// NOTE: we are not using for .. of .. here as it depletes the // NOTE: we are not using for .. of .. here as it depletes the
// generator even if the end is not reached... // generator even if the end is not reached...
while(true){ while(true){
@ -760,8 +765,23 @@ module.BaseParser = {
if(done){ if(done){
if(to){ if(to){
throw new Error( throw new Error(
'Premature end of unpit: Expected closing "'+ to +'"') } 'Premature end of inpit: Expected closing "'+ to +'"') }
return } return }
// special case: quoting -> collect text...
// NOTE: we do not care about nesting here...
if(quoting !== false){
if(value.name == to
&& value.type == 'closing'){
yield quoting.join('')
return
} else {
quoting.push(
typeof(value) == 'string' ?
value
: value.match ) }
continue }
// assert nesting rules... // assert nesting rules...
// NOTE: we only check for direct nesting... // NOTE: we only check for direct nesting...
// XXX might be a good idea to link nested block to the parent... // XXX might be a good idea to link nested block to the parent...
@ -780,14 +800,13 @@ module.BaseParser = {
//value.body = [...this.group(page, lex, value.name)] //value.body = [...this.group(page, lex, value.name)]
value.body = [...this.group(page, lex, value.name, value)] value.body = [...this.group(page, lex, value.name, value)]
value.type = 'block' value.type = 'block'
yield value
continue
// close block... // close block...
} else if(value.type == 'closing'){ } else if(value.type == 'closing'){
if(value.name != to){ if(value.name != to){
throw new Error('Unexpected closing "'+ value.name +'"') } throw new Error('Unexpected closing "'+ value.name +'"') }
// NOTE: we are intentionally not yielding the value here... // NOTE: we are intentionally not yielding the value here...
return } return }
// normal value...
yield value } }, yield value } },
// Expand macros... // Expand macros...
@ -825,6 +844,9 @@ module.BaseParser = {
// macro... // macro...
var {name, args, body} = value var {name, args, body} = value
// nested macro -- skip...
if(!(page.macros[name] instanceof Function)){
continue }
var res = var res =
page.macros[name].call(page, args, body, state, value) page.macros[name].call(page, args, body, state, value)
?? '' ?? ''
@ -895,6 +917,8 @@ object.Constructor('Page', BasePage, {
//NO_FILTERS: 'nofilters', //NO_FILTERS: 'nofilters',
ISOLATED_FILTERS: 'isolated', ISOLATED_FILTERS: 'isolated',
QUOTING_MACROS: ['quote'],
// //
// <filter>(<source>) // <filter>(<source>)
// -> <result> // -> <result>
@ -1051,9 +1075,42 @@ object.Constructor('Page', BasePage, {
function(){ function(){
return this.__parser__.parse(this, this.get(src).raw, state) }) }, return this.__parser__.parse(this, this.get(src).raw, state) }) },
// XXX this will need to quote pWiki code... //
// ...not sure about anything else... // @quote(<src>)
quote: function(){}, //
// <quote src=<src>[ filter="<filter> ..."]/>
//
// <quote text=" .. "[ filter="<filter> ..."]/>
//
// <quote[ filter="<filter> ..."]>
// ..
// </quote>
//
//
// NOTE: src ant text arguments are mutually exclusive, src takes
// priority.
//
quote: function(args, body, state){
var that = this
var src = args.src
?? args[0]
var filters = args.filter
var text = args.text
?? body
?? []
// source page...
if(src){
return filters ?
// apply filters...
this.__parser__.normalizeFilters(filters)
.reduce(
function(res, filter){
return that.filters[filter].call(that, res) },
this.get(src).raw)
: this.get(src).raw }
// body...
if(text){
return text.join('') } },
// //
// <slot name=<name>/> // <slot name=<name>/>
@ -1109,12 +1166,9 @@ object.Constructor('Page', BasePage, {
: function(state){ : function(state){
return state.slots[name] } }, return state.slots[name] } },
// XXX BUG: '<macro src="/moo/*"> <else> no moo!</else> </macro>' breaks... // XXX sorting not implemented yet....
// ...seams to be a bug in the parser...
macro: function(args, body, state){ macro: function(args, body, state){
// XXX var that = this
//return
var name = args.name ?? args[0] var name = args.name ?? args[0]
var src = args.src var src = args.src
var sort = (args.sort ?? '') var sort = (args.sort ?? '')
@ -1136,11 +1190,10 @@ object.Constructor('Page', BasePage, {
if(src){ if(src){
var pages = this.get(src).each() var pages = this.get(src).each()
console.log('---', pages.length)
// no matching pages -> get the else block... // no matching pages -> get the else block...
if(pages.length == 0 && text){ if(pages.length == 0 && text){
// XXX get the else block... var else_block =
var else_block = (text ?? []) (text ?? [])
.filter(function(e){ .filter(function(e){
return typeof(e) != 'string' return typeof(e) != 'string'
&& e.name == 'else' }) && e.name == 'else' })
@ -1152,7 +1205,7 @@ object.Constructor('Page', BasePage, {
else_block.args.text else_block.args.text
?? else_block.body ?? else_block.body
return else_block ? return else_block ?
this.__parser__.expand(this, else_block, state) [...this.__parser__.expand(this, else_block, state)]
: undefined } : undefined }
// sort pages... // sort pages...
@ -1161,10 +1214,12 @@ object.Constructor('Page', BasePage, {
throw new Error('macro sort: not implemented') throw new Error('macro sort: not implemented')
} }
// XXX apply macro text... // apply macro text...
// XXX not sure we should expand the whole thing directly here...
return pages return pages
.map(function(page){ .map(function(page){
return this.__parser__.expand(page, text, state) }) return [...that.__parser__.expand(page, text, state)] })
.flat()
} }, } },
// nesting rules... // nesting rules...