reworked filter contexts, now seem to be working...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2022-08-14 02:08:27 +03:00
parent effeac728b
commit be3b1f11ff
4 changed files with 68 additions and 59 deletions

View File

@ -583,6 +583,12 @@ object.Constructor('Page', BasePage, {
return source return source
.replace(/test/g, 'TEST') }, .replace(/test/g, 'TEST') },
'quote-tags': function(source){
return source
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;') },
// XXX one way to do this in a stable manner is to wrap the source // XXX one way to do this in a stable manner is to wrap the source
// in something like <span wikiwords=yes> .. </span> and only // in something like <span wikiwords=yes> .. </span> and only
// process those removing the wrapper in dom... // process those removing the wrapper in dom...
@ -626,19 +632,13 @@ object.Constructor('Page', BasePage, {
// <filter> <filter-spec> // <filter> <filter-spec>
// | -<filter> <filter-spec> // | -<filter> <filter-spec>
// //
//* XXX
filter: function(args, body, state, expand=true){ filter: function(args, body, state, expand=true){
var that = this var that = this
var filters = state.filters =
state.filters ?? []
// separate local filters...
if(body){
var outer_filters = filters
filters = state.filters =
[outer_filters] }
// merge in new filters... var outer = state.filters =
state.filters ?? []
var local = Object.keys(args) var local = Object.keys(args)
filters.splice(filters.length, 0, ...local)
// trigger quote-filter... // trigger quote-filter...
var quote = local var quote = local
@ -651,36 +651,30 @@ object.Constructor('Page', BasePage, {
// local filters... // local filters...
if(body){ if(body){
// isolate from parent...
state.filters.includes(this.ISOLATED_FILTERS)
&& state.filters[0] instanceof Array
&& state.filters.shift()
// expand the body... // expand the body...
var ast = expand ? var ast = expand ?
// XXX async...
//[...this.__parser__.expand(this, body, state)]
this.__parser__.expand(this, body, state) this.__parser__.expand(this, body, state)
: body instanceof Array ? : body instanceof Array ?
body body
// NOTE: wrapping the body in an array effectively // NOTE: wrapping the body in an array effectively
// escapes it from parsing... // escapes it from parsing...
: [body] : [body]
filters = state.filters
state.filters = outer_filters
// parse the body after we are done expanding...
return async function(state){ return async function(state){
var outer_filters = state.filters // XXX can we lose stuff from state this way???
state.filters = this.__parser__.normalizeFilters(filters) // ...at this stage it should more or less be static -- check!
var res = var res =
await this.parse(ast, state) await this.__parser__.filter(this, ast, {
.iter() ...state,
.flat() filters: local.includes(this.ISOLATED_FILTERS) ?
.join('') local
state.filters = outer_filters : [...outer, ...local],
return { data: res } } } }, })
return {data: res} }
// global filters...
} else {
state.filters = [...outer, ...local] } },
// //
// @include(<path>) // @include(<path>)
// //
@ -715,15 +709,12 @@ object.Constructor('Page', BasePage, {
handler = handler handler = handler
?? async function(src){ ?? async function(src){
return this.get(src) return isolated ?
.parse( {data: await this.get(src)
isolated ? .parse({seen: (state.seen ?? []).slice()})}
{seen: (state.seen ?? []).slice()} : this.get(src)
: state) } .parse(state) }
// XXX this is really odd -- works OK for multiple pages
// and res turns into a string '[object Promise]'
// for a non-pattern page...
return this.get(src) return this.get(src)
.each() .each()
.map(async function(page){ .map(async function(page){
@ -749,8 +740,7 @@ object.Constructor('Page', BasePage, {
if(!parent_seen){ if(!parent_seen){
delete state.seen } delete state.seen }
return res }) return res }) }),
.join('\n') }),
// NOTE: the main difference between this and @include is that // NOTE: the main difference between this and @include is that
// this renders the src in the context of current page while // this renders the src in the context of current page while
// include is rendered in the context of its page but with // include is rendered in the context of its page but with
@ -1116,14 +1106,6 @@ object.Constructor('Page', BasePage, {
// render template in context of page... // render template in context of page...
return this.get(path) return this.get(path)
.parse(await this.get(tpl).raw) }).call(this) }, .parse(await this.get(tpl).raw) }).call(this) },
/*/
var path = pwpath.split(this.path)
return [path.at(-1)[0] == '_' ?
await this.parse()
: await this.get('./'+ this.PAGE_TEMPLATE).parse()]
.flat()
.join('\n') }).call(this) },
//*/
set text(value){ set text(value){
this.__update__({text: value}) }, this.__update__({text: value}) },
//this.onTextUpdate(value) }, //this.onTextUpdate(value) },
@ -1240,10 +1222,16 @@ module.System = {
// text: '<macro src="." join="\n">- @source(.)</macro>' }, // text: '<macro src="." join="\n">- @source(.)</macro>' },
// //
_text: { _text: {
text: '@include(.)' }, text: '<macro src="." join="\n">@include(. isolated)</macro>' },
// XXX this does not separate items when getting patterns...
//text: '@include(. isolated)' },
_raw: { _raw: {
text: '@quote(.)' }, text: '@quote(.)' },
// XXX not sure if this is the right way to go...
_code: {
text: '<pre wikiwords="no"><quote filter="quote-tags" src="."/></pre>' },
// base system pages... // base system pages...
// //

View File

@ -391,6 +391,7 @@ module.BaseParser = {
// <string> // <string>
// // returned by .macros.filter(..) // // returned by .macros.filter(..)
// | { // | {
// // XXX is this still relevant...
// filters: [ // filters: [
// '<filter>' // '<filter>'
// | '-<filter>', // | '-<filter>',
@ -399,6 +400,9 @@ module.BaseParser = {
// data: [ <item>, .. ], // data: [ <item>, .. ],
// } // }
// //
// XXX macros: we are mixing up ast state and parse state...
// one should only be used for parsing and be forgotten after
// the ast is constructed the other should be part of the ast...
expand: async function*(page, ast, state={}){ expand: async function*(page, ast, state={}){
ast = ast == null ? ast = ast == null ?
//this.group(page) //this.group(page)
@ -454,6 +458,7 @@ module.BaseParser = {
// them on demand rather than on encounter (as is now), e.g. // them on demand rather than on encounter (as is now), e.g.
// a slot when loaded will replace the prior occurrences... // a slot when loaded will replace the prior occurrences...
// //
// XXX this should be recursive....
// XXX add a special filter to clear pending filters... (???) // XXX add a special filter to clear pending filters... (???)
parse: async function(page, ast, state={}){ parse: async function(page, ast, state={}){
var that = this var that = this
@ -474,8 +479,6 @@ module.BaseParser = {
: section })) : section }))
.flat() .flat()
// filters... // filters...
// XXX if one of the post-handlers is a promise this will
// need to sync...
.map(function(section){ .map(function(section){
return ( return (
// expand section... // expand section...
@ -496,6 +499,7 @@ module.BaseParser = {
// will have no effect on the result... // will have no effect on the result...
return page.filters[filter].call(page, res) return page.filters[filter].call(page, res)
?? res }, section) ?? res }, section)
//*/
// no global filters... // no global filters...
: section ) }) : section ) })
.flat() .flat()

View File

@ -58,13 +58,33 @@ pwiki.store.update('@pouch', {
// XXX TEST... // XXX TEST...
// XXX add filter tests... // XXX add filter tests...
pwiki.pwiki pwiki.pwiki
.update({
location: '/test/test',
text: 'test', })
.update({
location: '/test/filter',
text: object.doc`
Should be: AAAAaaaaAAAAaaaa : test<filter -test>test</filter>@include(../test)@include(../test isolated)
@filter(test)
`, })
.update({
location: '/test/filter-local',
text: object.doc`
Should be: aaaaAAAAaaaa : test<filter test>test</filter>test
`, })
.update({
location: '/test/filter-isolated',
text: object.doc`
Should be: AAAAaaaaAAAA : test<filter isolated>test</filter>test
@filter(test)
`, })
.update({ .update({
location: '/test/quote', location: '/test/quote',
text: object.doc` text: object.doc`
Inline quoted text: Inline quoted text:
--- ---
<quote> <quote>
this should not get expanded: @now() this test should not get expanded: @now()
</quote> </quote>
--- ---
@ -75,12 +95,11 @@ pwiki.pwiki
Quote filters: Quote filters:
--- ---
<quote filter="test"> <quote filter="quote-tags test">
test filters... test <now />...
</quote> </quote>
--- ---
`, `, })
})
.update({ .update({
location: '/test/wikiword', location: '/test/wikiword',
text: object.doc` text: object.doc`
@ -88,8 +107,7 @@ pwiki.pwiki
the [basic] forms and Versions of the [basic] forms and Versions of
/inline/links. /inline/links.
@filter(wikiword markdown) `, @filter(wikiword markdown) `, })
})
.update({ .update({
location: '/test/slots', location: '/test/slots',
text: object.doc` text: object.doc`
@ -100,8 +118,7 @@ pwiki.pwiki
...while this (<slot name="non-empty">text should be replaced...</slot>) ...while this (<slot name="non-empty">text should be replaced...</slot>)
<slot name="non-empty">text is filling a slot</slot> <slot name="non-empty">text is filling a slot</slot>
`, `, })
})
.update({ .update({
location: '/test/a', location: '/test/a',
text: 'a', text: 'a',

View File

@ -1,7 +1,7 @@
/********************************************************************** /**********************************************************************
* *
* *
* XXX BUG: .get('/*').raw hangs... * XXX BUG: browser: .get('/*').raw hangs...
* XXX add action to reset overloaded (bootstrap) pages... * XXX add action to reset overloaded (bootstrap) pages...
* - per page * - per page
* - global * - global