mirror of
				https://github.com/flynx/pWiki.git
				synced 2025-10-31 02:50: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