public override IBELObject ValueOf(string name, System.Collections.ArrayList arguments, ExecutionContext ctx) { Hashtable members = ctx.CurrentFederation.GetTopicProperties(Name); string val = (string)(members[name]); if (val == null) return null; val = val.Trim(); bool isBlock = val.StartsWith("{"); if (!isBlock) return new BELString(val); // It's a block, so fire up the interpreter if (!val.EndsWith("}")) throw new ExecutionException("Topic member " + name + " defined in " + Name.Fullname + " is not well-formed; missing closing '}' for code block."); ContentBase cb = CurrentFederation.ContentBaseForTopic(Name); TopicContext newContext = new TopicContext(ctx.CurrentFederation, cb, CurrentTopicInfo); BehaviorInterpreter interpreter = new BehaviorInterpreter(val, CurrentFederation, CurrentFederation.WikiTalkVersion, ctx.Presenter); if (!interpreter.Parse()) throw new ExecutionException("Parsing error evaluating topic member " + name + " defined in " + Name.Fullname + ": " + interpreter.ErrorString); IBELObject b1 = interpreter.EvaluateToObject(newContext, ctx.ExternalWikiMap); if (b1 == null) throw new ExecutionException("Error while evaluating topic member " + name + " defined in " + Name.Fullname + ": " + interpreter.ErrorString); Block block = (Block)b1; ArrayList evaluatedArgs = new ArrayList(); foreach (object each in arguments) { IBELObject add = null; if (each != null && each is IBELObject) add = each as IBELObject; else { ExposableParseTreeNode ptn = each as ExposableParseTreeNode; add = ptn.Expose(ctx); } evaluatedArgs.Add(add); } InvocationFrame invocationFrame = new InvocationFrame(); ctx.PushFrame(invocationFrame); TopicScope topicScope = new TopicScope(null, this); ctx.PushScope(topicScope); // make sure we can use local references IBELObject answer = block.Value(ctx, evaluatedArgs); ctx.PopScope(); ctx.PopFrame(); // make sure to transfer any new cache rules // BELTODO - want a test case for this foreach (CacheRule r in interpreter.CacheRules) ctx.AddCacheRule(r); return answer; }
public override IBELObject ValueOf(string name, System.Collections.ArrayList arguments, ExecutionContext ctx) { TopicPropertyCollection members = ctx.CurrentFederation.GetTopicProperties(Name); string val = members[name].LastValue; if (val == null) return null; val = val.Trim(); bool isBlock = val.StartsWith("{"); if (!isBlock) return new BELString(val); // It's a block, so fire up the interpreter if (!val.EndsWith("}")) throw new ExecutionException(ctx.CurrentLocation, "Topic member " + name + " defined in " + Name.DottedName + " is not well-formed; missing closing '}' for code block."); NamespaceManager cb = CurrentFederation.NamespaceManagerForTopic(Name); TopicContext newContext = new TopicContext(ctx.CurrentFederation, cb, CurrentTopicInfo); BehaviorInterpreter interpreter = new BehaviorInterpreter(Name.DottedName + "#" + name, val, CurrentFederation, CurrentFederation.WikiTalkVersion, ctx.Presenter); if (!interpreter.Parse()) throw new ExecutionException(ctx.CurrentLocation, "Syntax error in " + interpreter.ErrorString); IBELObject b1 = interpreter.EvaluateToObject(newContext, ctx.ExternalWikiMap); if (b1 == null) throw new ExecutionException(ctx.CurrentLocation, "Execution error in " + interpreter.ErrorString); Block block = (Block) b1; ArrayList evaluatedArgs = new ArrayList(); foreach (object each in arguments) { IBELObject add = null; if (each != null && each is IBELObject) add = each as IBELObject; else { ExposableParseTreeNode ptn = each as ExposableParseTreeNode; add = ptn.Expose(ctx); } evaluatedArgs.Add(add); } InvocationFrame invocationFrame = new InvocationFrame(); ctx.PushFrame(invocationFrame); TopicScope topicScope = new TopicScope(null, this); ctx.PushScope(topicScope); // make sure we can use local references IBELObject answer = block.Value(ctx, evaluatedArgs); ctx.PopScope(); ctx.PopFrame(); return answer; }
private string ProcessLineElements(string line) { // Break the line into parts, recognizing escape quotes ("") StringBuilder builder = new StringBuilder(); // Convert foo@bar external ref syntax to standardized InterWiki behavior // This must happen here because the actual interpretation of these is as a behavior line = externalWikiRef.Replace(line, new MatchEvaluator(externalWikiRefMatch)); ArrayList parameters = new ArrayList(); MatchCollection matches; // temp var used in several places in this method int index = 0; // temp var used in several places in this method #region GatherEscapedText matches = EscapedTextRegex.Matches(line); if (matches.Count > 0) { builder.Length = 0; index = 0; foreach (Match match in matches) { builder.Append(line.Substring(index, (match.Index - index))); // skip behaviors for now. We match them so that the Regex engine does the work // of dealing with @@""@@ and ""@@"" type things. Behaviors handled in the next block if (match.Groups[1].Success) { builder.Append(match.Value); index = match.Index + match.Length; continue; } if (match.Value.StartsWith(PreParam)) Parameterize(builder, parameters, match.Value); else Parameterize(builder, parameters, match.Value.Substring(2, match.Length - 2 - 2)); index = match.Index + match.Length; } builder.Append(line.Substring(index)); line = builder.ToString(); } #endregion #region TranslateBehaviors string escapedTwo = "\\@\\@"; matches = BehaviorRegex.Matches(line); if (matches.Count > 0) { builder.Length = 0; // reset index = 0; foreach (Match match in matches) { builder.Append(line.Substring(index, (match.Index - index))); if (!match.Groups[1].Success) { builder.Append(match.Value); index = match.Index + match.Length; continue; } // OK, we have one string expr = match.Value.Substring(2, match.Value.Length - (2 * 2)); // Turn any escape sequences into unescaped @@ expr = expr.Replace(escapedTwo, BehaviorDelimiter); TopicContext tc = new TopicContext(Federation, NamespaceManager, new TopicVersionInfo(Federation, CurrentTopic)); BehaviorInterpreter interpreter = new BehaviorInterpreter(CurrentTopic == null ? "" : CurrentTopic.DottedName, expr, Federation, Federation.WikiTalkVersion, this); string replacement = null; if (!interpreter.Parse()) { // parse failed replacement = ErrorMessage(null, interpreter.ErrorString); } else { // parse succeeded if (!interpreter.EvaluateToPresentation(tc, _externalWikiMap)) { // eval failed replacement = ErrorMessage(null, interpreter.ErrorString); } else { // eval succeeded WikiOutput nOut = WikiOutput.ForFormat(Output.Format, Output); interpreter.Value.OutputTo(nOut); replacement = nOut.ToString(); } } Parameterize(builder, parameters, replacement); index = match.Index + match.Length; } if (index < line.Length) builder.Append(line.Substring(index)); line = builder.ToString(); } #endregion line = LinkHyperLinks(line); matches = Regex.Matches(line, urlPattern); // hyperlinks are exempt from any emoticons or textile or anything else. if (matches.Count > 0) { builder.Length = 0; index = 0; foreach (Match m in matches) { builder.Append(line.Substring(index, (m.Index - index))); Parameterize(builder, parameters, line.Substring(m.Index, m.Length)); index = m.Index + m.Length; } builder.Append(line.Substring(index)); line = builder.ToString(); } if (((bool)Federation.Application["DisableWikiEmoticons"] == false) && (NamespaceManager.DisableNamespaceEmoticons == false)) { line = ConvertEmoticons(line); // needs to come before textile because of precedence in overlappign formatting rules } line = SentencePairedDelimiters(line); line = TextileFormat(line, parameters); line = ColorsEtcFormat(line); matches = Regex.Matches(line, @"(?:\<nowiki\>)(\<a.*?\<\/a\>)"); if (matches.Count > 0) { builder.Length = 0; index = 0; foreach (Match m in matches) { Group g = m.Groups[1]; builder.Append(line.Substring(index, (m.Index - index))); Parameterize(builder, parameters, line.Substring(g.Index, g.Length)); index = m.Index + m.Length; } builder.Append(line.Substring(index)); line = builder.ToString(); } line = LinkWikiNames(line); line = ProcessWikiLinks(line); line = ReplaceParameters(line, parameters); return line; }
ParseTreeNode Parse(BehaviorInterpreter interpreter) { textBoxLog.Text = ""; parseErrorLabel.Text = ""; ParseTreeNode result = null; if (interpreter.Parse()) result = interpreter.ParseTree; treeViewParseTree.Nodes.Clear(); if (result == null) { textBoxLog.Text = interpreter.ErrorString; parseErrorLabel.Text = interpreter.ErrorString; } else { treeViewParseTree.Nodes.Add(TreeNodesFor(result)); treeViewParseTree.ExpandAll(); } return result; }
private IBELObject BorderPropertyFromTopic(AbsoluteTopicName relativeToTopic, AbsoluteTopicName abs, Border border, CompositeCacheRule rule) { ContentBase cb = ContentBaseForTopic(abs); if (cb == null) { return null; } rule.Add(cb.CacheRuleForAllPossibleInstancesOfTopic(abs)); if (!cb.TopicExists(abs)) { return null; } // OK, looks like the topic exist -- let's see if the property is there string borderPropertyName = BorderPropertyName(border); string prop = GetTopicProperty(abs, borderPropertyName); if (prop == null || prop == "") { return null; } // Yup, so evaluate it! string code = "federation.GetTopic(\"" + abs.Fullname + "\")." + borderPropertyName + "(federation.GetTopicInfo(\"" + relativeToTopic + "\"))"; BehaviorInterpreter interpreter = new BehaviorInterpreter(code, this, this.WikiTalkVersion, null); if (!interpreter.Parse()) { throw new Exception("Border property expression failed to parse."); } TopicContext topicContext = new TopicContext(this, this.ContentBaseForTopic(abs), new TopicInfo(this, abs)); IBELObject obj = interpreter.EvaluateToObject(topicContext, null); if (interpreter.ErrorString != null) { obj = new BELString(interpreter.ErrorString); } foreach (CacheRule r in interpreter.CacheRules) { rule.Add(r); } return obj; }
/// <summary> /// Break the supplied line into BeL sequences and non-BeL sequences. Run the BeL interpreter to process /// the BeL sequences and do regular wiki processing on the non-BeL sequences /// </summary> /// <param name="line"></param> /// <returns></returns> string TranslateBehaviorsAndEverythingElse(string input) { // Convert foo@bar external ref syntax to standardized InterWiki behavior // This must happen here because the actual interpretation of these is as a behavior string str = externalWikiRef.Replace(input, new MatchEvaluator(externalWikiRefMatch)); string escapedTwo = "\\@\\@"; // If no behaviors, just process normally and return if (str.IndexOf(BehaviorDelimiter) == -1) return TranslateLineElements(input); while (true) { // Find the next BehaviorDelimiter marker int start = str.IndexOf(BehaviorDelimiter); if (start == -1) break; // Find the end int end = str.IndexOf(BehaviorDelimiter, start + 2); if (end == -1) break; // OK, we have one string expr = str.Substring(start + 2, end - start - 2); // Turn any escape sequences into unescaped @@ expr = expr.Replace(escapedTwo,BehaviorDelimiter); TopicContext tc = new TopicContext(TheFederation, ContentBase, new TopicInfo(TheFederation, CurrentTopic)); BehaviorInterpreter interpreter = new BehaviorInterpreter(expr, TheFederation, TheFederation.WikiTalkVersion, this); string replacement = null; if (!interpreter.Parse()) { // parse failed replacement = ErrorMessage(null, interpreter.ErrorString); } else { // parse succeeded if (!interpreter.EvaluateToPresentation(tc, _ExternalWikiMap)) { // eval failed replacement = ErrorMessage(null, interpreter.ErrorString); } else { // eval succeeded WikiOutput nOut = WikiOutput.ForFormat(Output.Format, Output); interpreter.Value.OutputTo(nOut); replacement = nOut.ToString(); } foreach (CacheRule r in interpreter.CacheRules) AddCacheRule(r); } str = TranslateLineElements(str.Substring(0, start)) + replacement + TranslateLineElements(str.Substring(end + 2)); } return str; }
private string wikiBehaviorMatch(Match match) { string replacement = match.ToString(); string linestart = match.Groups["LineStart"].Value; string lineend = match.Groups["LineEnd"].Value; string expr = match.Groups["Behavior"].Value; match = null; bool doBehavior = false; if (insideTable.IsMatch(linestart)) { doBehavior = true; } else if (!preBehavior.IsMatch(linestart)) { doBehavior = true; } if (doBehavior) { TopicContext tc = new TopicContext(_fed, _mgr, new TopicVersionInfo(_fed, _behaviorTopic)); BehaviorInterpreter interpreter = new BehaviorInterpreter(_behaviorTopic == null ? "" : _behaviorTopic.DottedName, expr, _fed, _fed.WikiTalkVersion, this); if (!interpreter.Parse()) { //parse failed replacement = ErrorMessage(null, interpreter.ErrorString); } else { //parse succeeded if (!interpreter.EvaluateToPresentation(tc, _mgr.ExternalReferences)) { //eval failed replacement = ErrorMessage(null, interpreter.ErrorString); _processBehaviorToText = false; } else { //eval succeeded WikiOutput nOut = new WomDocument(null); interpreter.Value.OutputTo(nOut); replacement = nOut.ToString(); } } if (replacement.Contains("<script")) { replacement = Regex.Replace(replacement, @"<script(.*?)>", @"<script$1>", RegexOptions.Singleline); replacement = Regex.Replace(replacement, @"</script>", @"</script>"); } replacement = Regex.Replace(replacement, @"^\|\|", "||}", RegexOptions.Multiline); replacement = Regex.Replace(replacement, @" \|\|$| \|\|\r\n| \{\|\|\r\n|\|\|\r\n", " {||\r\n", RegexOptions.Multiline); replacement = Regex.Replace(replacement, @"(?<!\{|"""")\|\|(?!\}|"""")", @" {||}"); if (_processBehaviorToText) { replacement = replacement.Replace(" ", "\t"); replacement = escAmpersand.Replace(replacement, "&"); //full escape causes some pages to fail replacement = ProcessText(replacement, _behaviorTopic, _mgr, true, 350).ParsedDocument; } } replacement = linestart + replacement + lineend; return replacement; }
private IBELObject BorderPropertyFromTopic(QualifiedTopicRevision relativeToTopic, QualifiedTopicRevision abs, Border border) { NamespaceManager namespaceManager = NamespaceManagerForTopic(abs); if (namespaceManager == null) { return null; } if (!namespaceManager.TopicExists(abs.LocalName, ImportPolicy.DoNotIncludeImports)) { return null; } // OK, looks like the topic exist -- let's see if the propertyName is there string borderPropertyName = BorderPropertyName(border); string prop = GetTopicPropertyValue(abs, borderPropertyName); if (prop == null || prop == "") { return null; } // Yup, so evaluate it! string code = "federation.GetTopic(\"" + abs.DottedName + "\")." + borderPropertyName + "(federation.GetTopicInfo(\"" + relativeToTopic + "\"))"; BehaviorInterpreter interpreter = new BehaviorInterpreter(abs.DottedName + "#" + borderPropertyName, code, this, this.WikiTalkVersion, null); if (!interpreter.Parse()) { throw new Exception("Border property expression failed to parse."); } TopicContext topicContext = new TopicContext(this, this.NamespaceManagerForTopic(abs), new TopicVersionInfo(this, abs)); IBELObject obj = interpreter.EvaluateToObject(topicContext, null); if (interpreter.ErrorString != null) { obj = new BELString(interpreter.ErrorString); } return obj; }