mirror of
https://github.com/flynx/pWiki.git
synced 2025-10-30 02:20:08 +00:00
now args now working...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
d40b9a96b1
commit
a0b377d542
408
pwiki2.js
408
pwiki2.js
@ -106,7 +106,6 @@ module.path = {
|
|||||||
parent = this.normalize(parent, 'array')
|
parent = this.normalize(parent, 'array')
|
||||||
return this.normalize(parent.concat(path), format) },
|
return this.normalize(parent.concat(path), format) },
|
||||||
|
|
||||||
//paths: function*(path='/', leading_slash=true){
|
|
||||||
paths: function*(path='/'){
|
paths: function*(path='/'){
|
||||||
path = this.normalize(path, 'array')
|
path = this.normalize(path, 'array')
|
||||||
// handle '', '.', and '/' paths...
|
// handle '', '.', and '/' paths...
|
||||||
@ -146,6 +145,10 @@ module.path = {
|
|||||||
: parts)
|
: parts)
|
||||||
.join('/'),
|
.join('/'),
|
||||||
'string') },
|
'string') },
|
||||||
|
basename: function(path){
|
||||||
|
return this.split(path).pop() },
|
||||||
|
dirname: function(path){
|
||||||
|
return this.relative(path, '..', 'string') },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -948,14 +951,6 @@ module.BaseParser = {
|
|||||||
return filter[0] != '-' })
|
return filter[0] != '-' })
|
||||||
.filter(function(filter){
|
.filter(function(filter){
|
||||||
return !skip.has(filter) })},
|
return !skip.has(filter) })},
|
||||||
/*/ XXX is this still used???
|
|
||||||
posArgs: function(args){
|
|
||||||
return Object.entries(args)
|
|
||||||
.reduce(function(res, [key, value]){
|
|
||||||
/^[0-9]+$/.test(key)
|
|
||||||
&& (res[key*1] = value)
|
|
||||||
return res }, []) },
|
|
||||||
//*/
|
|
||||||
//
|
//
|
||||||
// Spec format:
|
// Spec format:
|
||||||
// [<orderd>, ... [<keyword>, ...]]
|
// [<orderd>, ... [<keyword>, ...]]
|
||||||
@ -1295,6 +1290,7 @@ module.parser = {
|
|||||||
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
// XXX should these be something more generic like Object.assign(..) ???
|
||||||
|
|
||||||
// XXX revise...
|
// XXX revise...
|
||||||
var Filter =
|
var Filter =
|
||||||
@ -1305,6 +1301,19 @@ function(...args){
|
|||||||
&& Object.assign(func, args.pop())
|
&& Object.assign(func, args.pop())
|
||||||
return func }
|
return func }
|
||||||
|
|
||||||
|
// XXX do we need anything else like .doc, attrs???
|
||||||
|
var Macro =
|
||||||
|
module.Macro =
|
||||||
|
function(spec, func){
|
||||||
|
var args = [...arguments]
|
||||||
|
// function...
|
||||||
|
func = args.pop()
|
||||||
|
// arg sepc...
|
||||||
|
;(args.length > 0 && args[args.length-1] instanceof Array)
|
||||||
|
&& (func.arg_spec = args.pop())
|
||||||
|
// XXX do we need anything else like .doc, attrs???
|
||||||
|
return func }
|
||||||
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
@ -1405,7 +1414,7 @@ object.Constructor('Page', BasePage, {
|
|||||||
[outer_filters] }
|
[outer_filters] }
|
||||||
|
|
||||||
// merge in new filters...
|
// merge in new filters...
|
||||||
var local = Object.values(args)
|
var local = Object.keys(args)
|
||||||
filters.splice(filters.length, 0, ...local)
|
filters.splice(filters.length, 0, ...local)
|
||||||
|
|
||||||
// trigger quote-filter...
|
// trigger quote-filter...
|
||||||
@ -1460,59 +1469,63 @@ object.Constructor('Page', BasePage, {
|
|||||||
// XXX should we track recursion via the resolved (current) path
|
// XXX should we track recursion via the resolved (current) path
|
||||||
// or the given path???
|
// or the given path???
|
||||||
// XXX should this be lazy???
|
// XXX should this be lazy???
|
||||||
include: function(args, body, state, key='included', handler){
|
include: Macro(
|
||||||
// positional args...
|
['src', 'recursive', ['isolated']],
|
||||||
var src = args.src //|| args[0]
|
function(args, body, state, key='included', handler){
|
||||||
var recursive = args.recursive || body
|
// positional args...
|
||||||
var isolated = this.__parser__.posArgs(args).includes('isolated')
|
var src = args.src
|
||||||
|
var recursive = args.recursive || body
|
||||||
|
var isolated = args.isolated
|
||||||
|
|
||||||
if(!src){
|
if(!src){
|
||||||
return '' }
|
return '' }
|
||||||
|
|
||||||
handler = handler
|
handler = handler
|
||||||
?? function(){
|
?? function(){
|
||||||
return this.get(src)
|
return this.get(src)
|
||||||
.parse(
|
.parse(
|
||||||
isolated ?
|
isolated ?
|
||||||
{[key]: state[key]}
|
{[key]: state[key]}
|
||||||
: state) }
|
: state) }
|
||||||
|
|
||||||
// handle recursion...
|
// handle recursion...
|
||||||
var parent_seen = state[key]
|
var parent_seen = state[key]
|
||||||
var seen = state[key] =
|
var seen = state[key] =
|
||||||
(state[key] ?? [this.location]).slice()
|
(state[key] ?? [this.location]).slice()
|
||||||
var target = this.match(src)
|
var target = this.match(src)
|
||||||
target = target instanceof Array ?
|
target = target instanceof Array ?
|
||||||
target.join(',')
|
target.join(',')
|
||||||
: target
|
: target
|
||||||
// recursion detected...
|
// recursion detected...
|
||||||
if(this.match() == this.match(src)
|
if(this.match() == this.match(src)
|
||||||
|| seen.includes(target)){
|
|| seen.includes(target)){
|
||||||
if(!recursive){
|
if(!recursive){
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'include: include recursion detected: '
|
'include: include recursion detected: '
|
||||||
+ seen.concat([target]).join(' -> ')) }
|
+ seen.concat([target]).join(' -> ')) }
|
||||||
// have the 'recursive' arg...
|
// have the 'recursive' arg...
|
||||||
return this.__parser__.parse(this, recursive, state) }
|
return this.__parser__.parse(this, recursive, state) }
|
||||||
seen.push(target)
|
seen.push(target)
|
||||||
|
|
||||||
// load the included page...
|
// load the included page...
|
||||||
var res = handler.call(this)
|
var res = handler.call(this)
|
||||||
|
|
||||||
// restore previous include chain...
|
// restore previous include chain...
|
||||||
if(parent_seen){
|
if(parent_seen){
|
||||||
state[key] = parent_seen
|
state[key] = parent_seen
|
||||||
} else {
|
} else {
|
||||||
delete state[key] }
|
delete state[key] }
|
||||||
|
|
||||||
return res },
|
return res }),
|
||||||
source: function(args, body, state){
|
source: Macro(
|
||||||
var src = args.src //|| args[0]
|
['src'],
|
||||||
return this.macros.include.call(this,
|
function(args, body, state){
|
||||||
args, body, state, 'sources',
|
var src = args.src
|
||||||
function(){
|
return this.macros.include.call(this,
|
||||||
return this.__parser__.parse(this, this.get(src).raw +'', state) }) },
|
args, body, state, 'sources',
|
||||||
//
|
function(){
|
||||||
|
return this.__parser__.parse(this, this.get(src).raw +'', state) }) }),
|
||||||
|
//
|
||||||
// @quote(<src>)
|
// @quote(<src>)
|
||||||
//
|
//
|
||||||
// <quote src=<src>[ filter="<filter> ..."]/>
|
// <quote src=<src>[ filter="<filter> ..."]/>
|
||||||
@ -1531,53 +1544,55 @@ object.Constructor('Page', BasePage, {
|
|||||||
// not expanded...
|
// not expanded...
|
||||||
//
|
//
|
||||||
// XXX need a way to escape macros -- i.e. include </quote> in a quoted text...
|
// XXX need a way to escape macros -- i.e. include </quote> in a quoted text...
|
||||||
quote: function(args, body, state){
|
quote: Macro(
|
||||||
var src = args.src //|| args[0]
|
['src', 'filter', 'text'],
|
||||||
var text = args.text
|
function(args, body, state){
|
||||||
?? body
|
var src = args.src //|| args[0]
|
||||||
?? []
|
var text = args.text
|
||||||
text = src ?
|
?? body
|
||||||
// source page...
|
?? []
|
||||||
this.get(src).raw
|
text = src ?
|
||||||
: text instanceof Array ?
|
// source page...
|
||||||
text.join('')
|
this.get(src).raw
|
||||||
: text
|
: text instanceof Array ?
|
||||||
|
text.join('')
|
||||||
|
: text
|
||||||
|
|
||||||
// empty...
|
// empty...
|
||||||
if(!text){
|
if(!text){
|
||||||
return }
|
return }
|
||||||
|
|
||||||
var filters =
|
var filters =
|
||||||
args.filter
|
args.filter
|
||||||
&& args.filter
|
&& args.filter
|
||||||
.trim()
|
.trim()
|
||||||
.split(/\s+/g)
|
.split(/\s+/g)
|
||||||
|
|
||||||
// NOTE: we are delaying .quote_filters handling here to
|
// NOTE: we are delaying .quote_filters handling here to
|
||||||
// make their semantics the same as general filters...
|
// make their semantics the same as general filters...
|
||||||
// ...and since we are internally calling .filter(..)
|
// ...and since we are internally calling .filter(..)
|
||||||
// macro we need to dance around it's architecture too...
|
// macro we need to dance around it's architecture too...
|
||||||
// NOTE: since the body of quote(..) only has filters applied
|
// NOTE: since the body of quote(..) only has filters applied
|
||||||
// to it doing the first stage of .filter(..) as late
|
// to it doing the first stage of .filter(..) as late
|
||||||
// as the second stage here will have no ill effect...
|
// as the second stage here will have no ill effect...
|
||||||
return function(state){
|
return function(state){
|
||||||
// add global quote-filters...
|
// add global quote-filters...
|
||||||
filters =
|
filters =
|
||||||
(state.quote_filters
|
(state.quote_filters
|
||||||
&& !(filters ?? []).includes(this.ISOLATED_FILTERS)) ?
|
&& !(filters ?? []).includes(this.ISOLATED_FILTERS)) ?
|
||||||
[...state.quote_filters, ...(filters ?? [])]
|
[...state.quote_filters, ...(filters ?? [])]
|
||||||
: filters
|
: filters
|
||||||
if(filters){
|
if(filters){
|
||||||
filters = Object.fromEntries(Object.entries(filters))
|
filters = Object.fromEntries(Object.entries(filters))
|
||||||
return this.macros.filter
|
return this.macros.filter
|
||||||
.call(this, filters, text, state, false)
|
.call(this, filters, text, state, false)
|
||||||
.call(this, state) }
|
.call(this, state) }
|
||||||
return text } },
|
return text } }),
|
||||||
// very similar to @filter(..) but will affect @quote(..) filters...
|
// very similar to @filter(..) but will affect @quote(..) filters...
|
||||||
'quote-filter': function(args, body, state){
|
'quote-filter': function(args, body, state){
|
||||||
var filters = state.quote_filters =
|
var filters = state.quote_filters =
|
||||||
state.quote_filters ?? []
|
state.quote_filters ?? []
|
||||||
filters.splice(filters.length, 0, ...Object.values(args)) },
|
filters.splice(filters.length, 0, ...Object.keys(args)) },
|
||||||
//
|
//
|
||||||
// <slot name=<name>/>
|
// <slot name=<name>/>
|
||||||
//
|
//
|
||||||
@ -1601,92 +1616,94 @@ object.Constructor('Page', BasePage, {
|
|||||||
//
|
//
|
||||||
// XXX how do we handle a slot defined within a slot????
|
// XXX how do we handle a slot defined within a slot????
|
||||||
// ...seems that we'll fall into recursion on definition...
|
// ...seems that we'll fall into recursion on definition...
|
||||||
slot: function(args, body, state){
|
slot: Macro(
|
||||||
var name = args.name
|
['name', 'text', ['shown', 'hidden']],
|
||||||
var text = args.text
|
function(args, body, state){
|
||||||
?? body
|
var name = args.name
|
||||||
// NOTE: this can't be undefined for .expand(..) to work
|
var text = args.text
|
||||||
// correctly...
|
?? body
|
||||||
?? []
|
// NOTE: this can't be undefined for .expand(..) to work
|
||||||
|
// correctly...
|
||||||
|
?? []
|
||||||
|
|
||||||
var slots = state.slots =
|
var slots = state.slots =
|
||||||
state.slots
|
state.slots
|
||||||
?? {}
|
?? {}
|
||||||
|
|
||||||
//var hidden = name in slots
|
//var hidden = name in slots
|
||||||
// XXX EXPERIMENTAL
|
// XXX EXPERIMENTAL
|
||||||
var pos = this.__parser__.posArgs(args)
|
var hidden =
|
||||||
var hidden =
|
// 'hidden' has priority...
|
||||||
// 'hidden' has priority...
|
args.hidden
|
||||||
(pos.includes('hidden') || args.hidden)
|
// explicitly show... ()
|
||||||
// explicitly show... ()
|
|| (args.shown ?
|
||||||
|| ((pos.includes('shown') || args.shown) ?
|
false
|
||||||
false
|
// show first instance...
|
||||||
// show first instance...
|
: name in slots)
|
||||||
: name in slots)
|
|
||||||
|
|
||||||
slots[name] = [...this.__parser__.expand(this, text, state)]
|
slots[name] = [...this.__parser__.expand(this, text, state)]
|
||||||
|
|
||||||
return hidden ?
|
return hidden ?
|
||||||
''
|
''
|
||||||
: function(state){
|
: function(state){
|
||||||
return state.slots[name] } },
|
return state.slots[name] } }),
|
||||||
|
|
||||||
// XXX sorting not implemented yet....
|
// XXX sorting not implemented yet....
|
||||||
macro: function(args, body, state){
|
macro: Macro(
|
||||||
var that = this
|
['name', 'src', 'sort', 'text'],
|
||||||
var name = args.name //?? args[0]
|
function(args, body, state){
|
||||||
var src = args.src
|
var that = this
|
||||||
var sort = (args.sort ?? '')
|
var name = args.name //?? args[0]
|
||||||
.split(/\s+/g)
|
var src = args.src
|
||||||
.filter(function(e){
|
var sort = (args.sort ?? '')
|
||||||
return e != '' })
|
.split(/\s+/g)
|
||||||
var text = args.text
|
.filter(function(e){
|
||||||
?? body
|
return e != '' })
|
||||||
?? []
|
var text = args.text
|
||||||
|
?? body
|
||||||
|
?? []
|
||||||
|
|
||||||
if(name){
|
if(name){
|
||||||
// define new named macro...
|
// define new named macro...
|
||||||
if(text){
|
if(text){
|
||||||
;(state.macros = state.macros ?? {})[name] = text
|
;(state.macros = state.macros ?? {})[name] = text
|
||||||
// use existing macro...
|
// use existing macro...
|
||||||
} else if(state.macros
|
} else if(state.macros
|
||||||
&& name in state.macros){
|
&& name in state.macros){
|
||||||
text = state.macros[name] } }
|
text = state.macros[name] } }
|
||||||
|
|
||||||
if(src){
|
if(src){
|
||||||
var pages = this.get(src).each()
|
var pages = this.get(src).each()
|
||||||
// no matching pages -> get the else block...
|
// no matching pages -> get the else block...
|
||||||
if(pages.length == 0 && text){
|
if(pages.length == 0 && text){
|
||||||
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' })
|
||||||
if(else_block.length == 0){
|
if(else_block.length == 0){
|
||||||
return }
|
return }
|
||||||
// XXX do we take the first or the last (now) block???
|
// XXX do we take the first or the last (now) block???
|
||||||
else_block = else_block.pop()
|
else_block = else_block.pop()
|
||||||
else_block =
|
else_block =
|
||||||
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...
|
||||||
if(sort.length > 0){
|
if(sort.length > 0){
|
||||||
// XXX
|
// XXX
|
||||||
throw new Error('macro sort: not implemented')
|
throw new Error('macro sort: not implemented')
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply macro text...
|
// apply macro text...
|
||||||
// XXX not sure we should expand the whole thing directly here...
|
// XXX not sure we should expand the whole thing directly here...
|
||||||
return pages
|
return pages
|
||||||
.map(function(page){
|
.map(function(page){
|
||||||
return [...that.__parser__.expand(page, text, state)] })
|
return [...that.__parser__.expand(page, text, state)] })
|
||||||
.flat()
|
.flat() } }),
|
||||||
} },
|
|
||||||
|
|
||||||
// nesting rules...
|
// nesting rules...
|
||||||
'else': ['macro'],
|
'else': ['macro'],
|
||||||
@ -1834,51 +1851,6 @@ module.pwiki =
|
|||||||
Page('/', '/', store)
|
Page('/', '/', store)
|
||||||
|
|
||||||
|
|
||||||
// XXX should we also convert values??
|
|
||||||
// ...like:
|
|
||||||
// "true" -> true
|
|
||||||
// "123" -> 123
|
|
||||||
// ...
|
|
||||||
var parseArgs = function(spec, args){
|
|
||||||
// spec...
|
|
||||||
var order = spec.slice()
|
|
||||||
var bools = new Set(
|
|
||||||
order[order.length-1] instanceof Array ?
|
|
||||||
order.pop()
|
|
||||||
: [])
|
|
||||||
order = order
|
|
||||||
.filter(function(k){
|
|
||||||
return !(k in args) })
|
|
||||||
|
|
||||||
var res = {}
|
|
||||||
var pos = Object.entries(args)
|
|
||||||
// stage 1: populate res with explicit data and place the rest in pos...
|
|
||||||
.reduce(function(pos, [key, value]){
|
|
||||||
/^[0-9]+$/.test(key) ?
|
|
||||||
(bools.has(value) ?
|
|
||||||
// bool...
|
|
||||||
(res[value] = true)
|
|
||||||
// positional...
|
|
||||||
: (pos[key*1] = value))
|
|
||||||
// keyword...
|
|
||||||
: (res[key] = value)
|
|
||||||
return pos }, [])
|
|
||||||
// stage 2: populate implicit values from pos...
|
|
||||||
.forEach(function(e, i){
|
|
||||||
order.length == 0 ?
|
|
||||||
(res[e] = true)
|
|
||||||
: (res[order.shift()] = e) })
|
|
||||||
return res }
|
|
||||||
|
|
||||||
console.log('---',
|
|
||||||
parseArgs(
|
|
||||||
['src', 'bam', ['first', 'second']],
|
|
||||||
{1: 'first', 2: '..', src2: 'second', moo: 'third'}))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
// XXX experiments and testing...
|
// XXX experiments and testing...
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user