コード例 #1
0
        private void createContent(String varName, Object objectToPass, StringReader reader, String outputFileName)
        {
            Dictionary<String, Object> map = new Dictionary<String, Object>();
            map.Add(varName, objectToPass);

            String outputContent = null;
            StringTemplateGroup group = new StringTemplateGroup(reader);
            var contentTemplate = group.GetInstanceOf("Content");
            contentTemplate.Attributes = map;
            outputContent = contentTemplate.ToString();
            //StringBuilder sb = new StringBuilder(outputContent);
            StringWriter writer = new StringWriter(new StringBuilder(outputContent));
            writer.Flush();
            StreamWriter fileWriter = null;
            try
            {
                fileWriter = new StreamWriter(outputFileName + "/report.html.data");
                fileWriter.Write(writer.ToString());
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }

            writer.Close();
            fileWriter.Close();
        }
コード例 #2
0
        public void Generate(string path)
        {
            StringTemplateGroup group = new StringTemplateGroup("myGroup", @".\Templet");
            StringTemplate st = group.GetInstanceOf("CourseHome");
            int ID = 1;
            st.SetAttribute("Function", AllShiftFunction);
            st.SetAttribute("ProjectSum", projectSum);
            foreach (var testSummary in AllTableSummary) {
                st.SetAttribute("IDNum", ID++);
                st.SetAttribute("Title", testSummary.title);
                st.SetAttribute("Content", testSummary.attributions + "</p>" + testSummary.methodInfo);
                st.SetAttribute("Index", testSummary.tableIndex);
                foreach (var subSummary in AllColumnSummary)
                {
                    if (subSummary.tableName != testSummary.tableName) continue;
                    st.SetAttribute("IDNum", ID++);
                    st.SetAttribute("Title", subSummary.title);
                    st.SetAttribute("Content", subSummary.attributions + "</p>" + subSummary.methodInfo);
                }

            }

            String result = st.ToString();
            StreamWriter writetext = new StreamWriter(path);
            writetext.WriteLine(result);
            writetext.Close();
        }
コード例 #3
0
        //This function is used to generate the summary of whole target projet. The summary is showed in the left part of our report, the details is defined in the two HashSet above.
        public void GenerateSummary(string stsum)
        {
            Console.WriteLine("Now let's generate summary..");
            foreach(var table in db.tablesInfo)
            {
                table.generateDescription(db);
                if (table.directMethods.Count>0 || table.columns.Find(x => x.directMethods.Count>0)!=null)
                {
                    SingleSummary tcSummary = new SingleSummary(table.title, table.attribute, table.methodsDes,table.name,table.generateLeftIndex());
                    AllTableSummary.Add(tcSummary);
                }
                foreach(var column in table.columns)
                {
                    column.generateDescription(db);
                    if (column.directMethods.Count == 0) continue;
                    SingleSummary tcSummary = new SingleSummary(column.title, column.attribute, column.methodsDes,table.name,"");
                    AllColumnSummary.Add(tcSummary);
                }
            }

            //generating Javascript for webpage
            StringTemplateGroup group = new StringTemplateGroup("myGroup", @".\Templet");
            StringTemplate st = group.GetInstanceOf("GenerateScript");
            foreach(var me in extractor.methodsInfo)
            {
                st.SetAttribute("FunctionName",TakePointOff(me.name));
                st.SetAttribute("MethodFullName",me.name);
                st.SetAttribute("MethodName", me.methodself.Name);
            }
            FinalGenerator homePageGenerator = new FinalGenerator(this.AllTableSummary, this.AllColumnSummary,st.ToString(),stsum);
            homePageGenerator.Generate(outputLoc);
        }
コード例 #4
0
ファイル: Class1.cs プロジェクト: smartinz/randomhacking
 public string EvaluateFile(string fileName, IDictionary<string, object> context)
 {
     var stringTemplateGroup = new StringTemplateGroup("group", AppDomain.CurrentDomain.BaseDirectory);
     stringTemplateGroup.ErrorListener = new StringTemplateErrorListener();
     StringTemplate stringTemplate = stringTemplateGroup.GetInstanceOf(fileName, context);
     return stringTemplate.ToString();
 }
コード例 #5
0
ファイル: View.cs プロジェクト: mattburton/Simple.Web
 static View()
 {
     Group = new StringTemplateGroup("Views", Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Views"))
     {
         RefreshInterval = CachingIsEnabled() ? new TimeSpan(1, 0, 0) : TimeSpan.Zero
     };
 }
コード例 #6
0
 public FuncProtoToShimParser(string templatefile, ITokenStream input)
     : this(input, new RecognizerSharedState())
 {
     using (TextReader tr = new StreamReader(templatefile))
     {
         TemplateGroup = new StringTemplateGroup(tr);
         tr.Close();
     }
 }
コード例 #7
0
		static SlnFileRenderer()
		{
			var stream = typeof (SlnFileRenderer).Assembly.GetManifestResourceStream("SlimJim.Templates.SolutionTemplate.st");
			templateGroup = new StringTemplateGroup("SlnTemplates");
			using (stream)
			{
				templateGroup.DefineTemplate("SolutionTemplate", new StreamReader(stream).ReadToEnd());
			}
		}
コード例 #8
0
      /// <summary>Generate metadata repository and source files.</summary>
      private void generate() {
         // Clear repository
         Repository.Clear();
         Repository.TypesMapper.AddRange(this.TemplateInfo.TypesMap);
         foreach (BplPackage pkg in this.packages) {
            Repository.AllPackages.Add(pkg.CanonicName, pkg);
         }

         string appDir = Path.GetDirectoryName(Application.ExecutablePath);
         string tmpDir = Path.Combine(appDir, "Templates");

         Type lexarType = (this.TemplateInfo.Lexer.Equals("$")) 
            ? typeof(Antlr3.ST.Language.TemplateLexer)
            : typeof(Antlr3.ST.Language.AngleBracketTemplateLexer);

         // Read group from file
         using (StreamReader sr = new StreamReader(this.TemplateInfo.GroupFile)) {
            this.stGroup = new StringTemplateGroup(sr, lexarType);
         }


         // Filter packages
         List<BplPackage> packages = this.packages.Where<BplPackage>(pkg => this.TemplateInfo.IsMatch(pkg.CanonicName)).ToList<BplPackage>();

         // Build class metadata
         packages.Apply<BplPackage>(pkg => {
            this.notifyAction("Generating package {0} ...", pkg.Name);
            pkg.Classes.Apply<BplClass>(cls => new MetaClass(cls));
         });

         foreach (TemplateCommand tc in this.TemplateInfo.RunCommands) {
            if (tc.Level == TemplateLevel.Root) {
               // Generate root level source code
               this.generateRootFile(tc.TemplateName, tc.RelativeFolder, tc.FilePattern);
            } else if (tc.Level == TemplateLevel.Package) {
               // Generate packages source code
               Repository.RegisteredPackages.Values.Apply<BplPackage>(pkg => this.generatePackageFile(pkg, tc.TemplateName, tc.RelativeFolder, tc.FilePattern));
            } else if (tc.Level == TemplateLevel.Class) {
               // Generate classes source code
               Repository.RegisteredClasses.Values.Apply<MetaClass>(cls => { this.generateClassFile(cls, tc.TemplateName, tc.RelativeFolder, tc.FilePattern); });
            } else if (tc.Level == TemplateLevel.Primitive) {
               // Generate primitives source code
               Repository.RegisteredPrimitives.Values.Apply<MetaPrimitive>(prv => { this.generatePrimitiveFile(prv, tc.TemplateName, tc.RelativeFolder, tc.FilePattern); });
            } else if (tc.Level == TemplateLevel.Enum) {
               // Generate primitives source code
               Repository.RegisteredEnums.Values.Apply<MetaEnum>(enm => { this.generateEnumFile(enm, tc.TemplateName, tc.RelativeFolder, tc.FilePattern); });
            } else {
               throw new Exception("Unrecognized value");
            }
         }
         // Notify user about end of process
         MessageBox.Show("Code files generated successfully.");
      }
コード例 #9
0
        public string RenderTemplate(string groupName, string groupPath, string templateName, IEnumerable<KeyValuePair<string, object>> templateData)
        {
            var templateGroup = new StringTemplateGroup(groupName, groupPath);
            var template = templateGroup.GetInstanceOf(templateName);

            foreach(var d in templateData)
            {
                template.SetAttribute(d.Key, d.Value);
            }

            template.RegisterRenderer(typeof(DateTime), new DateRenderer());
            template.RegisterRenderer(typeof(String), new BasicFormatRenderer());

            return template.ToString();
        }
コード例 #10
0
ファイル: desMethod.cs プロジェクト: boyangwm/DBScribe-Ext
 //This method would generate the description of this method and we could show the description in the final report.
 public string getHtmlDescribe(List<string> allSql, string TorC, string optType)
 {
     string htmlText = "";
     StringTemplateGroup group = new StringTemplateGroup("myGroup", @".\Templet");
     StringTemplate st = group.GetInstanceOf("MethodDes");
     st.SetAttribute("FunctionName", TakePointOff(name));
     st.SetAttribute("MethodFullName", name);
     st.SetAttribute("MethodName", methodself.Name);
     st.SetAttribute("MethodSum", swumsummary);
     if (allSql != null)
     {
         foreach (var singleSql in allSql)
         {
             var tempText = translateStmt(singleSql, TorC, optType);
             if (tempText == "") continue;
             st.SetAttribute("SQLs", translateStmt(singleSql, TorC, optType));
         }
     }
     htmlText = st.ToString();
     return htmlText;
 }
コード例 #11
0
        //This method would generate the summary for the project and prepare all the other data for final report.
        public void run()
        {
            Console.WriteLine("Starting collecting data for reporter");

            StringTemplateGroup group = new StringTemplateGroup("myGroup", @".\Templet");
            StringTemplate stsum = group.GetInstanceOf("ProjectSummary");
            int tableCount = 0;
            int totalCount = 0;
            foreach (var tempT in db.tablesInfo)
            {
                if (tempT.directMethods.Count > 0) { tableCount++; totalCount++; }
                foreach (var tempC in tempT.columns)
                {
                    if (tempC.directMethods.Count > 0) totalCount++;
                }
            }
            stsum.SetAttribute("TableNumber", tableCount);
            stsum.SetAttribute("AllNumber", totalCount);
            stsum.SetAttribute("MethodNumber", extractor.allDirectMethods.Count);
            GenerateSummary(stsum.ToString());
        }
コード例 #12
0
        /// <summary>
        /// Given the output report path, generate HTML-formate report for the target project.
        /// </summary>
        /// <param name="path">Report location</param>
        public void Generate(string path)
        {
            List<string> methodFullNameAndParams = new List<string>();

            StringTemplateGroup group = new StringTemplateGroup("myGroup", Constants.TemplatesLoc);
            StringTemplate st = group.GetInstanceOf("Home");
            st.SetAttribute("ProjName", this.projName);
            st.SetAttribute("NUM_DB_METHODS", this.num_db_methods);
            st.SetAttribute("NUM_TOTAL_METHODS", this.num_total_methods);
            st.SetAttribute("NUM_SQL_OPERATING", this.num_sql_operating);
            st.SetAttribute("NUM_LOCAL", this.num_local);
            st.SetAttribute("NUM_DELEGATED", this.num_delegated);
            foreach (string methodTitle in allMethodTitles)
            {
                string[] tokens = methodTitle.Split(new string[] { "] " }, StringSplitOptions.None);
                string methodHeader = tokens[1];
                methodFullNameAndParams.Add(methodHeader);
                string methodDescription = allMethodFullDescriptions[methodTitle];

                st.SetAttribute("IDNum", globalMethodHeaderToIndex[methodHeader]);
                st.SetAttribute("MethodSignature", methodTitle);
                //st.SetAttribute("SourceCode", "...");
                //st.SetAttribute("SwumDesc", "xxx");
                st.SetAttribute("MethodBodyDesc", methodDescription);
                //allMethodSigniture.Add(methodTitle);
            }

            methodFullNameAndParams.Sort();
            //hyper index
            foreach (string mh in methodFullNameAndParams)
            {
                st.SetAttribute("MethodLinkID", mh);

            }

            //st.SetAttribute("Message", "hello ");
            String result = st.ToString(); // yields "int x = 0;"
            //Console.WriteLine(result);

            StreamWriter writetext = new StreamWriter(path);
            writetext.WriteLine(result);
            writetext.Close();
        }
 /// <summary>
 /// Creates a new instance of the StringTemplateViewEngine
 /// </summary>
 /// <param name="viewPath">The physical path to the root views directory</param>
 public StringTemplateViewEngine(string viewPath)
 {
     Group = new StringTemplateGroup("views", viewPath);
 }
コード例 #14
0
        private void button1_Click(object sender, EventArgs e)
        {
            /*StringTemplate template = new StringTemplate(txtTemplate.Text);
            template.SetAttribute(txtName.Text, txtValue.Text);
            template.SetAttribute(txtName2.Text, txtValue2.Text);
            txtOutput.Text = template.ToString();
            */
            System.IO.TextReader tr = new System.IO.StreamReader("stellar_test_group.stg");
            StringTemplateGroup stg = new StringTemplateGroup(tr,typeof(TemplateLexer)); //lexer added to use $..$ in group templates instead of <..>
            StringTemplate st = stg.GetInstanceOf("E57_URI");
            StringTemplate st2 = stg.GetInstanceOf("E19_URI");
            StringTemplate st3 = stg.GetInstanceOf("E57");
            StringTemplate st4 = stg.GetInstanceOf("E19");

            st2.SetAttribute("site", "molas");
            st2.SetAttribute("id", "12345");

            st3.SetAttribute("site", "molas");
            st3.SetAttribute("id", "12345");

            st4.SetAttribute("uri", st2.ToString());

            String s = st3.ToString();
            txtOutput.Text = s;
        }
コード例 #15
0
        private void dlgOpenTemplate_FileOk(object sender, CancelEventArgs e)
        {
            System.IO.TextReader tr;
            txtTemplateFileName.Text = dlgOpenTemplate.FileName;

            using(tr = new System.IO.StreamReader(dlgOpenTemplate.FileName))
            {
                //tr = new System.IO.StreamReader(dlgOpenTemplate.FileName);
                stg = new StringTemplateGroup(tr, typeof(TemplateLexer)); //lexer added to use $..$ in group templates instead of <..>
                //StringTemplate st = stg.GetInstanceOf("E57_URI");
                lstTemplates.Items.Clear();
                ICollection < String > names = stg.GetTemplateNames();

                //foreach (StringTemplate st in stg.Templates)
                foreach (String s in names)
                {
                    lstTemplates.Items.Add (s);
                }
                tr.Close();
            }
        }
コード例 #16
0
        public void TestCannotFindInterfaceFile()
        {
            // this also tests the group loader
            IStringTemplateErrorListener errors = new ErrorBuffer();
            string tmpdir = Path.GetTempPath();
            StringTemplateGroup.RegisterGroupLoader( new PathGroupLoader( tmpdir, errors ) );

            string templates =
                "group testG implements blort;" + newline +
                "t() ::= <<foo>>" + newline +
                "bold(item) ::= <<foo>>" + newline +
                "duh(a,b,c) ::= <<foo>>" + newline;

            WriteFile( tmpdir, "testG.stg", templates );

            StringTemplateGroup group =
                new StringTemplateGroup( new StreamReader( tmpdir + "/testG.stg" ), errors );

            string expecting = "no such interface file blort.sti";
            Assert.AreEqual( expecting, errors.ToString() );
        }
コード例 #17
0
        /** <summary>
         *  Return a list of all template names missing from group that are defined
         *  in this interface.  Return null if all is well.
         *  </summary>
         */
        public virtual IList<string> GetMissingTemplates( StringTemplateGroup group )
        {
            string[] missing =
                _templates.Values
                .Where( template => !template.optional && !group.IsDefined( template.name ) )
                .Select( template => template.name )
                .ToArray();

            return ( missing.Length == 0 ) ? null : missing;
        }
コード例 #18
0
 public static StringTemplateGroup LoadGroup( string name,
                                             StringTemplateGroup superGroup )
 {
     return LoadGroup( name, null, superGroup );
 }
コード例 #19
0
 public void TestComplicatedInheritance()
 {
     // in super: decls invokes labels
     // in sub:   overridden decls which calls super.decls
     //           overridden labels
     // Bug: didn't see the overridden labels.  In other words,
     // the overridden decls called super which called labels, but
     // didn't get the subgroup overridden labels--it calls the
     // one in the superclass.  Ouput was "DL" not "DSL"; didn't
     // invoke sub's labels().
     string basetemplates =
         "group base;" + newline +
         "decls() ::= \"D<labels()>\"" + newline +
         "labels() ::= \"L\"" + newline
         ;
     StringTemplateGroup @base =
         new StringTemplateGroup( new StringReader( basetemplates ) );
     string subtemplates =
         "group sub;" + newline +
         "decls() ::= \"<super.decls()>\"" + newline +
         "labels() ::= \"SL\"" + newline
         ;
     StringTemplateGroup sub =
             new StringTemplateGroup( new StringReader( subtemplates ) );
     sub.SuperGroup = @base;
     StringTemplate st = sub.GetInstanceOf( "decls" );
     string expecting = "DSL";
     string result = st.ToString();
     Assert.AreEqual( expecting, result );
 }
コード例 #20
0
 public void TestComplicatedIndirectTemplateApplication()
 {
     string templates =
             "group Java;" + newline +
             "" + newline +
             "file(variables) ::= <<" +
             "<variables:{ v | <v.decl:(v.format)()>}; separator=\"\\n\">" + newline +
             ">>" + newline +
             "intdecl(decl) ::= \"int <decl.name> = 0;\"" + newline +
             "intarray(decl) ::= \"int[] <decl.name> = null;\"" + newline
             ;
     StringTemplateGroup group =
             new StringTemplateGroup( new StringReader( templates ) );
     StringTemplate f = group.GetInstanceOf( "file" );
     f.SetAttribute( "variables.{decl,format}", new Decl( "i", "int" ), "intdecl" );
     f.SetAttribute( "variables.{decl,format}", new Decl( "a", "int-array" ), "intarray" );
     //System.out.println("f='"+f+"'");
     string expecting = "int i = 0;" + newline +
             "int[] a = null;";
     Assert.AreEqual( expecting, f.ToString() );
 }
コード例 #21
0
 public void TestCollectionAttributes()
 {
     StringTemplateGroup group =
             new StringTemplateGroup( "test" );
     StringTemplate bold = group.DefineTemplate( "bold", "<b>$it$</b>" );
     StringTemplate t =
         new StringTemplate( group, "$data$, $data:bold()$, " +
                                   "$list:bold():bold()$, $array$, $a2$, $a3$, $a4$" );
     List<object> v = new List<object>();
     v.Add( "1" );
     v.Add( "2" );
     v.Add( "3" );
     IList list = new List<object>();
     list.Add( "a" );
     list.Add( "b" );
     list.Add( "c" );
     t.SetAttribute( "data", v );
     t.SetAttribute( "list", list );
     t.SetAttribute( "array", new string[] { "x", "y" } );
     t.SetAttribute( "a2", new int[] { 10, 20 } );
     t.SetAttribute( "a3", new float[] { 1.2f, 1.3f } );
     t.SetAttribute( "a4", new double[] { 8.7, 9.2 } );
     //System.out.println(t);
     string expecting = "123, <b>1</b><b>2</b><b>3</b>, " +
         "<b><b>a</b></b><b><b>b</b></b><b><b>c</b></b>, xy, 1020, 1.21.3, 8.79.2";
     Assert.AreEqual( expecting, t.ToString() );
 }
コード例 #22
0
 public void TestChangingAttrValueTemplateApplicationToVector()
 {
     StringTemplateGroup group =
             new StringTemplateGroup( "test" );
     StringTemplate bold = group.DefineTemplate( "bold", "<b>$x$</b>" );
     StringTemplate t = new StringTemplate( group, "$names:bold(x=it)$" );
     t.SetAttribute( "names", "Terence" );
     t.SetAttribute( "names", "Tom" );
     //System.out.println("'"+t.toString()+"'");
     string expecting = "<b>Terence</b><b>Tom</b>";
     Assert.AreEqual( expecting, t.ToString() );
 }
コード例 #23
0
 public void TestChangingAttrValueRepeatedTemplateApplicationToVector()
 {
     StringTemplateGroup group = new StringTemplateGroup( "dummy", "." );
     StringTemplate bold = group.DefineTemplate( "bold", "<b>$item$</b>" );
     StringTemplate italics = group.DefineTemplate( "italics", "<i>$it$</i>" );
     StringTemplate members = new StringTemplate( group, "$members:bold(item=it):italics(it=it)$" );
     members.SetAttribute( "members", "Jim" );
     members.SetAttribute( "members", "Mike" );
     members.SetAttribute( "members", "Ashar" );
     //System.out.println("members="+members);
     string expecting = "<i><b>Jim</b></i><i><b>Mike</b></i><i><b>Ashar</b></i>";
     Assert.AreEqual( expecting, members.ToString() );
 }
 private void LoadGroup()
 {
     _group = new StringTemplateGroup("views", _viewPath);
     _group.ErrorListener = new StringTemplateErrorListener();
 }
コード例 #25
0
 /** <summary>
  *  Return a list of all template sigs that are present in the group, but
  *  that have wrong formal argument lists.  Return null if all is well.
  *  </summary>
  */
 public virtual IList<string> GetMismatchedTemplates( StringTemplateGroup group )
 {
     List<string> mismatched = new List<string>();
     foreach ( TemplateDefinition d in _templates.Values )
     {
         if ( group.IsDefined( d.name ) )
         {
             StringTemplate defST = group.GetTemplateDefinition( d.name );
             var formalArgs = defST.FormalArguments;
             bool ack = false;
             if ( ( d.formalArgs != null && formalArgs == null ) ||
                 ( d.formalArgs == null && formalArgs != null ) ||
                 d.formalArgs.Count != formalArgs.Count )
             {
                 ack = true;
             }
             if ( !ack )
             {
                 foreach ( var arg in formalArgs )
                 {
                     FormalArgument arg2;
                     if ( !d.formalArgs.TryGetValue( arg.name, out arg2 ) || arg2 == null )
                     {
                         ack = true;
                         break;
                     }
                 }
             }
             if ( ack )
             {
                 //System.out.println(d.formalArgs+"!="+formalArgs);
                 mismatched.Add( GetTemplateSignature( d ) );
             }
         }
     }
     if ( mismatched.Count == 0 )
     {
         mismatched = null;
     }
     return mismatched;
 }
コード例 #26
0
ファイル: dbTable.cs プロジェクト: boyangwm/DBScribe-Ext
 //This method is used to generate the index of this table and the index is put in the left side of the report. With this index we could put the table and the columns belong to this table together.
 public string generateLeftIndex()
 {
     StringTemplateGroup group = new StringTemplateGroup("myGroup", @".\Templet");
     StringTemplate st = group.GetInstanceOf("TableLeft");
     string finalstring = "";
     finalstring += "<a href=\"#" + this.title +"\">" + this.title +"</a><br>";
     foreach (var col in this.columns)
     {
         if (col.directMethods.Count==0) continue;
         st.SetAttribute("Columns", "Column:"+col.name);
         st.SetAttribute("Links", col.title);
     }
     finalstring += st.ToString();
     return finalstring;
 }
コード例 #27
0
 /** <summary>
  *  Create a group from the input stream, but use a nondefault lexer
  *  to break the templates up into chunks.  This is usefor changing
  *  the delimiter from the default $...$ to &lt;...>, for example.
  *  </summary>
  */
 public StringTemplateGroup( TextReader r,
                            Type lexer,
                            IStringTemplateErrorListener errors,
                            StringTemplateGroup superGroup )
 {
     this._templatesDefinedInGroupFile = true;
     // if no lexer specified, then assume <...> when loading from group file
     if ( lexer == null )
     {
         lexer = typeof( AngleBracketTemplateLexer );
     }
     TemplateLexerClass = lexer;
     if ( errors != null )
     {
         // always have to have a listener
         this._listener = errors;
     }
     SuperGroup = superGroup;
     ParseGroup( r );
     _nameToGroupMap[_name] = this;
     VerifyInterfaceImplementations();
 }
コード例 #28
0
 public void TestBackslash2()
 {
     StringTemplateGroup group = new StringTemplateGroup("test");
     StringTemplate t = group.DefineTemplate("t", "\\ ");
     string expecting = "\\ ";
     Assert.AreEqual(expecting, t.ToString());
 }
コード例 #29
0
 public static StringTemplateGroup LoadGroup( string name,
                                             Type lexer,
                                             StringTemplateGroup superGroup )
 {
     if ( _groupLoader != null )
     {
         return _groupLoader.LoadGroup( name, lexer, superGroup );
     }
     return null;
 }
コード例 #30
0
 public string GetTemplate(string groupName, string groupPath, string templateName)
 {
     var templateGroup = new StringTemplateGroup(groupName, groupPath);
     return templateGroup.GetInstanceOf(templateName).Template;
 }