From 323eb39c1b82a194c64f962ad9322cdb77de0f3f Mon Sep 17 00:00:00 2001 From: "Alex A. Naanou" Date: Wed, 31 Aug 2022 18:49:59 +0300 Subject: [PATCH] added @(..) as alias to @arg(..) + minor tweaks and fixes... Signed-off-by: Alex A. Naanou --- pwiki/page.js | 11 ++++++++ pwiki/parser.js | 70 +++++++++++++++++++++++++++++-------------------- pwiki2.html | 6 ++--- pwiki2.js | 45 ++++++++----------------------- 4 files changed, 67 insertions(+), 65 deletions(-) diff --git a/pwiki/page.js b/pwiki/page.js index 5355b59..bf818fe 100755 --- a/pwiki/page.js +++ b/pwiki/page.js @@ -618,10 +618,16 @@ object.Constructor('Page', BasePage, { // // XXX ASYNC make these support async page getters... macros: { + // + // @([ ][ local]) + // @(name=[ default=][ local]) // // @arg([ ][ local]) // @arg(name=[ default=][ local]) // + // [ ][ local]/> + // [ default=][ local]/> + // arg: Macro( ['name', 'default', ['local']], function(args){ @@ -630,6 +636,11 @@ object.Constructor('Page', BasePage, { && this.root && this.root.args[args.name]) || args.default }), + // alias to @arg(..)... + '': Macro( + ['name', 'default', ['local']], + function(args){ + return this.macros.arg.call(this, args) }), // // @filter() // /> diff --git a/pwiki/parser.js b/pwiki/parser.js index 56155e3..2cb844d 100755 --- a/pwiki/parser.js +++ b/pwiki/parser.js @@ -33,24 +33,20 @@ module.BaseParser = { // STOP -- '\\>' or ')' // PREFIX -- 'inline' or 'elem' // - // XXX quote escaping??? - // /(?['"])(\\\k|[^\1])*\k/ - // ...this will work but we'll also need to remove the \ in the - // final string... MACRO_ARGS: ['(\\s*(',[ // arg='val' | arg="val" | arg=val '(?[a-z-]+)\\s*=\\s*(?'+([ // XXX CHROME/NODE BUG: this does not work yet... //'\\s+(?[\'"])[^\\k]*\\k', - "'(?[^']*)'", - '"(?[^"]*)"', + '"(?(\\"|[^"])*?)"', + "'(?(\\'|[^'])*?)'", '(?[^\\sSTOP\'"]+)', ].join('|'))+')', // "arg" | 'arg' // XXX CHROME/NODE BUG: this does not work yet... //'\\s+(?[\'"])[^\\k]*\\k', - '"(?[^"]*)"', - "'(?[^']*)'", + '"(?(\\"|[^"])*?)"', + "'(?(\\'|[^'])*?)'", // arg // NOTE: this is last because it could eat up parts of // the above alternatives... @@ -77,15 +73,15 @@ module.BaseParser = { // // needs: // MACROS - // INLINE_ARGS -- MACRO_ARGS.replace(/STOP/, ')') - // ARGS -- MACRO_ARGS.replace(/STOP/, '\\/>') + // INLINE_ARGS + // UNNAMED_ARGS + // ARGS // - // XXX BUG: this fails to match inline macros with non-empty args @moo(a) - // ...the problem seems to be with the lack of whitespace - // between ( and the first arg -- @moo( a) is matched fine... MACRO: '('+([ // @macro(arg ..) '\\\\?@(?MACROS)\\((?INLINE_ARGS)\\)', + // @(arg ..) + '\\\\?@\\((?UNNAMED_ARGS)\\)', // | '<\\s*(?MACROS)(?ARGS)?\\s*/?>', // @@ -102,9 +98,15 @@ module.BaseParser = { // buildMacroPattern: function(macros=['MACROS'], regexp='smig'){ var pattern = this.MACRO - .replace(/MACROS/g, macros.join('|')) + .replace(/MACROS/g, + macros + .filter(function(m){ + return m.length > 0 }) + .join('|')) .replace(/INLINE_ARGS/g, this.buildArgsPattern('inline', ')', false) +'*') + .replace(/UNNAMED_ARGS/g, + this.buildArgsPattern('unnamed', ')', false) +'*') .replace(/ARGS/g, this.buildArgsPattern('elem', '\\/>', false) +'*') return regexp ? @@ -264,30 +266,42 @@ module.BaseParser = { var args = {} var i = -1 for(var {groups} - of (cur.argsInline ?? cur.argsOpen ?? '') + of (cur.argsInline + ?? cur.argsUnnamed + ?? cur.argsOpen + ?? '') .matchAll(macro_args_pattern)){ i++ args[groups.elemArgName ?? groups.inlineArgName + ?? groups.unnamedArgName ?? i] = - groups.elemSingleQuotedValue - ?? groups.inlineSingleQuotedValue - ?? groups.elemDoubleQuotedValue - ?? groups.inlineDoubleQuotedValue - ?? groups.elemValue - ?? groups.inlineValue - ?? groups.elemSingleQuotedArg - ?? groups.inlineSingleQuotedArg - ?? groups.elemDoubleQuotedArg - ?? groups.inlineDoubleQuotedArg - ?? groups.elemArg - ?? groups.inlineArg } + (groups.elemSingleQuotedValue + ?? groups.inlineSingleQuotedValue + ?? groups.unnamedSingleQuotedValue + ?? groups.elemDoubleQuotedValue + ?? groups.inlineDoubleQuotedValue + ?? groups.unnamedDoubleQuotedValue + ?? groups.elemValue + ?? groups.inlineValue + ?? groups.unnamedValue + ?? groups.elemSingleQuotedArg + ?? groups.inlineSingleQuotedArg + ?? groups.unnamedSingleQuotedArg + ?? groups.elemDoubleQuotedArg + ?? groups.inlineDoubleQuotedArg + ?? groups.unnamedDoubleQuotedArg + ?? groups.elemArg + ?? groups.inlineArg + ?? groups.unnamedArg) + .replace(/\\(["'])/g, '$1') } // macro-spec... yield { name: (cur.nameInline ?? cur.nameOpen - ?? cur.nameClose) + ?? cur.nameClose + ?? '') .toLowerCase(), type: match[0] == '@' ? 'inline' diff --git a/pwiki2.html b/pwiki2.html index ac16dab..8b572f4 100755 --- a/pwiki2.html +++ b/pwiki2.html @@ -106,7 +106,7 @@ require(['./browser'], function(browser){ // handle location.hash/history (both directions) window.addEventListener('hashchange', function(evt){ evt.preventDefault() - var [path, hash] = location.hash.slice(1).split('#') + var [path, hash] = decodeURI(location.hash).slice(1).split('#') path = path.trim() == '' ? pwiki.location //'/' @@ -142,7 +142,7 @@ require(['./browser'], function(browser){ // handle refresh... // NOTE: we need to do this as hashchange is only triggered // when the hash is actually changed... - for(var lnk of this.dom.querySelectorAll(`a[href="${window.location.hash}"]`)){ + for(var lnk of this.dom.querySelectorAll(`a[href="${location.hash}"]`)){ lnk.addEventListener('click', function(evt){ that.refresh() }) } }) @@ -150,7 +150,7 @@ require(['./browser'], function(browser){ browser.setup.then(function(){ // show current page... - pwiki.location = location.hash.slice(1) + pwiki.location = decodeURI(location.hash).slice(1) }) }) diff --git a/pwiki2.js b/pwiki2.js index bb2e312..953905b 100755 --- a/pwiki2.js +++ b/pwiki2.js @@ -1,40 +1,17 @@ /********************************************************************** * * -* XXX FEATURE add a uniform way to track some state in links in pwiki -* for things like paging and the like with simple user/macro -* access (???)... -* ...the simplest that comes to mind is to store in in path -* somehow: -* - ?=&... -* traditional "query string"... -* - /:/:/.../ -* stack-style arguments... -* + simple to implement -* - goes through page search??? -* - ::=:... -* - ... -* the general idea is to be: -* - flexible enough to allow the basics done -* - restrictive enough to prevent misuse -* ...the rest of the state can simply be stored in the root pwiki -* object in one of the following ways: -* - directly (attrs/dict) -* - a special page -* - virtual (path-specific) -* e.g. -* /some/path/@state/page -> 4 -* ...might be fun to implement a basic json editor -* and viewer with this api... -* ...controlled via js -* ...or special actions: -* /some/path/@state/page/next (increment) -* /some/path/@state/page/prev (decrement) -* /some/path/@state/page=10 (assign) -* ... -* - session -* - stored (config) -* ...css selector as path.... +* XXX FEATURE list macro paging... +* ...should this be macro level or handled in .each() +* what mode? +* - count + block-offset (preferred) +* - count + elem-offset +* - from + to +* XXX what should page caching use? +* - .path (current) +* - .location +* - .path + normalized .args +* ...should this be configurable??? * XXX FEATURE tags and accompanying API... * - add tags to page -- macro/filter * .text -> .tags (cached on .update(..))