/// <summary> Evaluate the argument, convert to a String, and Evaluate again /// (with the same context). /// </summary> /// <param name="context"> /// </param> /// <param name="writer"> /// </param> /// <param name="node"> /// </param> /// <returns> True if the directive rendered successfully. /// </returns> /// <throws> IOException </throws> /// <throws> ResourceNotFoundException </throws> /// <throws> ParseErrorException </throws> /// <throws> MethodInvocationException </throws> public override bool Render(IInternalContextAdapter context, System.IO.TextWriter writer, INode node) { /* * Evaluate the string with the current context. We know there is * exactly one argument and it is a string or reference. */ object value = node.GetChild(0).Value(context); string sourceText; if (value != null) { sourceText = value.ToString(); } else { sourceText = ""; } /* * The new string needs to be parsed since the text has been dynamically generated. */ string templateName = context.CurrentTemplateName; SimpleNode nodeTree = null; try { nodeTree = rsvc.Parse(new StringReader(sourceText), templateName, false); } catch (ParseException pex) { // use the line/column from the template Info info = new Info(templateName, node.Line, node.Column); throw new ParseErrorException(pex.Message, info); } catch (TemplateInitException pex) { Info info = new Info(templateName, node.Line, node.Column); throw new ParseErrorException(pex.Message, info); } /* * now we want to Init and render. Chain the context * to prevent any changes to the current context. */ if (nodeTree != null) { IInternalContextAdapter ica = new EvaluateContext(context, rsvc); ica.PushCurrentTemplateName(templateName); try { try { nodeTree.Init(ica, rsvc); } catch (TemplateInitException pex) { Info info = new Info(templateName, node.Line, node.Column); throw new ParseErrorException(pex.Message, info); } try { /* * now render, and let any exceptions fly */ nodeTree.Render(ica, writer); } catch (ParseErrorException pex) { // convert any parsing errors to the correct line/col Info info = new Info(templateName, node.Line, node.Column); throw new ParseErrorException(pex.Message, info); } } finally { ica.PopCurrentTemplateName(); } return(true); } return(false); }