diff --git a/pwiki/page.js b/pwiki/page.js index 7ce7571..a80205e 100755 --- a/pwiki/page.js +++ b/pwiki/page.js @@ -2409,9 +2409,16 @@ module.System = { // // NOTE: these are last resort pages, preferably overloaded in /Templates. // + ParseError: { + text: object.doc` + +
+
ParseError: @(msg)
+ Page: [@(path)] +
`,}, RecursionError: { text: 'RECURSION ERROR: @source(../path)' }, - NotFoundError: { + NotFoundError: { //text: 'NOT FOUND ERROR: @source(./path)' }, text: object.doc` diff --git a/pwiki/parser.js b/pwiki/parser.js index d9e3efb..b0d46bc 100755 --- a/pwiki/parser.js +++ b/pwiki/parser.js @@ -378,7 +378,7 @@ module.BaseParser = { if(done){ if(to){ throw new Error( - 'Premature end of input: Expected closing "'+ to +'"') } + 'Premature end of input: Expected ') } return } // special case: quoting -> collect text... @@ -404,9 +404,9 @@ module.BaseParser = { && !(value.name == to && value.type == 'closing')){ throw new Error( - 'Unexpected "'+ value.name +'" macro' + 'Unexpected <'+ value.name +'> macro' +(to ? - ' in "'+to+'"' + ' in <'+to+'>' : '')) } // open block... if(value.type == 'opening'){ @@ -416,7 +416,7 @@ module.BaseParser = { // close block... } else if(value.type == 'closing'){ if(value.name != to){ - throw new Error('Unexpected closing "'+ value.name +'"') } + throw new Error('Unexpected ') } // NOTE: we are intentionally not yielding the value here... return } // normal value... @@ -437,42 +437,66 @@ module.BaseParser = { // 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={}){ - ast = ast == null ? - //this.group(page) - this.group(page, await page.raw ?? '') - : typeof(ast) != 'object' ? - this.group(page, ast) - : ast instanceof types.Generator ? - ast - : ast.iter() + try{ + ast = ast == null ? + //this.group(page) + this.group(page, await page.raw ?? '') + : typeof(ast) != 'object' ? + this.group(page, ast) + : ast instanceof types.Generator ? + ast + : ast.iter() - while(true){ - var {value, done} = ast.next() - if(done){ - return } + while(true){ + var {value, done} = ast.next() + if(done){ + return } - // text block... - if(typeof(value) == 'string'){ - yield value - continue } + // text block... + if(typeof(value) == 'string'){ + yield value + continue } - // macro... - var {name, args, body} = value - // nested macro -- skip... - if(typeof(page.macros[name]) != 'function'){ - yield {...value, skip: true} - continue } + // macro... + var {name, args, body} = value + // nested macro -- skip... + if(typeof(page.macros[name]) != 'function'){ + yield {...value, skip: true} + continue } - var res = - await this.callMacro(page, name, args, body, state) - ?? '' + var res = + await this.callMacro(page, name, args, body, state) + ?? '' - // result... - if(res instanceof Array - || page.macros[name] instanceof types.Generator){ - yield* res - } else { - yield res } } }, + // result... + if(res instanceof Array + || page.macros[name] instanceof types.Generator){ + yield* res + } else { + yield res } } + + // error... + }catch(err){ + console.error(err) + yield await page.parse( + // XXX add line number and page path... + '@include("./ParseError' + +':path=' + // XXX use pwiki.encodeElem(..) ??? + + page.path + +':msg=' + + err.message + // quote html stuff... + .replace(/&/g, '&') + .replace(//g, '>') + // quote argument syntax... + .replace(/["']/g, function(c){ + return '%'+ c.charCodeAt().toString(16) }) + .replace(/:/g, ':') + .replace(/=/g, '=') + +'")') + return } }, // recursively resolve and enumerate the ast... // diff --git a/pwiki2.html b/pwiki2.html index fefdd94..a77e17a 100755 --- a/pwiki2.html +++ b/pwiki2.html @@ -150,6 +150,18 @@ body.loading .page.spinner span { } } +.error .msg { + font-weight: bold; + color: red; + margin-bottom: 1em; +} +.error { + background: lightyellow; + padding: 1em; + box-shadow: inset 3px 5px 15px 5px rgba(0,0,0,0.05); + border: dashed red 1px; +} + textarea { font-size: 1.2em; border: none; diff --git a/pwiki2.js b/pwiki2.js index bc63b62..abf6ace 100755 --- a/pwiki2.js +++ b/pwiki2.js @@ -36,12 +36,14 @@ * - * * +* XXX BUG? can't use < and > (bot?) in page title... +* XXX parser: error handling: revise page quoting... +* XXX parser: error handling: add line number + context... (???) * XXX BUG: parser: * This will break: * await pwiki.parse('@source(.)') * This will not: * await pwiki.parse('@source(.)') -* XXX ASAP parser: error handling: must output to page and be informative... * XXX ASAP test: can we store the file handler with permissions in a ServiceWorker?? * XXX the parser should handle all action return values, including: * - lists -- XXX