From 0f4cbfd124cd9341b0eec413eb8e5834956af7fa Mon Sep 17 00:00:00 2001 From: Noah Petherbridge Date: Thu, 19 Jan 2017 08:25:14 -0800 Subject: [PATCH 1/2] Allow synchronous call tags to work inside redirects --- src/brain.coffee | 22 +++++++++++++++------- src/parser.coffee | 4 ++-- test/test-objects.coffee | 21 +++++++++++++++++++++ 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/src/brain.coffee b/src/brain.coffee index f0ab643..3183fbb 100644 --- a/src/brain.coffee +++ b/src/brain.coffee @@ -93,10 +93,10 @@ class Brain # and it returns a promise, otherwise a string is returned ## processCallTags: (reply, scope, async) -> - reply = reply.replace(/\{__call__\}/ig, "") - reply = reply.replace(/\{\/__call__\}/ig, "") + reply = reply.replace(/«__call__»/ig, "") + reply = reply.replace(/«\/__call__»/ig, "") callRe = /([\s\S]+?)<\/call>/ig - argsRe = /{__call_arg__}([^{]*){\/__call_arg__}/ig + argsRe = /«__call_arg__»([\s\S]*?)«\/__call_arg__»/mig giveup = 0 matches = {} @@ -209,7 +209,7 @@ class Brain return result _wrapArgumentsInCallTags: (reply) -> - # wrap arguments inside in {__call_arg__}{/__call_arg__} + # wrap arguments inside in «__call_arg__»«/__call_arg__» callRegEx = /\s*(.*?)\s*<\/call>/ig callArgsRegEx = /\s*[^\s]+ (.*)<\/call>/ig @@ -234,7 +234,7 @@ class Brain wrappedArgs = [] for a in args - wrappedArgs.push "{__call_arg__}#{a}{/__call_arg__}" + wrappedArgs.push "«__call_arg__»#{a}«/__call_arg__»" wrappedCallSignature = wrappedCallSignature.replace(originalArgs, wrappedArgs.join(' ')) @@ -437,6 +437,10 @@ class Brain if matched.redirect? @say "Redirecting us to #{matched.redirect}" redirect = @processTags(user, msg, matched.redirect, stars, thatstars, step, scope) + + # Execute and resolve *synchronous* tags. + redirect = @processCallTags(redirect, scope, false) + @say "Pretend user said: #{redirect}" reply = @_getReply(user, redirect, context, step+1, scope) break @@ -860,8 +864,8 @@ class Brain # Handle all variable-related tags with an iterative regexp approach, to # allow for nesting of tags in arbitrary ways (think >) # Dummy out the tags first, because we don't handle them right here. - reply = reply.replace(//ig, "{__call__}") - reply = reply.replace(/<\/call>/ig, "{/__call__}") + reply = reply.replace(//ig, "«__call__»") + reply = reply.replace(/<\/call>/ig, "«/__call__»") while true # This regexp will match a which contains no other tag inside it, @@ -966,6 +970,10 @@ class Brain break target = utils.strip match[1] + + # Resolve any *synchronous* tags right now before redirecting. + target = @processCallTags(target, scope, false) + @say "Inline redirection to: #{target}" subreply = @_getReply(user, target, "normal", step+1, scope) reply = reply.replace(new RegExp("\\{@" + utils.quotemeta(match[1]) + "\\}", "i"), subreply) diff --git a/src/parser.coffee b/src/parser.coffee index f3d94b9..a84dbce 100644 --- a/src/parser.coffee +++ b/src/parser.coffee @@ -663,9 +663,9 @@ class Parser if line.match(/[A-Z\\.]/) return "Triggers can't contain uppercase letters, backslashes or dots in UTF-8 mode" - else if line.match(/[^a-z0-9(|)\[\]*_#@{}<>=\s]/) + else if line.match(/[^a-z0-9(|)\[\]*_#@{}<>=\/\s]/) return "Triggers may only contain lowercase letters, numbers, and - these symbols: ( | ) [ ] * _ # { } < > =" + these symbols: ( | ) [ ] * _ # { } < > = /" else if line.match(/\(\||\|\)/) return "Piped alternations can't begin or end with a |" else if line.match(/\([^\)].+\|\|.+\)/) diff --git a/test/test-objects.coffee b/test/test-objects.coffee index 54ff98f..ae9e87d 100644 --- a/test/test-objects.coffee +++ b/test/test-objects.coffee @@ -176,6 +176,27 @@ exports.test_objects_in_conditions = (test) -> ) ) +exports.test_objects_in_redirects = (test) -> + bot = new TestCase(test, """ + > object echo javascript + var message = args.join(" "); + return message; + < object + + + hello bot + - Hello human. + + + redirect to * + @ echo + + + inline to * + - "": {@ echo } + """) + bot.reply("hello bot", "Hello human.") + bot.reply("Redirect to Hello Bot", "Hello human.") + bot.reply("Inline to hello bot", '"Hello bot": Hello human.') + test.done() + exports.test_line_breaks_in_call = (test) -> bot = new TestCase(test, """ > object macro javascript From 7e2c8783ddae72540bdfc61a9b349b67c727e4cf Mon Sep 17 00:00:00 2001 From: Noah Petherbridge Date: Thu, 19 Jan 2017 08:33:06 -0800 Subject: [PATCH 2/2] Don't need /m on regexp --- src/brain.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/brain.coffee b/src/brain.coffee index 3183fbb..85d283f 100644 --- a/src/brain.coffee +++ b/src/brain.coffee @@ -96,7 +96,7 @@ class Brain reply = reply.replace(/«__call__»/ig, "") reply = reply.replace(/«\/__call__»/ig, "") callRe = /([\s\S]+?)<\/call>/ig - argsRe = /«__call_arg__»([\s\S]*?)«\/__call_arg__»/mig + argsRe = /«__call_arg__»([\s\S]*?)«\/__call_arg__»/ig giveup = 0 matches = {}