public void EvalTemplate(RCRunner runner, RCClosure closure, RCTemplate right) { RCClosure parent = new RCClosure(closure.Parent, closure.Bot, right, closure.Left, RCBlock.Empty, 0); DoEval(runner, parent, right); }
public void EvalTryParse(RCRunner runner, RCClosure closure, RCString right) { bool fragment; RCValue val; RCBlock result = RCBlock.Empty; try { val = DoParse(new RCLParser(RCSystem.Activator), right, false, out fragment); result = new RCBlock(result, "status", ":", new RCLong(0)); result = new RCBlock(result, "fragment", ":", new RCBoolean(fragment)); result = new RCBlock(result, "data", ":", val); } catch (Exception ex) { result = new RCBlock(result, "status", ":", new RCLong(1)); result = new RCBlock(result, "fragment", ":", new RCBoolean(false)); string message = ex.ToString(); RCBlock report = new RCBlock("", ":", new RCString(message + "\n")); int escapeCount = RCTemplate.CalculateReportTemplateEscapeLevel(message); result = new RCBlock(result, "error", ":", new RCTemplate(report, escapeCount, true)); } runner.Yield(closure, result); }
public static void DoEvalTemplate(RCRunner runner, RCClosure closure, RCTemplate template) { throw new Exception("Not implemented"); }
protected static RCString ExpandTemplate(StringBuilder builder, RCTemplate template, RCBlock right, int I, string parentIndent) { string indent = parentIndent; for (int i = 0; i < right.Count; ++i) { RCValue child = right.Get(i); RCVector <string> text = child as RCVector <string>; if (text == null) { RCArray <string> strings = new RCArray <string> (right.Count); RCBlock nestedBlock = (RCBlock)child; for (int j = 0; j < nestedBlock.Count; ++j) { strings.Write(nestedBlock.GetString(j)); } text = new RCString(strings); // ExpandTemplate (builder, template, (RCBlock) child, I + i, indent); } // else { bool somethingAdded = false; for (int j = 0; j < text.Count; ++j) { string section = text[j]; int start = 0; int lineNum = 0; for (int k = 0; k < section.Length; ++k) { if (section[k] == '\n') { string line; if (i % 2 == 1) { if (k > 0 && section.Length > 0 && section[k - 1] == '\r') { line = section.Substring(start, k - start - 1); } else { line = section.Substring(start, k - start); } // if (j > 0 || start > 0) // Using j and start here didn't work because sometimes empty strings // are added. Instead keep track of whether a line has been added. // We may need this variable to handle other cases as well, but // they haven't cropped yet. if (somethingAdded) { // Notice below in the section with w. If there is extra content // before the code section on the same line, it will have been // inserted/indented already. builder.Append(indent); } builder.Append(line); builder.Append("\n"); somethingAdded = true; } else { // In content sections after the first one, // skip newlines if they are the first thing in the section. line = section.Substring(start, k - start); if (I + i == 0) { builder.Append(line); builder.Append("\n"); } else if (line != "") { if (builder[builder.Length - 1] == '\n') { if (start == 0 && (k < section.Length - 1 || i == right.Count - 1)) { builder.Append(indent); } else if (k == section.Length - 1 && i < right.Count - 1) { builder.Append(indent); } } builder.Append(line); builder.Append("\n"); } else if (k > 0 || (builder.Length > 0 && builder[builder.Length - 1] != '\n')) { builder.Append(line); builder.Append("\n"); } } start = k + 1; ++lineNum; } } if (template.Multiline) { // If this is a code section, the lastPiece is just the last line of the // template. // There is no newline at the end. // If this is a text section, the lastPiece is a prefix for the next code // section. string lastPiece = section.Substring(start, section.Length - start); if (i % 2 == 1) { // Odd sections are always code sections. // Code sections don't have a newline at the end. if (j == 0) { // This means there was a newline at the end of section. if (start > 0 && lastPiece != "") { builder.Append(indent); } } else if (j == text.Count - 1) { indent = parentIndent; } builder.Append(lastPiece); } else { int w; for (w = 0; w < lastPiece.Length; ++w) { if (lastPiece[w] != ' ') { break; } } // indent only includes spaces before the first non-space character. // The non-space part of the text is only inserted once. // An edge case involves spaces inserted between code sections on the same // line. // \t not spoken here. // while (builder.Length == 0 || builder[builder.Length - 1] == '\n') { string end; if (builder.Length == 0 || builder[builder.Length - 1] == '\n') { indent = parentIndent + lastPiece.Substring(0, w); end = lastPiece.Substring(w, lastPiece.Length - w); } else { end = lastPiece; } if (i < right.Count - 1) { if (section.Length > 0) { if (builder.Length == 0 || builder[builder.Length - 1] == '\n') { builder.Append(indent); } } } builder.Append(end); } } } else { // If there are no newlines in the template then just drop the whole thing // in as is. builder.Append(text[j]); } } } } // Go back and remove the final newline now. // Let the enclosing template decide how to finish off. if (template.Multiline) { if (builder.Length > 0 && builder[builder.Length - 1] != '\n') { builder.Append("\n"); } } return(new RCString(builder.ToString())); }
public void EvalTemplate(RCRunner runner, RCClosure closure, RCBlock left, RCTemplate right) { RCClosure parent = UserOpClosure(closure, right, new RCArray <RCBlock> (left), noClimb: true); DoEval(runner, parent, right); }
public void EvalApply(RCRunner runner, RCClosure closure, RCTemplate left, object right) { RCClosure parent = UserOpClosure(closure, left, null, null, (RCValue)right); DoEval(runner, parent, left); }
public static void DoFormat(RCTemplate template, StringBuilder builder, RCFormat args, RCColmap colmap, int level) { // templates need to follow the same indenting rules as everyone else please. builder.Append("["); builder.Append('?', template.EscapeCount); // Use AppendLine not args.Newline, because the newline is signficant // and needs to be there no matter what. Otherwise when we parse it again ++level; if (template.Multiline) { builder.Append("\n"); for (int tab = args.Fragment ? 1 : 0; tab < level; ++tab) { builder.Append(args.Indent); } } for (int i = 0; i < template.Count - 1; ++i) { RCValue child = template.Get(i); RCString str = child as RCString; if (str != null && i % 2 == 0) { for (int j = 0; j < str.Count; ++j) { // Now go through str one char at a time to find the newlines. int start = 0, end = 0; for (; end < str[j].Length; ++end) { if (str[j][end] == '\n') { string line = str[j].Substring(start, end - start); builder.Append(line); builder.Append("\n"); if (i < template.Count - 2 || end < str[j].Length - 1) { for (int tab = args.Fragment ? 1 : 0; tab < level; ++tab) { builder.Append(args.Indent); } } start = end + 1; } else if (end == str[j].Length - 1) { builder.Append(str[j].Substring(start, 1 + end - start)); } } } } else { if (template.Multiline) { // for (int tab = 0; tab < level; ++tab) // { // builder.Append (args.Indent); // } /* * int k = builder.Length - 1; * while (k >= 0) * { * if (builder[k] == '\n') * { * for (int tab = 0; tab < level; ++tab) * { * builder.Append (args.Indent); * } * break; * } * else if (builder[k] != ' ') * { * break; * } * --k; * } */ } builder.Append("["); builder.Append('!', template.EscapeCount); builder.Append(' '); child.Format(builder, RCFormat.Default, colmap, level); builder.Append(' '); builder.Append('!', template.EscapeCount); builder.Append("]"); } } --level; if (template.Multiline) { for (int tab = args.Fragment ? 1 : 0; tab < level; ++tab) { builder.Append(args.Indent); } } builder.Append('?', template.EscapeCount); builder.Append("]"); }