diff --git a/pwiki/page.js b/pwiki/page.js index d2ce754..f46de2b 100755 --- a/pwiki/page.js +++ b/pwiki/page.js @@ -1742,6 +1742,32 @@ object.Constructor('Page', BasePage, { // and debugging, set comment it out to disable... //__debug_last_render_state: undefined, // XXX should this handle pattern paths??? + //* XXX EXPERIMENTAL + parse: function(text, state){ + var that = this + return Promise.awaitOrRun( + text, + function(text){ + // .parser() + if(arguments.length == 1 + && text instanceof Object + && !(text instanceof Array)){ + state = text + text = null } + state = state ?? {} + state.renderer = state.renderer ?? that + // this is here for debugging and introspection... + '__debug_last_render_state' in that + && (that.__debug_last_render_state = state) + // parse... + return that.__parser__.parse( + that.get('.', { + renderer: state.renderer, + args: that.args, + }), + text, + state) }) }, + /*/ // XXX ASYNC parse: async function(text, state){ var that = this text = await text @@ -1764,6 +1790,7 @@ object.Constructor('Page', BasePage, { }), text, state) }, + //*/ // raw page text... // diff --git a/pwiki/parser.js b/pwiki/parser.js index d5a98f7..4977285 100755 --- a/pwiki/parser.js +++ b/pwiki/parser.js @@ -604,37 +604,36 @@ module.BaseParser = { ast = typeof(ast) != 'object' ? this.expand(page, ast, state) : ast - - // NOTE: this expects .flat() on the containing array... - var handleItem = function(e){ - // expand delayed sections... - e = typeof(e) == 'function' ? - e.call(page, state) - : e - // expand arrays... - if(e instanceof Array - | e instanceof types.Generator){ - return that.resolve(page, e, state) - // data -- unwrap content... - } else if(e instanceof Object && 'data' in e){ - return that.resolve(page, e.data, state) - .then(function(e){ - return { data: e } }) - // skipped items... - } else if(e instanceof Object && e.skip){ - return [] - } else { - return [e] } } - - return ast instanceof Array ? - ast.map(handleItem) - .flat() - // NOTE: we need to await for ast here as we need stage 2 of - // parsing to happen AFTER everything else completes... - : ast.then(function(ast){ - return ast.map(handleItem) - .flat() }) - .iter() }, + // XXX .awaitOrRun(..) will check inside the array for promises, do + // we need to do this??? + ast = Promise.awaitOrRun( + ast, + function(ast){ + return ast + .map(function(e){ + // expand delayed sections... + e = typeof(e) == 'function' ? + e.call(page, state) + : e + // expand arrays... + if(e instanceof Array + | e instanceof types.Generator){ + return that.resolve(page, e, state) + // data -- unwrap content... + } else if(e instanceof Object && 'data' in e){ + return that.resolve(page, e.data, state) + .then(function(e){ + return { data: e } }) + // skipped items... + } else if(e instanceof Object && e.skip){ + return [] + } else { + return [e] } }) + .flat() }) + return ast instanceof Promise ? + // keep the API consistently array-like... + ast.iter() + : ast }, /*/ // XXX ASYNC resolve: async function*(page, ast, state={}){ ast = ast @@ -687,6 +686,43 @@ module.BaseParser = { // a slot when loaded will replace the prior occurrences... // // XXX add a special filter to clear pending filters... (???) + //* XXX EXPERIMENTAL... + parse: function(page, ast, state={}){ + var that = this + return this.resolve(page, ast, state) + // filters... + .map(function(section){ + // normalize types... + section = + typeof(section) == 'number' ? + section + '' + : section == null ? + '' + : section + return ( + // expand section... + typeof(section) != 'string' ? + section.data + // global filters... + : state.filters ? + that.normalizeFilters(state.filters) + .reduce(function(res, filter){ + // unknown filter... + // NOTE: we try not to break on user errors + // if we can help it... + if(page.filters[filter] == null){ + console.warn( + '.parse(..): unsupported filter: '+ filter) + return res } + // NOTE: if a filter returns falsy then it + // will have no effect on the result... + return page.filters[filter].call(page, res) + ?? res }, section) + // no global filters... + : section ) }) + .flat() + .join('') }, + /*/ // XXX ASYNC parse: async function(page, ast, state={}){ var that = this return await this.resolve(page, ast, state) @@ -722,6 +758,7 @@ module.BaseParser = { : section ) }) .flat() .join('') }, + //*/ } var parser =