Esempio n. 1
0
        private void CompileConcept(DocTemplateUsage concept, DocModelView view, TypeBuilder tb)
        {
            bool includeconcept = true;

            if (this.m_exchange != null)
            {
                includeconcept = false;
                foreach (DocExchangeItem ei in concept.Exchanges)
                {
                    if (ei.Exchange == this.m_exchange && ei.Applicability == DocExchangeApplicabilityEnum.Export &&
                        (ei.Requirement == DocExchangeRequirementEnum.Mandatory || ei.Requirement == DocExchangeRequirementEnum.Optional))
                    {
                        includeconcept = true;
                    }
                }
            }

            // bool ConceptTemplateA([Parameter1, ...]);
            // {
            //    // for loading reference value:
            //    .ldfld [AttributeRule]
            //    .ldelem [Index] // for collection, get element by index
            //    .castclass [EntityRule] for entity, cast to expected type;
            //    // for object graphs, repeat the above instructions to load value
            //
            //    for loading constant:
            //    .ldstr 'value'
            //
            //    for comparison functions:
            //    .cge
            //
            //    for logical aggregations, repeat each item, pushing 2 elements on stack, then run comparison
            //    .or
            //
            //    return the boolean value on the stack
            //    .ret;
            // }

            // bool[] ConceptA()
            // {
            //    bool[] result = new bool[2];
            //
            //    if parameters are specified, call for each template rule; otherwise call just once
            //    result[0] = ConceptTemplateA([Parameter1, ...]); // TemplateRule#1
            //    result[1] = ConceptTemplateA([Parameter1, ...]); // TemplateRule#2
            //
            //    return result;
            // }

            // compile a method for the template definition, where parameters are passed to the template


#if true
            if (includeconcept && concept.Definition != null)
            {
                MethodInfo methodTemplate = this.RegisterTemplate(concept.Definition);

                // verify that definition is compatible with entity (user error)
                if (methodTemplate != null && methodTemplate.DeclaringType.IsAssignableFrom(tb))
                {
                    string methodname = DocumentationISO.MakeLinkName(view) + "_" + DocumentationISO.MakeLinkName(concept.Definition);



                    MethodBuilder method    = tb.DefineMethod(methodname, MethodAttributes.Public, CallingConventions.HasThis, typeof(bool[]), null);
                    ILGenerator   generator = method.GetILGenerator();

                    DocModelRule[] parameters = concept.Definition.GetParameterRules();

                    if (parameters != null && parameters.Length > 0)
                    {
                        // allocate array of booleans, store as local variable
                        generator.DeclareLocal(typeof(bool[]));
                        generator.Emit(OpCodes.Ldc_I4, concept.Items.Count);
                        generator.Emit(OpCodes.Newarr, typeof(bool));
                        generator.Emit(OpCodes.Stloc_0);

                        // call for each item with specific parameters
                        for (int row = 0; row < concept.Items.Count; row++)
                        {
                            DocTemplateItem docItem = concept.Items[row];

                            generator.Emit(OpCodes.Ldloc_0);                               // push the array object onto the stack, for storage later
                            generator.Emit(OpCodes.Ldc_I4, row);                           // push the array index onto the stack for storage later

                            generator.Emit(OpCodes.Ldarg_0);                               // push the *this* pointer for the IFC object instance

                            // push parameters onto stack
                            for (int col = 0; col < parameters.Length; col++)
                            {
                                DocModelRule docParam   = parameters[col];
                                string       paramvalue = docItem.GetParameterValue(docParam.Identification);
                                if (paramvalue != null)
                                {
                                    DocDefinition docParamType = concept.Definition.GetParameterType(docParam.Identification, this.m_definitions);
                                    if (docParamType is DocDefined)
                                    {
                                        DocDefined docDefined = (DocDefined)docParamType;
                                        switch (docDefined.DefinedType)
                                        {
                                        case "INTEGER":
                                        {
                                            Int64 ival = 0;
                                            Int64.TryParse(paramvalue, out ival);
                                            generator.Emit(OpCodes.Ldc_I8, ival);
                                            generator.Emit(OpCodes.Box);
                                        }
                                        break;

                                        case "REAL":
                                        {
                                            Double dval = 0.0;
                                            Double.TryParse(paramvalue, out dval);
                                            generator.Emit(OpCodes.Ldc_R8, dval);
                                            generator.Emit(OpCodes.Box);
                                        }
                                        break;

                                        case "STRING":
                                            generator.Emit(OpCodes.Ldstr, paramvalue);
                                            break;

                                        default:
                                            generator.Emit(OpCodes.Ldstr, paramvalue);
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        // assume string
                                        generator.Emit(OpCodes.Ldstr, paramvalue);
                                    }
                                }
                                else
                                {
                                    generator.Emit(OpCodes.Ldnull);
                                }
                            }

                            generator.Emit(OpCodes.Call, methodTemplate);                  // call the validation function for the concept template
                            generator.Emit(OpCodes.Stelem_I1);                             // store the result (bool) into an array slot
                        }

                        // return the array of boolean results
                        generator.Emit(OpCodes.Ldloc_0);
                        generator.Emit(OpCodes.Ret);
                    }
                    else
                    {
                        // allocate array of booleans, store as local variable
                        generator.DeclareLocal(typeof(bool[]));
                        generator.Emit(OpCodes.Ldc_I4, 1);
                        generator.Emit(OpCodes.Newarr, typeof(bool));
                        generator.Emit(OpCodes.Stloc_0);

                        generator.Emit(OpCodes.Ldloc_0);                           // push the array object onto the stack, for storage later
                        generator.Emit(OpCodes.Ldc_I4, 0);                         // push the array index onto the stack for storage later

                        // call once
                        generator.Emit(OpCodes.Ldarg_0);                           // push the *this* pointer for the IFC object instance
                        generator.Emit(OpCodes.Call, methodTemplate);              // call the validation function for the concept template
                        generator.Emit(OpCodes.Stelem_I1);                         // store the result (bool) into an array slot

                        // return the array of boolean results
                        generator.Emit(OpCodes.Ldloc_0);
                        generator.Emit(OpCodes.Ret);
                    }
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine("Incompatible template: " + tb.Name + " - " + concept.Definition.Name);
                }
            }
#endif
            // recurse
            foreach (DocTemplateUsage docChild in concept.Concepts)
            {
                CompileConcept(docChild, view, tb);
            }
        }
Esempio n. 2
0
        public string FormatData(DocProject docProject, DocPublication docPublication, DocExchangeDefinition docExchange, Dictionary <string, DocObject> map, Dictionary <long, SEntity> instances, SEntity root, bool markup)
        {
            //Guid guidMapping = Guid.Parse("");//...

            StringBuilder sb = new StringBuilder();

            foreach (DocModelView docView in docPublication.Views)
            {
                foreach (DocConceptRoot docRoot in docView.ConceptRoots)
                {
                    // look for specific concept root dealing with mappings
                    foreach (DocTemplateUsage docConcept in docRoot.Concepts)
                    {
                        if (docConcept.Definition != null && docConcept.Definition.Name.Equals("External Data Constraints") && docConcept.Items.Count > 0)//...
                        {
                            bool included = true;

                            if (docExchange != null)
                            {
                                included = false;
                                // if exhcnage specified, check for inclusion
                                foreach (DocExchangeItem docExchangeItem in docConcept.Exchanges)
                                {
                                    if (docExchangeItem.Exchange == docExchange && docExchangeItem.Requirement == DocExchangeRequirementEnum.Mandatory)
                                    {
                                        included = true;
                                        break;
                                    }
                                }
                            }

                            // check if there are any instances to populate table
                            if (included)
                            {
                                included = false;
                                foreach (SEntity e in instances.Values)
                                {
                                    string eachname = e.GetType().Name;
                                    if (docRoot.ApplicableEntity.IsInstanceOfType(e))
                                    {
                                        included = true;
                                        break;
                                    }
                                }
                            }

                            if (included)
                            {
                                string table = docConcept.Items[0].GetParameterValue("Table");
                                string query = docConcept.Items[0].GetParameterValue("Reference");

                                sb.AppendLine("<h4>" + docConcept.Name + "</h4>");
                                sb.AppendLine("<table class=\"gridtable\">");

                                List <string>       colstyles = new List <string>();
                                List <string>       colformat = new List <string>();
                                List <CvtValuePath> colmaps   = new List <CvtValuePath>();

                                // generate header row
                                sb.AppendLine("<tr>");
                                foreach (DocTemplateItem docItem in docConcept.Items)
                                {
                                    string name = docItem.GetParameterValue("Name");
                                    string disp = "#" + docItem.GetColor().ToArgb().ToString("X8"); //docItem.GetParameterValue("Color");docItem.GetParameterValue("Color");
                                    string expr = docItem.GetParameterValue("Reference");
                                    string form = docItem.GetParameterValue("Format");

                                    string style = "";
                                    if (!String.IsNullOrEmpty(disp))
                                    {
                                        style = " style=\"background-color:" + disp + ";\"";
                                    }
                                    colstyles.Add(style);

                                    string format = "";
                                    if (!String.IsNullOrEmpty(form))
                                    {
                                        format = form;
                                    }
                                    colformat.Add(format);

                                    string       desc    = "";
                                    CvtValuePath valpath = CvtValuePath.Parse(expr, map); //todo: move out of loop
                                    colmaps.Add(valpath);
                                    if (valpath != null)
                                    {
                                        desc = /*valpath.GetDescription(map) + "&#10;&#10;" + */ valpath.ToString().Replace("\\", "&#10;");
                                    }

                                    sb.Append("<th><a href=\"../../schema/views/" + DocumentationISO.MakeLinkName(docView) + "/" + DocumentationISO.MakeLinkName(docExchange) + ".htm#" + DocumentationISO.MakeLinkName(docConcept) + "\" title=\"" + desc + "\">");
                                    sb.Append(name);
                                    sb.Append("</a></th>");
                                }
                                ;
                                sb.AppendLine("</tr>");

                                // generate data rows
                                foreach (SEntity e in instances.Values)
                                {
                                    string eachname = e.GetType().Name;
                                    if (docRoot.ApplicableEntity.IsInstanceOfType(e))
                                    {
                                        bool          includerow = true;
                                        StringBuilder sbRow      = new StringBuilder();

                                        sbRow.Append("<tr>");
                                        int iCol = 0;
                                        foreach (DocTemplateItem docItem in docConcept.Items)
                                        {
                                            sbRow.Append("<td" + colstyles[iCol]);
                                            CvtValuePath valpath = colmaps[iCol];
                                            string       format  = colformat[iCol];

                                            iCol++;

                                            if (valpath != null)
                                            {
                                                string nn = docItem.GetParameterValue("Name");

                                                object value = valpath.GetValue(e, null);

                                                if (value == e)
                                                {
                                                    value = e.GetType().Name;
                                                }
                                                else if (value is SEntity)
                                                {
                                                    // use name
                                                    FieldInfo fieldValue = value.GetType().GetField("Name");
                                                    if (fieldValue != null)
                                                    {
                                                        value = fieldValue.GetValue(value);
                                                    }
                                                }
                                                else if (value is System.Collections.IList)
                                                {
                                                    System.Collections.IList list   = (System.Collections.IList)value;
                                                    StringBuilder            sbList = new StringBuilder();
                                                    foreach (object elem in list)
                                                    {
                                                        FieldInfo fieldName = elem.GetType().GetField("Name");
                                                        if (fieldName != null)
                                                        {
                                                            object elemname = fieldName.GetValue(elem);
                                                            if (elemname != null)
                                                            {
                                                                FieldInfo fieldValue = elemname.GetType().GetField("Value");
                                                                if (fieldValue != null)
                                                                {
                                                                    object elemval = fieldValue.GetValue(elemname);
                                                                    sbList.Append(elemval.ToString());
                                                                }
                                                            }
                                                        }
                                                        sbList.Append("; <br/>");
                                                    }
                                                    value = sbList.ToString();
                                                }
                                                else if (value is Type)
                                                {
                                                    value = ((Type)value).Name;
                                                }

                                                if (!String.IsNullOrEmpty(format))
                                                {
                                                    if (format.Equals("Required") && value == null)
                                                    {
                                                        includerow = false;
                                                    }
                                                }

                                                if (value != null)
                                                {
                                                    FieldInfo fieldValue = value.GetType().GetField("Value");
                                                    if (fieldValue != null)
                                                    {
                                                        value = fieldValue.GetValue(value);
                                                    }

                                                    if (format != null && format.Equals("True") && (value == null || !value.ToString().Equals("True")))
                                                    {
                                                        includerow = false;
                                                    }

                                                    if (value is Double)
                                                    {
                                                        sbRow.Append(" align=\"right\">");

                                                        sbRow.Append(((Double)value).ToString("N3"));
                                                    }
                                                    else if (value is List <Int64> )
                                                    {
                                                        sbRow.Append(">");

                                                        // latitude or longitude
                                                        List <Int64> intlist = (List <Int64>)value;
                                                        if (intlist.Count >= 3)
                                                        {
                                                            sbRow.Append(intlist[0] + "° " + intlist[1] + "' " + intlist[2] + "\"");
                                                        }
                                                    }
                                                    else if (value != null)
                                                    {
                                                        sbRow.Append(">");
                                                        sbRow.Append(value.ToString()); // todo: html-encode
                                                    }
                                                }
                                                else
                                                {
                                                    sbRow.Append(">");
                                                    sbRow.Append("&nbsp;");
                                                }
                                            }
                                            else
                                            {
                                                sbRow.Append(">");
                                            }

                                            sbRow.Append("</td>");
                                        }
                                        sbRow.AppendLine("</tr>");

                                        if (includerow)
                                        {
                                            sb.Append(sbRow.ToString());
                                        }
                                    }
                                }

                                sb.AppendLine("</table>");
                                sb.AppendLine("<br/>");
                            }
                        }
                    }
                }
            }

            return(sb.ToString());
        }
Esempio n. 3
0
        /// <summary>
        /// Saves all content to folder hierarchy
        /// </summary>
        /// <param name="project"></param>
        /// <param name="path"></param>
        public static void Save(DocProject project, string path, Dictionary <string, DocObject> mapEntity, FolderStorageOptions options)
        {
            bool bExportSchema    = ((options & FolderStorageOptions.Schemas) != 0);
            bool bExportExchanges = ((options & FolderStorageOptions.Exchanges) != 0);
            bool bExportExamples  = ((options & FolderStorageOptions.Examples) != 0);
            bool bExportLocalize  = ((options & FolderStorageOptions.Localization) != 0);

            Compiler compiler = new Compiler(project, null, null, false);

            System.Reflection.Emit.AssemblyBuilder assembly = compiler.Assembly;

            // -exchanges (or mvd?)
            //  {exchange}.mvdxml - definition
            //  {exchange}.cs     - C# partial classes for capturing exchange --- later
            //  templates.mvdxml - shared templates
            // -figures -- manually added
            // -formats
            //  -json
            //  -step
            //  -ttl
            //  -xml
            // -samples
            //  {sample}.ifcxml - ifcxml is native format for easier browsing, comparing, and validating
            //  {sample}.htm    - documentation for example
            //  {sample}.png    - preview image of example
            //  {sample} - subdirectory if children
            // -schemas
            //  {version}
            //   {schema}
            //    {class}.cs   - definition in C#
            //    {class}.htm  - documentation in HTML
            //    schema.cs    - functions and
            //    schema.htm   - documentation of schema in HTML
            //    schema.svg   - diagram of schema in SVG
            //    templates.ifcxml - property and quantity templates
            //   localization
            //   {locale}.txt    - localized definitions
            //  ifc.csproj

            if (bExportSchema)
            {
                string pathClasses = path + @"\schemas\" + project.GetSchemaIdentifier();
                System.IO.Directory.CreateDirectory(pathClasses);
                FormatCSC.GenerateCode(project, pathClasses, mapEntity, DocCodeEnum.All);

                // generate ifcxml for templates
                DocumentationISO.DoExport(project, null, pathClasses + @"\templates.ifcxml", null, null, DocDefinitionScopeEnum.Default, null, mapEntity);

                // XSD configuration // not needed -- can re-read from C# classes
                //DocumentationISO.DoExport(project, null, pathClasses + @"\xsdconfig.xml", null, null, DocDefinitionScopeEnum.Default, null, mapEntity);
            }

            if (bExportExchanges)
            {
                string pathExchanges = path + @"\exchanges";
                System.IO.Directory.CreateDirectory(pathExchanges);
                foreach (DocModelView docView in project.ModelViews)
                {
                    string pathView = pathExchanges + @"\" + DocumentationISO.MakeLinkName(docView);
                    DocumentationISO.DoExport(project, null, pathView + ".mvdxml", new DocModelView[] { docView }, null, DocDefinitionScopeEnum.Default, null, mapEntity);

                    //... future: once it works flawlessly...FormatCSC.GenerateExchange(project, docView, pathView, mapEntity);
                }
            }

            if (bExportExamples)
            {
                // compile schema into assembly
                Type typeProject = Compiler.CompileProject(project);

                string pathSamples    = path + @"\examples";
                string pathSamplesWeb = "examples";
                System.IO.Directory.CreateDirectory(pathSamples);
                using (StreamWriter writerIndex = new StreamWriter(Stream.Null))                //...pathSamples + @"\index.htm"))
                {
                    writerIndex.WriteLine("<html><body>");

                    writerIndex.WriteLine("<table>");
                    foreach (DocExample docExam in project.Examples)
                    {
                        // generate ifcxml for each sample
                        ExportExample(pathSamples, pathSamplesWeb, typeProject, docExam, writerIndex);
                    }
                    writerIndex.WriteLine("</table>");

                    writerIndex.WriteLine("</body></html>");
                }
            }

            // terms, abbreviations, references, bibliography, ...
#if false
            string pathTerms = path + @"\terms";
            System.IO.Directory.CreateDirectory(pathSamples);
            foreach (DocTerm docTerm in this.m_project.Terms)
            {
            }
#endif

            // localization
            SortedList <string, string> listLocale = new SortedList <string, string>();
            foreach (DocObject eachobj in mapEntity.Values)
            {
                if (eachobj.Localization != null)
                {
                    foreach (DocLocalization doclocal in eachobj.Localization)
                    {
                        // only deal with languages, not regions
                        if (doclocal.Locale != null && doclocal.Locale.Length >= 2)
                        {
                            string language = doclocal.Locale.Substring(0, 2);

                            if (!listLocale.ContainsKey(language))
                            {
                                listLocale.Add(language, doclocal.Locale);
                            }
                        }
                    }
                }
            }

            if (bExportLocalize)
            {
                string pathLocalize = path + @"\localize";
                System.IO.Directory.CreateDirectory(pathLocalize);
                foreach (string locale in listLocale.Keys)
                {
                    string pathLocale = path + @"\localize\" + locale + ".txt";
                    using (FormatCSV format = new FormatCSV(pathLocale))
                    {
                        format.Instance = project;
                        format.Locales  = new string[] { locale };
                        format.Scope    = DocDefinitionScopeEnum.Default;
                        format.Save();
                    }
                }
            }
        }
Esempio n. 4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="path">Path of parent</param>
        /// <param name="docExample"></param>
        private static void ExportExample(string path, string webpath, Type typeProject, DocExample docExample, StreamWriter writerIndex)
        {
            string pathExample    = path + @"\" + DocumentationISO.MakeLinkName(docExample);
            string pathExampleWeb = webpath + "/" + DocumentationISO.MakeLinkName(docExample);

            // load SPF from internal content
            if (docExample.File != null)
            {
                try
                {
                    using (MemoryStream streamSource = new MemoryStream(docExample.File))
                    {
                        StepSerializer serSource = new StepSerializer(typeProject);
                        object         project   = serSource.ReadObject(streamSource);

                        // write original IFC file as-is (including comments)  -- or could be normalized using StepSerializer
                        using (FileStream streamIFC = new FileStream(pathExample + ".ifc", FileMode.Create))
                        {
                            streamIFC.Write(docExample.File, 0, docExample.File.Length);
                        }

#if false
                        using (FileStream streamXML = new FileStream(pathExample + ".ifcxml", FileMode.Create))
                        {
                            BuildingSmart.Serialization.Xml.XmlSerializer streamTarget = new BuildingSmart.Serialization.Xml.XmlSerializer(typeProject);
                            streamTarget.WriteObject(streamXML, project);
                        }

                        using (FileStream streamJSN = new FileStream(pathExample + ".json", FileMode.Create))
                        {
                            BuildingSmart.Serialization.Json.JsonSerializer streamTarget = new BuildingSmart.Serialization.Json.JsonSerializer(typeProject);
                            streamTarget.WriteObject(streamJSN, project);
                        }

                        using (FileStream streamTTL = new FileStream(pathExample + ".ttl", FileMode.Create))
                        {
                            BuildingSmart.Serialization.Turtle.TurtleSerializer streamTarget = new BuildingSmart.Serialization.Turtle.TurtleSerializer(typeProject);
                            streamTarget.WriteObject(streamTTL, project);
                        }
#endif
                    }
                }
                catch (Exception xx)
                {
                    System.Diagnostics.Debug.WriteLine(xx.Message);
                    return;
                }

                writerIndex.WriteLine("<tr><td><a href=\"./" + webpath + ".htm\">" + docExample.Name + "</a></td>");
                WriteExampleIndexFormat(writerIndex, pathExampleWeb, "ifc");
                WriteExampleIndexFormat(writerIndex, pathExampleWeb, "ifcxml");
                WriteExampleIndexFormat(writerIndex, pathExampleWeb, "json");
                WriteExampleIndexFormat(writerIndex, pathExampleWeb, "ttl");

                // github link
                writerIndex.WriteLine("<td><a href=\"https://github.com/BuildingSMART/IfcDoc/blob/master/IfcKit/" + pathExampleWeb + ".ifc\"><img src=\"github.png\" width=\"32\" height=\"32\" /></a></td>");

                writerIndex.WriteLine("</tr>");
            }
            else
            {
                // write header row
                writerIndex.WriteLine("<tr><th colspan=\"6\"><a href=\"./" + pathExampleWeb + ".htm\">" + docExample.Name + "</a></th></tr>");
            }

            if (!String.IsNullOrEmpty(docExample.Documentation))
            {
                string filehtml = pathExample + ".htm";
                using (StreamWriter writerHtml = new StreamWriter(filehtml, false, Encoding.UTF8))
                {
                    writerHtml.Write(docExample.Documentation);
                }
            }

            if (docExample.Examples.Count > 0)
            {
                System.IO.Directory.CreateDirectory(pathExample);

                // recurse
                foreach (DocExample docSub in docExample.Examples)
                {
                    ExportExample(pathExample, pathExampleWeb, typeProject, docSub, writerIndex);
                }
            }
        }
Esempio n. 5
0
        public string FormatDataConcept(DocProject docProject, DocPublication docPublication, DocExchangeDefinition docExchange, Dictionary <string, DocObject> map, Dictionary <string, Type> typemap, Dictionary <long, SEntity> instances, SEntity root, bool markup, DocModelView docView, DocConceptRoot docRoot, DocTemplateUsage docConcept)
        {
            StringBuilder sb = new StringBuilder();

            string table = docConcept.Items[0].GetParameterValue("Table");
            string query = docConcept.Items[0].GetParameterValue("Reference");

            sb.AppendLine("<h4>" + docConcept.Name + "</h4>");
            sb.AppendLine("<table class=\"gridtable\">");

            List <string>       colstyles = new List <string>();
            List <string>       colformat = new List <string>();
            List <CvtValuePath> colmaps   = new List <CvtValuePath>();

            // generate header row
            sb.AppendLine("<tr>");
            foreach (DocTemplateItem docItem in docConcept.Items)
            {
                string name = docItem.GetParameterValue("Name");
                string disp = "#" + docItem.GetColor().ToArgb().ToString("X8");                 //docItem.GetParameterValue("Color");docItem.GetParameterValue("Color");
                string expr = docItem.GetParameterValue("Reference");
                string form = docItem.GetParameterValue("Format");

                string style = "";
                if (!String.IsNullOrEmpty(disp))
                {
                    style = " style=\"background-color:" + disp + ";\"";
                }
                colstyles.Add(style);

                string format = "";
                if (!String.IsNullOrEmpty(form))
                {
                    format = form;
                }
                colformat.Add(format);

                string       desc    = "";
                CvtValuePath valpath = CvtValuePath.Parse(expr, map);
                colmaps.Add(valpath);
                if (valpath != null)
                {
                    desc = /*valpath.GetDescription(map) + "&#10;&#10;" + */ valpath.ToString().Replace("\\", "&#10;");
                }

                sb.Append("<th><a href=\"../../schema/views/" + DocumentationISO.MakeLinkName(docView) + "/" + DocumentationISO.MakeLinkName(docExchange) + ".htm#" + DocumentationISO.MakeLinkName(docConcept) + "\" title=\"" + desc + "\">");
                sb.Append(name);
                sb.Append("</a></th>");
            }
            ;
            sb.AppendLine("</tr>");

            // generate data rows
            List <DocModelRule> trace = new List <DocModelRule>();

            foreach (SEntity e in instances.Values)
            {
                string eachname = e.GetType().Name;
                if (docRoot.ApplicableEntity.IsInstanceOfType(e))
                {
                    bool includerow = true;

                    // if root has more complex rules, check them
                    if (docRoot.ApplicableTemplate != null && docRoot.ApplicableItems.Count > 0)
                    {
                        includerow = false;

                        // must check1
                        foreach (DocTemplateItem docItem in docRoot.ApplicableItems)
                        {
                            foreach (DocModelRule rule in docRoot.ApplicableTemplate.Rules)
                            {
                                try
                                {
                                    trace.Clear();
                                    bool?result = rule.Validate(e, docItem, typemap, trace, e, null, null);
                                    if (result == true && docRoot.ApplicableOperator == DocTemplateOperator.Or)
                                    {
                                        includerow = true;
                                        break;
                                    }
                                }
                                catch
                                {
                                    docRoot.ToString();
                                }
                            }

                            // don't yet support AND or other operators

                            if (includerow)
                            {
                                break;
                            }
                        }
                    }


                    if (includerow)
                    {
                        StringBuilder sbRow = new StringBuilder();

                        sbRow.Append("<tr>");
                        int iCol = 0;
                        foreach (DocTemplateItem docItem in docConcept.Items)
                        {
                            sbRow.Append("<td" + colstyles[iCol]);
                            CvtValuePath valpath = colmaps[iCol];
                            string       format  = colformat[iCol];

                            iCol++;

                            if (valpath != null)
                            {
                                string nn = docItem.GetParameterValue("Name");

                                object value = valpath.GetValue(e, null);

                                if (value == e)
                                {
                                    value = e.GetType().Name;
                                }
                                else if (value is SEntity)
                                {
                                    // use name
                                    FieldInfo fieldValue = value.GetType().GetField("Name");
                                    if (fieldValue != null)
                                    {
                                        value = fieldValue.GetValue(value);
                                    }
                                }
                                else if (value is System.Collections.IList)
                                {
                                    System.Collections.IList list   = (System.Collections.IList)value;
                                    StringBuilder            sbList = new StringBuilder();
                                    foreach (object elem in list)
                                    {
                                        FieldInfo fieldName = elem.GetType().GetField("Name");
                                        if (fieldName != null)
                                        {
                                            object elemname = fieldName.GetValue(elem);
                                            if (elemname != null)
                                            {
                                                FieldInfo fieldValue = elemname.GetType().GetField("Value");
                                                if (fieldValue != null)
                                                {
                                                    object elemval = fieldValue.GetValue(elemname);
                                                    sbList.Append(elemval.ToString());
                                                }
                                            }
                                        }
                                        sbList.Append("; <br/>");
                                    }
                                    value = sbList.ToString();
                                }
                                else if (value is Type)
                                {
                                    value = ((Type)value).Name;
                                }

                                if (!String.IsNullOrEmpty(format))
                                {
                                    if (format.Equals("Required") && value == null)
                                    {
                                        includerow = false;
                                    }
                                }

                                if (value != null)
                                {
                                    FieldInfo fieldValue = value.GetType().GetField("Value");
                                    if (fieldValue != null)
                                    {
                                        value = fieldValue.GetValue(value);
                                    }

                                    if (format != null && format.Equals("True") && (value == null || !value.ToString().Equals("True")))
                                    {
                                        includerow = false;
                                    }

                                    if (value is Double)
                                    {
                                        sbRow.Append(" align=\"right\">");

                                        sbRow.Append(((Double)value).ToString("N3"));
                                    }
                                    else if (value is List <Int64> )
                                    {
                                        sbRow.Append(">");

                                        // latitude or longitude
                                        List <Int64> intlist = (List <Int64>)value;
                                        if (intlist.Count >= 3)
                                        {
                                            sbRow.Append(intlist[0] + "° " + intlist[1] + "' " + intlist[2] + "\"");
                                        }
                                    }
                                    else if (value != null)
                                    {
                                        sbRow.Append(">");
                                        sbRow.Append(value.ToString());                                         // todo: html-encode
                                    }
                                }
                                else
                                {
                                    sbRow.Append(">");
                                    sbRow.Append("&nbsp;");
                                }
                            }
                            else
                            {
                                sbRow.Append(">");
                            }

                            sbRow.Append("</td>");
                        }
                        sbRow.AppendLine("</tr>");

                        if (includerow)
                        {
                            sb.Append(sbRow.ToString());
                        }
                    }
                }
            }

            sb.AppendLine("</table>");
            sb.AppendLine("<br/>");

            return(sb.ToString());
        }