From 8c24ba36bdc8843018cb526ad15cc9e11629aa99 Mon Sep 17 00:00:00 2001 From: "Alex A. Naanou" Date: Fri, 5 Aug 2022 02:47:31 +0300 Subject: [PATCH] tweaks, fixes and some refactoring... Signed-off-by: Alex A. Naanou --- lib/path.js | 2 +- page.js | 87 ++++++++++++++++++++++++++++---------------------- pwiki2-test.js | 4 +-- pwiki2.js | 9 ++++++ 4 files changed, 61 insertions(+), 41 deletions(-) diff --git a/lib/path.js b/lib/path.js index 1cbaca1..25047a1 100755 --- a/lib/path.js +++ b/lib/path.js @@ -28,7 +28,7 @@ module = { ALTERNATIVE_PAGES: [ 'EmptyPage', - 'NotFound', + 'NotFoundError', ], // Default alternate search locations... diff --git a/page.js b/page.js index aa7da70..b272820 100755 --- a/page.js +++ b/page.js @@ -477,8 +477,6 @@ function(spec, func){ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -module.PAGE_NOT_FOUND = '404: PAGE NOT FOUND: $PATH' - // XXX PATH_VARS need to handle path variables... // XXX filters (and macros?) should be features for simpler plugin handlng (???) // XXX STUB filters... @@ -503,7 +501,9 @@ object.Constructor('Page', BasePage, { // as if we reach this it's likely all the bootstrap is either also // not present or broken. // NOTE: to force the system to fail set this to undefined. - PAGE_NOT_FOUND: module.PAGE_NOT_FOUND, + NOT_FOUND_ERROR: 'NotFoundError', + + RECURSION_ERROR: 'RecursionError', // // () @@ -634,7 +634,8 @@ object.Constructor('Page', BasePage, { async function(args, body, state, key='included', handler){ var macro = 'include' if(typeof(args) == 'string'){ - var [macro, args, body, state, key="included", handler] = arguments } + var [macro, args, body, state, key, handler] = arguments + key = key ?? 'included' } // positional args... var src = args.src var recursive = args.recursive || body @@ -647,50 +648,44 @@ object.Constructor('Page', BasePage, { var full = this.get(src).path handler = handler - ?? function(){ + ?? function(src){ return this.get(src) .parse( isolated ? - {[key]: state[key]} + {seen: (state.seen ?? []).slice()} : state) } // handle recursion... - var parent_seen = state[key] - var seen = state[key] = - state[key] - ?? [] + var parent_seen = 'seen' in state + var seen = state.seen = + (state.seen + ?? []).slice() // recursion detected... - if(seen.includes(full)){ + if(seen.includes(full) || full == this.path){ if(!recursive){ - throw new Error( - macro +': recursion detected: ' - + seen.concat([full]).join(' -> ')) } + return this.parse(this.get('./'+this.RECURSIVE_TPL).raw) } // have the 'recursive' arg... return this.parse(recursive, state) } seen.push(full) // load the included page... - var res = await handler.call(this) + var res = await handler.call(this, src) - // restore previous include chain... - if(parent_seen){ - state[key] = parent_seen - } else { - delete state[key] } + if(!parent_seen){ + delete state.seen } return res }), + // NOTE: the main difference between this and @include is that + // this renders the src in the context of current page while + // include is rendered in the context of its page but with + // the same state... source: Macro( ['src'], async function(args, body, state){ - var src = args.src - // parse arg values... - src = src ? - await this.parse(src, state) - : src return this.macros.include.call(this, 'source', args, body, state, 'sources', - async function(){ + async function(src){ return await this.parse(await this.get(src).raw +'', state) }) }), // // @quote() @@ -1008,12 +1003,12 @@ object.Constructor('Page', BasePage, { // not even the System/NotFound page, i.e. something // went really wrong... if(data == null){ - var msg = (this.PAGE_NOT_FOUND - || module.PAGE_NOT_FOUND) - .replace(/\$PATH/, this.path) - if(this.PAGE_NOT_FOUND){ - return msg } - throw new Error(msg) } + if(this.NOT_FOUND_ERROR){ + var msg = this.get('./'+ this.NOT_FOUND_ERROR) + if(await msg.match()){ + return msg.raw } } + // last resort... + throw new Error('NOT FOUND ERROR: '+ this.path) } // get the data... return ( // action... @@ -1036,6 +1031,15 @@ object.Constructor('Page', BasePage, { // // NOTE: this uses .PAGE_TPL to render the page. // NOTE: writing to .raw is the same as writing to .text... + //* XXX not sure if this is a good strategy... + get text(){ return (async function(){ + var path = pwpath.split(this.path) + return [path.at(-1)[0] == '_' ? + await this.parse() + : await this.get('./'+ this.PAGE_TPL).parse()] + .flat() + .join('\n') }).call(this) }, + /*/ get text(){ return (async function(){ var tpl = '/'+ await this.find('./'+ this.PAGE_TPL) return [await this.parse( @@ -1044,6 +1048,7 @@ object.Constructor('Page', BasePage, { : [] )] .flat() .join('\n') }).call(this) }, + //*/ set text(value){ this.__update__({text: value}) }, //this.onTextUpdate(value) }, @@ -1058,13 +1063,19 @@ var System = module.System = { // base templates... // - // XXX revise this... - // ...need to be able to do: /some/path/_text _text: { - text: '@source(.)' }, - NotFound: { - text: module.PAGE_NOT_FOUND - .replace('$PATH', '@source(./path)') }, + // XXX join does not seem to do anything... + // ...this might be applied to each page rather than to a + // set of pages... + //text: '@source(.)' }, + text: '@include(..)' }, + _list: { + text: '@source(.)' }, + + RecursionError: { + text: 'RECURSION ERROR: @quote(./path)' }, + NotFoundError: { + text: 'NOT FOUND ERROR: @quote(./path)' }, // XXX tests... test_list: function(){ diff --git a/pwiki2-test.js b/pwiki2-test.js index 90826da..bfbdd4d 100755 --- a/pwiki2-test.js +++ b/pwiki2-test.js @@ -49,7 +49,7 @@ pwiki.store.update('@pouch', { // XXX experiments and testing... // XXX for persistent stores test if the data is already loaded here... -pwiki.store.load(bootstrap) +//pwiki.store.load(bootstrap) // XXX TEST... @@ -106,7 +106,7 @@ pwiki.pwiki +'@slot(name=b text="non-filled slot")\n' +'\n' +'Including /other #1: @include(/other)\n' - +'Including /other #2: @include(/other)\n' + //+'Including /other #2: @include(/other)\n' +'\n' +'Including /test: @include(/test recursive="Recursion type 1 ()")\n' +'\n' diff --git a/pwiki2.js b/pwiki2.js index ad656b7..8b43f43 100755 --- a/pwiki2.js +++ b/pwiki2.js @@ -1,6 +1,15 @@ /********************************************************************** * * +* XXX the following are not the same: +* pwiki.get(/test).parse('@source('./path')') +* and +* pwiki.get('/test/*').parse('@source('./path')') +* the former is called once and iterates while the later is called +* per-page... +* ...should be the same -- i.e. the macro should decide... +* page range -> include -> joun +* page range -> macro -> iterate * XXX wikiword filter seems to hang on / * XXX do filters affect the whole page or only what comes after??? * XXX need to be able to affect the default render wrpaper...