Compare commits

..

2 Commits

Author SHA1 Message Date
d967a15a5d refacoring: now in macros is the parser and not the page -- not sure how that happened =)
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
2026-07-01 20:07:40 +03:00
5cabfd0754 testing + minor bugfix...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
2026-07-01 19:50:44 +03:00
2 changed files with 118 additions and 79 deletions

View File

@ -223,6 +223,7 @@ module.BaseParser = {
// NOTE: this unifies the body, body argument and text argument (in
// order of priority) and passes the value in the body macro
// handler argument.
// XXX should a macro be run in the context of the page or the parser???
callMacro: function(page, macro, args, body, state, ...rest){
do {
macro = this.macros[macro]
@ -244,12 +245,7 @@ module.BaseParser = {
body
?? args.body
?? args.text }
return macro.call(page,
this,
args,
body,
state,
...rest) },
return macro.call(this, page, args, body, state, ...rest) },
// Strip comments...
@ -1164,21 +1160,21 @@ module.parser = {
'': 'arg',
arg: Macro(
['name', 'else', ['local']],
function(parser, args, _, state){
var v = (this.args ?? {})[args.name]
function(page, args, _, state){
var v = (page.args ?? {})[args.name]
|| (!args.local
&& (this.renderer
&& this.renderer.args[args.name])
|| (this.root
&& this.root.args[args.name]))
&& (page.renderer
&& page.renderer.args[args.name])
|| (page.root
&& page.root.args[args.name]))
v = v === true ?
args.name
: v
return v
|| (args['else']
&& parser.expand(this, args['else'], state)) }),
args: function(){
return pwpath.obj2args(this.args) },
&& this.expand(this, args['else'], state)) }),
args: function(page){
return pwpath.obj2args(page.args) },
// XXX EXPERIMENTAL...
//
@ -1198,13 +1194,14 @@ module.parser = {
/*/
['shown', 'hidden']],
//*/
function(parser, args, body, state){
function(page, args, body, state){
var that = this
var name = args.name
if(!name){
return '' }
return Promise.awaitOrRun(
parser.parseNested(this, name, state),
this.parseNested(page, name, state),
function(name){
// XXX INC_DEC
var inc = args.inc
@ -1275,7 +1272,7 @@ module.parser = {
if(text){
return Promise.awaitOrRun(
//state.waitNested,
parser.parseNested(this, text, state),
that.parseNested(page, text, state),
function(value){
text = vars[name] = value
return show ?? false ?
@ -1284,12 +1281,13 @@ module.parser = {
// get...
} else {
return handleFormat(vars[name] ?? '') } }) }),
vars: function(parser, args, body, state){
vars: function(page, args, body, state){
var that = this
var lst = []
for(var [name, value] of Object.entries(args)){
lst.push(
parser.parseNested(this, name, state),
parser.parseNested(this, value, state)) }
this.parseNested(page, name, state),
this.parseNested(page, value, state)) }
var vars = state.vars ??= {}
return Promise.awaitOrRun(
state.waitNested,
@ -1342,11 +1340,12 @@ module.parser = {
// NOTE: this is needed to be able to control the sequence of
// overrides in nesteed slots...
lazy(
function(parser, args, body, state){
function(page, args, body, state){
var that = this
var name = args.name
return Promise.awaitOrRun(
parser.parseNested(this, name, state),
this.parseNested(page, name, state),
function(name){
var slots = state.slots ??= {}
@ -1369,7 +1368,7 @@ module.parser = {
slot.splice(0, slot.length, placeholder)
// expand body...
body = body ?
parser.expand(this, body ?? [], state)
that.expand(page, body ?? [], state)
: body
// if slot not overriden, write our value...
if(slot[0] === placeholder){
@ -1425,13 +1424,16 @@ module.parser = {
// not 100% correct manner focusing on path depth and ignoring
// the context, this potentially can lead to false positives.
//
// XXX add path recursion test to data -- fail if two paths resolve
// to the same context...
// XXX need a way to make encode option transparent...
// XXX need a way to wrap the included page...
// - template page...
// - prefix/sufix...
// XXX store a page cache in state...
// XXX do we want to load a specific slot/block???
// XXX UPDATE...
include2: Macro(
include: Macro(
['src', 'recursive', 'join',
['s', 'strict', 'isolated']],
// XXX thinking that reimplementing this is a bit less boring than
@ -1443,7 +1445,8 @@ module.parser = {
// .get(path)
// is this a promise/value, iterable promise a generator
// an async generator, ... or a combination/stack of the above???
function(parser, args, body, state, key='included', handler){
lazy(
function(page, args, body, state, key='included', handler){
var that = this
var recursive =
@ -1452,11 +1455,12 @@ module.parser = {
?? body
?? state.recursive
var base = this.basepath
var src = this.resolvePathVars(args.src)
var base = page.basepath
// XXX we do this before or after we parse???
var src = page.resolvePathVars(args.src)
return Promise.awaitOrRun(
parser.parseNested(this, src, state),
this.parseNested(page, src, state),
function(src){
var cache = state.cache ??= {}
if(cache[src]){
@ -1488,14 +1492,14 @@ module.parser = {
// content handler...
handler ??=
function(parser, text, state){
return parser._parse(that, text, state) }
function(page, text, state){
return this._parse(page, text, state) }
var pageHandler =
function(text, i, l){
return [
handler.call(that,
parser,
page,
text,
// isolated up -- will see all
// the state but can have no
@ -1509,7 +1513,7 @@ module.parser = {
// join...
(args.join
&& i < l.length - 1) ?
parser._parse(that, args.join, state)
that._parse(page, args.join, state)
: []
].flat() }
var resultHandler =
@ -1529,7 +1533,7 @@ module.parser = {
// get and run things...
return Promise.awaitOrRun(
that.get(src).raw,
page.get(src).raw,
function(pages){
pages = pages instanceof Array ?
pages
@ -1541,9 +1545,9 @@ module.parser = {
.map( pageHandler ))
.flat()
.sync(),
resultHandler ) }) }) }),
resultHandler ) }) }) })),
include: Macro(
_include: Macro(
['src', 'recursive', 'join',
['s', 'strict', 'isolated']],
async function*(parser, args, body, state, key='included', handler){
@ -2070,32 +2074,5 @@ module.parser = {
// XXX for testing...
var P =
module.P = {
//* XXX
_content: [
'first page text',
'second page text',
],
/*/
_content: 'page text',
//*/
path: '/path/to/page',
basepath: '/path/to/',
get raw(){
return this._content ?? '' },
get: function(){
return this },
resolvePathVars: function(path){
return path },
}
/**********************************************************************
* vim:set ts=4 sw=4 nowrap : */ return module })

View File

@ -1,12 +1,52 @@
#!/usr/bin/node
//---------------------------------------------------------------------
var path = require('path')
var test = require('ig-test')
var serialize = require('ig-serialize')
var parser = require('../parser').parser
//---------------------------------------------------------------------
var PAGES =
module.exports.PAGES = {
'/blank': '',
'/page': 'Page',
'/async/page': Promise.resolve('Page'),
'/includePage': '@include(/page)',
}
var P =
module.exports.P = {
__pages__: PAGES,
__parser__: parser,
path: '/',
get basepath(){
return path.dirname(this.path ?? '') },
get raw(){
return this.__pages__[this.path] ?? '' },
get text(){
return this.__parser__.parse(this, this.raw, {}) },
get: function(p){
return {
__proto__: P,
path: path.resolve(this.path, p),
} },
// XXX
resolvePathVars: function(path){
return path },
}
//---------------------------------------------------------------------
test.Setups({
@ -140,6 +180,28 @@ test.Setups({
// XXX arg...
// XXX
// include...
// XXX these do not play well with modifiers...
include: function(assert, path='/blank', expected){
return {
page: P,
code: [
`@include(${path})`,
// XXX for some reason this does not parse int a macro....
//'<include /blank />',
`<include "${path}" />`,
expected
?? P.get(path).raw,
],
}},
include_page: function(assert){
return this.include(assert, '/page') },
include_include_page: function(assert){
return this.include(assert, '/includePage', 'Page') },
/* XXX
include_async: function(assert){
return this.include(assert, '/async/page') },
//*/
})