Example #1
0
        public CheckGridExchange(DocExchangeDefinition docExchange, DocModelView docView, DocProject docProject)
        {
            this.m_project      = docProject;
            this.m_view         = docView;
            this.m_exchange     = docExchange;
            this.m_listTemplate = docProject.GetTemplateList();

            // filter out template list to only those that are currently used
            for (int i = this.m_listTemplate.Count - 1; i >= 0; i--)
            {
                bool used = false;
                foreach (DocConceptRoot docRoot in this.m_view.ConceptRoots)
                {
                    foreach (DocTemplateUsage docUsage in docRoot.Concepts)
                    {
                        if (docUsage.Definition == this.m_listTemplate[i])
                        {
                            used = true;
                            break;
                        }
                    }
                }

                if (!used)
                {
                    this.m_listTemplate.RemoveAt(i);
                }
            }
        }
Example #2
0
 public FormValidateMappings(DocProject docProject, DocModelView docView, Dictionary <string, DocObject> mapEntity, Dictionary <long, object> instances) : this()
 {
     this.m_project   = docProject;
     this.m_view      = docView;
     this.m_mapEntity = mapEntity;
     this.m_instances = instances;
 }
Example #3
0
        public CheckGridEntity(DocConceptRoot docRoot, DocModelView docView, DocProject docProject, Dictionary <string, DocObject> map)
        {
            this.m_root         = docRoot;
            this.m_view         = docView;
            this.m_project      = docProject;
            this.m_listTemplate = new List <DocTemplateDefinition>();

            List <DocTemplateDefinition> listTemplate = docProject.GetTemplateList();

            //... filter out templates to only those that apply to entity...

            foreach (DocTemplateDefinition docTemplate in listTemplate)
            {
                if (docTemplate.Rules != null && docTemplate.Rules.Count > 0) // don't include abstract/organizational templates
                {
                    bool include = false;

                    // check for inheritance
                    DocObject docApplicableEntity = null;
                    if (docTemplate.Type != null && map.TryGetValue(docTemplate.Type, out docApplicableEntity) && docApplicableEntity is DocEntity)
                    {
                        // check for inheritance
                        DocEntity docBase = docRoot.ApplicableEntity;
                        while (docBase != null)
                        {
                            if (docBase == docApplicableEntity)
                            {
                                include = true;
                                break;
                            }

                            if (docBase.BaseDefinition == null)
                            {
                                break;
                            }

                            DocObject docEach = null;
                            if (map.TryGetValue(docBase.BaseDefinition, out docEach))
                            {
                                docBase = (DocEntity)docEach;
                            }
                            else
                            {
                                docBase = null;
                            }
                        }
                    }

                    if (include)
                    {
                        this.m_listTemplate.Add(docTemplate);
                    }
                }
            }
        }
Example #4
0
 public FormSelectExchange(DocModelView docView)
     : this()
 {
     foreach (DocExchangeDefinition docExchange in docView.Exchanges)
     {
         ListViewItem lvi = new ListViewItem();
         lvi.Tag        = docExchange;
         lvi.Text       = docExchange.Name;
         lvi.ImageIndex = 0;
         this.listView.Items.Add(lvi);
     }
 }
 public FormSelectExchange(DocModelView docView)
     : this()
 {
     foreach (DocExchangeDefinition docExchange in docView.Exchanges)
     {
         ListViewItem lvi = new ListViewItem();
         lvi.Tag = docExchange;
         lvi.Text = docExchange.Name;
         lvi.ImageIndex = 0;
         this.listView.Items.Add(lvi);
     }
 }
Example #6
0
        private void comboBoxView_SelectedIndexChanged(object sender, EventArgs e)
        {
            DocModelView docView = this.comboBoxView.SelectedItem as DocModelView;

            if (docView == null)
            {
                return;
            }

            this.comboBoxExchange.Items.Clear();
            foreach (DocExchangeDefinition docExchange in docView.Exchanges)
            {
                this.comboBoxExchange.Items.Add(docExchange);
            }
        }
Example #7
0
        private void buttonOK_Click(object sender, EventArgs e)
        {
            this.textBoxUrl.Enabled = false;
            this.progressBar.Value  = 0;
            this.buttonOK.Enabled   = false;
            this.errorProvider.Clear();

            // register views locally
            this.m_views.Clear();

            if (this.m_download)
            {
                foreach (ListViewItem lvi in this.listViewViews.Items)
                {
                    if (lvi.Checked)
                    {
                        IfdContext ifdContext = (IfdContext)lvi.Tag;
                        Guid       guidView   = IfcDoc.Schema.SGuid.Parse(ifdContext.guid);

                        DocModelView docView = this.m_project.GetView(guidView);
                        if (docView == null)
                        {
                            docView           = new DocModelView();
                            docView.Uuid      = guidView;
                            docView.Name      = lvi.Text;
                            docView.Status    = ifdContext.status;
                            docView.Version   = ifdContext.versionId;
                            docView.Copyright = ifdContext.versionDate;
                            // access rights not captured -- specific to user
                            this.m_project.ModelViews.Add(docView);
                        }

                        this.m_views.Add(docView);
                    }
                }
            }

            // start upload
            this.backgroundWorkerPublish.RunWorkerAsync();
        }
Example #8
0
        public void Redraw()
        {
            if (this.m_image != null)
            {
                this.m_image.Dispose();
                this.m_image = null;
            }

            this.m_rcSelection = Rectangle.Empty;
            this.m_rcHighlight = Rectangle.Empty;
            this.m_hitmap.Clear();
            if (this.m_template != null && this.m_project != null)
            {
                this.m_image = FormatPNG.CreateTemplateDiagram(this.m_template, this.m_hitmap, this.m_project, this.m_instance);
                if (this.m_image != null)
                {
                    this.AutoScrollMinSize = new Size(this.m_image.Width, this.m_image.Height);
                }
            }
            else if (this.m_conceptroot != null && this.m_project != null && this.m_conceptroot.ApplicableEntity != null)
            {
                DocModelView docView = null;
                foreach (DocModelView eachView in this.m_project.ModelViews)
                {
                    if (eachView.ConceptRoots.Contains(this.m_conceptroot))
                    {
                        docView = eachView;
                        break;
                    }
                }

                this.m_image = FormatPNG.CreateConceptDiagram(this.m_conceptroot.ApplicableEntity, docView, this.m_hitmap, this.m_project, this.m_instance);
                if (this.m_image != null)
                {
                    this.AutoScrollMinSize = new Size(this.m_image.Width, this.m_image.Height);
                }
            }

            this.Invalidate();
        }
Example #9
0
        public FormValidate(DocProject project, DocModelView docView, DocExchangeDefinition docExchange) : this()
        {
            this.textBoxPath.Text = Properties.Settings.Default.ValidateFile;
            this.checkBoxReport.Checked = Properties.Settings.Default.ValidateReport;

            foreach (DocModelView docEachView in project.ModelViews)
            {
                this.comboBoxView.Items.Add(docEachView);
            }

            if (docView == null && project.ModelViews.Count > 0)
            {
                docView = project.ModelViews[0];
            }
            this.comboBoxView.SelectedItem = docView;

            if (docExchange == null && docView != null && docView.Exchanges.Count > 0)
            {
                docExchange = docView.Exchanges[0];
            }
            this.comboBoxExchange.SelectedItem = docExchange;
        }
Example #10
0
        public FormValidate(DocProject project, DocModelView docView, DocExchangeDefinition docExchange) : this()
        {
            this.textBoxPath.Text       = Properties.Settings.Default.ValidateFile;
            this.checkBoxReport.Checked = Properties.Settings.Default.ValidateReport;

            foreach (DocModelView docEachView in project.ModelViews)
            {
                this.comboBoxView.Items.Add(docEachView);
            }

            if (docView == null && project.ModelViews.Count > 0)
            {
                docView = project.ModelViews[0];
            }
            this.comboBoxView.SelectedItem = docView;

            if (docExchange == null && docView != null && docView.Exchanges.Count > 0)
            {
                docExchange = docView.Exchanges[0];
            }
            this.comboBoxExchange.SelectedItem = docExchange;
        }
Example #11
0
        private void FillTree(TreeNode tnParent, DocModelView docView)
        {
            TreeNode tn = new TreeNode();

            tn.Tag        = docView;
            tn.Text       = docView.Name;
            tn.ImageIndex = 0;

            if (tnParent != null)
            {
                tnParent.Nodes.Add(tn);
            }
            else
            {
                this.treeView.Nodes.Add(tn);
            }

            // recurse
            foreach (DocModelView docSub in docView.ModelViews)
            {
                FillTree(tn, docSub);
            }
        }
Example #12
0
 public CheckGridConcept(DocTemplateDefinition docTemplate, DocModelView docView, DocProject docProject)
 {
     this.m_template = docTemplate;
     this.m_view = docView;
     this.m_project = docProject;
 }
Example #13
0
        /// <summary>
        /// Recursively validates a concept and all referenced concepts
        /// </summary>
        /// <param name="docUsage">The concept to validate</param>
        /// <param name="docView">The model view containing the concept</param>
        /// <param name="reqInherit">For a referenced concept, indicates requirements defined by the referencing (outer) concept.</param>
        /// <param name="typeEntity">The compiled type corresponding to entity.</param>
        /// <param name="list">List of entities to test for concept.</param>
        /// <param name="sb">String builder to append for reporting results.</param>
        /// <param name="typemap">Map of identifiers to compiled types</param>
        /// <param name="grandtotalpass">The total tests passing (less than or equal to total tests executed).</param>
        /// <param name="grandtotallist">The total tests executed.</param>
        private void ValidateConcept(DocTemplateUsage docUsage, DocModelView docView, DocExchangeRequirementEnum reqInherit, Type typeEntity, List<SEntity> list, StringBuilder sb, Dictionary<string, Type> typemap, ref int grandtotalpass, ref int grandtotalskip, ref int grandtotallist)
        {
            if (docUsage.Definition == null || docUsage.Definition.IsDisabled || docUsage.Suppress)
                return;

            DocExchangeRequirementEnum req = DocExchangeRequirementEnum.NotRelevant;
            bool includeconcept = true;
            if (this.m_filterexchange != null)
            {
                includeconcept = false;
                foreach (DocExchangeItem ei in docUsage.Exchanges)
                {
                    if (ei.Exchange == this.m_filterexchange && ei.Applicability == DocExchangeApplicabilityEnum.Export &&
                        (ei.Requirement == DocExchangeRequirementEnum.Mandatory || ei.Requirement == DocExchangeRequirementEnum.Optional))
                    {
                        includeconcept = true;
                        req = ei.Requirement;
                    }
                }
            }
            else
            {
                // check net requirement if mandatory for any exchange
                foreach (DocExchangeItem docExchangeItem in docUsage.Exchanges)
                {
                    switch (docExchangeItem.Requirement)
                    {
                        case DocExchangeRequirementEnum.Mandatory:
                            req = DocExchangeRequirementEnum.Mandatory;
                            break;

                        case DocExchangeRequirementEnum.Optional:
                            if (req == DocExchangeRequirementEnum.NotRelevant)
                            {
                                req = DocExchangeRequirementEnum.Optional;
                            }
                            break;

                        case DocExchangeRequirementEnum.Excluded:
                            if (req == DocExchangeRequirementEnum.NotRelevant)
                            {
                                req = DocExchangeRequirementEnum.Excluded;
                            }
                            break;
                    }
                }
            }

            if (req == DocExchangeRequirementEnum.NotRelevant)
            {
                req = reqInherit;
                if (reqInherit != DocExchangeRequirementEnum.NotRelevant)
                {
                    includeconcept = true;
                }
            }

            if (!includeconcept)
                return;

            if (list.Count == 0)
            {
                sb.Append("<details><summary>");
                sb.Append(docUsage.Definition.Name);
                sb.AppendLine("</summary></details>");
                return;
            }

            StringBuilder sbDetail = new StringBuilder();

            if (docUsage.Definition != null && docUsage.Definition.Rules != null)
            {
                // new-style validation -- compiled code (fast)
                string methodname = DocumentationISO.MakeLinkName(docView) + "_" + DocumentationISO.MakeLinkName(docUsage.Definition);
                System.Reflection.MethodInfo method = typeEntity.GetMethod(methodname);

                int fail = 0;
                int pass = 0; // pass graph check
                int passRule = 0; // pass rule check
                int failRule = 0; // fail rule check
                List<DocModelRule> trace = new List<DocModelRule>();

                DocModelRule[] parameterrules = docUsage.Definition.GetParameterRules();
                Dictionary<DocModelRuleAttribute, bool> conditions = new Dictionary<DocModelRuleAttribute, bool>();

                if (docUsage.Definition.Name.Contains("-086"))
                {
                    this.ToString();
                }

                foreach (SEntity ent in list)
                {
                    if(docUsage.Definition.Name.Contains("-077") && ent.GetType().Name.Equals("IfcWindow"))
                    {
                        this.ToString();
                    }

                    object[] args = new object[0];
                    if (parameterrules != null && parameterrules.Length > 0)
                    {
                        args = new object[parameterrules.Length];

                        foreach (DocTemplateItem docItem in docUsage.Items)
                        {
                            //if (!docItem.Optional)
                            {
                                trace.Clear();
                                conditions.Clear();

                                if (docItem == docUsage.Items[0])
                                {
                                    sbDetail.Append("<tr valign=\"top\"><td rowspan=\"" + docUsage.Items.Count + "\">#");
                                    sbDetail.Append(ent.OID);
                                    sbDetail.Append("</td>");
                                }
                                else
                                {
                                    sbDetail.Append("<tr valign=\"top\">");
                                }

                                for (int iParam = 0; iParam < parameterrules.Length; iParam++)
                                {
                                    DocModelRule prule = parameterrules[iParam];

                                    sbDetail.Append("<td>");
                                    DocTemplateUsage docUsageInner = docItem.GetParameterConcept(prule.Identification, null);//verify...
                                    if (docUsageInner != null)
                                    {
                                        // report inner rules...
                                        foreach (DocTemplateItem docItemInner in docUsageInner.Items)
                                        {
                                            sbDetail.Append(docItemInner.RuleParameters);
                                            if (docItemInner.Optional)
                                            {
                                                sbDetail.Append("*");
                                            }
                                            sbDetail.Append("<br/>");
                                        }
                                    }
                                    else
                                    {
                                        string pval = docItem.GetParameterValue(prule.Identification);
                                        sbDetail.Append(pval);
                                    }
                                    sbDetail.Append("</td>");
                                }

                                sbDetail.Append("<td>");
                                bool? result = true;
                                foreach (DocModelRule rule in docUsage.Definition.Rules)
                                {
                                    trace.Clear();
                                    bool? itemresult = rule.Validate(ent, docItem, typemap, trace, ent, docUsage, conditions);
                                    if (itemresult != null && !itemresult.Value && result != null)
                                    {
                                        result = false;

                                        // check if conditions were all met; if not, then not a failure
                                        foreach(DocModelRule checkparam in parameterrules)
                                        {
                                            if(checkparam.IsCondition())
                                            {
                                                bool paramspec = false;
                                                if (!conditions.TryGetValue((DocModelRuleAttribute)checkparam, out paramspec) || paramspec == false)
                                                {
                                                    result = null;
                                                    break;
                                                }
                                            }
                                        }

                                        break;
                                    }
                                    else if (itemresult == null)
                                    {
                                        result = null; //verify: was commented out -- put back in to indicate that entire rule is inapplicable.
                                    }
                                }

                                if (result != null && !result.Value)
                                {
                                    foreach (DocModelRule mm in trace)
                                    {
                                        if (mm is DocModelRuleEntity)
                                        {
                                            sbDetail.Append("\\");
                                        }
                                        else if (mm is DocModelRuleAttribute)
                                        {
                                            sbDetail.Append(".");
                                        }
                                        sbDetail.Append(mm.Name);
                                    }

                                    docItem.ValidationStructure[ent] = false;

            #if false // don't mark overall usage as failure, since operator may only require one to be true
                                    if (!docItem.Optional)
                                    {
                                        docUsage.ValidationStructure[ent] = false;
                                        docUsage.Validation = false;
                                        docUsage.Definition.Validation = false;
                                        fail++;
                                    }
            #endif
                                }
                                else if (result != null && result.Value)
                                {
                                    // check for any nested failures
                                    foreach (DocTemplateUsage docInnerConcept in docItem.Concepts)
                                    {
                                        foreach (DocTemplateItem docInnerItem in docInnerConcept.Items)
                                        {
                                            bool innerresult = false;
                                            if(docInnerItem.ValidationStructure.TryGetValue(ent, out innerresult))
                                            {
                                                if(!innerresult)
                                                {
                                                    sbDetail.Append("~");
                                                    sbDetail.Append(docInnerItem.RuleParameters);
                                                    sbDetail.Append("<br/>");

                                                    result = false;
                                                    fail++;
                                                    break;
                                                }
                                            }
                                        }
                                    }

                                    if (result != null && result.Value)
                                    {
                                        sbDetail.Append("+");
                                        pass++;

                                        docItem.ValidationStructure[ent] = true;
                                        if (!docUsage.ValidationStructure.ContainsKey(ent)) // if no failures so far, then concept passes for now
                                        {
                                            docUsage.ValidationStructure[ent] = true;
                                        }
                                    }
                                }
                                else if (result == null)
                                {
                                    sbDetail.Append("*"); // NOT APPLICABLE

                                    // new V9.5: don't mark non-applicable as passing
                                    /*
                                    docItem.ValidationStructure[ent] = true;
                                    if (!docUsage.ValidationStructure.ContainsKey(ent))
                                    {
                                        docUsage.ValidationStructure[ent] = true;
                                    }*/
                                }

                                sbDetail.Append("</td><td>");

                                if (result == null)
                                {
                                    // don't evaluate constraint if it doesn't apply
                                }
                                else if (method != null)
                                {
                                    try
                                    {
                                        bool[] ruleresult = (bool[])method.Invoke(ent, null);//, args);
                                        if (ruleresult != null)
                                        {
                                            bool allpass = true;
                                            foreach (bool compresult in ruleresult)
                                            {
                                                if (!compresult)
                                                {
                                                    allpass = false;
                                                    break;
                                                }
                                            }

                                            if (allpass)
                                            {
                                                sbDetail.Append("+");
                                                passRule++;

                                                docUsage.ValidationConstraints[ent] = true;

                                                if (docUsage.Validation == null)
                                                {
                                                    docUsage.Validation = true;
                                                }
                                            }
                                            else
                                            {
                                                // run detailed report
                                                foreach (DocModelRule rule in docUsage.Definition.Rules)
                                                {
                                                    TraceRule(docUsage.Definition, rule, sbDetail, ent, list);
                                                }

                                                failRule++;

                                                docUsage.ValidationConstraints[ent] = false;
                                                docUsage.Validation = false;
                                            }
                                        }
                                        else
                                        {
                                            sbDetail.Append("FAIL");
                                            failRule++;
                                        }
                                    }
                                    catch (System.Reflection.TargetInvocationException et)
                                    {
                                        sbDetail.Append(et.InnerException.GetType().Name);
                                        failRule++;
                                    }
                                    catch (Exception ex)
                                    {
                                        sbDetail.Append(ex.GetType().Name);
                                        failRule++;
                                    }
                                }
                                else
                                {
                                    sbDetail.Append("FAIL - Incompatible Template");
                                }

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

                        // capture items that didn't match
                    }
                    else
                    {
                        // check for if there are no parameters

                        sbDetail.Append("<tr valign=\"top\"><td>#");
                        sbDetail.Append(ent.OID);
                        sbDetail.Append("</td><td>");

                        DocModelRule ruleFail = null;
                        bool? result = true;
                        foreach (DocModelRule rule in docUsage.Definition.Rules)
                        {
                            trace.Clear();
                            bool? itemresult = rule.Validate(ent, null, typemap, trace, ent, docUsage, conditions);
                            if (itemresult != null && !itemresult.Value)
                            {
                                result = false;
                            }
                            else if (itemresult == null)
                            {
                                result = null;
                            }

                            if (itemresult != null && !itemresult.Value)
                            {
                                if (ruleFail != null)
                                {
                                    sbDetail.Append("<br/>");
                                }
                                ruleFail = rule;

                                foreach (DocModelRule mm in trace)
                                {
                                    if (mm is DocModelRuleEntity)
                                    {
                                        sbDetail.Append("\\");
                                    }
                                    else if (mm is DocModelRuleAttribute)
                                    {
                                        sbDetail.Append(".");
                                    }
                                    sbDetail.Append(mm.Name);
                                }
                            }
                        }

                        if (result == null)
                        {
                            // no applicable rules, so passing
                            pass++;
                        }
                        else if (result != null && result.Value)
                        {
                            // all rules passed
                            docUsage.ValidationStructure[ent] = true;
                            if (docUsage.Validation == null)
                            {
                                docUsage.Validation = true;
                            }
                            pass++;
                        }
                        else if (ruleFail != null)
                        {
                            docUsage.ValidationStructure[ent] = false;
                            docUsage.Validation = false;
                            fail++;
                        }

                        if (result == null)
                        {
                            sbDetail.Append("*");
                        }
                        else if (ruleFail == null)
                        {
                            sbDetail.Append("+");
                        }

                        sbDetail.Append("</td><td>");

                        if (method != null)
                        {
                            try
                            {
                                bool[] ruleresult = (bool[])method.Invoke(ent, args);
                                if (ruleresult != null)
                                {
                                    bool allpass = true;
                                    foreach (bool compresult in ruleresult)
                                    {
                                        if (!compresult)
                                        {
                                            allpass = false;
                                            break;
                                        }
                                    }

                                    if (allpass)
                                    {
                                        sbDetail.Append("+");
                                        docUsage.ValidationConstraints[ent] = true;
                                        passRule++;
                                    }
                                    else
                                    {
                                        // run second-stage validation and trace
                                        bool debugpass = true;
                                        StringBuilder sbCheck = new StringBuilder();
                                        foreach (DocModelRule rule in docUsage.Definition.Rules)
                                        {
                                            bool eachpass = TraceRule(docUsage.Definition, rule, sbCheck, ent, list);
                                            if (!eachpass)
                                            {
                                                debugpass = false;
                                            }
                                        }
                                        if (!debugpass)
                                        {
                                            sbDetail.Append(sbCheck.ToString());
                                            docUsage.ValidationConstraints[ent] = false;
                                            docUsage.Validation = false;
                                            failRule++;
                                        }
                                        else
                                        {
                                            sbDetail.Append("+");
                                            docUsage.ValidationConstraints[ent] = true;
                                            if (docUsage.Validation == null)
                                            {
                                                docUsage.Validation = true;
                                            }
                                            passRule++;
                                        }
                                    }
                                }
                                else
                                {
                                    sbDetail.Append("FAIL");
                                    failRule++;
                                }
                            }
                            catch (System.Reflection.TargetInvocationException et)
                            {
                                sbDetail.Append(et.InnerException.GetType().Name);
                                failRule++;
                            }
                            catch (Exception ex)
                            {
                                sbDetail.Append(ex.GetType().Name);
                                failRule++;
                            }
                        }
                        else
                        {
                            sbDetail.Append("FAIL - Incompatible Template");
                        }
                        sbDetail.AppendLine("</td></tr>");
                    }

                }

                grandtotallist++;

                // nested concepts -- only one must pass
                StringBuilder sbNested = new StringBuilder();
                if (docUsage.Concepts.Count > 0)
                {
                    sbNested.AppendLine("<p>Validation of concept groups (only one must pass):</p>");

                    int subtotalpass = 0;
                    int subtotalskip = 0;
                    int subtotallist = 0;
                    foreach (DocTemplateUsage docSub in docUsage.Concepts)
                    {
                        ValidateConcept(docSub, docView, reqInherit, typeEntity, list, sbNested, typemap, ref subtotalpass, ref subtotalskip, ref subtotallist);
                    }

                    if (subtotalpass > 0)
                    {
                        //grandtotalpass++;
                        sbNested.AppendLine("<p>RESULT: PASS (" + subtotalpass + "/" + subtotallist + ")</p>");
                    }
                    else
                    {
                        fail++;
                        sbNested.AppendLine("<p>RESULT: FAIL (" + subtotalpass + "/" + subtotallist + ")</p>");
                    }
                }

                sb.AppendLine("<details><summary>" + docUsage.Definition.Name);

                sb.Append(" (Operator: " + docUsage.Operator.ToString() + ")");

                if(req == DocExchangeRequirementEnum.Optional)
                {
                    sb.Append(" [OPTIONAL]");
                }
                if (fail > 0 || failRule > 0)
                {
                    docUsage.Validation = false;
                    docUsage.Definition.Validation = false;

                    if(req == DocExchangeRequirementEnum.Optional)
                    {
                        grandtotalskip++;
                    }

                    sb.AppendLine(" - [FAIL]");
                }
                else
                {
                    docUsage.Validation = true;
                    if (docUsage.Definition.Validation == null)
                    {
                        docUsage.Definition.Validation = true;
                    }

                    grandtotalpass++;
                }

                sb.AppendLine("</summary>");
                sb.AppendLine("<table border=\"1\" >");
                sb.Append("<tr><th>Instance</th>");

                foreach (DocModelRule docRule in parameterrules)
                {
                    sb.Append("<th>");
                    sb.Append(docRule.Identification);

                    if (docRule.IsCondition())
                    {
                        sb.Append("?");
                    }

                    sb.Append("</th>");
                }

                sb.Append("<th>Structure</th>");
                sb.Append("<th>Constraints</th>");
                sb.AppendLine("</tr>");

                sb.AppendLine(sbDetail.ToString());

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

                sb.AppendLine(sbNested.ToString());

                sb.AppendLine("</details>");
            }
        }
Example #14
0
        /// <summary>
        /// Creates a concept diagram for a particular entity, including all concepts at specified view and base view(s).
        /// </summary>
        /// <param name="docEntity"></param>
        /// <param name="docView"></param>
        /// <param name="map"></param>
        /// <param name="layout"></param>
        /// <param name="docProject"></param>
        /// <param name="instance"></param>
        /// <returns></returns>
        internal static Image CreateConceptDiagram(DocEntity docEntity, DocModelView docView, Dictionary<string, DocObject> map, Dictionary<Rectangle, DocModelRule> layout, DocProject docProject, SEntity instance)
        {
            DocSchema docSchema = docProject.GetSchemaOfDefinition(docEntity);

            layout.Clear();
            List<int> lanes = new List<int>(); // keep track of position offsets in each lane
            for (int i = 0; i < 16; i++)
            {
                lanes.Add(0);
            }

            // determine boundaries
            DrawEntity(null, 0, lanes, docEntity, docView, null, null, map, layout, docProject, docSchema, instance);
            Rectangle rcBounds = Rectangle.Empty;
            foreach (Rectangle rc in layout.Keys)
            {
                if (rc.Right > rcBounds.Width)
                {
                    rcBounds.Width = rc.Right;
                }

                if (rc.Bottom > rcBounds.Bottom)
                {
                    rcBounds.Height = rc.Bottom;
                }
            }
            rcBounds.Width += FormatPNG.Border;
            rcBounds.Height += FormatPNG.Border;

            Image image = new Bitmap(rcBounds.Width, rcBounds.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

            using (Graphics g = Graphics.FromImage(image))
            {
                g.FillRectangle(Brushes.White, new Rectangle(0, 0, image.Width, image.Height));

                layout.Clear();
                lanes = new List<int>(); // keep track of position offsets in each lane
                for (int i = 0; i < 16; i++)
                {
                    lanes.Add(0);
                }

                DrawEntity(g, 0, lanes, docEntity, docView, null, null, map, layout, docProject, docSchema, instance);

                g.DrawRectangle(Pens.Black, 0, 0, rcBounds.Width - 1, rcBounds.Height - 1);
            }

            return image;
        }
Example #15
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="docProject"></param>
        /// <param name="docModelView"></param>
        /// <param name="entity"></param>
        /// <param name="root"></param>
        /// <param name="usage">Optional usage or NULL to format table from concept root applicability</param>
        /// <param name="mapEntity"></param>
        /// <param name="mapSchema"></param>
        /// <returns></returns>
        private static string FormatConceptTable(
            DocProject docProject,
            DocModelView docModelView,
            DocEntity entity,
            DocConceptRoot root,
            DocTemplateUsage usage,
            Dictionary<string, DocObject> mapEntity,
            Dictionary<string, string> mapSchema)
        {
            StringBuilder sb = new StringBuilder();

            DocTemplateDefinition docTemplate = null;
            DocTemplateItem[] listItems = null;
            if (usage != null)
            {
                docTemplate = usage.Definition;
                listItems = FindTemplateItems(docProject, entity, usage.Definition, docModelView);

                if (usage.Override)
                {
                    listItems = usage.Items.ToArray();
                }

                if (listItems.Length == 0)
                {
                    // scenario for referenced inner templates
                    listItems = usage.Items.ToArray();
                }
            }
            else
            {
                docTemplate = root.ApplicableTemplate;
                listItems = root.ApplicableItems.ToArray();
            }

            // new way with table
            DocModelRule[] parameters = docTemplate.GetParameterRules();
            if (parameters != null && parameters.Length > 0 && listItems.Length > 0)
            {
                // check if descriptions are provided
                bool showdescriptions = false;
                foreach (DocTemplateItem item in listItems)
                {
                    if (item.Documentation != null)
                    {
                        showdescriptions = true;
                        break;
                    }
                }

                sb.AppendLine("<table class=\"gridtable\">");

                // header
                sb.Append("<tr>");
                foreach (DocModelRule parameter in parameters)
                {
                    sb.Append("<th><b>");

                    // hack until fixed in data
                    if (parameter.Identification.Equals("Name") && docTemplate.Name.Equals("External Data Constraints"))
                    {
                        sb.Append("Column");
                    }
                    else
                    {
                        sb.Append(parameter.Identification);
                    }
                    sb.Append("</b></th>");
                }
                if (showdescriptions)
                {
                    sb.Append("<th><b>Description</b></th>");
                }
                sb.AppendLine("</tr>");

                // items
                foreach (DocTemplateItem item in listItems)
                {
                    sb.Append("<tr>");
                    foreach (DocModelRule parameter in parameters)
                    {
                        string value = item.GetParameterValue(parameter.Identification);
                        string schema = null;

                        sb.Append("<td>");
                        //if (value != null)
                        {
                            DocDefinition docDef = docTemplate.GetParameterType(parameter.Identification, mapEntity);
                            if (docDef is DocEnumeration)
                            {
                                if(value != null)
                                {
                                    schema = mapSchema[docDef.Name];

                                    sb.Append("<a href=\"../../");
                                    sb.Append(schema.ToLower());
                                    sb.Append("/lexical/");
                                    sb.Append(docDef.Name.ToLower());
                                    sb.Append(".htm\">");
                                    sb.Append(value);
                                    sb.Append("</a>");
                                }
                            }
                            else if (docDef is DocEntity && docDef.Name.Equals("IfcReference"))
                            {
                                // ...hyperlinks
                                if (value != null)
                                {
                                    string reftext = FormatReference(docProject, value);
                                    sb.Append(reftext);
                                }
                                //sb.Append(value);
                            }
                            else if (docDef is DocEntity)
                            {
                                DocTemplateDefinition docTemplateInner = null;
                                if (parameter is DocModelRuleAttribute)
                                {
                                    List<string> cols = new List<string>();
                                    List<DocTemplateItem> rows = new List<DocTemplateItem>();
                                    List<DocTemplateUsage> usages = new List<DocTemplateUsage>();

                                    DocModelRuleAttribute dma = (DocModelRuleAttribute)parameter;
                                    foreach(DocModelRule docInnerRule in dma.Rules)
                                    {
                                        if (docInnerRule is DocModelRuleEntity)
                                        {
                                            DocModelRuleEntity dme = (DocModelRuleEntity)docInnerRule;
                                            if (dme.References.Count == 1)
                                            {
                                                docTemplateInner = dme.References[0];

                                                // new: combine nested tables -- properties are shown together

                                                DocTemplateUsage docConceptInner = item.GetParameterConcept(parameter.Identification, docTemplateInner);
                                                if (docConceptInner != null)
                                                {
                                                    DocModelRule[] innerparameters = docTemplateInner.GetParameterRules();
                                                    foreach (DocModelRule innerparam in innerparameters)
                                                    {
                                                        if (!cols.Contains(innerparam.Identification))
                                                        {
                                                            cols.Add(innerparam.Identification);
                                                        }
                                                    }

                                                    foreach(DocTemplateItem docItemInner in docConceptInner.Items)
                                                    {
                                                        string orderstr = docItemInner.GetParameterValue("Order");
                                                        int ordernum;
                                                        if(!String.IsNullOrEmpty(orderstr) && Int32.TryParse(orderstr, out ordernum))
                                                        {
                                                            while (rows.Count < ordernum)
                                                            {
                                                                rows.Add(null);
                                                                usages.Add(null);
                                                            }

                                                            rows[ordernum - 1] = docItemInner;
                                                            usages[ordernum - 1] = docConceptInner;
                                                        }
                                                    }
                                                }

                                                //break;

                                                /*
                                                DocTemplateUsage docConceptInner = item.GetParameterConcept(parameter.Identification, docTemplateInner);
                                                if (docConceptInner != null)
                                                {
                                                    string inner = FormatConceptTable(docProject, docModelView, (DocEntity)docDef, root, docConceptInner, mapEntity, mapSchema);
                                                    sb.Append("<a href=\"../../templates/" + MakeLinkName(docTemplateInner) + ".htm\">" + docTemplateInner.Name + "</a><br/>");
                                                    sb.Append(inner);
                                                }
                                                */
                                            }
                                        }
                                    }

                                    if(rows.Count > 0)
                                    {
                                        sb.Append("<table class=\"gridtable\"><tr>");
                                        sb.Append("<th>Template</th>");
                                        foreach(string colname in cols)
                                        {
                                            sb.Append("<th>");
                                            sb.Append(colname);
                                            sb.Append("</th>");
                                        }
                                        sb.AppendLine("</tr>");

                                        for (int iSubRow = 0; iSubRow < rows.Count; iSubRow++ )
                                        {
                                            DocTemplateItem docItem = rows[iSubRow];
                                            DocTemplateUsage docUsage = usages[iSubRow];

                                            //todo: show template with link... define icon at template...
                                            if (docItem != null)
                                            {
                                                sb.Append("<tr>");
                                                sb.Append("<td><a href=\"../../templates/");
                                                sb.Append(MakeLinkName(docUsage.Definition));
                                                sb.Append(".htm\">");
                                                sb.Append(docUsage.Definition.Name);
                                                sb.Append("</a></td>");
                                                foreach (string colname in cols)
                                                {
                                                    string pval = docItem.GetParameterValue(colname);
                                                    pval = FormatField(docProject, pval, pval, pval, pval);

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

                                        sb.Append("</table>");
                                    }
                                }

                                if (docTemplateInner == null && value != null && mapSchema.TryGetValue(value, out schema))
                                {
                                    sb.Append("<a href=\"../../");
                                    sb.Append(schema.ToLower());
                                    sb.Append("/lexical/");
                                    sb.Append(value.ToLower());
                                    sb.Append(".htm\">");
                                    sb.Append(value);
                                    sb.Append("</a>");
                                }
                                else if(value != null)
                                {
                                    sb.Append(value);
                                }
                            }
                            else if (docDef != null && value != null)
                            {
                                value = FormatField(docProject, value, value, docDef.Name, value);
                                sb.Append(value);
                            }
                            else if (value != null)
                            {
                                sb.Append(value);
                            }
                            else
                            {
                                sb.Append("&nbsp;");
                            }
                        }
                        sb.Append("</td>");
                    }

                    if (showdescriptions)
                    {
                        sb.Append("<td>");
                        if (item.Documentation != null)
                        {
                            sb.Append(item.Documentation);
                        }
                        else
                        {
                            sb.Append("&nbsp;");
                        }
                        sb.Append("</td>");
                    }

                    sb.AppendLine("</tr>");
                }

                sb.AppendLine("</table>");
            }
            return sb.ToString();
        }
Example #16
0
        internal static void ImportCnfAttribute(IfcDoc.Schema.CNF.exp_attribute exp_attribute, bool keep, Schema.CNF.boolean_or_unspecified tagless, DocEntity docEntity, DocAttribute docAttribute, DocModelView docView)
        {
            DocXsdFormatEnum xsdformat = DocXsdFormatEnum.Default;
            if (exp_attribute == Schema.CNF.exp_attribute.attribute_content)
            {
                xsdformat = DocXsdFormatEnum.Content;
            }
            else if (exp_attribute == Schema.CNF.exp_attribute.attribute_tag)
            {
                xsdformat = DocXsdFormatEnum.Attribute;
            }
            else if (exp_attribute == Schema.CNF.exp_attribute.double_tag)
            {
                xsdformat = DocXsdFormatEnum.Element;
            }
            else if (!keep)
            {
                xsdformat = DocXsdFormatEnum.Hidden;
            }
            else
            {
                xsdformat = DocXsdFormatEnum.Element;
            }

            bool? booltagless = null;
            switch (tagless)
            {
                case Schema.CNF.boolean_or_unspecified.boolean_true:
                    booltagless = true;
                    break;

                case Schema.CNF.boolean_or_unspecified.boolean_false:
                    booltagless = false;
                    break;
            }

            if (docView != null)
            {
                // configure specific model view
                DocXsdFormat docFormat = new DocXsdFormat();
                docFormat.Entity = docEntity.Name;
                docFormat.Attribute = docAttribute.Name;
                docFormat.XsdFormat = xsdformat;
                docFormat.XsdTagless = booltagless;
                docView.XsdFormats.Add(docFormat);
            }
            else
            {
                // configure default
                docAttribute.XsdFormat = xsdformat;
                docAttribute.XsdTagless = booltagless;
            }
        }
        private static string FormatRequirements(DocTemplateUsage eachusage, DocModelView docModel, bool showexchanges)
        {
            if (eachusage.Exchanges == null || eachusage.Exchanges.Count == 0 && (eachusage.Items.Count == 0 || eachusage.Definition.Type == ""))
                return null; // don't show if no rules or exchanges

            if (!Properties.Settings.Default.Requirement)
                return String.Empty;

            StringBuilder sb = new StringBuilder();

            if (showexchanges && docModel.Exchanges.Count > 0)
            {
                sb.AppendLine("<table class=\"exchange\">");

                sb.AppendLine("<tr>");
                sb.AppendLine("<th>Exchange</th>");
                foreach (DocExchangeDefinition docExchange in docModel.Exchanges)
                {
                    sb.Append("<th><a href=\"../../views/");
                    sb.Append(MakeLinkName(docModel));
                    sb.Append("/");
                    sb.Append(MakeLinkName(docExchange));
                    sb.Append(".htm\"><img width=\"16\" src=\"../../../img/mvd-");
                    sb.Append(MakeLinkName(docExchange));
                    sb.Append(".png\" title=\"");
                    sb.Append(docExchange.Name);
                    sb.Append("\"/></a></th>");
                    sb.AppendLine();
                }
                sb.AppendLine("</tr>");

                sb.AppendLine("<tr>");
                sb.AppendLine("<td>Import</td>");
                foreach (DocExchangeDefinition docExchange in docModel.Exchanges)
                {
                    sb.Append("<td>");
                    foreach (DocExchangeItem dti in eachusage.Exchanges)
                    {
                        if (dti.Exchange == docExchange && dti.Applicability == DocExchangeApplicabilityEnum.Import)
                        {
                            AppendRequirement(sb, dti.Requirement, 3);
                        }
                    }
                    sb.Append("</td>");
                    sb.AppendLine();
                }
                sb.AppendLine("</tr>");

                sb.AppendLine("<tr>");
                sb.AppendLine("<td>Export</td>");
                foreach (DocExchangeDefinition docExchange in docModel.Exchanges)
                {
                    sb.Append("<td>");
                    foreach (DocExchangeItem dti in eachusage.Exchanges)
                    {
                        if (dti.Exchange == docExchange && dti.Applicability == DocExchangeApplicabilityEnum.Export)
                        {
                            AppendRequirement(sb, dti.Requirement, 3);
                        }
                    }
                    sb.Append("</td>");
                    sb.AppendLine();
                }
                sb.AppendLine("</tr>");

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

            return sb.ToString();
        }
Example #18
0
        public CheckGridExchange(DocExchangeDefinition docExchange, DocModelView docView, DocProject docProject)
        {
            this.m_project = docProject;
            this.m_view = docView;
            this.m_exchange = docExchange;
            this.m_listTemplate = docProject.GetTemplateList();

            // filter out template list to only those that are currently used
            for (int i = this.m_listTemplate.Count - 1; i >= 0; i--)
            {
                bool used = false;
                foreach (DocConceptRoot docRoot in this.m_view.ConceptRoots)
                {
                    foreach (DocTemplateUsage docUsage in docRoot.Concepts)
                    {
                        if (docUsage.Definition == this.m_listTemplate[i])
                        {
                            used = true;
                            break;
                        }
                    }
                }

                if (!used)
                {
                    this.m_listTemplate.RemoveAt(i);
                }
            }
        }
Example #19
0
        internal static void ImportCnf(IfcDoc.Schema.CNF.configuration cnf, DocProject docProject, DocModelView docView)
        {
            Dictionary<string, DocEntity> mapEntity = new Dictionary<string, DocEntity>();
            foreach (DocSection docSection in docProject.Sections)
            {
                foreach (DocSchema docSchema in docSection.Schemas)
                {
                    foreach (DocEntity docEntity in docSchema.Entities)
                    {
                        mapEntity.Add(docEntity.Name, docEntity);
                    }
                }
            }

            foreach (IfcDoc.Schema.CNF.entity ent in cnf.entity)
            {
                DocEntity docEntity = null;
                if (mapEntity.TryGetValue(ent.select, out docEntity))
                {
                    if (ent.attribute != null)
                    {
                        foreach (IfcDoc.Schema.CNF.attribute atr in ent.attribute)
                        {
                            // find attribute on entity
                            foreach (DocAttribute docAttribute in docEntity.Attributes)
                            {
                                if (atr.select != null && atr.select.Equals(docAttribute.Name))
                                {
                                    ImportCnfAttribute(atr.exp_attribute, atr.keep, atr.tagless, docEntity, docAttribute, docView);
                                }
                            }
                        }
                    }

                    if (ent.inverse != null)
                    {
                        foreach (IfcDoc.Schema.CNF.inverse inv in ent.inverse)
                        {
                            // find attribute on entity
                            foreach (DocAttribute docAttribute in docEntity.Attributes)
                            {
                                if (inv.select != null && inv.select.Equals(docAttribute.Name))
                                {
                                    ImportCnfAttribute(inv.exp_attribute, true, Schema.CNF.boolean_or_unspecified.unspecified, docEntity, docAttribute, docView);
                                }
                            }
                        }
                    }

                }
            }
        }
Example #20
0
        /// <summary>
        /// Exports file according to format.
        /// </summary>
        /// <param name="filepath">File path to export.</param>
        /// <param name="templates">Optional filter of templates to export.</param>
        /// <param name="views">Optional filter of views to export.</param>
        /// <param name="schemas">Optional filter of schemas to export.</param>
        /// <param name="locales">Optional filter of locales to export.</param>
        public static void DoExport(DocProject docProject, string filepath, DocModelView[] views, string[] locales, Dictionary<long, SEntity> instances)
        {
            string ext = System.IO.Path.GetExtension(filepath).ToLower();

            Dictionary<DocObject, bool> included = null;
            if (views != null)
            {
                included = new Dictionary<DocObject, bool>();
                foreach (DocModelView docView in views)
                {
                    docProject.RegisterObjectsInScope(docView, included);
                }
            }

            // special case for zip files -- determine based on special naming; make configurable in future
            Type typeExport = null;
            if (filepath.EndsWith("-psd.zip"))
            {
                typeExport = typeof(DocPropertySet);
            }
            else if(filepath.EndsWith("-qto.zip"))
            {
                typeExport = typeof(DocQuantitySet);
            }

            switch (ext)
            {
                case ".ifc":
                    using (FormatSPF format = new FormatSPF(filepath, Schema.IFC.SchemaIfc.Types, instances))
                    {
                        string filename = System.IO.Path.GetFileName(filepath);
                        format.InitHeaders(filename, "IFC4"); // we always use IFC4 (not later schema) for exporting templates, as that is the earliest version required.
                        Schema.IFC.IfcProject ifcProject = new IfcDoc.Schema.IFC.IfcProject();
                        Program.ExportIfc(ifcProject, docProject, included);
                        format.Save();
                    }
                    break;

                case ".ifcxml":
                    using (FormatXML format = new FormatXML(filepath, typeof(Schema.IFC.IfcProject), "http://www.buildingsmart-tech.org/ifcXML/IFC4"))
                    {
                        Schema.IFC.IfcProject ifcProject = new IfcDoc.Schema.IFC.IfcProject();
                        Program.ExportIfc(ifcProject, docProject, included);
                        format.Instance = ifcProject;
                        format.Save();
                    }
                    break;

                case ".mvdxml":
                    using (FormatXML format = new FormatXML(filepath, typeof(mvdXML), mvdXML.DefaultNamespace))
                    {
                        mvdXML mvd = new mvdXML();
                        Program.ExportMvd(mvd, docProject, included);
                        format.Instance = mvd;
                        format.Save();
                    }
                    break;

                case ".cs":
                    using (FormatCSC format = new FormatCSC(filepath))
                    {
                        format.Instance = docProject;
                        format.Save();
                    }
                    break;

                case ".exp":
                    // use currently visible model view(s)
                    using (FormatEXP format = new FormatEXP(filepath))
                    {
                        format.Instance = docProject;
                        format.ModelViews = views;
                        format.Save();
                    }
                    break;

                case ".xsd":
                    // use currently visible model view(s)
                    using (FormatXSD format = new FormatXSD(filepath))
                    {
                        format.Instance = docProject;
                        format.ModelViews = views;
                        format.Save();
                    }
                    break;

                case ".xml": // Express XSD Configuration
                    using (FormatXML format = new FormatXML(filepath, typeof(Schema.CNF.configuration), null, Schema.CNF.SchemaCNF.Prefixes))
                    {
                        Schema.CNF.configuration config = new Schema.CNF.configuration();
                        Program.ExportCnf(config, docProject, views, included);
                        format.Instance = config;
                        format.Save();
                    }
                    break;

                case ".txt":
                    // pick locale
                    using (FormatCSV format = new FormatCSV(filepath))
                    {
                        format.Instance = docProject;
                        format.Locales = locales;
                        format.Save();
                    }
                    break;

                case ".sch":
                    using (FormatXML format = new FormatXML(filepath, typeof(Schema.SCH.schema), "http://purl.oclc.org/dsdl/schematron"))
                    {
                        Schema.SCH.schema sch = new Schema.SCH.schema();
                        Program.ExportSch(sch, docProject, included);
                        format.Instance = sch;
                        format.Save();
                    }
                    break;

                case ".zip":
                    using (FormatZIP format = new FormatZIP(new System.IO.FileStream(filepath, System.IO.FileMode.Create), docProject, included, typeExport))
                    {
                        format.Save();
                    }
                    break;

            }
        }
Example #21
0
        /// <summary>
        /// Formats table for single exchange
        /// </summary>
        /// <param name="def"></param>
        /// <returns></returns>
        private static string FormatExchange(DocProject docProject, DocModelView docView, DocExchangeDefinition def, Dictionary<string, DocObject> mapEntity, Dictionary<string, string> mapSchema, DocPublication docPublication)
        {
            // format content
            StringBuilder sbMain = new StringBuilder();

            if(!String.IsNullOrEmpty(def.ExchangeClass))
            {
                sbMain.AppendLine("<table class=\"gridtable\">");
                sbMain.AppendLine("<tr><th>Process</th><th>Sender</th><th>Receiver</th></tr>");
                sbMain.AppendLine("<tr><td>" + def.ExchangeClass + "</td><td>" + def.SenderClass + "</td><td>" + def.ReceiverClass + "</td></tr>");
                sbMain.AppendLine("</table>");
            }

            // 1. manual content
            sbMain.Append(def.Documentation);

            // 2. map of entities and templates -- Identity | Template | Import | Export
            sbMain.AppendLine("<p></p>");//This exchange involves the following entities:</p>");

            SortedList<string, DocConceptRoot> sortlist = new SortedList<string, DocConceptRoot>();

            foreach (DocConceptRoot docRoot in docView.ConceptRoots)
            {
                foreach (DocTemplateUsage docUsage in docRoot.Concepts)
                {
                    foreach (DocExchangeItem docReq in docUsage.Exchanges)
                    {
                        //if (docReq.Exchange == def && docReq.Requirement != DocExchangeRequirementEnum.NotRelevant && docReq.Requirement != DocExchangeRequirementEnum.Excluded && !sortlist.ContainsKey(docRoot.ApplicableEntity.Name))
                        if (docReq.Exchange == def && docReq.Requirement != DocExchangeRequirementEnum.NotRelevant && !sortlist.ContainsKey(docRoot.ApplicableEntity.Name))
                        {
                            sortlist.Add(docRoot.ApplicableEntity.Name, docRoot);
                        }
                    }
                }
            }

            bool externaldataconstraints = false;

            // new style - table
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("<table class=\"exchange\">");
            sb.AppendLine("<tr><th colspan=\"5\"><img src=\"../../../img/mvd-" + MakeLinkName(def) + ".png\" />&nbsp; " + def.Name + "</th></tr>");
            sb.AppendLine("<tr><th>Entity/Concept</th><th>Attributes</th><th>Constraints</th><th>I</th><th>E</th></tr>");
            foreach (string ent in sortlist.Keys)
            {
                DocConceptRoot docRoot = sortlist[ent];

                sb.Append("<tr><td colspan=\"5\"><b><i>");
                sb.Append(docRoot.ApplicableEntity.Name);
                sb.AppendLine("</i></b></td></tr>");

                // determine schema
                string schema = mapSchema[ent];

                foreach (DocTemplateUsage docConcept in docRoot.Concepts)
                {
                    if (docConcept.Definition != null)
                    {
                        DocExchangeRequirementEnum reqImport = DocExchangeRequirementEnum.NotRelevant;
                        DocExchangeRequirementEnum reqExport = DocExchangeRequirementEnum.NotRelevant;
                        foreach (DocExchangeItem docReq in docConcept.Exchanges)
                        {
                            if (docReq.Exchange == def)
                            {
                                if (docReq.Applicability == DocExchangeApplicabilityEnum.Export)
                                {
                                    reqExport = docReq.Requirement;
                                }
                                else if (docReq.Applicability == DocExchangeApplicabilityEnum.Import)
                                {
                                    reqImport = docReq.Requirement;
                                }
                            }
                        }

                        if (reqImport != DocExchangeRequirementEnum.NotRelevant || reqExport != DocExchangeRequirementEnum.NotRelevant)
                        {
                            if (docConcept.Definition.Name.Equals("External Data Constraints"))
                            {
                                if(!externaldataconstraints)
                                {
                                    // show heading for first time
                                    sbMain.Append("<h4>Data Requirements for tabular formats</h4>");
                                    externaldataconstraints = true;
                                }

                                // new for GSA: cross-tab report to show mappings between exchanges and applications and vice-versa
                                List<DocModelView> listViewCross = new List<DocModelView>();
                                if (true)//docPublication.Comparison)
                                {
                                    foreach (DocModelView docEachView in docPublication.Views)
                                    {
                                        if (docEachView != docView )
                                        {
                                            listViewCross.Add(docEachView);
                                        }
                                    }
                                }

                                // table and description
                                sbMain.Append("<h5>" + docConcept.Name + "</h5>");
                                sbMain.Append(docConcept.Documentation);

                                sbMain.AppendLine("<table class=\"gridtable\">");
                                sbMain.Append("<tr><th>Column</th><th>Mapping</th><th>Definition</th><th>Notes</th>");
                                foreach(DocModelView docViewCross in listViewCross)
                                {
                                    foreach (DocExchangeDefinition docExchangeCross in docViewCross.Exchanges)
                                    {
                                        sbMain.Append("<th><a href=\"../../views/");
                                        sbMain.Append(MakeLinkName(docViewCross));
                                        sbMain.Append("/");
                                        sbMain.Append(MakeLinkName(docExchangeCross));
                                        sbMain.Append(".htm\"><img width=\"16\" src=\"../../../img/mvd-");
                                        sbMain.Append(MakeLinkName(docExchangeCross));
                                        sbMain.Append(".png\" title=\"");
                                        sbMain.Append(docExchangeCross.Name);
                                        sbMain.Append("\"/></a></th>");
                                    }
                                }
                                sbMain.AppendLine("</tr>");
                                foreach(DocTemplateItem docItem in docConcept.Items)
                                {
                                    string name = docItem.GetParameterValue("Name");
                                    string refv = docItem.GetParameterValue("Reference");
                                    string mapp = FormatReference(docProject, refv);

                                    string desc = null;
                                    CvtValuePath valpath = CvtValuePath.Parse(refv, mapEntity);

                                    if (valpath != null &&
                                        valpath.Property != null &&
                                        valpath.Property.Name.Equals("IsDefinedBy") &&
                                        valpath.InnerPath != null && valpath.InnerPath.Type.Name.Equals("IfcRelDefinesByProperties"))
                                    {
                                        DocObject docPset = null;
                                        mapEntity.TryGetValue(valpath.Identifier, out docPset);

                                        if (docPset is DocPropertySet)
                                        {
                                            DocProperty docProp = ((DocPropertySet)docPset).GetProperty(valpath.InnerPath.InnerPath.Identifier);
                                            if (docProp != null)
                                            {
                                                desc = docProp.Documentation;// localize??
                                            }
                                        }
                                        else if (docPset is DocQuantitySet)
                                        {
                                            DocQuantity docProp = ((DocQuantitySet)docPset).GetQuantity(valpath.InnerPath.InnerPath.Identifier);
                                            if (docProp != null)
                                            {
                                                desc = docProp.Documentation;// localize??
                                            }
                                        }
                                    }
                                    else if (valpath != null &&
                                        valpath.Property != null &&
                                        valpath.Property.Name.Equals("HasPropertySets") &&
                                        valpath.InnerPath != null && valpath.InnerPath.Type.Name.Equals("IfcPropertySet"))
                                    {
                                        DocObject docPset = null;
                                        mapEntity.TryGetValue(valpath.Identifier, out docPset);

                                        if (docPset is DocPropertySet)
                                        {
                                            DocProperty docProp = ((DocPropertySet)docPset).GetProperty(valpath.InnerPath.Identifier);
                                            if (docProp != null)
                                            {
                                                desc = docProp.Documentation;// localize??
                                            }
                                        }
                                    }

                                    if (desc == null)
                                    {
                                        while (valpath != null && valpath.InnerPath != null && valpath.InnerPath.Property != null)
                                        {
                                            valpath = valpath.InnerPath;
                                        }
                                        if (valpath != null && valpath.Property != null)
                                        {
                                            desc = valpath.Property.Documentation;
                                        }
                                        else if(valpath != null)
                                        {
                                            desc = "The IFC class identifier indicating the subtype of object.";
                                        }
                                    }

                                    sbMain.Append("<tr><td>" + name + "</td><td>" + mapp + "</td><td>" + desc + "</td><td>" + docItem.Documentation + "</td>");
                                    foreach (DocModelView docViewCross in listViewCross)
                                    {
                                        foreach (DocExchangeDefinition docExchangeCross in docViewCross.Exchanges)
                                        {
                                            // find any table in that exchange containing a matching mapping
                                            sbMain.Append("<td>");

                                            foreach (DocConceptRoot docRootCross in docViewCross.ConceptRoots)
                                            {
                                                foreach (DocTemplateUsage docConceptCross in docRootCross.Concepts)
                                                {
                                                    if (docConceptCross.Definition != null && docConceptCross.Definition.Name.Equals("External Data Constraints"))
                                                    {
                                                        DocExchangeRequirementEnum reqImportCross = DocExchangeRequirementEnum.NotRelevant;
                                                        DocExchangeRequirementEnum reqExportCross = DocExchangeRequirementEnum.NotRelevant;
                                                        foreach (DocExchangeItem docReq in docConceptCross.Exchanges)
                                                        {
                                                            if (docReq.Exchange == docExchangeCross)
                                                            {
                                                                if (docReq.Applicability == DocExchangeApplicabilityEnum.Export)
                                                                {
                                                                    reqExportCross = docReq.Requirement;
                                                                }
                                                                else if (docReq.Applicability == DocExchangeApplicabilityEnum.Import)
                                                                {
                                                                    reqImportCross = docReq.Requirement;
                                                                }

                                                            }
                                                        }

                                                        // found it, now look for any matching data mappings
                                                        if (reqImportCross != DocExchangeRequirementEnum.NotRelevant || reqExportCross != DocExchangeRequirementEnum.NotRelevant)
                                                        {
                                                            foreach (DocTemplateItem docItemCross in docConceptCross.Items)
                                                            {
                                                                string crossrefv = docItemCross.GetParameterValue("Reference");
                                                                if (crossrefv != null && crossrefv.Equals(refv))
                                                                {
                                                                    string crosstabl = docItemCross.GetParameterValue("Table");
                                                                    string crossname = docItemCross.GetParameterValue("Name");

                                                                    sbMain.Append("<a href=\"../../views/");
                                                                    sbMain.Append(MakeLinkName(docViewCross));
                                                                    sbMain.Append("/");
                                                                    sbMain.Append(MakeLinkName(docExchangeCross));
                                                                    sbMain.Append(".htm\"><img width=\"16\" src=\"../../../img/attr-mandatory");
                                                                    sbMain.Append(".png\" title=\"");
                                                                    sbMain.Append(docExchangeCross.Name + ": " + crosstabl + "." + crossname);
                                                                    sbMain.Append("\"/></a>");

                                                                    //sbMain.Append(crosstabl + "." + crossname); //... use icon to show import or export, with tooltip showing name...
                                                                    break;
                                                                }
                                                            }
                                                        }

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

                                // bring out separately
                                //string table = FormatConceptTable(docProject, docView, docRoot.ApplicableEntity, docRoot, docConcept, mapEntity, mapSchema);
                                //sbMain.Append(table);
                            }
                            else
                            {
                                sb.Append("<tr><td>&nbsp;&nbsp;<a href=\"../../templates/");
                                sb.Append(MakeLinkName(docConcept.Definition));
                                sb.Append(".htm\">");
                                sb.Append(docConcept.Definition.Name);
                                sb.Append("</a></td><td>");

                                bool first = true;
                                if (docConcept.Definition.Rules != null)
                                {
                                    foreach (DocModelRule docRule in docConcept.Definition.Rules)
                                    {
                                        if (!first)
                                        {
                                            sb.Append("<br/>");
                                        }
                                        sb.Append(docRule.Name);
                                        first = false;
                                    }
                                }
                                sb.Append("</td><td>");

                                string table = FormatConceptTable(docProject, docView, docRoot.ApplicableEntity, docRoot, docConcept, mapEntity, mapSchema);
                                sb.Append(table);

                                sb.Append("</td><td>");
                                AppendRequirement(sb, reqImport, 3);
                                sb.Append("</td><td>");
                                AppendRequirement(sb, reqExport, 3);
                                sb.AppendLine("</td></tr>");
                            }
                        }
                    }
                }

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

            // then general table for IFC
            sbMain.AppendLine("<h4>Data Requirements for IFC formats</h4>");
            sbMain.Append(sb.ToString());

            return sbMain.ToString();
        }
Example #22
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="docProject"></param>
        /// <param name="docModelView"></param>
        /// <param name="entity"></param>
        /// <param name="root"></param>
        /// <param name="usage">Optional usage or NULL to format table from concept root applicability</param>
        /// <param name="mapEntity"></param>
        /// <param name="mapSchema"></param>
        /// <returns></returns>
        private static string FormatConceptTable(
            DocProject docProject,
            DocModelView docModelView,
            DocEntity entity,
            DocConceptRoot root,
            DocTemplateUsage usage,
            Dictionary<string, DocObject> mapEntity,
            Dictionary<string, string> mapSchema)
        {
            StringBuilder sb = new StringBuilder();

            DocTemplateDefinition docTemplate = null;
            DocTemplateItem[] listItems = null;
            if (usage != null)
            {
                docTemplate = usage.Definition;
                listItems = FindTemplateItems(docProject, entity, usage.Definition, docModelView);

                if (usage.Override)
                {
                    listItems = usage.Items.ToArray();
                }

                if (listItems.Length == 0)
                {
                    // scenario for referenced inner templates
                    listItems = usage.Items.ToArray();
                }
            }
            else
            {
                docTemplate = root.ApplicableTemplate;
                listItems = root.ApplicableItems.ToArray();
            }

            // new way with table
            DocModelRule[] parameters = docTemplate.GetParameterRules();
            if (parameters != null && parameters.Length > 0 && listItems.Length > 0)
            {
                // check if descriptions are provided
                bool showdescriptions = false;
                foreach (DocTemplateItem item in listItems)
                {
                    if (item.Documentation != null)
                    {
                        showdescriptions = true;
                        break;
                    }
                }

                sb.AppendLine("<table class=\"gridtable\">");

                // header
                sb.Append("<tr>");
                foreach (DocModelRule parameter in parameters)
                {
                    sb.Append("<th><b>");

                    // hack until fixed in data
                    if (parameter.Identification.Equals("Name") && docTemplate.Name.Equals("External Data Constraints"))
                    {
                        sb.Append("Column");
                    }
                    else
                    {
                        sb.Append(parameter.Identification);
                    }
                    sb.Append("</b></th>");
                }
                if (showdescriptions)
                {
                    sb.Append("<th><b>Description</b></th>");
                }
                sb.AppendLine("</tr>");

                // items
                foreach (DocTemplateItem item in listItems)
                {
                    sb.Append("<tr>");
                    foreach (DocModelRule parameter in parameters)
                    {
                        string value = item.GetParameterValue(parameter.Identification);
                        string schema = null;

                        if(parameter.Name.Equals("Columns"))
                        {
                            parameter.ToString();
                        }

                        sb.Append("<td>");
                        //if (value != null)
                        {
                            DocDefinition docDef = docTemplate.GetParameterType(parameter.Identification, mapEntity);
                            if (docDef is DocEnumeration)
                            {
                                if(value != null)
                                {
                                    schema = mapSchema[docDef.Name];

                                    sb.Append("<a href=\"../../");
                                    sb.Append(schema.ToLower());
                                    sb.Append("/lexical/");
                                    sb.Append(docDef.Name.ToLower());
                                    sb.Append(".htm\">");
                                    sb.Append(value);
                                    sb.Append("</a>");
                                }
                            }
                            else if (docDef is DocEntity)
                            {
                                DocTemplateDefinition docTemplateInner = null;
                                if (parameter is DocModelRuleAttribute)
                                {
                                    DocModelRuleAttribute dma = (DocModelRuleAttribute)parameter;
                                    foreach(DocModelRule docInnerRule in dma.Rules)
                                    {
                                        if (docInnerRule is DocModelRuleEntity)
                                        {
                                            DocModelRuleEntity dme = (DocModelRuleEntity)docInnerRule;
                                            if (dme.References.Count == 1)
                                            {
                                                docTemplateInner = dme.References[0];

                                                DocTemplateUsage docConceptInner = item.GetParameterConcept(parameter.Identification, docTemplateInner);
                                                if (docConceptInner != null)
                                                {
                                                    string inner = FormatConceptTable(docProject, docModelView, (DocEntity)docDef, root, docConceptInner, mapEntity, mapSchema);
                                                    sb.Append("<a href=\"../../templates/" + MakeLinkName(docTemplateInner) + ".htm\">" + docTemplateInner.Name + "</a><br/>");
                                                    sb.Append(inner);
                                                }

                                            }
                                        }
                                    }
                                }

                                if (docTemplateInner == null && value != null && mapSchema.TryGetValue(value, out schema))
                                {
                                    if(value.StartsWith("Pset_"))
                                    {
                                        value.ToString();
                                    }

                                    sb.Append("<a href=\"../../");
                                    sb.Append(schema.ToLower());
                                    sb.Append("/lexical/");
                                    sb.Append(value.ToLower());
                                    sb.Append(".htm\">");
                                    sb.Append(value);
                                    sb.Append("</a>");
                                }
                                else if(docDef.Name.Equals("IfcReference"))
                                {
                                    // ...hyperlinks
                                    if(value != null)
                                    {
                                        string reftext = FormatReference(docProject, value);
                                        sb.Append(reftext);
                                    }
                                    //sb.Append(value);
                                }
                                else if(value != null)
                                {
                                    sb.Append(value);
                                }
                            }
                            else if (docDef != null && value != null)
                            {
                                value = FormatField(docProject, value, value, docDef.Name, value);
                                sb.Append(value);
                            }
                            else if (value != null)
                            {
                                sb.Append(value);
                            }
                            else
                            {
                                sb.Append("&nbsp;");
                            }
                        }
                        sb.Append("</td>");
                    }

                    if (showdescriptions)
                    {
                        sb.Append("<td>");
                        if (item.Documentation != null)
                        {
                            sb.Append(item.Documentation);
                        }
                        else
                        {
                            sb.Append("&nbsp;");
                        }
                        sb.Append("</td>");
                    }

                    sb.AppendLine("</tr>");
                }

                sb.AppendLine("</table>");
            }
            return sb.ToString();
        }
        /// <summary>
        /// Exports file according to format.
        /// </summary>
        /// <param name="filepath">File path to export.</param>
        /// <param name="templates">Optional filter of templates to export.</param>
        /// <param name="views">Optional filter of views to export.</param>
        /// <param name="schemas">Optional filter of schemas to export.</param>
        /// <param name="locales">Optional filter of locales to export.</param>
        public static void DoExport(DocProject docProject, string filepath, DocModelView[] views, string[] locales, Dictionary<long, SEntity> instances)
        {
            string ext = System.IO.Path.GetExtension(filepath).ToLower();

            Dictionary<DocObject, bool> included = null;
            if (views != null)
            {
                included = new Dictionary<DocObject, bool>();
                foreach (DocModelView docView in views)
                {
                    docProject.RegisterObjectsInScope(docView, included);
                }
            }

            switch (ext)
            {
                case ".ifc":
                    using (FormatSPF format = new FormatSPF(filepath, Schema.IFC.SchemaIfc.Types, instances))
                    {
                        format.InitHeaders(docProject.Annotations[0].Code, "IFC4");
                        Schema.IFC.IfcProject ifcProject = new IfcDoc.Schema.IFC.IfcProject();
                        Program.ExportIfc(ifcProject, docProject, included);
                        format.Save();
                    }
                    break;

                case ".ifcxml":
                    using (FormatXML format = new FormatXML(filepath, typeof(Schema.IFC.IfcProject), "http://www.buildingsmart-tech.org/ifcXML/IFC4"))
                    {
                        Schema.IFC.IfcProject ifcProject = new IfcDoc.Schema.IFC.IfcProject();
                        Program.ExportIfc(ifcProject, docProject, included);
                        format.Instance = ifcProject;
                        format.Save();
                    }
                    break;

                case ".mvdxml":
                    using (FormatXML format = new FormatXML(filepath, typeof(mvdXML), mvdXML.DefaultNamespace))
                    {
                        mvdXML mvd = new mvdXML();
                        Program.ExportMvd(mvd, docProject, included);
                        format.Instance = mvd;
                        format.Save();
                    }
                    break;

                case ".cs":
                    using (FormatCSC format = new FormatCSC(filepath))
                    {
                        format.Instance = docProject;
                        format.Save();
                    }
                    break;

                case ".exp":
                    // use currently visible model view(s)
                    using (FormatEXP format = new FormatEXP(filepath))
                    {
                        format.Instance = docProject;
                        format.ModelViews = views;
                        format.Save();
                    }
                    break;

                case ".xsd":
                    // use currently visible model view(s)
                    using (FormatXSD format = new FormatXSD(filepath))
                    {
                        format.Instance = docProject;
                        format.ModelViews = views;
                        format.Save();
                    }
                    break;

                case ".xml": // Express XSD Configuration
                    using (FormatXML format = new FormatXML(filepath, typeof(Schema.CNF.configuration), null, Schema.CNF.SchemaCNF.Prefixes))
                    {
                        Schema.CNF.configuration config = new Schema.CNF.configuration();
                        Program.ExportCnf(config, docProject, views, included);
                        format.Instance = config;
                        format.Save();
                    }
                    break;

                case ".txt":
                    // pick locale
                    using (FormatCSV format = new FormatCSV(filepath))
                    {
                        format.Instance = docProject;
                        format.Locales = locales;
                        format.Save();
                    }
                    break;

                case ".sch":
                    using (FormatXML format = new FormatXML(filepath, typeof(Schema.SCH.schema), "http://purl.oclc.org/dsdl/schematron"))
                    {
                        Schema.SCH.schema sch = new Schema.SCH.schema();
                        Program.ExportSch(sch, docProject, included);
                        format.Instance = sch;
                        format.Save();
                    }
                    break;
            }

        }
Example #24
0
        internal static void ImportMvd(mvdXML mvd, DocProject docProject, string filepath)
        {
            if (mvd.Templates != null)
            {
                Dictionary<EntityRule, DocModelRuleEntity> fixups = new Dictionary<EntityRule, DocModelRuleEntity>();
                foreach (ConceptTemplate mvdTemplate in mvd.Templates)
                {
                    DocTemplateDefinition docDef = docProject.GetTemplate(mvdTemplate.Uuid);
                    if (docDef == null)
                    {
                        docDef = new DocTemplateDefinition();
                        docProject.Templates.Add(docDef);
                    }

                    ImportMvdTemplate(mvdTemplate, docDef, fixups);
                }

                foreach(EntityRule er in fixups.Keys)
                {
                    DocModelRuleEntity docEntityRule = fixups[er];
                    if(er.References != null)
                    {
                        foreach(TemplateRef tr in er.References)
                        {
                            DocTemplateDefinition dtd = docProject.GetTemplate(tr.Ref);
                            if(dtd != null)
                            {
                                docEntityRule.References.Add(dtd);
                            }
                        }
                    }
                }
            }

            if (mvd.Views != null)
            {
                foreach (ModelView mvdView in mvd.Views)
                {
                    DocModelView docView = docProject.GetView(mvdView.Uuid);
                    if (docView == null)
                    {
                        docView = new DocModelView();
                        docProject.ModelViews.Add(docView);
                    }

                    ImportMvdObject(mvdView, docView);

                    docView.BaseView = mvdView.BaseView;
                    docView.Exchanges.Clear();
                    Dictionary<Guid, ExchangeRequirement> mapExchange = new Dictionary<Guid, ExchangeRequirement>();
                    foreach (ExchangeRequirement mvdExchange in mvdView.ExchangeRequirements)
                    {
                        mapExchange.Add(mvdExchange.Uuid, mvdExchange);

                        DocExchangeDefinition docExchange = new DocExchangeDefinition();
                        ImportMvdObject(mvdExchange, docExchange);
                        docView.Exchanges.Add(docExchange);

                        docExchange.Applicability = (DocExchangeApplicabilityEnum)mvdExchange.Applicability;

                        // attempt to find icons if exists -- remove extention
                        try
                        {
                            string iconpath = filepath.Substring(0, filepath.Length - 7) + @"\mvd-" + docExchange.Name.ToLower().Replace(' ', '-') + ".png";
                            if (System.IO.File.Exists(iconpath))
                            {
                                docExchange.Icon = System.IO.File.ReadAllBytes(iconpath);
                            }
                        }
                        catch
                        {

                        }
                    }

                    foreach (ConceptRoot mvdRoot in mvdView.Roots)
                    {
                        // find the entity
                        DocEntity docEntity = LookupEntity(docProject, mvdRoot.ApplicableRootEntity);
                        if (docEntity != null)
                        {
                            DocConceptRoot docConceptRoot = docView.GetConceptRoot(mvdRoot.Uuid);
                            if (docConceptRoot == null)
                            {
                                docConceptRoot = new DocConceptRoot();
                                if (docView.ConceptRoots == null)
                                {
                                    docView.ConceptRoots = new List<DocConceptRoot>();
                                }
                                docView.ConceptRoots.Add(docConceptRoot);
                            }

                            ImportMvdObject(mvdRoot, docConceptRoot);
                            docConceptRoot.ApplicableEntity = docEntity;

                            if (mvdRoot.Applicability != null)
                            {
                                docConceptRoot.ApplicableTemplate = docProject.GetTemplate(mvdRoot.Applicability.Template.Ref);
                                if(mvdRoot.Applicability.TemplateRules != null)
                                {
                                    docConceptRoot.ApplicableOperator = (DocTemplateOperator)Enum.Parse(typeof(TemplateOperator), mvdRoot.Applicability.TemplateRules.Operator.ToString());
                                    foreach (TemplateRule r in mvdRoot.Applicability.TemplateRules.TemplateRule)
                                    {
                                        DocTemplateItem docItem = ImportMvdItem(r, docProject, mapExchange);
                                        docConceptRoot.ApplicableItems.Add(docItem);
                                    }
                                }
                            }

                            docConceptRoot.Concepts.Clear();
                            foreach (Concept mvdNode in mvdRoot.Concepts)
                            {
                                DocTemplateUsage docUse = new DocTemplateUsage();
                                docConceptRoot.Concepts.Add(docUse);
                                ImportMvdConcept(mvdNode, docUse, docProject, mapExchange);
                            }
                        }
                        else
                        {
                            //TODO: log error
                        }
                    }
                }
            }
        }
        private static string FormatDiagram(DocProject docProject, DocObject def, DocModelView docView, List<ContentRef> listFigures, Dictionary<string, DocObject> mapEntity, Dictionary<string, string> mapSchema)
        {
            // return if nothing to generate
            if (def is DocTemplateDefinition)
            {
                DocTemplateDefinition dtd = (DocTemplateDefinition)def;
                if (dtd.Rules == null || dtd.Rules.Count == 0)
                    return null;
            }
            else if (def is DocEntity)
            {
            }
            else
            {
                return null;
            }

            // create the figure file
            string filename = MakeLinkName(def) + ".png";
            Dictionary<Rectangle, DocModelRule> layout = new Dictionary<Rectangle, DocModelRule>();
            if (!Properties.Settings.Default.SkipDiagrams)
            {
                try
                {
                    if (def is DocTemplateDefinition)
                    {
                        System.IO.Directory.CreateDirectory(Properties.Settings.Default.OutputPath + "\\schema\\templates\\diagrams");
                        using (Image image = IfcDoc.Format.PNG.FormatPNG.CreateTemplateDiagram((DocTemplateDefinition)def, mapEntity, layout, docProject, null))
                        {
                            if (image != null)
                            {
                                string filepath = Properties.Settings.Default.OutputPath + "\\schema\\templates\\diagrams\\" + filename;
                                image.Save(filepath, System.Drawing.Imaging.ImageFormat.Png);
                            }
                        }
                    }
                    else if (def is DocEntity) // no longer used directly; now for each model view in annex D
                    {
                        System.IO.Directory.CreateDirectory(Properties.Settings.Default.OutputPath + "\\diagrams\\" + MakeLinkName(docView));
                        using (Image image = IfcDoc.Format.PNG.FormatPNG.CreateConceptDiagram((DocEntity)def, docView, mapEntity, layout, docProject, null))
                        {
                            string filepath = Properties.Settings.Default.OutputPath + "\\diagrams\\" + MakeLinkName(docView) + "\\" + filename;
                            image.Save(filepath, System.Drawing.Imaging.ImageFormat.Png);
                        }
                    }
                }
                catch
                {
                }
            }

            // 2. figure
            StringBuilder sb = new StringBuilder();
            if (def is DocTemplateDefinition)
            {
                listFigures.Add(new ContentRef(def.Name + " instance diagram", def));

                // Per ISO guidelines, all figures must be referenced from text.
                sb.Append("<p class=\"fig-ref\">Figure ");
                sb.Append(listFigures.Count);
                sb.Append(" illustrates an instance diagram.</p>\r\n");
            }

            // include the figure with formatting below per ISO
            sb.Append("<table><tr><td><img alt=\"");
            sb.Append(def.Name);

            if (def is DocTemplateDefinition)
            {
                sb.Append("\" src=\"./diagrams/");
            }
            else
            {
                sb.Append("\" src=\"../../../diagrams/");
                sb.Append(MakeLinkName(docView));
                sb.Append("/");
            }
            sb.Append(filename);
            sb.Append("\" usemap=\"#f");
            sb.Append(listFigures.Count.ToString());
            sb.Append("\">");
            sb.Append("<map name=\"f");
            sb.Append(listFigures.Count.ToString());
            sb.Append("\">");
            foreach (Rectangle rc in layout.Keys)
            {
                DocModelRule rule = layout[rc];
                DocObject ruleObject = null;
                string strschema = null;

                string typename = null;
                if (rule != null)
                {
                    typename = rule.Name;
                }
                else if (def is DocTemplateDefinition)
                {
                    DocTemplateDefinition dtd = (DocTemplateDefinition)def;
                    typename = dtd.Type;
                }
                else if (def is DocObject)
                {
                    typename = def.Name;
                }

                if (mapEntity.TryGetValue(typename, out ruleObject) && mapSchema.TryGetValue(typename, out strschema))
                {
                    // hyperlink to IFC entity                       
                    // replace it with hyperlink                        
                    string relative = @"../";
                    if (def is DocEntity)
                    {
                        relative = "../../../schema/";
                    }
                    string hyperlink = relative + strschema.ToLower() + @"/lexical/" + ruleObject.Name.ToLower() + ".htm";

                    int indent = 0;
                    sb.Append("<area shape=\"rect\" coords=\"");
                    sb.Append(rc.Left + indent);
                    sb.Append(",");
                    sb.Append(rc.Top + indent);
                    sb.Append(",");
                    sb.Append(rc.Right + indent);
                    sb.Append(",");
                    sb.Append(rc.Bottom + indent);
                    sb.Append("\" href=\"");
                    sb.Append(hyperlink);
                    sb.Append("\" alt=\"");
                    sb.Append(ruleObject.Name);
                    sb.Append("\" />");
                }
            }
            sb.Append("</map>");

            // number figures in templates, but not annex
            if (def is DocTemplateDefinition)
            {
                sb.Append("</td></tr>");
                sb.Append("<tr><td><p class=\"figure\">Figure ");
                sb.Append(listFigures.Count);
                sb.Append(" &mdash; ");
                sb.Append(def.Name);
                sb.Append("</p></td></tr>");
            }

            sb.Append("</table>\r\n");
            sb.AppendLine();

            return sb.ToString();
        }
Example #26
0
        /// <summary>
        /// Extracts description of referenced data, using properties, quantities, and attributes.
        /// </summary>
        /// <param name="mapEntity"></param>
        /// <param name="docView">Optional model view, for retrieving more specific descriptions such as for ports</param>
        /// <returns></returns>
        public string GetDescription(Dictionary<string, DocObject> mapEntity, DocModelView docView)
        {
            string desc = null;
            CvtValuePath valpath = this;

            if (valpath != null &&
                valpath.Property != null &&
                valpath.Property.Name.Equals("IsDefinedBy") &&
                valpath.InnerPath != null && valpath.InnerPath.Type.Name.Equals("IfcRelDefinesByProperties"))
            {
                DocObject docPset = null;
                mapEntity.TryGetValue(valpath.Identifier, out docPset);

                if (docPset is DocPropertySet)
                {
                    DocProperty docProp = ((DocPropertySet)docPset).GetProperty(valpath.InnerPath.InnerPath.Identifier);
                    if (docProp != null)
                    {
                        desc = docProp.Documentation;// localize??
                    }
                }
                else if (docPset is DocQuantitySet)
                {
                    DocQuantity docProp = ((DocQuantitySet)docPset).GetQuantity(valpath.InnerPath.InnerPath.Identifier);
                    if (docProp != null)
                    {
                        desc = docProp.Documentation;// localize??
                    }
                }
            }
            else if (valpath != null &&
                valpath.Property != null &&
                valpath.Property.Name.Equals("HasPropertySets") &&
                valpath.InnerPath != null && valpath.InnerPath.Type.Name.Equals("IfcPropertySet"))
            {
                DocObject docPset = null;
                mapEntity.TryGetValue(valpath.Identifier, out docPset);

                if (docPset is DocPropertySet)
                {
                    DocProperty docProp = ((DocPropertySet)docPset).GetProperty(valpath.InnerPath.Identifier);
                    if (docProp != null)
                    {
                        desc = docProp.Documentation;// localize??
                    }
                }
            }
            else if(valpath != null &&
                valpath.Property != null &&
                valpath.Property.Name.Equals("Material") &&
                valpath.InnerPath != null && valpath.InnerPath.Type.Name.Equals("IfcMaterial") &&
                valpath.InnerPath.InnerPath != null && valpath.InnerPath.InnerPath.Type.Name.Equals("IfcMaterialProperties"))
            {
                DocObject docPset = null;
                mapEntity.TryGetValue(valpath.InnerPath.Identifier, out docPset);

                if(docPset is DocPropertySet)
                {
                    DocProperty docProp = ((DocPropertySet)docPset).GetProperty(valpath.InnerPath.InnerPath.Identifier);
                    if(docProp != null)
                    {
                        desc = docProp.Documentation;
                    }
                }
            }
            else if (valpath != null && 
                valpath.Property != null &&
                valpath.Property.Name.Equals("IsNestedBy") &&
                valpath.InnerPath != null && valpath.InnerPath.InnerPath != null && valpath.InnerPath.InnerPath != null)
            {
                CvtValuePath pathInner = valpath.InnerPath.InnerPath;
                if (pathInner.Type != null && pathInner.Type.Name.Equals("IfcDistributionPort"))
                {
                    string portname = valpath.InnerPath.Identifier;
                    if (pathInner.Property != null && pathInner.Property.Name.Equals("IsDefinedBy"))
                    {
                        // lookup description of property at port
                        DocObject docPset = null;
                        mapEntity.TryGetValue(pathInner.Identifier, out docPset);

                        if (docPset is DocPropertySet)
                        {
                            DocProperty docProp = ((DocPropertySet)docPset).GetProperty(pathInner.InnerPath.InnerPath.Identifier);
                            if (docProp != null)
                            {
                                desc = portname + ": " + docProp.Documentation;
                            }
                        }

                    }
                    else
                    {
                        desc = portname;

                        // lookup description of port
                        Guid guidPortNesting = new Guid("bafc93b7-d0e2-42d8-84cf-5da20ee1480a");
                        foreach (DocConceptRoot docRoot in docView.ConceptRoots)
                        {
                            if (docRoot.ApplicableEntity == valpath.Type)
                            {
                                foreach(DocTemplateUsage docConcept in docRoot.Concepts)
                                {
                                    if(docConcept.Definition != null && docConcept.Definition.Uuid == guidPortNesting)
                                    {
                                        foreach (DocTemplateItem docItem in docConcept.Items)
                                        {
                                            if(docItem.Name.Equals(portname))
                                            {
                                                desc = docItem.Documentation;
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            if (desc == null)
            {
                while (valpath != null && valpath.InnerPath != null && valpath.InnerPath.Property != null)
                {
                    valpath = valpath.InnerPath;
                }
                if (valpath != null && valpath.Property != null)
                {
                    desc = valpath.Property.Documentation;
                }
                else if (valpath != null)
                {
                    desc = "The IFC class identifier indicating the subtype of object.";
                }
            }

            return desc;
        }
        /// <summary>
        /// Formats table for all exchanges within a view
        /// </summary>
        /// <param name="mvd"></param>
        /// <returns></returns>
        private static string FormatView(DocProject docProject, DocModelView docView, Dictionary<string, DocObject> mapEntity, Dictionary<string, string> mapSchema)
        {
            // format content
            StringBuilder sb = new StringBuilder();

            // 1. manual content
            sb.Append(docView.Documentation);

#if false // don't show anymore
            // 2. map of entities and templates -- Identity | Template | Import | Export
            sb.AppendLine("<p></p>");

            SortedList<string, DocConceptRoot> sortlist = new SortedList<string, DocConceptRoot>();

            // base view
            DocModelView docBase = docView;
            while (docBase != null)
            {
                foreach (DocConceptRoot docRoot in docBase.ConceptRoots)
                {
                    if (!sortlist.ContainsKey(docRoot.ApplicableEntity.Name))
                    {
                        sortlist.Add(docRoot.ApplicableEntity.Name, docRoot);
                    }
                }

                if (!String.IsNullOrEmpty(docBase.BaseView))
                {
                    docBase = docProject.GetView(Guid.Parse(docBase.BaseView));
                }
                else
                {
                    docBase = null;
                }
            }

            int cols = 3 + docView.Exchanges.Count;

            // new style - table
            sb.AppendLine("<table class=\"exchange\">");
            sb.AppendLine("<tr><th colspan=\"" + cols.ToString() + "\">" + docView.Name + "</th></tr>");
            sb.Append("<tr><th>Entity/Concept</th><th>Attributes</th><th>Constraints</th>");
            //<th>I</th><th>E</th></tr>");
            foreach (DocExchangeDefinition docExchange in docView.Exchanges)
            {
                sb.Append("<th>");
                sb.Append("<img src=\"../../../img/mvd-");
                sb.Append(docExchange.Name.ToLower().Replace(' ', '-'));
                sb.Append(".png\" title=\"");
                sb.Append(docExchange.Name);
                sb.Append("\" />");
                sb.Append("</th>");
            }
            sb.AppendLine("</tr>");

            foreach (string ent in sortlist.Keys)
            {
                DocConceptRoot docRoot = sortlist[ent];

                sb.Append("<tr><td colspan=\"" + cols.ToString() + "\"><b><i>");
                sb.Append(docRoot.ApplicableEntity.Name);
                sb.AppendLine("</i></b></td></tr>");

                // determine schema
                string schema = mapSchema[ent];

                foreach (DocTemplateUsage docConcept in docRoot.Concepts)
                {
                    if (docConcept.Definition != null)
                    {

                        sb.Append("<tr><td>&nbsp;&nbsp;<a href=\"../../");
                        sb.Append(schema.ToLower());
                        sb.Append("/lexical/");
                        sb.Append(ent.ToLower());
                        sb.Append(".htm#");
                        sb.Append(docConcept.Definition.Name.ToLower().Replace(' ', '-'));
                        sb.Append("\">");
                        sb.Append(docConcept.Definition.Name);
                        sb.Append("</a></td><td>");

                        bool first = true;
                        if (docConcept.Definition.Rules != null)
                        {
                            foreach (DocModelRule docRule in docConcept.Definition.Rules)
                            {
                                if (!first)
                                {
                                    sb.Append("<br/>");
                                }
                                sb.Append(docRule.Name);
                                first = false;
                            }
                        }

                        sb.Append("</td><td>");

                        // IfcDoc 6.4: use tables
                        string table = FormatConceptTable(docProject, docView, docRoot.ApplicableEntity, docRoot, docConcept, mapEntity, mapSchema);
                        sb.Append(table);
#if false
                    // build list of inherited items
                    first = true;
                    DocTemplateItem[] items = FindTemplateItems(docProject, docRoot.ApplicableEntity, docConcept.Definition, docView);
                    foreach (DocTemplateItem docItem in items)
                    {
                        if (!first)
                        {
                            sb.Append("<br/>");
                        }
                        sb.Append(docItem.RuleParameters);
                        first = false;
                    }
#endif

                        sb.Append("</td>");

                        foreach (DocExchangeDefinition docExchange in docView.Exchanges)
                        {
                            DocExchangeRequirementEnum reqExport = DocExchangeRequirementEnum.NotRelevant;
                            foreach (DocExchangeItem docItem in docConcept.Exchanges)
                            {
                                if (docItem.Exchange == docExchange && docItem.Applicability == DocExchangeApplicabilityEnum.Export)
                                {
                                    reqExport = docItem.Requirement;
                                }
                            }

                            sb.Append("<td>");
                            AppendRequirement(sb, reqExport, 3);
                            sb.Append("</td>");
                        }

                        sb.AppendLine("</tr>");
                    }

                }
            }
            sb.AppendLine("</table>");
#endif
            return sb.ToString();
        }
Example #28
0
        public static void Export(DocProject project, DocModelView docView, string path, Dictionary<string, DocObject> mapEntity, Dictionary<string, string> mapSchema)
        {
            Dictionary<DocObject, bool> included = docView.Filter(project);

            const string HEADERCELL = "<th style=\"-webkit-transform:rotate(90deg); writing-mode:tb-rl; -moz-transform:rotate(90deg); -o-transform: rotate(90deg); white-space:nowrap; display:blocking; ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=0.083)\"; >";

            // get list of entities in order
            List<DocEntity> sortEntity = project.GetEntityList();

            // build list of templates in use (to preserve sort order)
            Dictionary<DocTemplateDefinition, List<DocConceptRoot>> mapTemplates = new Dictionary<DocTemplateDefinition, List<DocConceptRoot>>();

            // double-loop not optimal, but lists aren't that large
            foreach (DocEntity docSortEnt in sortEntity)
            {
                foreach (DocConceptRoot docRoot in docView.ConceptRoots)
                {
                    if (docRoot.ApplicableEntity == docSortEnt)
                    {
                        foreach (DocTemplateUsage docConcept in docRoot.Concepts)
                        {
                            if (!mapTemplates.ContainsKey(docConcept.Definition))
                            {
                                mapTemplates.Add(docConcept.Definition, new List<DocConceptRoot>());
                            }
                            mapTemplates[docConcept.Definition].Add(docRoot);
                        }
                    }
                }
            }

            // build list of concept roots sorted by entity order
            List<DocConceptRoot> sortConceptRoot = new List<DocConceptRoot>();
            foreach (DocEntity docSortEntity in sortEntity)
            {
                foreach (DocConceptRoot docRoot in docView.ConceptRoots)
                {
                    if (docRoot.ApplicableEntity == docSortEntity)
                    {
                        sortConceptRoot.Add(docRoot);
                        break;
                    }
                }
            }

            using (FormatEXP formatEXP = new FormatEXP(path + @"\" + docView.Code + ".exp"))
            {
                formatEXP.Instance = project;
                formatEXP.ModelViews = new DocModelView[] { docView };
                formatEXP.Save();
            }

            using (FormatXSD formatXSD = new FormatXSD(path + @"\" + docView.Code + ".xsd"))
            {
                formatXSD.Instance = project;
                formatXSD.ModelViews = new DocModelView[] { docView };
                formatXSD.Save();
            }

            using (FormatSPF format = new FormatSPF(path + @"\" + docView.Code + ".ifc", Schema.IFC.SchemaIfc.Types, new Dictionary<long, SEntity>()))
            {
                format.InitHeaders(docView.Code, "IFC4");
                Schema.IFC.IfcProject ifcProject = new IfcDoc.Schema.IFC.IfcProject();
                Program.ExportIfc(ifcProject, project, included);
                format.Save();
            }

            using (FormatXML format = new FormatXML(path + @"\" + docView.Code + ".mvdxml", typeof(mvdXML), mvdXML.DefaultNamespace))
            {
                mvdXML mvd = new mvdXML();
                Program.ExportMvd(mvd, project, included);
                format.Instance = mvd;
                format.Save();
            }

            using (FormatHTM format = new FormatHTM(path + @"\" + docView.Code + ".htm", mapEntity, new Dictionary<string, string>(), included))
            {
                format.WriteHeader(docView.Name, 0, null);

                // 1 Scope
                // 1.1 Business Case Description
                // 1.2 Participants and Stakeholders

                // 2 Normative References

                // 3 Terms and definitions

                // 4 Symbols and abbreviated terms

                // 5 Business processes
                // 5.1 Process models provided
                // 5.2 Representative process models
                // 5.3 Process models formatting

                format.WriteLine("<h1>6 Exchange requirements</h1>");
                format.WriteLine("<h2>6.1 Exchange requirements legibility</h2>");
                format.WriteLine("<h3>6.1.1 Exchange requirements list</h3>");
                format.WriteLine("<p>Each exchange is listed by name as follows.</p>");
                Dictionary<string, string> mapExchangeClass = new Dictionary<string, string>();
                format.WriteLine("<ul>");
                foreach (DocExchangeDefinition docExchange in docView.Exchanges)
                {
                    if (docExchange.ExchangeClass != null && !mapExchangeClass.ContainsKey(docExchange.ExchangeClass) && !String.IsNullOrEmpty(docExchange.ExchangeClass))
                    {
                        mapExchangeClass.Add(docExchange.ExchangeClass, docExchange.ExchangeClass);
                    }

                    format.WriteLine("<li>" + docExchange.Name + "</li>");
                }
                format.WriteLine("</ul>");

                format.WriteLine("<h3>6.1.2 Exchange requirement classification list</h3>");
                format.WriteLine("<p>Each phase classification used by this model view is listed by Omniclass notation and title as follows.</p>");
                format.WriteLine("<ul>");
                foreach (string key in mapExchangeClass.Keys)
                {
                    format.WriteLine("<li>" + key + "</li>");
                }
                format.WriteLine("</ul>");

                format.WriteLine("<h3>6.1.3 Exchange requirement coverage analysis</h3>");
                format.WriteLine("<p>Each exchange is listed by name and corresponding classifications for the process undertaken, the sender of the information, and the receiver of the information.</p>");
                format.WriteLine("<table class=\"gridtable\">");
                format.WriteLine("<tr><th>Exchange</th><th>Process</th><th>Sender</th><th>Receiver</th></tr>");
                foreach (DocExchangeDefinition docExchange in docView.Exchanges)
                {
                    format.WriteLine("<tr><td>" + docExchange.Name + "</td><td>" + docExchange.ExchangeClass + "</td><td>" + docExchange.SenderClass + "</td><td>" + docExchange.ReceiverClass);
                }
                format.WriteLine("</table>");

                format.WriteLine("<h2>6.2 Exchange requirements detail</h2>");
                format.WriteLine("<h3>6.2.1 Exchange requirements definition</h3>");
                format.WriteLine("<p>Each exchange is listed by name and a description of the information contained.</p>");
                foreach (DocExchangeDefinition docExchange in docView.Exchanges)
                {
                    format.WriteLine("<h4>" + docExchange.Name + "</h4>");
                    format.WriteLine(docExchange.Documentation);
                }

                format.WriteLine("<h3>6.2.2 Business rule list</h3>");
                format.WriteLine("<p>Each exchange consists of a set of entity data definitions with usage defined according to business rule concepts. " +
                    "An entity describes an object class having one or more attributes, where each attribute may refer to values, collections, or references to other objects. "+
                    "A concept describes usage of object classes, where allowable values and object types are indicated for specific attributes." +
                    "Each heading that follows refers to an exchange, where each table row corresponds to an entity, each table column corresponds to an exchange, and each cell indicates whether the concept is used for the entity within the exchange.</p>");
                foreach (DocExchangeDefinition docExchange in docView.Exchanges)
                {
                    format.WriteLine("<h4>" + docExchange.Name + "</h4>");

                    List<DocTemplateDefinition> listTemplate = project.GetTemplateList();
                    List<DocTemplateDefinition> usedTemplate = new List<DocTemplateDefinition>();

                    foreach (DocConceptRoot docRoot in docView.ConceptRoots)
                    {
                        foreach (DocTemplateUsage docConcept in docRoot.Concepts)
                        {
                            if (!usedTemplate.Contains(docConcept.Definition))
                            {
                                foreach (DocExchangeItem docExchangeItem in docConcept.Exchanges)
                                {
                                    if (docExchangeItem.Exchange == docExchange &&
                                        (docExchangeItem.Requirement == DocExchangeRequirementEnum.Mandatory || docExchangeItem.Requirement == DocExchangeRequirementEnum.Optional))
                                    {
                                        usedTemplate.Add(docConcept.Definition);
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    for(int i = listTemplate.Count - 1; i >= 0; i--)
                    {
                        if (!usedTemplate.Contains(listTemplate[i]))
                        {
                            listTemplate.RemoveAt(i);
                        }
                    }

                    format.WriteLine("<table class=\"gridtable\">");
                    format.Write("<tr>");
                    format.Write("<th>Entity</th>");
                    for (int i = 0; i < listTemplate.Count; i++)
                    {
                        format.Write(HEADERCELL);
                        format.Write(listTemplate[i].Name);
                        format.Write("</th>");
                    }
                    format.WriteLine("</tr>");

                    foreach (DocConceptRoot docRoot in sortConceptRoot)
                    {
                        DocExchangeRequirementEnum[] reqs = new DocExchangeRequirementEnum[listTemplate.Count];
                        bool include = false;
                        foreach (DocTemplateUsage docConcept in docRoot.Concepts)
                        {
                            foreach (DocExchangeItem docExchangeItem in docConcept.Exchanges)
                            {
                                if (docExchangeItem.Exchange == docExchange &&
                                    (docExchangeItem.Requirement == DocExchangeRequirementEnum.Mandatory || docExchangeItem.Requirement == DocExchangeRequirementEnum.Optional))
                                {
                                    int index = listTemplate.IndexOf(docConcept.Definition);
                                    reqs[index] = docExchangeItem.Requirement;
                                    include = true;
                                    break;
                                }
                            }
                        }

                        if (include)
                        {
                            format.Write("<tr>");
                            format.Write("<td>" + docRoot.ApplicableEntity.Name + "</td>");
                            for (int i = 0; i < reqs.Length; i++)
                            {
                                format.Write("<td>");
                                switch (reqs[i])
                                {
                                    case DocExchangeRequirementEnum.Mandatory:
                                        format.Write("R");
                                        break;

                                    case DocExchangeRequirementEnum.Optional:
                                        format.Write("O");
                                        break;
                                }
                                format.Write("</td>");
                            }
                            format.WriteLine("</tr>");
                        }
                    }

                    format.WriteLine("</table>");
                }

                format.WriteLine("<h3>6.2.3 Business rule definition</h3>");
                format.WriteLine("<p>Business rule definitions are all defined as re-usable templates as indicated in Clause 7.3.5.</p>");

                format.WriteLine("<h2>6.3 Exchange requirements reusability</h2>");
                format.WriteLine("<p>Names and classifications of exchanges are intended to be consistent across other model views where applicable, "+
                    "while the content of a particular exchange is intended to be unique.</p>");

                format.WriteLine("<h3>6.3.1 Related business process list</h3>");
                format.WriteLine("<p>Business processes within this model view are correlated with those used in other model views as follows.</p>");

                // Rows: Business processes; Columns: Views; Cells: mark if applicable
                format.WriteLine("<table class=\"gridtable\">");
                format.Write("<tr><th>Process</th>");
                foreach (DocModelView docEachView in project.ModelViews)
                {
                    format.Write(HEADERCELL + docEachView.Name + "</th>");
                }
                format.WriteLine("</tr>");
                foreach (string proc in mapExchangeClass.Keys)
                {
                    format.Write("<tr><td>" + proc + "</td>");
                    foreach (DocModelView docEachView in project.ModelViews)
                    {
                        bool yes = false;
                        foreach (DocExchangeDefinition docEachExchange in docEachView.Exchanges)
                        {
                            if (!String.IsNullOrEmpty(docEachExchange.ExchangeClass) && docEachExchange.ExchangeClass.Equals(proc))
                            {
                                yes = true;
                                break;
                            }
                        }

                        format.Write("<td>");
                        if (yes)
                        {
                            format.Write("X");
                        }
                        format.Write("</td>");
                    }
                    format.WriteLine("</tr>");
                }
                format.WriteLine("</table>");

                format.WriteLine("<h3>6.3.2 Related exchange requirement list</h3>");
                format.WriteLine("<p>Exchange requirements within this model view are correlated with those used in other model views as follows.</p>");
                // Rows: Exchanges; Columns: Views; Cells: Mark if applicable
                format.WriteLine("<table class=\"gridtable\">");
                format.Write("<tr><th>Exchange</th>");
                foreach (DocModelView docEachView in project.ModelViews)
                {
                    format.Write(HEADERCELL + docEachView.Name + "</th>");
                }
                format.WriteLine("</tr>");
                foreach (DocExchangeDefinition docExchange in docView.Exchanges)
                {
                    format.Write("<tr><td>" + docExchange.Name + "</td>");
                    foreach (DocModelView docEachView in project.ModelViews)
                    {
                        bool yes = false;
                        foreach (DocExchangeDefinition docEachExchange in docEachView.Exchanges)
                        {
                            if (!String.IsNullOrEmpty(docEachExchange.Name) && docEachExchange.Name.Equals(docExchange.Name))
                            {
                                yes = true;
                                break;
                            }
                        }

                        format.Write("<td>");
                        if (yes)
                        {
                            format.Write("X");
                        }
                        format.Write("</td>");
                    }
                    format.WriteLine("</tr>");
                }
                format.WriteLine("</table>");

                format.WriteLine("<h3>6.3.3 Related exchange requirement reuse analysis</h3>");
                format.WriteLine("<p>Exchange requirements across other model views are correlated as follows.</p>");

                // Rows: Exchange names; Columns: Views; Cells: Mark if applicable
                List<string> listExchangeNames = new List<string>();
                foreach (DocModelView docEachView in project.ModelViews)
                {
                    foreach (DocExchangeDefinition docEachExchange in docEachView.Exchanges)
                    {
                        if (!listExchangeNames.Contains(docEachExchange.Name))
                        {
                            listExchangeNames.Add(docEachExchange.Name);
                        }
                    }
                }
                format.WriteLine("<table class=\"gridtable\">");
                format.Write("<tr><th>Exchange</th>");
                foreach (DocModelView docEachView in project.ModelViews)
                {
                    format.Write(HEADERCELL + docEachView.Name + "</th>");
                }
                format.WriteLine("</tr>");
                foreach (string exchangename in listExchangeNames)
                {
                    format.Write("<tr><td>" + exchangename + "</td>");
                    foreach (DocModelView docEachView in project.ModelViews)
                    {
                        bool yes = false;
                        foreach (DocExchangeDefinition docEachExchange in docEachView.Exchanges)
                        {
                            if (!String.IsNullOrEmpty(docEachExchange.Name) && docEachExchange.Name.Equals(exchangename))
                            {
                                yes = true;
                                break;
                            }
                        }

                        format.Write("<td>");
                        if (yes)
                        {
                            format.Write("X");
                        }
                        format.Write("</td>");
                    }
                    format.WriteLine("</tr>");
                }
                format.WriteLine("</table>");

                format.WriteLine("<h1>7 Model view definition</h1>");
                format.WriteLine("<h2>7.1 Data Definition</h2>");
                format.WriteLine("<h3>7.1.1 Data definitions list</h3>");
                format.WriteLine("<p>Each entity data definition is listed by schema and entity name as follows.</p>");
                format.WriteLine("<ul>");
                string lastschema = null;
                foreach (DocConceptRoot docRoot in sortConceptRoot)
                {
                    string schema = mapSchema[docRoot.ApplicableEntity.Name];
                    if (schema != lastschema)
                    {
                        // close out last
                        if (docRoot != sortConceptRoot[0])
                        {
                            format.WriteLine("</ul></li>");
                        }

                        // open next
                        format.WriteLine("<li>" + schema + "<ul>");

                        lastschema = schema;
                    }

                    format.WriteLine("<li>" + docRoot.ApplicableEntity.Name + "</li>");
                }
                format.WriteLine("</ul></ul>");

                format.WriteLine("<h3>7.1.2 Data definitions</h3>");
                format.WriteLine("<p>Each entity data definition is described within subsections as follows, with electronic representations provided in EXPRESS and XSD formats.</p>");
                FormatXSD formatXSD = new FormatXSD(null);
                foreach (DocConceptRoot docRoot in sortConceptRoot)
                {
                    string xsd = formatXSD.FormatEntity(docRoot.ApplicableEntity, mapEntity, included);

                    format.WriteLine("<h4>" + docRoot.ApplicableEntity.Name + "</h4>");
                    format.WriteLine(docRoot.ApplicableEntity.Documentation);
                    format.WriteLine("<br/>");

                    format.WriteExpressEntitySpecification(docRoot.ApplicableEntity, true, false);
                    format.WriteLine("<br/>");
                    format.WriteFormatted(xsd);
                }

                format.WriteLine("<h3>7.1.3 Data definition reference schema list</h3>");
                format.WriteLine("<p>Each referenced schema is listed by standards body notation and official title.</p>");
                format.WriteLine("<table class=\"gridtable\">");
                format.WriteLine("<tr><th>Reference</th><th>Description</th></tr>");
                format.WriteLine("<tr><td>ISO 16739:2013</td><td>Industry Foundation Classes (IFC) for data sharing in the construction and facilities management industries</td></tr>");
                format.WriteLine("</table>");

                // 7.2 Concept definitions
                format.WriteLine("<h2>7.2 Concept definitions</h2>");
                format.WriteLine("<h3>7.2.1 Concept list</h3>");
                format.WriteLine("<p>Each concept is listed by entity name and concept template within the following table. "+
                    "Each row corresponds to an entity, each column corresponds to a concept template, and each cell indicates usage of a concept template for an entity.</p>");
                format.WriteLine("<table class=\"gridtable\">");
                format.Write("<tr><th>Entity</th>");
                foreach (DocTemplateDefinition docTemplate in mapTemplates.Keys)
                {
                    format.Write(HEADERCELL + docTemplate.Name + "</th>");
                }
                format.WriteLine("</tr>");

                foreach (DocConceptRoot docRoot in sortConceptRoot)
                {
                    if (docRoot.Concepts.Count > 0)
                    {
                        format.Write("<tr><td>" + docRoot.ApplicableEntity.Name + "</td>");

                        foreach (DocTemplateDefinition docTemplate in mapTemplates.Keys)
                        {
                            format.Write("<td>");
                            foreach (DocTemplateUsage docConcept in docRoot.Concepts)
                            {
                                if (docConcept.Definition == docTemplate)
                                {
                                    format.Write("X");
                                }
                            }
                            format.Write("</td>");
                        }

                        format.WriteLine("</tr>");
                    }
                }
                format.WriteLine("</table>");

                string pathImages = path + "\\" + docView.Code;
                System.IO.Directory.CreateDirectory(pathImages);

                format.WriteLine("<h3>7.2.2 Concept definitions</h3>");
                format.WriteLine("<p>Each entity is described within subsections, with diagrams indicating the graph of attributes and objects representing the combination of all concepts applied to instances of the entity. "+
                    "Each block in the diagram represents an entity, where the entity name is shown at the top of the block with background in black.  "+
                    "Each attribute within the entity is shown in order, where black is used to indicate a direct attribute and grey is used to indicate an inverse attribute. "+
                    "Notation to the right of each attribute indicates aggregation, where S indicates a SET (unordered unique objects) and L indicates a LIST (ordered objects), "+
                    "the first number in brackets indicates the minimum count, and the second number in brackets indicates the maximum count or “?” for unlimited. "+
                    "Lines connecting blocks indicates attributes that point to objects of other data definitions.</p>");
                foreach (DocConceptRoot docRoot in sortConceptRoot)
                {
                    format.WriteLine("<h4>" + docRoot.ApplicableEntity.Name + "</h4>");

                    string img = "";
                    if (docView.Code != null)
                    {
                        int cx = 0;
                        int cy = 0;
                        try
                        {
                            using (System.Drawing.Image image = IfcDoc.Format.PNG.FormatPNG.CreateConceptDiagram(docRoot.ApplicableEntity, docView, mapEntity, new Dictionary<System.Drawing.Rectangle,DocModelRule>(), project, null))
                            {
                                cx = image.Width;
                                cy = image.Height;
                                string filepath = path + "\\" + docView.Code.ToLower() + "\\" + docRoot.ApplicableEntity.Name.ToLower() + ".png";
                                image.Save(filepath, System.Drawing.Imaging.ImageFormat.Png);
                            }
                        }
                        catch
                        {
                        }

                        // shrink for access from MS Word
                        cx = cx / 2;
                        cy = cy / 2;

                        img = "<br/><img src=\"" + docView.Code.ToLower() + "/" + docRoot.ApplicableEntity.Name.ToLower() + ".png\" width=\"" + cx + "\" height=\"" + cy + "\"/>";
                    }

                    format.WriteLine(docRoot.Documentation);
                    format.WriteLine(img);
                    foreach (DocTemplateUsage docConcept in docRoot.Concepts)
                    {
                        if (!String.IsNullOrEmpty(docConcept.Documentation))
                        {
                            format.WriteLine("<h5>" + docConcept.Definition.Name + "</h5>");
                            format.WriteLine(docConcept.Documentation);
                        }
                    }
                }
                format.WriteLine("</table>");

                format.WriteLine("<h3>7.2.3 Concept attributes list</h3>");
                format.WriteLine("<p>Concepts may be defined that use parameters to indicate applicable values. "+
                    "For example, plumbing objects may make use of ports to enable connectivity to other objects for distribution of water, "+
                    "and a specific entity such as a hot water heater may have specific ports such as “ColdWaterIn” and “HotWaterOut”. "+
                    "Defining attributes at concepts enables re-use of concepts where the data structures are the same, but applicable values may differ."+
                    "Each concept is shown in a subsection as follows, with rows correspoding to entities and rule instances, columns corresponding to template parameters, and cells corresponding to values applied to rules.</p>");

                // then format each template
                foreach (DocTemplateDefinition docTemplate in mapTemplates.Keys)
                {
                    string[] parameters = docTemplate.GetParameterNames();

                    if (parameters.Length > 0)
                    {
                        format.WriteLine("<h4>" + docTemplate.Name + "</h4>");
                        format.WriteLine("<table class=\"gridtable\">");
                        format.Write("<tr><th>Entity</th>");

                        foreach (string parm in parameters)
                        {
                            format.Write("<th>" + parm + "</th>");
                        }

                        format.WriteLine("</tr>");

                        List<DocConceptRoot> listRoots = mapTemplates[docTemplate];
                        foreach (DocConceptRoot docRoot in listRoots)
                        {
                            foreach (DocTemplateUsage docConcept in docRoot.Concepts)
                            {
                                if (docConcept.Definition == docTemplate)
                                {
                                    if (docConcept.Items.Count == 0)
                                    {
                                        format.WriteLine("<tr><td>" + docRoot.ApplicableEntity.Name + "</td></tr>");
                                    }
                                    else
                                    {
                                        foreach (DocTemplateItem docItem in docConcept.Items)
                                        {
                                            if (docItem == docConcept.Items[0])
                                            {
                                                format.Write("<tr><td rowspan=\"" + docConcept.Items.Count + "\">" + docRoot.ApplicableEntity.Name + "</td>");
                                            }
                                            else
                                            {
                                                format.Write("<tr>");
                                            }

                                            foreach (string parm in parameters)
                                            {
                                                string val = docItem.GetParameterValue(parm);
                                                format.Write("<td>" + val + "</td>");
                                            }

                                            format.WriteLine("</tr>");
                                        }
                                    }
                                }
                            }
                        }

                        format.WriteLine("</table>");
                    }
                }

                format.WriteLine("<h3>7.2.4 Concept relationship description</h3>");
                format.WriteLine("<p>Concepts may inherit from other concepts such that more generic rules may be defined at a higher level and more specific rules at a lower level.  "+
                    "For example, geometry may be defined for a distribution segment (e.g. ducts, pipes, cables) that indicate permitted use of an extruded area solid (IfcExtrudedAreaSolid) "+
                    "which defines a 2D cross section extruded along a 3D linear segment. "+
                    "Such rule may be further refined for ducts to indicate that the cross-sections are further restricted to shapes such as hollow rectangles (IfcRectangleHollowProfileDef) "+
                    "or hollow circles (IfcCircleHollowProfileDef)."+
                    "Concepts are shown in a hierarchy as follows where inner concepts inherit from outer concepts.</p>");
                WriteTemplateList(format, project.Templates, included);

                format.WriteLine("<h3>7.2.5 Concept requirements applicability</h3>");
                format.WriteLine("<p>Each entity is shown in subsections as follows, with rows corresponding to concepts, columns corresponding to exchanges, "+
                    "and cells indicating requirements where 'R' indicates required and 'O' indicates optional.</p>");
                foreach (DocConceptRoot docRoot in sortConceptRoot)
                {
                    if (docRoot.Concepts.Count > 0)
                    {
                        format.WriteLine("<h4>" + docRoot.ApplicableEntity.Name + "</h4>");

                        format.WriteLine("<table class=\"gridtable\">");
                        format.Write("<tr><th>Concept</th>");
                        for (int i = 0; i < docView.Exchanges.Count; i++)
                        {
                            format.Write(HEADERCELL);
                            format.Write(docView.Exchanges[i].Name);
                            format.Write("</th>");
                        }
                        format.WriteLine("</tr>");

                        DocExchangeRequirementEnum[] reqs = new DocExchangeRequirementEnum[docView.Exchanges.Count];

                        foreach (DocTemplateUsage docConcept in docRoot.Concepts)
                        {
                            StringBuilder sbRequired = new StringBuilder();
                            StringBuilder sbOptional = new StringBuilder();
                            foreach (DocExchangeItem docExchangeItem in docConcept.Exchanges)
                            {
                                int index = docView.Exchanges.IndexOf(docExchangeItem.Exchange);
                                reqs[index] = docExchangeItem.Requirement;
                            }

                            format.Write("<tr><td>" + docConcept.Definition.Name + "</td>");
                            for (int i = 0; i < docView.Exchanges.Count; i++)
                            {
                                format.Write("<td>");
                                switch (reqs[i])
                                {
                                    case DocExchangeRequirementEnum.Mandatory:
                                        format.Write("R");
                                        break;

                                    case DocExchangeRequirementEnum.Optional:
                                        format.Write("O");
                                        break;
                                }
                                format.Write("</td>");
                            }
                            format.WriteLine("</tr>");
                        }

                        format.WriteLine("</table>");
                    }
                }

                format.WriteLine("<h2>7.3 Concept reusability</h2>");
                format.WriteLine("<h3>7.3.1 Concept list</h3>");
                format.WriteLine("<p>Each concept used within this model view is listed as follows.</p>");

                format.WriteLine("<ul>");
                foreach (DocTemplateDefinition docTemplate in mapTemplates.Keys)
                {
                    format.WriteLine("<li>" + docTemplate.Name + "</li>");
                }

                format.WriteLine("</ul>");

                format.WriteLine("<h3>7.3.2 Related existing concept list</h3>");
                format.WriteLine("<p>In the following table, each row corresponds to a concept used within this model view, "+
                    "each column corresponds to another model view, and each cell indicates usage of the concept within the corresponding model view.</p>");
                format.WriteLine("<table class=\"gridtable\">");
                format.Write("<tr><th>Concept</th>");
                foreach (DocModelView docEachView in project.ModelViews)
                {
                    format.Write(HEADERCELL + docEachView.Name + "</th>");
                }
                format.WriteLine("</tr>");

                foreach (DocTemplateDefinition docTemplate in mapTemplates.Keys)
                {
                    format.Write("<tr><td>" + docTemplate.Name + "</td>");

                    foreach (DocModelView docEachView in project.ModelViews)
                    {
                        bool yes = false;
                        foreach (DocConceptRoot docEachRoot in docEachView.ConceptRoots)
                        {
                            foreach (DocTemplateUsage docEachUsage in docEachRoot.Concepts)
                            {
                                if (docEachUsage.Definition == docTemplate)
                                {
                                    yes = true;
                                    break;
                                }
                            }
                        }

                        if (yes)
                        {
                            format.Write("<td>X</td>");
                        }
                        else
                        {
                            format.Write("<td></td>");
                        }
                    }

                    format.WriteLine("</tr>");
                }
                format.WriteLine("</table>");

                format.WriteLine("<h3>7.3.4 Concept business rule list</h3>");
                format.WriteLine("<p>Each concept template is defined in a subsection as follows, with rows corresponding to each business rule. "+
                    "The <i>Reference</i> column identifies the path to the entity and attribute. " +
                    "The <i>Cardinality</i> column indicates whether the number of permitted instances is restricted differently than the underlying schema, using [N:M] notation where N indicates the minimum number of instances, M indicates the maximum number of instances, where '?' indicates unbounded. "+
                    "The <i>Parameter</i> column indicates the name of a substitutable parameter, if applicable, defined at each usage of the business rule.<p>");
                foreach (DocTemplateDefinition docTemplate in mapTemplates.Keys)
                {
                    format.WriteLine("<h4>" + docTemplate.Name + "</h4>");

                    format.WriteLine("<table class=\"gridtable\">");
                    format.WriteLine("<tr><th>Reference</th><th>Cardinality</th><th>Parameter</th></tr>");

                    if (docTemplate.Rules != null)
                    {
                        foreach (DocModelRule docRule in docTemplate.Rules)
                        {
                            WriteModelRule(format, docRule, "\\" + docTemplate.Type + "." + docRule.Name);
                        }
                    }

                    format.WriteLine("</table>");
                }

                format.WriteLine("<h3>7.3.5 Concept business rule description</h3>");
                format.WriteLine("<p>Each concept template is described in a subsection as follows, with diagrams indicating usage of attributes and entities reflecting defined business rules.</p>");
                foreach (DocTemplateDefinition docTemplate in mapTemplates.Keys)
                {
                    format.WriteLine("<h4>" + docTemplate.Name + "</h4>");

                    format.WriteLine(docTemplate.Documentation);

                    string img = "";
                    if (docTemplate.Rules != null && docTemplate.Rules.Count > 0)
                    {
                        img = GenerateTemplateImage(docTemplate, mapEntity, project, path);
                        format.WriteLine(img);
                    }
                }

                format.WriteLine("<h2>7.4 Implementation</h2>");
                format.WriteLine("<h3>7.4.1 MVD Schema Listing</h3>");
                format.WriteLine("The schema encapsulating the data definitions for this model view is published in multiple representations. " +
            "<p>An MVDXML file defines the referenced entities and rules for this model view. This file may be used to validate instance data (in IFC-SPF or IFC-XML files), filter instance data to include entities and attributes within scope of this model view, or generate sub-schemas (including the EXP and XSD representations). " +
            "<p>An EXP file represents the schema in EXPRESS format (ISO 10303-11) which adapts the referenced Industry Foundation Classes schema (ISO 16739) by including a subset of data definitions and a subset of attributes within each data definition. The EXP file may be used by software development tools for generating programming languages schemas (e.g. C++, C#, Java), database definitions (e.g. SQL DDL), and data transport schema definitions (e.g. XSD). " +
            "<p>An XSD file represents the schema in XML Data Definition Language (XSD) which adapts the referenced subset of data definitions. The XSD file may be used by software development tools (e.g. Eclipse, Microsoft Visual Studio) to validate XML files and generate language-specific classes. " +
            "<p>An IFC file represents the dynamic portions of the schema in the form of property sets within an SPF (ISO 10303-21) instance file.</p>" +
            "<p>The rationale for publishing multiple representations is to provide the richest level of integration for different implementations; "+
            "while XSD is often used in defining web standards replacing document-based exchanges (e.g. invoices), it lacks data model information needed for type safety, data integrity, indexing, and optimization; "+
            "all of which may be derived from the EXPRESS representation. "+
            "</p>");
                format.WriteLine("<table class=\"gridtable\">");
                format.WriteLine("<tr><th>File</th><th>Format</th></tr>");
                format.WriteLine("<tr><td>" + docView.Code + ".exp</td><td>EXPRESS schema definition</td></tr>");
                format.WriteLine("<tr><td>" + docView.Code + ".xsd</td><td>XML schema definition (XSD)</td></tr>");
                format.WriteLine("<tr><td>" + docView.Code + ".mvdxml</td><td>MVDXML schema transform</td></tr>");
                format.WriteLine("<tr><td>" + docView.Code + ".ifc</td><td>IFC dynamic schema definition</td></tr>");
                format.WriteLine("</table>");

                format.WriteLine("<h3>7.4.2 MVD Format Description</h3>");

                format.WriteLine("<p>Implementations of this model view may publish instance data in various formats. "+
                    "Such format indicates the data encoding and does not necessarily imply that data may only be exchanged using physical files on computers; "+
                    "formats may be transmitted over the Internet as the “presentation layer” (OSI Layer 6) of any API. "+
                    "As the IFC data model supports both full and partial data models where all objects can be tagged to indicate merge directives (Create/Update/Delete using IfcOwnerHistory.ChangeAction), "+
                    "data may be transmitted in whole or in part, such as indicating only data changes.</p>");
                format.WriteLine("<p>As other OSI layers are already standardized, a full web API may be defined by referencing each layer as follows:</p>");
                format.WriteLine("<table class=\"gridtable\">");
                format.WriteLine("<tr><th>OSI Layer</th><th>OSI Layer Name</th><th>Protocol</th><th>Description</th></tr>");
                format.WriteLine("<tr><td>7</td><td>Application</td><td>WebDav</td><td>Defines valid operations such as GET, PUT, POST, DELETE, MKCOL, LOCK, UNLOCK</td></tr>");
                format.WriteLine("<tr><td>6</td><td>Presentation</td><td>IFC-SPF/IFC-XML</td><td>Defines data encoding</td></tr>");
                format.WriteLine("<tr><td>5</td><td>Session</td><td>HTTP/HTTPS</td><td>Defines establishment of sessions, compression, authentication, requests, responses, and errors</td></tr>");
                format.WriteLine("<tr><td>4</td><td>Transport</td><td>TCP</td><td>Defines message delivery</td></tr>");
                format.WriteLine("<tr><td>3</td><td>Network</td><td>IP</td><td>Defines network paths across multiple nodes</td></tr>");
                format.WriteLine("<tr><td>2</td><td>Data Link</td><td>MAC</td><td>Defines data frame communications between two nodes</td></tr>");
                format.WriteLine("<tr><td>1</td><td>Physical</td><td>(undefined)</td><td>Defines physical connectivity</td></tr>");
                format.WriteLine("</table>");

                format.WriteLine("<p>Each supported format is listed by name, with Extension indicating the default file extension to use on applicable platforms (e.g. Windows), MIME type for indicating the HTTP header when transmitting over the Internet, and Reference standard indicating the presentation layer encoding format.</p>");

                format.WriteLine("<table class=\"gridtable\">");
                format.WriteLine("<tr><th>Format</th><th>Extension</th><th>MIME</th><th>Reference</th></tr>");
                format.WriteLine("<tr><td>IFC-SPF</td><td>.ifc</td><td>application/step</td><td>ISO 10303-21</td></tr>");
                format.WriteLine("<tr><td>IFC-XML</td><td>.ifcxml</td><td>application/xml</td><td>ISO 10303-28</td></tr>");
                format.WriteLine("</table>");

                format.WriteLine("<p>IFC-SPF (ISO 10303-21) is a text format optimized to carry data with complex relationships, supporting human readability yet more compact representation (typically around 10% of size of equivalent XML).</p>");

                format.WriteLine("<p>IFC-HDF (ISO 10303-26) is a binary file format encapsulating data in a compact, indexable encoding optimized for quick retrieval and minimal memory usage. ");
                format.WriteLine("<blockquote class=\"note\">NOTE&nbsp; As this file type is not yet widely implemented, it is not officially part of this model view, however implementations may prefer such format for internal use.</blockquote>");

                format.WriteLine("<p>IFC-XML (ISO 10303-28) is a hierarchical markup format with wide support from software development tools and platforms, supporting greater human readability at the expense of larger representation.  </p>");
                format.WriteLine("<blockquote class=\"note\">NOTE&nbsp; As typical buildings contain millions of elements with graphs of relationships resulting in gigabytes of data, " +
            "XML is not yet suitable for representing complete buildings from a pragmatic standpoint of data size, transmission cost, and loading time. " +
            "However, using derived formats along with MVDXML to filter data sets may enable more efficient exchanges to take place.</blockquote>");

                format.WriteLine("<p>IFC-ZIP (ISO 21320-1) is a compressed file format encapsulating one of the above formats to minimize data size. ");
                format.WriteLine("<blockquote class=\"note\">NOTE&nbsp; As this model view is primarily intended for web-based exchange, zip compression may be selected by other means according to the client and server; therefore, the IFC-ZIP format is not officially part of this model view.</blockquote>");

                format.WriteLine("<h3>7.4.3 MVD Dynamic Schema Analysis</h3>");
                format.WriteLine("<p>Portions of data definitions are defined dynamically, to allow software applications to support extensible definitions while minimizing implementation overhead. "+
                    "Each property set is shown within a subsection as follows, with rows corresponding to properties. See <i>IfcPropertySet</i> for usage information.</p>");
                foreach (DocSection docSection in project.Sections)
                {
                    foreach (DocSchema docSchema in docSection.Schemas)
                    {
                        foreach (DocPropertySet docPset in docSchema.PropertySets)
                        {
                            if (included == null || included.ContainsKey(docPset))
                            {
                                format.WriteLine("<h4>" + docPset.Name + "</h4>");
                                format.WriteLine("<table class=\"gridtable\">");
                                format.WriteLine("<tr><th>Property</th><th>Property Type</th><th>Data Type</th><th>Description</th></tr>");

                                foreach (DocProperty docProp in docPset.Properties)
                                {
                                    string datatype = docProp.PrimaryDataType;
                                    if (!String.IsNullOrEmpty(docProp.SecondaryDataType))
                                    {
                                        datatype += "/" + docProp.SecondaryDataType;
                                    }

                                    format.WriteLine("<tr><td>" + docProp.Name + "</td><td>" + docProp.PropertyType + "</td><td>" + datatype + "</td><td>" + docProp.Documentation + "</td></tr>");
                                }

                                format.WriteLine("</table>");
                            }
                        }
                    }
                }

                format.WriteLine("<h3>7.4.4 Non-Applicable Entity Exclusion Analysis</h3>");
                format.WriteLine("<p>The referenced IFC schema is shown in the following table, with each row corresponding to a schema namespace, with data definitions listed within, where bold items indicate definitions within scope of this Model View Definition.</p>");
                format.WriteLine("<table class=\"gridtable\">");
                format.WriteLine("<tr><th>Namespace</th><th>Definitions</th><th>Usage</th></tr>");
                foreach (DocSection docSection in project.Sections)
                {
                    if (docSection.Schemas.Count > 0)
                    {
                        foreach (DocSchema docSchema in docSection.Schemas)
                        {
                            format.Write("<tr><td>" + docSchema.Name + "</td><td>");

                            int min = 0;
                            int max = 0;

                            foreach (DocEntity docEntity in docSchema.Entities)
                            {
                                max++;
                                if (included == null || included.ContainsKey(docEntity))
                                {
                                    min++;
                                    format.Write("<b>");
                                }
                                format.Write(docEntity.Name);
                                format.Write("; ");
                                if (included == null || included.ContainsKey(docEntity))
                                {
                                    format.Write("</b>");
                                }
                            }

                            foreach (DocType docType in docSchema.Types)
                            {
                                max++;
                                if (included == null || included.ContainsKey(docType))
                                {
                                    min++;
                                    format.Write("<b>");
                                }
                                format.Write(docType.Name);
                                format.Write("; ");
                                if (included == null || included.ContainsKey(docType))
                                {
                                    format.Write("</b>");
                                }
                            }

                            format.Write("</td>");

                            format.Write("<td>" + min + "/" + max + " (" + (100.0 *(double)min/(double)max).ToString("N0") + "%)</td>");

                            format.WriteLine("</tr>");

                        }
                    }
                }
                format.WriteLine("</table>");

                // 8 Conformance testing procedures

                // 9 Implementation resources

                // 10 Revision Plans

                format.WriteFooter("");
            }
        }
Example #29
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());
        }
Example #30
0
        public Compiler(DocProject project, DocModelView[] views, DocExchangeDefinition exchange)
        {
            this.m_project = project;
            this.m_views = views;
            this.m_exchange = exchange;

            this.m_assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("IFC4"), AssemblyBuilderAccess.RunAndSave);
            this.m_module = this.m_assembly.DefineDynamicModule("IFC4.dll", "IFC4.dll");
            this.m_definitions = new Dictionary<string, DocObject>();
            this.m_types = new Dictionary<string, Type>();
            this.m_fields = new Dictionary<Type, Dictionary<string, FieldInfo>>();
            this.m_templates = new Dictionary<DocTemplateDefinition, MethodInfo>();
            this.m_namespaces = new Dictionary<string, string>();

            Dictionary<DocObject, bool> included = null;
            if (this.m_views != null)
            {
                included = new Dictionary<DocObject, bool>();
                foreach (DocModelView docView in this.m_views)
                {
                    this.m_project.RegisterObjectsInScope(docView, included);
                }
            }

            foreach (DocSection docSection in project.Sections)
            {
                foreach (DocSchema docSchema in docSection.Schemas)
                {
                    foreach (DocEntity docEntity in docSchema.Entities)
                    {
                        if (included == null || included.ContainsKey(docEntity))
                        {
                            if (!this.m_definitions.ContainsKey(docEntity.Name))
                            {
                                this.m_definitions.Add(docEntity.Name, docEntity);
                                this.m_namespaces.Add(docEntity.Name, docSchema.Name);
                            }
                        }
                    }

                    foreach (DocType docType in docSchema.Types)
                    {
                        if (included == null || included.ContainsKey(docType))
                        {
                            if (!this.m_definitions.ContainsKey(docType.Name))
                            {
                                this.m_definitions.Add(docType.Name, docType);
                                this.m_namespaces.Add(docType.Name, docSchema.Name);
                            }
                        }
                    }
                }
            }

            // first register types and fields
            foreach (string key in this.m_definitions.Keys)
            {
                RegisterType(key);
            }

            // now register template functions (may depend on fields existing)

            // find associated ConceptRoot for model view, define validation function
            if (this.m_views != null)
            {
                foreach (DocModelView view in this.m_views)
                {
                    string viewname = view.Code;
                    foreach (DocConceptRoot root in view.ConceptRoots)
                    {
                        Type tOpen= null;
                        
                        if (this.m_types.TryGetValue(root.ApplicableEntity.Name, out tOpen) && tOpen is TypeBuilder)
                        {
                            TypeBuilder tb = (TypeBuilder)tOpen;
                            foreach (DocTemplateUsage concept in root.Concepts)
                            {
                                CompileConcept(concept, view, tb);
                            }
                        }
                    }
                }
            }



            // seal types once all are built
            List<TypeBuilder> listBase = new List<TypeBuilder>();
            foreach (string key in this.m_definitions.Keys)
            {
                Type tOpen = this.m_types[key];
                while (tOpen is TypeBuilder)
                {
                    listBase.Add((TypeBuilder)tOpen);
                    tOpen = tOpen.BaseType;
                }

                // seal in base class order
                for (int i = listBase.Count - 1; i >= 0; i--)
                {
                    Type tClosed = listBase[i].CreateType();
                    this.m_types[tClosed.Name] = tClosed;
                }
                listBase.Clear();
            }
        }
Example #31
0
        /// <summary>
        /// Draws entity and recurses.
        /// </summary>
        /// <param name="g">Graphics device.</param>
        /// <param name="lane">Horizontal lane for which to draw the entity.</param>
        /// <param name="lanes">List of lanes left-to-right.</param>
        /// <param name="docEntity">The entity to draw.</param>
        /// <param name="docView">The model view for which to draw the entity.</param>
        /// <param name="docTemplate">The template to draw.</param>
        /// <param name="docRule">Optional rule for recursing.</param>
        /// <param name="map">Map of definitions.</param>
        /// <param name="layout">Optional layout to receive rectangles for building image map</param>
        /// <param name="docProject">Required project.</param>
        /// <param name="instance">Optional instance where included or missing attributes are highlighted.</param>
        private static void DrawEntity(
            Graphics g, 
            int lane, 
            List<int> lanes, 
            DocEntity docEntity,
            DocModelView docView,
            DocTemplateDefinition docTemplate, 
            DocModelRuleEntity docRule, 
            Dictionary<string, DocObject> map, 
            Dictionary<Rectangle, DocModelRule> layout,
            DocProject docProject,
            DocSchema docSchema,
            object instance)
        {
            List<DocAttribute> listAttr = new List<DocAttribute>();
            BuildAttributeList(docEntity, listAttr, map);

            while(lanes.Count < lane + 1)
            {
                int miny = 0;
                if (lanes.Count > lane)
                {
                    miny = lanes[lane];
                }

                lanes.Add(miny);
            }

            int x = lane * CX + FormatPNG.Border;
            int y = lanes[lane] + FormatPNG.Border;

            if (g != null)
            {
                Brush brush = Brushes.Black;

                if (instance != null)
                {
                    brush = Brushes.Red;

                    if (instance is System.Collections.IList)
                    {
                        string typename = instance.GetType().Name;

                        // keep going until matching instance
                        System.Collections.IList list = (System.Collections.IList)instance;
                        foreach (object member in list)
                        {
                            string membertypename = member.GetType().Name;
                            DocEntity docType = docProject.GetDefinition(membertypename) as DocEntity;
                            while (docType != null)
                            {
                                if (docType == docEntity)
                                {
                                    brush = Brushes.Lime;
                                    instance = member;
                                    break;
                                }

                                docType = docProject.GetDefinition(docType.BaseDefinition) as DocEntity;
                            }

                            if (brush != Brushes.Red)
                                break;
                        }
                    }
                    else
                    {
                        string typename = instance.GetType().Name;
                        DocEntity docType = docProject.GetDefinition(typename) as DocEntity;
                        while (docType != null)
                        {
                            if (docType == docEntity)
                            {
                                brush = Brushes.Lime;
                                break;
                            }

                            docType = docProject.GetDefinition(docType.BaseDefinition) as DocEntity;
                        }
                    }
                }
                else if (docEntity.IsAbstract())
                {
                    brush = Brushes.Gray;
                }
                else
                {
                    brush = Brushes.Black;
                }
                g.FillRectangle(brush, x, y, CX - DX, CY);
                g.DrawRectangle(Pens.Black, x, y, CX - DX, CY);
                using (Font font = new Font(FontFamily.GenericSansSerif, 8.0f, FontStyle.Bold))
                {
                    g.DrawString(docEntity.Name, font, Brushes.White, x, y);
                }

                if (docRule != null && docRule.Identification == "Value")
                {
                    // mark rule serving as default value
                    g.FillEllipse(Brushes.Green, new Rectangle(x + CX - DX - CY, y, CY, CY));
                }

                g.DrawRectangle(Pens.Black, x, y + CY, CX - DX, CY * listAttr.Count);
                using (Font font = new Font(FontFamily.GenericSansSerif, 8.0f, FontStyle.Regular))
                {
                    for (int iAttr = 0; iAttr < listAttr.Count; iAttr++)
                    {
                        DocAttribute docAttr = listAttr[iAttr];

                        string display = docAttr.GetAggregationExpression();
                        brush = Brushes.Black;
                        if (docAttr.Inverse != null)
                        {
                            brush = Brushes.Gray;
                        }
                        if(String.IsNullOrEmpty(display))
                        {
                            if(docAttr.IsOptional)
                            {
                                display = "[0:1]";
                            }
                            else
                            {
                                display = "[1:1]";
                            }
                        }

                        g.DrawString(docAttr.Name, font, brush, x, y + CY * (iAttr + 1));
                        using (StringFormat fmt = new StringFormat())
                        {
                            fmt.Alignment = StringAlignment.Far;
                            g.DrawString(display, font, brush, new RectangleF(x, y + CY * (iAttr + 1), CX - DX, CY), fmt);
                        }

                    }
                }
            }

            // record rectangle
            if (layout != null)
            {
                layout.Add(new Rectangle(x, y, CX - DX, CY + CY * listAttr.Count), docRule);
            }

            SortedList<int, List<DocModelRuleAttribute>> mapAttribute = new SortedList<int, List<DocModelRuleAttribute>>();
            Dictionary<DocModelRuleAttribute, DocTemplateDefinition> mapTemplate = new Dictionary<DocModelRuleAttribute,DocTemplateDefinition>();
            if (docRule != null && docRule.Rules != null)
            {
                // map inner rules

                // sort
                foreach (DocModelRule rule in docRule.Rules)
                {
                    if (rule is DocModelRuleAttribute)
                    {
                        DocModelRuleAttribute ruleAttribute = (DocModelRuleAttribute)rule;
                        for (int i = 0; i < listAttr.Count; i++)
                        {
                            if (listAttr[i].Name.Equals(ruleAttribute.Name))
                            {
                                // found it
                                if (!mapAttribute.ContainsKey(i))
                                {
                                    mapAttribute.Add(i, new List<DocModelRuleAttribute>());
                                }

                                mapAttribute[i].Add(ruleAttribute);
                                break;
                            }
                        }
                    }
                }
            }
            else if (docTemplate != null)
            {
                if (docTemplate.Rules != null)
                {
                    foreach (DocModelRuleAttribute ruleAttribute in docTemplate.Rules)
                    {
                        for (int i = 0; i < listAttr.Count; i++)
                        {
                            if (listAttr[i].Name != null && listAttr[i].Name.Equals(ruleAttribute.Name))
                            {
                                // found it
                                //iAttr = i;
                                if (!mapAttribute.ContainsKey(i))
                                {
                                    mapAttribute.Add(i, new List<DocModelRuleAttribute>());
                                }
                                mapAttribute[i].Add(ruleAttribute);
                                break;
                            }
                        }
                    }
                }
            }
            else
            {
                // map each use definition at top-level

                // build list of inherited views
                List<DocModelView> listViews = new List<DocModelView>();
                DocModelView docBaseView = docView;
                while (docBaseView != null)
                {
                    listViews.Add(docBaseView);

                    if (!String.IsNullOrEmpty(docBaseView.BaseView))
                    {
                        Guid guidBase = Guid.Parse(docBaseView.BaseView);
                        if (guidBase != docBaseView.Uuid)
                        {
                            docBaseView = docProject.GetView(guidBase);
                        }
                        else
                        {
                            docBaseView = null;
                        }
                    }
                    else
                    {
                        docBaseView = null;
                    }
                }

                // build from inherited entities too

                List<DocTemplateDefinition> listTemplates = new List<DocTemplateDefinition>(); // keep track of templates so we don't repeat at supertypes
                List<DocTemplateDefinition> listSuppress = new List<DocTemplateDefinition>(); // list of templates that are suppressed

                DocEntity docEntitySuper = docEntity;
                while(docEntitySuper != null)
                {

                    foreach (DocModelView docEachView in docProject.ModelViews)
                    {
                        if (docView == null || listViews.Contains(docEachView))
                        {
                            foreach (DocConceptRoot docRoot in docEachView.ConceptRoots)
                            {
                                if (docRoot.ApplicableEntity == docEntitySuper)
                                {
                                    foreach (DocTemplateUsage docUsage in docRoot.Concepts)
                                    {
                                        if (docUsage.Definition != null && docUsage.Definition.Rules != null && !listTemplates.Contains(docUsage.Definition) && !listSuppress.Contains(docUsage.Definition))
                                        {
                                            if (docUsage.Suppress)
                                            {
                                                listSuppress.Add(docUsage.Definition);
                                            }
                                            else
                                            {

                                                listTemplates.Add(docUsage.Definition);

                                                foreach (DocModelRuleAttribute ruleAttribute in docUsage.Definition.Rules)
                                                {
                                                    for (int i = 0; i < listAttr.Count; i++)
                                                    {
                                                        if (listAttr[i].Name.Equals(ruleAttribute.Name))
                                                        {
                                                            // found it
                                                            if (!mapAttribute.ContainsKey(i))
                                                            {
                                                                mapAttribute.Add(i, new List<DocModelRuleAttribute>());
                                                            }

                                                            mapAttribute[i].Add(ruleAttribute);
                                                            if (!mapTemplate.ContainsKey(ruleAttribute))
                                                            {
                                                                mapTemplate.Add(ruleAttribute, docUsage.Definition);
                                                            }
                                                            break;
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }

                    DocObject docTest = null;
                    if (docEntitySuper.BaseDefinition != null && map.TryGetValue(docEntitySuper.BaseDefinition, out docTest))
                    {
                        docEntitySuper = docTest as DocEntity;
                    }
                    else
                    {
                        docEntitySuper = null;
                    }
                }
            }

            int offset = -mapAttribute.Values.Count / 2;

            DocTemplateDefinition lastTemplate = null;
            foreach (List<DocModelRuleAttribute> listSort in mapAttribute.Values)
            {
                if (docRule == null && docTemplate == null)
                {
                    // offset all lanes
                    int maxlane = 0;
                    for (int i = 1; i < lanes.Count; i++)
                    {
                        if (lanes[i] > maxlane)
                        {
                            maxlane = lanes[i];
                        }
                    }

                    for (int i = 1; i < lanes.Count; i++)
                    {
                        lanes[i] = maxlane;
                    }
                }

                foreach (DocModelRuleAttribute ruleAttributeSort in listSort)
                {
                    // indicate each template
                    DocTemplateDefinition eachTemplate = null;
                    if (mapTemplate.TryGetValue(ruleAttributeSort, out eachTemplate))
                    {
                        // offset for use definition
                        int minlan = 0;
                        for (int i = 1; i < lanes.Count; i++)
                        {
                            if (eachTemplate != lastTemplate)
                            {
                                lanes[i] += CY * 2;
                            }

                            if (lanes[i] > minlan)
                            {
                                minlan = lanes[i];
                            }
                        }

                        // verify this...
                        for (int i = 1; i < lanes.Count; i++)
                        {
                            if (lanes[i] < minlan)
                            {
                                lanes[i] = minlan;
                            }
                        }

                        if (g != null && eachTemplate != lastTemplate)
                        {
                            using (Font font = new Font(FontFamily.GenericSansSerif, 8.0f, FontStyle.Italic))
                            {
                                g.DrawString(eachTemplate.Name, font, Brushes.Gray, CX + FormatPNG.Border, lanes[1] - CY * 2 + FormatPNG.Border);
                            }
                            int lineY = lanes[1] - CY * 2 + FormatPNG.Border;
                            g.DrawLine(Pens.Gray, CX + FormatPNG.Border, lineY, 1920, lineY);
                        }

                        lastTemplate = eachTemplate;
                    }

                    DrawAttribute(g, lane, lanes, docEntity, docView, ruleAttributeSort, map, offset, layout, docProject, docSchema, instance as SEntity);
                }
                offset++;
            }

            // increment lane offset
            int minlane = y + CY * (listAttr.Count + 2);
            if (lanes[lane] < minlane)
            {
                lanes[lane] = minlane;
            }
        }
Example #32
0
        private static void Dereference(DocExample docExample, DocModelView docModelView)
        {
            if (docExample.Views.Contains(docModelView))
            {
                docExample.Views.Remove(docModelView);
            }

            if (docExample.Examples != null)
            {
                foreach (DocExample docSub in docExample.Examples)
                {
                    Dereference(docSub, docModelView);
                }
            }
        }
Example #33
0
        private static void DrawAttribute(
            Graphics g, 
            int lane, 
            List<int> lanes, 
            DocEntity docEntity, 
            DocModelView docView, 
            DocModelRuleAttribute ruleAttribute, 
            Dictionary<string, DocObject> map, 
            int offset, 
            Dictionary<Rectangle, DocModelRule> layout, 
            DocProject docProject,
            DocSchema docSchema,
            SEntity instance)
        {
            int x = lane * CX + FormatPNG.Border;
            int y = lanes[lane] + FormatPNG.Border;

            // find the index of the attribute
            List<DocAttribute> listAttr = new List<DocAttribute>();
            BuildAttributeList(docEntity, listAttr, map);

            int iAttr = -1;
            for (int i = 0; i < listAttr.Count; i++)
            {
                if (listAttr[i].Name.Equals(ruleAttribute.Name))
                {
                    // found it
                    iAttr = i;
                    break;
                }
            }

            if (iAttr >= 0)
            {
                DocAttribute docAttr = listAttr[iAttr];

                object valueinstance = null;
                if (instance != null)
                {
                    System.Reflection.FieldInfo field = instance.GetType().GetField(docAttr.Name);
                    if(field != null)
                    {
                        valueinstance = field.GetValue(instance);
                    }
                }

                // map it
                foreach (DocModelRule ruleEach in ruleAttribute.Rules)
                {
                    if (ruleEach is DocModelRuleEntity)
                    {
                        DocModelRuleEntity ruleEntity = (DocModelRuleEntity)ruleEach;

                        DocObject docObj = null;

                        if (docSchema != null)
                        {
                            docObj = docSchema.GetDefinition(ruleEntity.Name);
                            if (docObj is DocDefinitionRef)
                                docObj = null;
                        }

                        if (docObj == null)
                        {
                            map.TryGetValue(ruleEntity.Name, out docObj);
                        }

                        {
                            int dest = FormatPNG.Border;
                            if (lanes.Count > lane + 1)
                            {
                                dest = lanes[lane + 1] + FormatPNG.Border;
                            }

                            if (docObj is DocEntity)
                            {
                                DocEntity docEntityTarget = (DocEntity)docObj;

                                // resolve inverse attribute
                                List<DocAttribute> listTarget = new List<DocAttribute>();
                                BuildAttributeList(docEntityTarget, listTarget, map);
                                for (int i = 0; i < listTarget.Count; i++)
                                {
                                    DocAttribute docAttrTarget = listTarget[i];
                                    if (docAttr.Inverse != null && docAttrTarget.Name.Equals(docAttr.Inverse))
                                    {
                                        // found it
                                        dest += CY * (i + 1);
                                        break;
                                    }
                                    else if (docAttrTarget.Inverse != null && docAttr.Name.Equals(docAttrTarget.Inverse))
                                    {
                                        //...also need to check for type compatibility

                                        bool found = false;
                                        DocEntity docTest = docEntity;
                                        while (docTest != null)
                                        {
                                            if (docTest.Name.Equals(docAttrTarget.DefinedType))
                                            {
                                                found = true;
                                                break;
                                            }

                                            if (docTest.BaseDefinition == null)
                                                break;

                                            DocObject docBase = null;
                                            if (map.TryGetValue(docTest.BaseDefinition, out docBase))
                                            {
                                                docTest = docBase as DocEntity;
                                            }
                                            else
                                            {
                                                break;
                                            }
                                        }

                                        // found it
                                        if (found)
                                        {
                                            dest += CY * (i + 1);
                                            break;
                                        }
                                    }
                                }

                                // draw the entity, recurse
                                DrawEntity(g, lane + 1, lanes, docEntityTarget, docView, null, ruleEntity, map, layout, docProject, docSchema, valueinstance);
                            }
                            else
                            {
                                int targetY = lanes[lane + 1] + FormatPNG.Border;

                                if (g != null)
                                {
                                    Brush brush = Brushes.Black;

                                    if (instance != null)
                                    {
                                        if (valueinstance == null)
                                        {
                                            brush = Brushes.Red;
                                        }
                                        else if(valueinstance is System.Collections.IList)
                                        {
                                            brush = Brushes.Blue;
                                        }
                                        else
                                        {
                                            string typename = valueinstance.GetType().Name;
                                            if (typename == ruleEntity.Name)
                                            {
                                                brush = Brushes.Lime;
                                            }
                                            else
                                            {
                                                brush = Brushes.Red;
                                            }
                                        }
                                    }

                                    g.FillRectangle(brush, x + CX, targetY, CX - DX, CY);
                                    g.DrawRectangle(Pens.Black, x + CX, targetY, CX - DX, CY);
                                    using (Font font = new Font(FontFamily.GenericSansSerif, 8.0f))
                                    {
                                        string content = ruleEntity.Name;//docObj.Name;
                                        foreach (DocModelRule ruleConstraint in ruleEntity.Rules)
                                        {
                                            if (ruleConstraint.Description != null && ruleConstraint.Description.StartsWith("Value="))
                                            {
                                                content = ruleConstraint.Description.Substring(6);

                                                using (StringFormat fmt = new StringFormat())
                                                {
                                                    fmt.Alignment = StringAlignment.Far;
                                                    g.DrawString(content, font, Brushes.White, new RectangleF(x + CX, targetY, CX - DX, CY), fmt);
                                                }
                                            }
                                        }

                                        g.DrawString(ruleEntity.Name, font, Brushes.White, x + CX, targetY);

                                        if (ruleEntity.Identification == "Value")
                                        {
                                            // mark rule serving as default value
                                            g.FillEllipse(Brushes.Green, new Rectangle(x + CX - DX - CY, y, CY, CY));
                                        }
                                    }
                                }

                                // record rectangle
                                if (layout != null)
                                {
                                    layout.Add(new Rectangle(x + CX, targetY, CX - DX, CY), ruleEntity);
                                }

                                // increment lane offset for all lanes
                                int minlane = targetY + CY * 2;
                                int i = lane + 1;
                                if (lanes[i] < minlane)
                                {
                                    lanes[i] = minlane;
                                }
                            }

                            // draw arrow
                            if (g != null)
                            {
                                int x0 = x + CX - DX;
                                int y0 = y + CY * (iAttr + 1) + CY / 2;
                                int x1 = x + CX;
                                int y1 = dest + CY / 2;
                                int xM = x0 + DX / 2 - offset * 2;

                                if(!String.IsNullOrEmpty(ruleAttribute.Identification))
                                {
                                    // mark the attribute as using parameter
                                    //g.DrawRectangle(Pens.Blue, x, y + CY * (iAttr + 1), CX - DX, CY);
                                    using (Font font = new Font(FontFamily.GenericSansSerif, 8.0f, FontStyle.Regular))
                                    {
                                        using (StringFormat fmt = new StringFormat())
                                        {
                                            fmt.Alignment = StringAlignment.Near;
                                            g.DrawString(docAttr.Name, font, Brushes.Blue, x, y + CY * (iAttr + 1), fmt);
                                        }
                                    }
                                }

                                g.DrawLine(Pens.Black, x0, y0, xM, y0);
                                g.DrawLine(Pens.Black, xM, y0, xM, y1);
                                g.DrawLine(Pens.Black, xM, y1, x1, y1);
                            }
                        }
                    }
                }

                if (g != null && ruleAttribute.Identification == "Name")
                {
                    // mark rule serving as default name
                    g.FillEllipse(Brushes.Blue, new Rectangle(x + CX - DX - CY, y + CY * (iAttr+1), CY, CY));
                }

            #if false
                string card = ruleAttribute.GetCardinalityExpression();
                if (g != null && card != null)
                {
                    card = card.Trim();
                    switch (docAttr.GetAggregation())
                    {
                        case DocAggregationEnum.SET:
                            card = "S" + card;
                            break;

                        case DocAggregationEnum.LIST:
                            card = "L" + card;
                            break;
                    }

                    int px = x + CX - DX;
                    int py = y + CY * (iAttr + 1);
                    g.FillRectangle(Brushes.White, px - CX / 5, py, CX / 5, CY);
                    using (Font font = new Font(FontFamily.GenericSansSerif, 8.0f, FontStyle.Regular))
                    {
                        using (StringFormat fmt = new StringFormat())
                        {
                            fmt.Alignment = StringAlignment.Far;
                            g.DrawString(card, font, Brushes.Blue, px, py, fmt);
                        }
                    }
                }
            #endif
            }
        }
Example #34
0
        public CheckGridEntity(DocConceptRoot docRoot, DocModelView docView, DocProject docProject, Dictionary<string, DocObject> map)
        {
            this.m_root = docRoot;
            this.m_view = docView;
            this.m_project = docProject;
            this.m_listTemplate = new List<DocTemplateDefinition>();
            
            List<DocTemplateDefinition> listTemplate = docProject.GetTemplateList();

            //... filter out templates to only those that apply to entity...

            foreach (DocTemplateDefinition docTemplate in listTemplate)
            {
                if (docTemplate.Rules != null && docTemplate.Rules.Count > 0) // don't include abstract/organizational templates
                {
                    bool include = false;

                    // check for inheritance                
                    DocObject docApplicableEntity = null;
                    if (docTemplate.Type != null && map.TryGetValue(docTemplate.Type, out docApplicableEntity) && docApplicableEntity is DocEntity)
                    {
                        // check for inheritance
                        DocEntity docBase = docRoot.ApplicableEntity;
                        while (docBase != null)
                        {
                            if (docBase == docApplicableEntity)
                            {
                                include = true;
                                break;
                            }

                            if (docBase.BaseDefinition == null)
                                break;

                            DocObject docEach = null;
                            if (map.TryGetValue(docBase.BaseDefinition, out docEach))
                            {
                                docBase = (DocEntity)docEach;
                            }
                            else
                            {
                                docBase = null;
                            }
                        }
                    }

                    if (include)
                    {
                        this.m_listTemplate.Add(docTemplate);
                    }
                }
            }

        }
Example #35
0
        internal static void ExportCnf(IfcDoc.Schema.CNF.configuration cnf, DocProject docProject, DocModelView[] docViews, Dictionary<DocObject, bool> included)
        {
            // configure general settings

            /*
              <cnf:option inheritance="true" exp-type="unspecified" concrete-attribute="attribute-content" entity-attribute="double-tag" tagless="unspecified" naming-convention="preserve-case" generate-keys="false"/>
              <cnf:schema targetNamespace="http://www.buildingsmart-tech.org/ifcXML/IFC4/final" embed-schema-items="true" elementFormDefault="qualified" attributeFormDefault="unqualified">
            <cnf:namespace prefix="ifc" alias="http://www.buildingsmart-tech.org/ifcXML/IFC4/final"/>
              </cnf:schema>
              <cnf:uosElement name="ifcXML"/>
              <cnf:type select="NUMBER" map="xs:double"/>
              <cnf:type select="BINARY" map="xs:hexBinary"/>
              <cnf:type select="IfcStrippedOptional" keep="false"/>
            */
            cnf.id = "IFC4";

            IfcDoc.Schema.CNF.option opt = new Schema.CNF.option();
            opt.inheritance = true;
            opt.exp_type = Schema.CNF.exp_type.unspecified;
            opt.concrete_attribute = Schema.CNF.exp_attribute_global.attribute_content;
            opt.entity_attribute = Schema.CNF.exp_attribute_global.double_tag;
            opt.tagless = Schema.CNF.boolean_or_unspecified.unspecified;
            opt.naming_convention = Schema.CNF.naming_convention.preserve_case;
            opt.generate_keys = false;
            cnf.option.Add(opt);

            IfcDoc.Schema.CNF.schema sch = new IfcDoc.Schema.CNF.schema();
            sch.targetNamespace = "http://www.buildingsmart-tech.org/ifcXML/IFC4/final"; //... make parameter...
            sch.embed_schema_items = true;
            sch.elementFormDefault = Schema.CNF.qual.qualified;
            sch.attributeFormDefault = Schema.CNF.qual.unqualified;

            IfcDoc.Schema.CNF._namespace ns = new Schema.CNF._namespace();
            ns.prefix = "ifc";
            ns.alias = "http://www.buildingsmart-tech.org/ifcXML/IFC4/final";
            sch._namespace = ns;

            cnf.schema.Add(sch);

            IfcDoc.Schema.CNF.uosElement uos = new Schema.CNF.uosElement();
            uos.name = "ifcXML";
            cnf.uosElement.Add(uos);

            IfcDoc.Schema.CNF.type typeNumber = new Schema.CNF.type();
            typeNumber.select = "NUMBER";
            typeNumber.map = "xs:double";
            cnf.type.Add(typeNumber);

            IfcDoc.Schema.CNF.type typeBinary = new Schema.CNF.type();
            typeBinary.select = "BINARY";
            typeBinary.map = "xs:hexBinary";
            cnf.type.Add(typeBinary);

            IfcDoc.Schema.CNF.type typeStripped = new Schema.CNF.type();
            typeStripped.select = "IfcStrippedOptional";
            typeStripped.keep = false;
            cnf.type.Add(typeStripped);

            SortedDictionary<string, IfcDoc.Schema.CNF.entity> mapEntity = new SortedDictionary<string, Schema.CNF.entity>();

            // export default configuration -- also export for Common Use Definitions (base view defined as itself to include everything)
            //if (docViews == null || docViews.Length == 0 || (docViews.Length == 1 && docViews[0].BaseView == docViews[0].Uuid.ToString()))
            {
                foreach (DocSection docSection in docProject.Sections)
                {
                    foreach (DocSchema docSchema in docSection.Schemas)
                    {
                        foreach(DocEntity docEntity in docSchema.Entities)
                        {
                            bool include = true; //... check if included in graph?
                            if (included != null && !included.ContainsKey(docEntity))
                            {
                                include = false;
                            }

                            if (include)
                            {
                                foreach (DocAttribute docAttr in docEntity.Attributes)
                                {
                                    if (docAttr.XsdFormat != DocXsdFormatEnum.Default || docAttr.XsdTagless == true)
                                    {
                                        IfcDoc.Schema.CNF.entity ent = null;
                                        if (!mapEntity.TryGetValue(docEntity.Name, out ent))
                                        {
                                            ent = new Schema.CNF.entity();
                                            ent.select = docEntity.Name;
                                            mapEntity.Add(docEntity.Name, ent);
                                        }

                                        ExportCnfAttribute(ent, docAttr, docAttr.XsdFormat, docAttr.XsdTagless);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // export view-specific configuration
            foreach (DocModelView docView in docViews)
            {
                foreach (DocXsdFormat format in docView.XsdFormats)
                {
                    DocEntity docEntity = docProject.GetDefinition(format.Entity) as DocEntity;
                    if (docEntity != null)
                    {
                        DocAttribute docAttr = null;
                        foreach (DocAttribute docEachAttr in docEntity.Attributes)
                        {
                            if (docEachAttr.Name != null && docEachAttr.Name.Equals(format.Attribute))
                            {
                                docAttr = docEachAttr;
                                break;
                            }
                        }

                        if (docAttr != null)
                        {
                            IfcDoc.Schema.CNF.entity ent = null;
                            if (!mapEntity.TryGetValue(docEntity.Name, out ent))
                            {
                                ent = new Schema.CNF.entity();
                                mapEntity.Add(docEntity.Name, ent);
                            }

                            ExportCnfAttribute(ent, docAttr, format.XsdFormat, format.XsdTagless);
                        }
                    }
                }
            }

            // add at end, such that sorted
            foreach(IfcDoc.Schema.CNF.entity ent in mapEntity.Values)
            {
                cnf.entity.Add(ent);
            }
        }
Example #36
0
        private void toolStripMenuItemInsertViewDefinition_Click(object sender, EventArgs e)
        {
            DocModelView docView = new DocModelView();
            this.m_project.ModelViews.Add(docView);

            TreeNode tnParent = this.treeView.Nodes[0];
            this.treeView.SelectedNode = this.LoadNode(tnParent, docView, docView.ToString(), true);

            toolStripMenuItemEditRename_Click(this, e);
        }
Example #37
0
        /// <summary>
        /// Extracts description of referenced data, using properties, quantities, and attributes.
        /// </summary>
        /// <param name="mapEntity"></param>
        /// <param name="docView">Optional model view, for retrieving more specific descriptions such as for ports</param>
        /// <returns></returns>
        public string GetDescription(Dictionary <string, DocObject> mapEntity, DocModelView docView)
        {
            string       desc    = null;
            CvtValuePath valpath = this;

            if (valpath != null &&
                valpath.Property != null &&
                valpath.Property.Name.Equals("IsDefinedBy") &&
                valpath.InnerPath != null && valpath.InnerPath.Type.Name.Equals("IfcRelDefinesByProperties") &&
                valpath.Identifier != null)
            {
                DocObject docPset = null;
                mapEntity.TryGetValue(valpath.Identifier, out docPset);

                if (docPset is DocPropertySet)
                {
                    DocProperty docProp = ((DocPropertySet)docPset).GetProperty(valpath.InnerPath.InnerPath.Identifier);
                    if (docProp != null)
                    {
                        desc = docProp.Documentation;// localize??

                        if (String.IsNullOrEmpty(docProp.Documentation))
                        {
                            this.ToString();
                        }
                    }
                }
                else if (docPset is DocQuantitySet)
                {
                    DocQuantity docProp = ((DocQuantitySet)docPset).GetQuantity(valpath.InnerPath.InnerPath.Identifier);
                    if (docProp != null)
                    {
                        desc = docProp.Documentation;// localize??

                        if (String.IsNullOrEmpty(docProp.Documentation))
                        {
                            this.ToString();
                        }
                    }
                }
            }
            else if (valpath != null &&
                     valpath.Property != null &&
                     valpath.Property.Name.Equals("HasAssignments") &&
                     valpath.InnerPath != null && valpath.InnerPath.Type.Name.Equals("IfcRelAssignsToControl") &&
                     valpath.InnerPath.InnerPath != null && valpath.InnerPath.InnerPath.Type.Name.Equals("IfcPerformanceHistory"))
            {
                DocObject docPset = null;
                if (mapEntity.TryGetValue(valpath.InnerPath.InnerPath.Identifier, out docPset))
                {
                    DocProperty docProp = ((DocPropertySet)docPset).GetProperty(valpath.InnerPath.InnerPath.InnerPath.InnerPath.Identifier);
                    if (docProp != null)
                    {
                        desc = docProp.Documentation;// localize??

                        if (docProp.Documentation == null)
                        {
                            DocLocalization docLoc = docProp.GetLocalization(null);
                            if (docLoc != null)
                            {
                                desc = docLoc.Documentation;
                            }
                        }
                    }
                }

                this.ToString();
            }
            else if (valpath != null &&
                     valpath.Property != null &&
                     valpath.Property.Name.Equals("HasPropertySets") &&
                     valpath.InnerPath != null && valpath.InnerPath.Type.Name.Equals("IfcPropertySet"))
            {
                DocObject docPset = null;
                mapEntity.TryGetValue(valpath.Identifier, out docPset);

                if (docPset is DocPropertySet)
                {
                    DocProperty docProp = ((DocPropertySet)docPset).GetProperty(valpath.InnerPath.Identifier);
                    if (docProp != null)
                    {
                        desc = docProp.Documentation;// localize??

                        if (String.IsNullOrEmpty(docProp.Documentation))
                        {
                            this.ToString();
                        }
                    }
                }
            }
            else if (valpath != null &&
                     valpath.Property != null &&
                     valpath.Property.Name.Equals("Material") &&
                     valpath.InnerPath != null && valpath.InnerPath.Type.Name.Equals("IfcMaterial") &&
                     valpath.InnerPath.InnerPath != null && valpath.InnerPath.InnerPath.Type.Name.Equals("IfcMaterialProperties"))
            {
                DocObject docPset = null;
                mapEntity.TryGetValue(valpath.InnerPath.Identifier, out docPset);

                if (docPset is DocPropertySet)
                {
                    DocProperty docProp = ((DocPropertySet)docPset).GetProperty(valpath.InnerPath.InnerPath.Identifier);
                    if (docProp != null)
                    {
                        desc = docProp.Documentation;
                    }
                }
            }
            else if (valpath != null &&
                     valpath.Property != null &&
                     valpath.Property.Name.Equals("HasProperties") &&
                     valpath.InnerPath != null && valpath.InnerPath.Type.Name.Equals("IfcMaterialProperties"))
            {
                DocObject docPset = null;
                mapEntity.TryGetValue(valpath.Identifier, out docPset);

                if (docPset is DocPropertySet)
                {
                    DocProperty docProp = ((DocPropertySet)docPset).GetProperty(valpath.InnerPath.Identifier);
                    if (docProp != null)
                    {
                        desc = docProp.Documentation;
                    }
                }
            }
            else if (valpath != null &&
                     valpath.Property != null &&
                     valpath.Property.Name.Equals("IsNestedBy") &&
                     valpath.InnerPath != null && valpath.InnerPath.InnerPath != null && valpath.InnerPath.InnerPath != null)
            {
                CvtValuePath pathInner = valpath.InnerPath.InnerPath;
                if (pathInner.Type != null && pathInner.Type.Name.Equals("IfcDistributionPort"))
                {
                    string portname = valpath.InnerPath.Identifier;
                    if (pathInner.Property != null && pathInner.Property.Name.Equals("IsDefinedBy"))
                    {
                        // lookup description of property at port
                        DocObject docPset = null;
                        mapEntity.TryGetValue(pathInner.Identifier, out docPset);

                        if (docPset is DocPropertySet)
                        {
                            DocProperty docProp = ((DocPropertySet)docPset).GetProperty(pathInner.InnerPath.InnerPath.Identifier);
                            if (docProp != null)
                            {
                                desc = portname + ": " + docProp.Documentation;
                            }
                        }
                    }
                    else
                    {
                        desc = portname;

                        // lookup description of port
                        Guid guidPortNesting = new Guid("bafc93b7-d0e2-42d8-84cf-5da20ee1480a");
                        if (docView != null)
                        {
                            foreach (DocConceptRoot docRoot in docView.ConceptRoots)
                            {
                                if (docRoot.ApplicableEntity == valpath.Type)
                                {
                                    foreach (DocTemplateUsage docConcept in docRoot.Concepts)
                                    {
                                        if (docConcept.Definition != null && docConcept.Definition.Uuid == guidPortNesting)
                                        {
                                            foreach (DocTemplateItem docItem in docConcept.Items)
                                            {
                                                if (docItem.Name != null && docItem.Name.Equals(portname))
                                                {
                                                    desc = docItem.Documentation;
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            if (desc == null)
            {
                while (valpath != null && valpath.InnerPath != null && valpath.InnerPath.Property != null)
                {
                    valpath = valpath.InnerPath;
                }
                if (valpath != null && valpath.Property != null)
                {
                    desc = valpath.Property.Documentation;
                }
                else if (valpath != null)
                {
                    desc = "The IFC class identifier indicating the subtype of object.";
                }
            }

            // clear out any notes
            int block = desc.IndexOf("<blockquote");

            if (block != -1)
            {
                desc = desc.Substring(0, block);
            }

            return(desc);
        }
Example #38
0
        public static void Download(DocProject project, BackgroundWorker worker, string baseurl, string username, string password, DocModelView[] docViews)
        {
            string sessionid = Connect(project, worker, baseurl, username, password);

            if (sessionid == null)
            {
                return;
            }

            //foreach (DocModelView docView in docViews)
            string page = null;

            do
            {
                //string url = baseurl + "api/4.0/IfdContext/" + SGuid.Format(docView.Uuid);
                string url = baseurl + "api/4.0/IfdConcept/filter/SUBJECT"; // ifc-2X4
                //string url = baseurl + "api/4.0/IfdConcept/search/filter/language/1ASQw0qJqHuO00025QrE$V/*";//type/SUBJECT/*";
                if (page != null)
                {
                    url += "?page=" + page;
                }

                HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
                request.Accept = "application/json";
                request.Headers.Add("cookie", "peregrineapisessionid=" + sessionid);
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                Stream          stream   = response.GetResponseStream();

                page = response.Headers.Get("Next-Page");
                System.Diagnostics.Debug.WriteLine(page);

                ResponseSearch responseSearch = null;
                try
                {
                    DataContractJsonSerializerSettings settings = new DataContractJsonSerializerSettings();
                    DataContractJsonSerializer         ser      = new DataContractJsonSerializer(typeof(ResponseSearch));
                    responseSearch = (ResponseSearch)ser.ReadObject(stream);
                    if (responseSearch != null)
                    {
                        responseSearch.ToString();

                        foreach (IfdConcept ifdConcept in responseSearch.IfdConcept)
                        {
                            DocModelView docView = new DocModelView();

                            if (ifdConcept.shortNames != null)
                            {
                                foreach (IfdName ifdName in ifdConcept.shortNames)
                                {
                                    DocLocalization docLoc = new DocLocalization();
                                    docLoc.Locale = ifdName.language.languageCode;
                                    docLoc.Name   = ifdName.name;
                                    docView.Localization.Add(docLoc);

                                    if (ifdName.language.languageCode == "en")
                                    {
                                        docView.Name = ifdName.name;
                                    }
                                }
                            }
                            else if (ifdConcept.fullNames != null)
                            {
                                ifdConcept.ToString();
                            }

                            docView.Uuid      = SGuid.Parse(ifdConcept.guid);
                            docView.Version   = ifdConcept.versionId;
                            docView.Copyright = ifdConcept.versionDate;
                            docView.Status    = ifdConcept.status;
                            //docView.Owner = ifdConcept.owner;
                            //docView.Documentation = ifdConcept.comments

                            project.ModelViews.Add(docView);

                            ifdConcept.ToString();
                        }
                        //foreach (IfdDescription ifcDesc in ifdContext.definitions)
                        {
                            // create/update concept root
                            //...
                        }
                    }
                }
                catch (Exception xx)
                {
                    xx.ToString();
                }
            }while (!String.IsNullOrEmpty(page));
        }
Example #39
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 (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);
                }
            }

            // recurse
            foreach (DocTemplateUsage docChild in concept.Concepts)
            {
                CompileConcept(docChild, view, tb);
            }
        }
        private static string FormatConceptTable(
            DocProject docProject,
            DocModelView docModelView,
            DocEntity entity,
            DocConceptRoot root,
            DocTemplateUsage usage,
            Dictionary<string, DocObject> mapEntity,
            Dictionary<string, string> mapSchema)
        {
            StringBuilder sb = new StringBuilder();

            DocTemplateItem[] listItems = FindTemplateItems(docProject, entity, usage.Definition, docModelView);

            if(listItems.Length == 0)
            {
                // scenario for referenced inner templates
                listItems = usage.Items.ToArray();
            }

            // new way with table
            DocModelRule[] parameters = usage.Definition.GetParameterRules();
            if (parameters != null && parameters.Length > 0 && listItems.Length > 0)
            {
                // check if descriptions are provided
                bool showdescriptions = false;
                foreach (DocTemplateItem item in listItems)
                {
                    if (item.Documentation != null)
                    {
                        showdescriptions = true;
                        break;
                    }
                }

                sb.AppendLine("<table class=\"gridtable\">");

                // header
                sb.Append("<tr>");
                foreach (DocModelRule parameter in parameters)
                {
                    sb.Append("<th><b>");
                    sb.Append(parameter.Identification);
                    sb.Append("</b></th>");
                }
                if (showdescriptions)
                {
                    sb.Append("<th><b>Description</b></th>");
                }
                sb.AppendLine("</tr>");

                // items
                foreach (DocTemplateItem item in listItems)
                {
                    sb.Append("<tr>");
                    foreach (DocModelRule parameter in parameters)
                    {
                        string value = item.GetParameterValue(parameter.Identification);
                        string schema = null;

                        if(parameter.Name.Equals("Columns"))
                        {
                            parameter.ToString();
                        }

                        sb.Append("<td>");
                        //if (value != null)
                        {
                            DocDefinition docDef = usage.Definition.GetParameterType(parameter.Identification, mapEntity);
                            if (docDef is DocEnumeration)
                            {
                                if(value != null)
                                {
                                    schema = mapSchema[docDef.Name];

                                    sb.Append("<a href=\"../../");
                                    sb.Append(schema.ToLower());
                                    sb.Append("/lexical/");
                                    sb.Append(docDef.Name.ToLower());
                                    sb.Append(".htm\">");
                                    sb.Append(value);
                                    sb.Append("</a>");
                                }
                            }
                            else if (docDef is DocEntity)
                            {
                                DocTemplateDefinition docTemplateInner = null;
                                if (parameter is DocModelRuleAttribute)
                                {
                                    DocModelRuleAttribute dma = (DocModelRuleAttribute)parameter;
                                    foreach(DocModelRule docInnerRule in dma.Rules)
                                    {
                                        if (docInnerRule is DocModelRuleEntity)
                                        {
                                            DocModelRuleEntity dme = (DocModelRuleEntity)docInnerRule;
                                            if (dme.References.Count == 1)
                                            {
                                                docTemplateInner = dme.References[0];

                                                DocTemplateUsage docConceptInner = item.GetParameterConcept(parameter.Identification, docTemplateInner);
                                                if (docConceptInner != null)
                                                {
                                                    string inner = FormatConceptTable(docProject, docModelView, (DocEntity)docDef, root, docConceptInner, mapEntity, mapSchema);
                                                    sb.Append("<a href=\"../../templates/" + MakeLinkName(docTemplateInner) + ".htm\">" + docTemplateInner.Name + "</a><br/>");
                                                    sb.Append(inner);
                                                }

                                            }
                                        }
                                    }
                                }

                                if (docTemplateInner == null && value != null && mapSchema.TryGetValue(value, out schema))
                                {
                                    if(value.StartsWith("Pset_"))
                                    {
                                        value.ToString();
                                    }

                                    sb.Append("<a href=\"../../");
                                    sb.Append(schema.ToLower());
                                    sb.Append("/lexical/");
                                    sb.Append(value.ToLower());
                                    sb.Append(".htm\">");
                                    sb.Append(value);
                                    sb.Append("</a>");
                                }
                                else if(docDef.Name.Equals("IfcReference"))
                                {
                                    // ...hyperlinks
                                    if(value != null)
                                    {
                                        string[] parts = value.Split('\\');
                                        foreach(string part in parts)
                                        {
                                            string[] tokens = part.Split('.');
                                            if (tokens.Length > 0)
                                            {
                                                sb.Append("\\");

                                                DocDefinition docToken = docProject.GetDefinition(tokens[0]);
                                                if (docToken != null)
                                                {
                                                    DocSchema docSchema = docProject.GetSchemaOfDefinition(docToken);
                                                    string relative = @"../../";
                                                    string hyperlink = relative + docSchema.Name.ToLower() + @"/lexical/" + docToken.Name.ToLower() + ".htm";
                                                    string format = "<a href=\"" + hyperlink + "\">" + tokens[0] + "</a>";
                                                    sb.Append(format);
                                                }

                                                if (tokens.Length > 1)
                                                {
                                                    sb.Append(".");
                                                    sb.Append(tokens[1]);
                                                }

                                                sb.Append("<br>");
                                            }
                                        }
                                    }
                                    //sb.Append(value);                                    
                                }
                                else if(value != null)
                                {
                                    sb.Append(value);
                                }
                            }
                            else if (docDef != null && value != null)
                            {
                                value = FormatField(docProject, value, value, docDef.Name, value);
                                sb.Append(value);
                            }
                            else if (value != null)
                            {
                                sb.Append(value);
                            }
                            else
                            {
                                sb.Append("&nbsp;");
                            }
                        }
                        /*
                        else
                        {
                            sb.Append("&nbsp;");
                        }*/
                        sb.Append("</td>");
                    }

                    if (showdescriptions)
                    {
                        sb.Append("<td>");
                        if (item.Documentation != null)
                        {
                            sb.Append(item.Documentation);
                        }
                        else
                        {
                            sb.Append("&nbsp;");
                        }
                        sb.Append("</td>");
                    }

                    sb.AppendLine("</tr>");
                }

                sb.AppendLine("</table>");
            }
            return sb.ToString();
        }
Example #41
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);
            }
        }
        /// <summary>
        /// Builds list of items in order, using inherited concepts.
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="template"></param>
        /// <param name="view"></param>
        private static DocTemplateItem[] FindTemplateItems(DocProject docProject, DocEntity entity, DocTemplateDefinition template, DocModelView view)
        {
            // inherited concepts first

            List<DocTemplateItem> listItems = new List<DocTemplateItem>();
            DocEntity basetype = entity;
            bool inherit = true;
            while (basetype != null)
            {
                // find templates for base
                foreach (DocModelView docView in docProject.ModelViews)
                {
                    if (view == docView || view.BaseView == docView.Name)
                    {
                        foreach (DocConceptRoot docRoot in docView.ConceptRoots)
                        {
                            if (docRoot.ApplicableEntity == basetype)
                            {
                                foreach (DocTemplateUsage eachusage in docRoot.Concepts)
                                {
                                    if (eachusage.Definition == template)
                                    {
                                        // found it

                                        string[] parameters = template.GetParameterNames();

                                        foreach (DocTemplateItem eachitem in eachusage.Items)
                                        {
                                            string[] values = new string[parameters.Length];
                                            for (int iparam = 0; iparam < parameters.Length; iparam++)
                                            {
                                                values[iparam] = eachitem.GetParameterValue(parameters[iparam]);
                                            }

                                            // new (IfcDoc 4.9d): only add if we don't override by parameters matching exactly
                                            bool include = true;
                                            foreach (DocTemplateItem existitem in listItems)
                                            {
                                                bool samevalues = true;

                                                for (int iparam = 0; iparam < parameters.Length; iparam++)
                                                {
                                                    string value = values[iparam];
                                                    string match = existitem.GetParameterValue(parameters[iparam]);
                                                    if (match != value || (match != null && !match.Equals(value, StringComparison.Ordinal)))
                                                    {
                                                        samevalues = false;
                                                        break;
                                                    }
                                                }

                                                if (samevalues)
                                                {
                                                    include = false;
                                                    break;
                                                }
                                            }

                                            if (include)
                                            {
                                                listItems.Add(eachitem);
                                            }
                                        }

                                        inherit = !eachusage.Override;
                                    }
                                }
                            }
                        }
                    }
                }

                // inherit concepts from supertypes unless overriding
                if (basetype.BaseDefinition != null && inherit)
                {
                    basetype = docProject.GetDefinition(basetype.BaseDefinition) as DocEntity;
                }
                else
                {
                    basetype = null;
                }
            }

            return listItems.ToArray();
        }
Example #43
0
 public CheckGridConcept(DocTemplateDefinition docTemplate, DocModelView docView, DocProject docProject)
 {
     this.m_template = docTemplate;
     this.m_view     = docView;
     this.m_project  = docProject;
 }
        public static void GenerateDocumentation(
            DocProject docProject, 
            string path,
            Dictionary<long, SEntity> instances,
            Dictionary<string, DocObject> mapEntity, 
            Dictionary<string, string> mapSchema, 
            DocModelView[] views,
            string[] locales,
            BackgroundWorker worker, 
            FormProgress formProgress)
        {
            // copy over static content * if it doesn't already exist *
            string pathContent = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
            if (pathContent.EndsWith(@"bin\x86\Debug")) // debugging
            {
                pathContent = System.IO.Path.GetDirectoryName(pathContent);
                pathContent = System.IO.Path.GetDirectoryName(pathContent);
                pathContent = System.IO.Path.GetDirectoryName(pathContent);
            }
            pathContent = System.IO.Path.Combine(pathContent, "content");

            if(!System.IO.Directory.Exists(path))
            {
                System.IO.Directory.CreateDirectory(path);
            }

            CopyFiles(pathContent, path);

            System.IO.Directory.CreateDirectory(Properties.Settings.Default.OutputPath + "\\diagrams");

            Dictionary<string, DocPropertyEnumeration> mapPropEnum = new Dictionary<string, DocPropertyEnumeration>();
            foreach (DocSection docSection in docProject.Sections)
            {
                foreach (DocSchema docSchema in docSection.Schemas)
                {
                    foreach (DocPropertyEnumeration docEnum in docSchema.PropertyEnums)
                    {
                        mapPropEnum.Add(docEnum.Name, docEnum);
                    }
                }
            }

            Dictionary<DocObject, string> mapNumber = new Dictionary<DocObject, string>(); // map items to section (e.g. "1.1.1.1")

            string pathSchema = path + @"\schema";

            // count progress
            int progressTotal = docProject.Sections.Count + docProject.Annexes.Count + 2;
            formProgress.SetProgressTotal(progressTotal);

            int progressCurrent = 0;


            // build list of locales in use
            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);
                            }
                        }
                    }
                }
            }

            // build filter
            Dictionary<DocObject, bool> included = null;
            if (views != null)
            {
                included = new Dictionary<DocObject, bool>();
                foreach (DocModelView docEachView in views)
                {
                    docProject.RegisterObjectsInScope(docEachView, included);
                }
            }

            Dictionary<DocObject, bool>[] dictionaryViews = new Dictionary<DocObject, bool>[docProject.ModelViews.Count];
            for (int i = 0; i < docProject.ModelViews.Count; i++)
            {
                DocModelView docView = docProject.ModelViews[i];
                if (included != null && included.ContainsKey(docView))
                {
                    dictionaryViews[i] = new Dictionary<DocObject, bool>();
                    docProject.RegisterObjectsInScope(docProject.ModelViews[i], dictionaryViews[i]);
                }
            }


            DocEntity docEntityRoot = docProject.GetDefinition("IfcRoot") as DocEntity;

            // upper contents page
            string pathHeaderFrame = path + "\\content.htm";
            using (FormatHTM htmProp = new FormatHTM(pathHeaderFrame, mapEntity, mapSchema, included))
            {
                DocAnnotation docCover = docProject.Annotations[0];
                string projectname = docCover.Code;
                if (!String.IsNullOrEmpty(docCover.Version))
                {
                    projectname += " - " + docCover.Version;
                }
                if (!String.IsNullOrEmpty(docCover.Status))
                {
                    projectname += " [" + docCover.Status + "]";
                }
                string projectcopy = docCover.Copyright;

                htmProp.Write(
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n" + 
"<html lang=\"en\">" + 
  "<head>" +
    "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=us-ascii\">" +
    "<link rel=\"STYLESHEET\" href=\"./ifc-styles.css\" type=\"text/css\">" +
  "</head>" +
  "<body class=\"image\">" +
    "<div class=\"content\">" +
      "<table summary=\"title\" class=\"content\" frameborder=\"0\">" +
        "<tr>" +
          "<td>" +
            "<p class=\"td\">" +
              "<b>" + projectname + "</b>" +
            "</p>" +
          "</td>" +
          "<td>" +
            "<p class=\"td right\">" +
              "<b>" + projectcopy + "</b>" +
            "</p>" +
          "</td>" +
        "</tr>" +
      "</table>" +
      "<table summary=\"short table of content\" class=\"content\">" +
        "<col width=\"15%\">" +
        "<col width=\"25%\">" +
        "<col width=\"20%\">" +
        "<col width=\"25%\">" +
        "<col width=\"15%\">" +
        "<tr>" +
          "<td class=\"content\">" +
            "<ol class=\"td none\">" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"cover.htm\" target=\"info\">" + docProject.Annotations[0].Name + "</a></li>" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"toc.htm\" target=\"info\">" + docProject.Annotations[1].Name + "</a></li>" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"foreword.htm\" target=\"info\">" + docProject.Annotations[2].Name + "</a></li>" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"introduction.htm\" target=\"info\">" + docProject.Annotations[3].Name + "</a></li>" +
            "</ol>" +
          "</td>" +
          "<td class=\"content\">" +
            "<ol class=\"td num\">" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"schema/chapter-1.htm\" target=\"info\">" + docProject.Sections[0].Name + "</a></li>" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"schema/chapter-2.htm\" target=\"info\">" + docProject.Sections[1].Name + "</a></li>" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"schema/chapter-3.htm\" target=\"info\">" + docProject.Sections[2].Name + "</a></li>" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"schema/chapter-4.htm\" target=\"info\">" + docProject.Sections[3].Name + "</a></li>" +
            "</ol>" +
          "</td>" +
          "<td class=\"content\">" +
            "<ol class=\"td num\" start=\"5\">" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"schema/chapter-5.htm\" target=\"info\">" + docProject.Sections[4].Name + "</a></li>" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"schema/chapter-6.htm\" target=\"info\">" + docProject.Sections[5].Name + "</a></li>" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"schema/chapter-7.htm\" target=\"info\">" + docProject.Sections[6].Name + "</a></li>" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"schema/chapter-8.htm\" target=\"info\">" + docProject.Sections[7].Name + "</a></li>" +
            "</ol>" +
          "</td>" +
          "<td class=\"content\">" +
            "<ol class=\"td alpha\">" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"annex/annex-a.htm\" target=\"info\">" + docProject.Annexes[0].Name + "</a></li>" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"annex/annex-b.htm\" target=\"info\">" + docProject.Annexes[1].Name + "</a></li>" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"annex/annex-c.htm\" target=\"info\">" + docProject.Annexes[2].Name + "</a></li>" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"annex/annex-d.htm\" target=\"info\">" + docProject.Annexes[3].Name + "</a></li>" +
            "</ol>" +
          "</td>" +
          "<td class=\"content\">" +
            "<ol class=\"td alpha\" start=\"5\">" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"annex/annex-e.htm\" target=\"info\">" + docProject.Annexes[4].Name + "</a></li>" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"annex/annex-f.htm\" target=\"info\">" + docProject.Annexes[5].Name + "</a></li>" +
            "</ol>" +
            "<ol class=\"td none\">" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"bibliography.htm\" target=\"info\">Bibliography</a></li>" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"doc_index.htm\" target=\"info\">Index</a></li>" +
            "</ol>" +
          "</td>" +
        "</tr>" +
      "</table>" +
    "</div>" +
  "</body>" +
"</html>");
            }

            // cover

            using (FormatHTM htmSection = new FormatHTM(path + "\\cover.htm", mapEntity, mapSchema, included))
            {
                DocAnnotation docAnnotation = docProject.Annotations[0];
                htmSection.WriteHeader(docAnnotation.Name, 0);
                htmSection.Write(
                    "\r\n" +
                    "<script type=\"text/javascript\">\r\n" +
                    "<!--\r\n" +
                    "    parent.index.location.replace(\"credits.htm\");\r\n" +
                    "//-->\r\n" +
                    "</script>\r\n");
                htmSection.WriteLine(docAnnotation.Documentation);
                htmSection.WriteFooter(Properties.Settings.Default.Footer);
            }

            using (FormatHTM htmSection = new FormatHTM(path + "\\foreword.htm", mapEntity, mapSchema, included))
            {
                DocAnnotation docAnnotation = docProject.Annotations[2];
                htmSection.WriteHeader(docAnnotation.Name, 0);
                htmSection.Write(
                    "\r\n" +
                    "<script type=\"text/javascript\">\r\n" +
                    "<!--\r\n" +
                    "    parent.index.location.replace(\"blank.htm\");\r\n" +
                    "//-->\r\n" +
                    "</script>\r\n");

                htmSection.WriteLine("      <h1 class=\"std\">" + docAnnotation.Name + "</h1>");
                htmSection.WriteLine(docAnnotation.Documentation);
                htmSection.WriteLinkTo("foreword", 0);
                htmSection.WriteFooter(Properties.Settings.Default.Footer);
            }

            using (FormatHTM htmSection = new FormatHTM(path + "\\introduction.htm", mapEntity, mapSchema, included))
            {
                DocAnnotation docAnnotation = docProject.Annotations[3];
                htmSection.WriteHeader(docAnnotation.Name, 0);
                htmSection.Write(
                    "\r\n" +
                    "<script type=\"text/javascript\">\r\n" +
                    "<!--\r\n" +
                    "    parent.index.location.replace(\"blank.htm\");\r\n" +
                    "//-->\r\n" +
                    "</script>\r\n");

                htmSection.WriteLine("      <h1 class=\"std\">" + docAnnotation.Name + "</h1>");
                htmSection.WriteLine(docAnnotation.Documentation);
                htmSection.WriteLinkTo("introduction", 0);
                htmSection.WriteFooter(Properties.Settings.Default.Footer);
            }

#if false
            Dictionary<Rectangle, DocEntity> mapRectangle = new Dictionary<Rectangle, DocEntity>();
            using (Image imgDiagram = FormatPNG.CreateInheritanceDiagram(docProject, included, docEntityRoot, new Font(FontFamily.GenericSansSerif, 8.0f), mapRectangle))
            {
                imgDiagram.Save(path + @"\img\cover.png");
                    
                using (FormatHTM htmCover = new FormatHTM(path + @"\cover.htm", mapEntity, mapSchema, included))
                {
                    htmCover.WriteHeader(String.Empty, 1);

                    htmCover.WriteLine("<img src=\"" + path + "/img/cover.png\" usemap=\"#f\"/>");
                    htmCover.WriteLine("<map name=\"f\">");

                    foreach (Rectangle rc in mapRectangle.Keys)
                    {
                        DocEntity docEntref = mapRectangle[rc];
                        DocSchema docEntsch = docProject.GetSchemaOfDefinition(docEntref);

                        string hyperlink = "./schema/" + docEntsch.Name.ToLower() + "/lexical/" + docEntref.Name.ToLower() + ".htm";
                        htmCover.WriteLine("<area shape=\"rect\" coords=\"" + rc.Left + "," + rc.Top + "," + rc.Right + "," + rc.Bottom + "\" href=\"" + hyperlink + "\" alt=\"" + docEntref.Name + "\" />");
                    }
                    htmCover.WriteLine("</map>");


                    htmCover.WriteFooter(String.Empty);
                }
            }
#endif

            // NEW: property set index -- build index
            SortedList<string, SortedList<string, DocPropertySet>> mapProperty = new SortedList<string, SortedList<string, DocPropertySet>>();
            foreach (DocSection docSection in docProject.Sections)
            {
                foreach (DocSchema docSchema in docSection.Schemas)
                {
                    foreach (DocPropertySet docPset in docSchema.PropertySets)
                    {
                        if (included == null || included.ContainsKey(docPset))
                        {
                            // include locales
                            foreach (DocLocalization doclocal in docPset.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);
                                    }
                                }
                            }


                            foreach (DocProperty docProp in docPset.Properties)
                            {
                                string datatype = docProp.PrimaryDataType;
                                if (datatype == null)
                                {
                                    datatype = "IfcLabel"; // enumerations
                                }

                                string match = docProp.Name + " (" + docProp.PropertyType.ToString() + "/" + datatype.ToString() + ")";

                                SortedList<string, DocPropertySet> mapPset = null;
                                if (!mapProperty.TryGetValue(match, out mapPset))
                                {
                                    mapPset = new SortedList<string, DocPropertySet>();
                                    mapProperty.Add(match, mapPset);
                                }

                                mapPset.Add(docPset.Name, docPset);


                                // include locales
                                foreach (DocLocalization doclocal in docProp.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);
                                        }
                                    }
                                }

                            }
                        }
                    }
                }
            }

            // now format listing of properties
            StringBuilder sbProperties = new StringBuilder();
            foreach (string nameProp in mapProperty.Keys)
            {
                sbProperties.Append("<li>");
                sbProperties.Append(nameProp);

                sbProperties.Append("<ul>");
                SortedList<string, DocPropertySet> mapPset = mapProperty[nameProp];

                foreach (DocPropertySet pset in mapPset.Values)
                {
                    string proplinkurl = "../../schema/" + mapSchema[pset.Name].ToLower() + "/pset/" + pset.Name.ToLower() + ".htm";

                    sbProperties.Append("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
                    sbProperties.Append("<a class=\"listing-link\" href=\"");
                    sbProperties.Append(proplinkurl);
                    sbProperties.Append("\">");
                    sbProperties.Append(pset.Name);
                    sbProperties.Append("</a><br/>");
                }

                sbProperties.Append("</ul></li>");
            }
            string pathProps = path + @"/annex/annex-b/alphabeticalorder_properties.htm";
            using (FormatHTM htmProp = new FormatHTM(pathProps, mapEntity, mapSchema, included))
            {
                htmProp.WriteHeader("Properties", 2);

                htmProp.WriteLine("<h2 class=\"annex\">Individual Properties (" + mapProperty.Count + ")</h2>");
                htmProp.WriteLine("<ul class=\"std\">");

                htmProp.WriteLine(sbProperties.ToString());

                htmProp.WriteLine("</ul>");

                htmProp.WriteFooter(Properties.Settings.Default.Footer);
            }

            // capture figures and tables
            List<ContentRef> listFigures = new List<ContentRef>();
            List<ContentRef> listTables = new List<ContentRef>();

            // NEW: section 4 templates
            int iTemplate = 0;
            foreach (DocTemplateDefinition docTemplate in docProject.Templates)
            {
                if (included == null || included.ContainsKey(docTemplate))
                {
                    iTemplate++;
                    int[] indexpath = new int[] { 4, iTemplate };
                    GenerateTemplate(docProject, docTemplate, mapEntity, mapSchema, included, indexpath, listFigures, listTables);
                }
            }

            // NEW: model view definitions
            int iView = 0;
            if (Properties.Settings.Default.ConceptTables)
            {
                foreach (DocModelView docProjectModelView in docProject.ModelViews)
                {
                    if (included == null || included.ContainsKey(docProjectModelView))
                    {
                        iView++;
                        string pathTemplate = pathSchema + @"\views\" + docProjectModelView.Name.Replace(' ', '-').ToLower() + "\\index.htm";
                        using (FormatHTM htmTemplate = new FormatHTM(pathTemplate, mapEntity, mapSchema, included))
                        {
                            htmTemplate.WriteHeader(docProjectModelView.Name, 1, iView, 0, 0, Properties.Settings.Default.Header);
                            htmTemplate.WriteScript(1, iView, 0, 0);
                            {
                                string indexer = "1." + iView.ToString();
                                string tag = "h3";
                                string id = docProjectModelView.Name.ToLower();
                                htmTemplate.WriteLine("<" + tag + "><a id=\"" + id + "\" name=\"" + id + "\">" + indexer + " " + docProjectModelView.Name + "</a></" + tag + ">");

                                // write table of status for MVD
                                htmTemplate.WriteLine("<table class=\"gridtable\">");
                                htmTemplate.WriteLine("<tr><th>Code</th><th>Version</th><th>Status</th><th>Author</th><th>Copyright</th></tr>");
                                htmTemplate.WriteLine("<tr><td>" + docProjectModelView.Code + "</td><td>" + docProjectModelView.Version + "</td><td>" + docProjectModelView.Status + "</td><td>" + docProjectModelView.Author + "</td><td>" + docProjectModelView.Copyright + "</td></tr>");
                                htmTemplate.WriteLine("</table>");

                                string viewtable = FormatView(docProject, docProjectModelView, mapEntity, mapSchema);
                                htmTemplate.WriteDocumentationForISO(viewtable, docProjectModelView, false);
                            }

                            htmTemplate.WriteFooter(Properties.Settings.Default.Footer);
                        }
                        // each exchange... (or sub-page?)

                        if (Properties.Settings.Default.Requirement)
                        {
                            for (int iExchange = 0; iExchange < docProjectModelView.Exchanges.Count; iExchange++)
                            {
                                DocExchangeDefinition docExchange = docProjectModelView.Exchanges[iExchange];

                                string pathExchange = pathSchema + @"\views\" + MakeLinkName(docProjectModelView) + "\\" + MakeLinkName(docExchange) + ".htm";
                                using (FormatHTM htmExchange = new FormatHTM(pathExchange, mapEntity, mapSchema, included))
                                {
                                    htmExchange.WriteHeader(docExchange.Name, 1, iView, 0, 0, Properties.Settings.Default.Header);
                                    htmExchange.WriteScript(1, iView, iExchange + 1, 0);

                                    string indexer = "1." + iView.ToString() + "." + (iExchange + 1).ToString();
                                    string tag = "h4";
                                    string id = docExchange.Name.ToLower();

                                    htmExchange.WriteLine("<" + tag + "><a id=\"" + id + "\" name=\"" + id + "\">" + indexer + " " + docExchange.Name + "</a></" + tag + ">");
                                    htmExchange.WriteLine("<p class=\"std\">");

                                    string exchangedoc = FormatExchange(docProject, docProjectModelView, docExchange, mapEntity, mapSchema);
                                    htmExchange.WriteDocumentationForISO(exchangedoc, docExchange, false);
                                    htmExchange.WriteLine("</p>");
                                }

                                // icons for each exchange
                                if (docExchange.Icon != null)
                                {
                                    string pathIcon = path + @"\img\mvd-" + MakeLinkName(docExchange) + ".png";

                                    try
                                    {
                                        using (System.IO.FileStream fs = new System.IO.FileStream(pathIcon, System.IO.FileMode.Create))
                                        {
                                            fs.Write(docExchange.Icon, 0, docExchange.Icon.Length);
                                            fs.Close();
                                        }
                                    }
                                    catch
                                    {
                                    }
                                }
                            }
                        }
                    }
                }
            }

            string pathTOC = path + @"\toc.htm";
            using (FormatHTM htmTOC = new FormatHTM(pathTOC, mapEntity, mapSchema, included))
            {
                htmTOC.WriteHeader("Contents", 0);

                htmTOC.WriteLine("    <script type=\"text/javascript\">");
                htmTOC.WriteLine("        <!--");
                htmTOC.WriteLine("        parent.index.location = \"blank.htm\";");
                htmTOC.WriteLine("        parent.menu.location = \"content.htm\"");
                htmTOC.WriteLine("        -->");
                htmTOC.WriteLine("    </script>");

                htmTOC.WriteLine("      <h1 class=\"std\">Contents</h1>");

                htmTOC.WriteLine("<p>");

                // each section
                int iSection = 0;
                foreach (DocSection section in docProject.Sections)
                {
                    worker.ReportProgress(++progressCurrent, section);
                    if (worker.CancellationPending)
                        return;

                    iSection++;
                    using (FormatHTM htmSectionTOC = new FormatHTM(pathSchema + @"\toc-" + iSection.ToString() + ".htm", mapEntity, mapSchema, included))
                    {

                        htmSectionTOC.WriteLine(
                            "<html> \r\n" +
                            "<head> \r\n" +
                            "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"> \r\n" +
                            "<link rel=\"stylesheet\" type=\"text/css\" href=\"../ifc-styles.css\"> \r\n" +
                            "<title>Section Contents</title> \r\n" +
                            "</head> \r\n" +
                            "<body class=\"image\"> \r\n" +
                            "<div class=\"menu\">\r\n" +
                            "<table class=\"menu\" summary=\"Table of Contents\">\r\n");

                        htmTOC.WriteTOC(0, "<a class=\"listing-link\" href=\"schema/chapter-" + iSection.ToString() + ".htm\">" + iSection.ToString() + ". " + section.Name + "</a>");

                        mapNumber.Add(section, iSection.ToString() + ".");

                        htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">" + iSection + ". <a class=\"listing-link\" href=\"chapter-" + iSection + ".htm\" target=\"info\" >" + section.Name + "</a></td></tr>\r\n");

                        // write the section page
                        using (FormatHTM htmSection = new FormatHTM(pathSchema + @"\chapter-" + iSection.ToString() + @".htm", mapEntity, mapSchema, included))
                        {
                            htmSection.WriteHeader(section.Name, iSection - 1, 0, 0, 0, Properties.Settings.Default.Header);
                            htmSection.WriteScript(iSection, 0, 0, 0);
                            htmSection.WriteLine("<h1 class=\"num\" id=\"scope\">" + section.Name + "</h1>");

                            section.Documentation = UpdateNumbering(section.Documentation, listFigures, listTables, section);
                            htmSection.WriteDocumentationForISO(section.Documentation, section, Properties.Settings.Default.NoHistory);


                            if (iSection == 1)
                            {
                                if (Properties.Settings.Default.ConceptTables)
                                {
                                    int iModel = 0;
                                    foreach (DocModelView docModelView in docProject.ModelViews)
                                    {
                                        if (included == null || included.ContainsKey(docModelView))
                                        {
                                            iModel++;

                                            string htmllink = "<a class=\"listing-link\" href=\"views/" + MakeLinkName(docModelView) + "/index.htm\" target=\"info\">" +
                                                iSection.ToString() + "." + iModel.ToString() + " " + docModelView.Name + "</a>";
                                            htmTOC.WriteTOC(1, "<a class=\"listing-link\" href=\"schema/views/" + MakeLinkName(docModelView) + "/index.htm\" >" +
                                                iSection.ToString() + "." + iModel.ToString() + " " + docModelView.Name + "</a>");
                                            htmSectionTOC.WriteLine("<tr><td>&nbsp;</td></tr>");
                                            htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">" + htmllink + "</td></tr>");

                                            if (Properties.Settings.Default.Requirement)
                                            {
                                                int iExchange = 0;
                                                foreach (DocExchangeDefinition docExchange in docModelView.Exchanges)
                                                {
                                                    iExchange++;

                                                    htmllink = "<a class=\"listing-link\" href=\"views/" + MakeLinkName(docModelView) + "/" + MakeLinkName(docExchange) + ".htm\" target=\"info\">" +
                                                        iSection.ToString() + "." + iModel.ToString() + "." + iExchange.ToString() + " " + docExchange.Name + "</a>";

                                                    htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"schema/views/" + MakeLinkName(docModelView) + "/" + MakeLinkName(docExchange) + ".htm\" >" +
                                                        iSection.ToString() + "." + iModel.ToString() + "." + iExchange.ToString() + " " + docExchange.Name + "</a>");
                                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">" + htmllink + "</td></tr>");
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            else if (iSection == 2)
                            {
                                htmSection.WriteLine("<dl>");
                                if (docProject.NormativeReferences != null)
                                {
                                    foreach (DocReference docRef in docProject.NormativeReferences)
                                    {
                                        htmSection.WriteLine("<dt class=\"normativereference\"><a id=\"" + MakeLinkName(docRef) + "\">" + docRef.Name + "</a>, <i>" + docRef.Documentation + "</i></dt>");
                                        htmSection.WriteLine("<dd>&nbsp;</dd>");
                                    }
                                }
                                htmSection.WriteLine("</dl>");
                            }
                            else if (iSection == 3)
                            {
                                htmTOC.WriteTOC(0, "<a class=\"listing-link\" href=\"schema/chapter-3.htm#terms\">3.1 Terms and definitions</a>");
                                htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">3.1 <a class=\"listing-link\" href=\"chapter-3.htm#terms\" target=\"info\" >Terms and definitions</a></td></tr>\r\n");

                                htmTOC.WriteTOC(0, "<a class=\"listing-link\" href=\"schema/chapter-3.htm#abbreviated\">3.2 Abbreviated terms</a>");
                                htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">3.2 <a class=\"listing-link\" href=\"chapter-3.htm#abbreviated\" target=\"info\" >Abbreviated terms</a></td></tr>\r\n");

                                htmSection.WriteLine("<a id=\"terms\"/>");
                                htmSection.WriteLine("<h2>3.1 Terms and definitions</h2>");
                                htmSection.WriteLine("<dl>");
                                if (docProject.Terms != null)
                                {
                                    foreach(DocTerm docTerm in docProject.Terms)
                                    {
                                        htmSection.WriteTerm(docTerm);
                                    }
                                }
                                htmSection.WriteLine("</dl>");
                                htmSection.WriteLine("<a id=\"abbreviated\"/>");
                                htmSection.WriteLine("<h2>3.2 Abbreviated terms</h2>");
                                htmSection.WriteLine("<table class=\"abbreviatedterms\">");
                                if (docProject.Abbreviations != null)
                                {
                                    SortedList<string, DocAbbreviation> sl = new SortedList<string, DocAbbreviation>();
                                    foreach (DocAbbreviation docRef in docProject.Abbreviations)
                                    {
                                        sl.Add(docRef.Name, docRef);
                                    }

                                    foreach (string s in sl.Keys)
                                    {
                                        DocAbbreviation docRef = sl[s];
                                        htmSection.WriteLine("<tr><td class=\"abbreviatedterm\" id=\"" + MakeLinkName(docRef) + "\">" + docRef.Name + "</td>");
                                        htmSection.WriteLine("<td class=\"abbrebiatedterm\">" + docRef.Documentation + "</td></tr>");
                                    }
                                }
                                htmSection.WriteLine("</table>");
                            }
                            else if (iSection == 4)
                            {
                                FormatHTM.WriteTOCforTemplates(docProject.Templates, 1, iSection.ToString(), htmTOC, htmSectionTOC, included);

                                htmSection.WriteLine("<table class=\"gridtable\">");
                                htmSection.WriteLine("<tr><th>Template</th>");

                                for (int i = 0; i < docProject.ModelViews.Count; i++)
                                {
                                    DocModelView docView = docProject.ModelViews[i];
                                    if (included != null && included.ContainsKey(docView))
                                    {
                                        htmSection.WriteLine("<th>" + docProject.ModelViews[i].Name + "</th>");
                                    }
                                }

                                htmSection.WriteLine("</tr>");

                                foreach (DocTemplateDefinition docTemplateDefinition in docProject.Templates)
                                {
                                    htmSection.WriteTemplateTable(docProject, docTemplateDefinition, 0, dictionaryViews);
                                }
                                htmSection.WriteLine("</table>");


                            }

                            htmSection.WriteLine("<p>");

                            int iListSchema = 0;
                            foreach (DocSchema schema in section.Schemas)
                            {
                                if (included == null || included.ContainsKey(schema))
                                {
                                    iListSchema++;
                                    htmSection.WriteLine("<a class=\"listing-link\" href=\"" + schema.Name.ToLower() + "/content.htm\">" + iSection.ToString() + "." + iListSchema.ToString() + " " + schema.Name + "</a><br>");
                                }
                            }
                            htmSection.WriteLine("</p>");

                            htmSection.WriteLinkTo("chapter-" + iSection, 1);

                            htmSection.WriteFooter(Properties.Settings.Default.Footer);
                        }

                        // each schema
                        int iSchema = 0;
                        foreach (DocSchema schema in section.Schemas)
                        {
                            if (worker.CancellationPending)
                                return;

                            if (included == null || included.ContainsKey(schema))
                            {
                                iSchema++;

                                // ensure directory exists
                                System.IO.Directory.CreateDirectory(pathSchema + @"\" + schema.Name.ToLower() + @"\lexical\");

                                // create schema document
                                using (FormatHTM htmSchema = new FormatHTM(pathSchema + @"\" + schema.Name.ToLower() + @"\content.htm", mapEntity, mapSchema, included))
                                {
                                    {
                                        mapNumber.Add(schema, iSection.ToString() + "." + iSchema.ToString());

                                        htmTOC.WriteTOC(1, "<a class=\"listing-link\" href=\"schema/" + schema.Name.ToLower() + "/content.htm\">" + iSection.ToString() + "." + iSchema.ToString() + " " + schema.Name + "</a>");

                                        // extra line between each schema
                                        htmSectionTOC.WriteLine("<tr><td>&nbsp;</td></tr>");
                                        htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\"><a id=\"" + iSection.ToString() + "." + iSchema.ToString() + "\">" + iSection.ToString() + "." + iSchema.ToString() + "</a> <a class=\"listing-link\" href=\"" + schema.Name.ToLower() + "/content.htm\" target=\"info\">" + schema.Name + "</a></td></tr>\r\n");

                                        htmSchema.WriteHeader(schema.Name, iSection, iSchema, 0, 0, Properties.Settings.Default.Header);

                                        htmSchema.WriteScript(iSection, iSchema, 0, 0);

                                        htmSchema.WriteLine("<h2 class=\"std\">" + iSection.ToString() + "." + iSchema.ToString() + " " + schema.Name + "</h2>");

                                        int iSubSection = 1; // first subsection for schema semantic definition
                                        htmTOC.WriteTOC(2, iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + " Schema Definition");
                                        htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">" + iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + " Schema Definition</td></tr>\r\n");
                                        htmSchema.WriteLine("<h3 class=\"std\">" + iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + " Schema Definition</h3>");

                                        schema.Documentation = UpdateNumbering(schema.Documentation, listFigures, listTables, schema);
                                        htmSchema.WriteDocumentationForISO(schema.Documentation, schema, Properties.Settings.Default.NoHistory);

                                        // each type
                                        if (schema.Types.Count > 0)
                                        {
                                            iSubSection++;

                                            htmTOC.WriteTOC(2, iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + " Types");
                                            htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">" + iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + " Types</td></tr>\r\n");
                                            int iType = 0;
                                            foreach (DocType type in schema.Types)
                                            {
                                                if (worker.CancellationPending)
                                                    return;

                                                if (type.Name.Equals("IfcNullStyle", StringComparison.OrdinalIgnoreCase) && schema.Name.Equals("IfcConstructionMgmtDomain", StringComparison.OrdinalIgnoreCase))
                                                {
                                                    // bug -- exclude
                                                }
                                                else if (included == null || included.ContainsKey(type))
                                                {
                                                    iType++;

                                                    string formatnum = iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + "." + iType.ToString();
                                                    mapNumber.Add(type, formatnum);

                                                    htmTOC.WriteTOC(3, "<a class=\"listing-link\" href=\"schema/" + mapSchema[type.Name].ToLower() + "/lexical/" + type.Name.ToLower() + ".htm\">" + formatnum.ToString() + " " + type.Name + "</a>");
                                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\"><a id=\"" + formatnum + "\">" + iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + "." + iType.ToString() + "</a> <a class=\"listing-link\" href=\"" + mapSchema[type.Name].ToLower() + "/lexical/" + type.Name.ToLower() + ".htm\" target=\"info\">" + type.Name + "</a><td></tr>\r\n");


                                                    using (FormatHTM htmDef = new FormatHTM(pathSchema + @"\" + schema.Name.ToLower() + "\\lexical\\" + type.Name.ToLower() + ".htm", mapEntity, mapSchema, included))
                                                    {
                                                        htmDef.WriteHeader(type.Name, iSection, iSchema, iSubSection, iType, Properties.Settings.Default.Header);

                                                        htmDef.WriteScript(iSection, iSchema, iSubSection, iType);

                                                        htmDef.WriteLine("<h4 class=\"num\">" + type.Name + "</h4>");
                                                        htmDef.WriteLocalizedNames(type);
                                                        htmDef.WriteChangeLog(type, docProject);

                                                        htmDef.WriteLine("<section>");
                                                        htmDef.WriteLine("<h5 class=\"num\">Semantic definitions at the type</h5>");

                                                        if (type.Documentation != null)
                                                        {
                                                            type.Documentation = UpdateNumbering(type.Documentation, listFigures, listTables, type);
                                                        }

                                                        htmDef.WriteSummaryHeader("Type definition", true);
                                                        htmDef.WriteDocumentationForISO(type.Documentation, type, Properties.Settings.Default.NoHistory);
                                                        htmDef.WriteSummaryFooter();

                                                        if(type is DocEnumeration)
                                                        {
                                                            DocEnumeration docEnumeration = (DocEnumeration)type;

                                                            htmDef.WriteSummaryHeader("Enumeration definition", true);
                                                            htmDef.WriteLine("<table class=\"attributes\">");
                                                            htmDef.WriteLine("<tr><th>Constant</th><th>Description</th></tr>");
                                                            foreach (DocConstant docConstant in docEnumeration.Constants)
                                                            {
                                                                htmDef.Write("<tr><td>");
                                                                htmDef.Write(docConstant.Name);
                                                                htmDef.Write("</td><td>");
                                                                htmDef.Write(docConstant.Documentation);
                                                                htmDef.Write("</td></tr>");
                                                            }
                                                            htmDef.WriteLine("</table>");
                                                            htmDef.WriteSummaryFooter();
                                                        }
                                                        else if (type is DocSelect)
                                                        {
                                                            DocSelect docSelect = (DocSelect)type;

                                                            htmDef.WriteSummaryHeader("Select definition", true);
                                                            htmDef.WriteLine("<table class=\"attributes\">");
                                                            htmDef.WriteLine("<tr><th>Type</th><th>Description</th></tr>");
                                                            foreach (DocSelectItem docSelectItem in docSelect.Selects)
                                                            {
                                                                DocObject docRef = null;
                                                                if (mapEntity.TryGetValue(docSelectItem.Name, out docRef))
                                                                {
                                                                    if (included == null || included.ContainsKey(docRef))
                                                                    {
                                                                        htmDef.Write("<tr><td>");
                                                                        htmDef.WriteDefinition(docSelectItem.Name);
                                                                        //htmDef.Write(docSelectItem.Name);
                                                                        htmDef.Write("</td><td>");
                                                                        htmDef.Write(docSelectItem.Documentation);
                                                                        htmDef.Write("</td></tr>");
                                                                    }
                                                                }
                                                            }
                                                            htmDef.WriteLine("</table>");
                                                            htmDef.WriteSummaryFooter();
                                                        }

                                                        htmDef.WriteLine("</section>");


                                                        // where rules (for defined types)

                                                        if (type is DocDefined && ((DocDefined)type).WhereRules != null && ((DocDefined)type).WhereRules.Count > 0)
                                                        {
                                                            DocDefined entity = (DocDefined)type;

                                                            // formal propositions
                                                            htmDef.WriteSummaryHeader("Formal Propositions", true);

                                                            htmDef.WriteLine("<table class=\"propositions\">");
                                                            htmDef.WriteLine("<tr><th>Rule</th><th>Description</th></tr>");
                                                            foreach (DocWhereRule docAttr in entity.WhereRules)
                                                            {
                                                                htmDef.Write("<tr><td>");
                                                                htmDef.Write(docAttr.Name);
                                                                htmDef.Write("</td><td>");
                                                                if (docAttr.Documentation != null)
                                                                {
                                                                    htmDef.WriteDocumentationForISO(docAttr.Documentation, entity, Properties.Settings.Default.NoHistory);
                                                                }
                                                                htmDef.WriteLine("</td></tr>");
                                                            }
                                                            htmDef.WriteLine("</table>\r\n");

                                                            htmDef.WriteSummaryFooter();
                                                        }



                                                        htmDef.WriteLine("<section>");
                                                        htmDef.WriteLine("<h5 class=\"num\">Formal representations</h5>");

                                                        if (!Properties.Settings.Default.NoXsd)
                                                        {
                                                            htmDef.WriteSummaryHeader("XSD Specification", false);
                                                            htmDef.Write("<div class=\"xsd\"><code class=\"xsd\">");
                                                            if (type is DocSelect)
                                                            {
                                                                htmDef.WriteFormatted(FormatXSD.FormatSelect((DocSelect)type, mapEntity, included));
                                                            }
                                                            else if (type is DocEnumeration)
                                                            {
                                                                htmDef.WriteFormatted(FormatXSD.FormatEnum((DocEnumeration)type));
                                                            }
                                                            else if (type is DocDefined)
                                                            {
                                                                htmDef.WriteFormatted(FormatXSD.FormatDefined((DocDefined)type, mapEntity));
                                                            }
                                                            htmDef.Write("</code></div>");
                                                            htmDef.WriteSummaryFooter();
                                                        }

                                                        htmDef.WriteExpressTypeAndDocumentation(type, Properties.Settings.Default.NoHistory, Properties.Settings.Default.ExpressComments);

                                                        htmDef.WriteLine("</section>");

                                                        // write url for incoming page link
                                                        htmDef.WriteLinkTo(type);

                                                        htmDef.WriteFooter(Properties.Settings.Default.Footer);
                                                    }
                                                }
                                            }

                                        }

                                        // each entity
                                        if (schema.Entities.Count > 0)
                                        {
                                            iSubSection++;

                                            htmTOC.WriteTOC(2, iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + " Entities");
                                            htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">" + iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + " Entities</td></tr>\r\n");
                                            int iEntity = 0;
                                            foreach (DocEntity entity in schema.Entities)
                                            {
                                                if (worker.CancellationPending)
                                                    return;

                                                if (included == null || included.ContainsKey(entity))
                                                {
                                                    iEntity++;

                                                    string formatnum = iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + "." + iEntity.ToString();
                                                    mapNumber.Add(entity, formatnum);

                                                    htmTOC.WriteTOC(3, "<a class=\"listing-link\" href=\"schema/" + mapSchema[entity.Name].ToLower() + "/lexical/" + entity.Name.ToLower() + ".htm\">" + formatnum + " " + entity.Name + "</a>");
                                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\"><a id=\"" + formatnum + "\">" + iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + "." + iEntity.ToString() + "</a> <a class=\"listing-link\" href=\"" + mapSchema[entity.Name].ToLower() + "/lexical/" + entity.Name.ToLower() + ".htm\" target=\"info\">" + entity.Name + "</a></td></tr>\r\n");

                                                    using (FormatHTM htmDef = new FormatHTM(pathSchema + @"\" + schema.Name.ToLower() + "\\lexical\\" + entity.Name.ToLower() + ".htm", mapEntity, mapSchema, included))
                                                    {
                                                        htmDef.WriteHeader(entity.Name, iSection, iSchema, iSubSection, iEntity, Properties.Settings.Default.Header);
                                                        htmDef.WriteScript(iSection, iSchema, iSubSection, iEntity);

                                                        htmDef.WriteLine("<h4 class=\"num\">" + entity.Name + "</h4>");
                                                        htmDef.WriteLocalizedNames(entity);
                                                        htmDef.WriteChangeLog(entity, docProject);
                                                        htmDef.WriteLine("<section>");
                                                        htmDef.WriteLine("<h5 class=\"num\">Semantic definitions at the entity</h5>");

                                                        string entitydocumentation = FormatEntityDescription(docProject, entity, listFigures, listTables);

                                                        htmDef.WriteSummaryHeader("Entity definition", true);
                                                        htmDef.WriteDocumentationForISO(entitydocumentation, entity, Properties.Settings.Default.NoHistory);
                                                        htmDef.WriteSummaryFooter();

                                                        if (entity.Attributes != null && entity.Attributes.Count > 0)
                                                        {
                                                            htmDef.WriteSummaryHeader("Attribute definitions", true);

                                                            htmDef.WriteLine("<table class=\"attributes\">");
                                                            htmDef.WriteLine("<tr><th>#</th><th>Attribute</th><th>Type</th><th>Cardinality</th><th>Description</th>");

                                                            if (views != null)
                                                            {
                                                                foreach (DocModelView docViewHeader in views)
                                                                {
                                                                    htmDef.Write("<th>");
                                                                    htmDef.Write(docViewHeader.Name.Substring(0, 1));
                                                                    htmDef.Write("</th>");
                                                                }
                                                            }
                                                            htmDef.WriteLine("</tr>");

                                                            int sequence = 0;

                                                            // count direct attributes of base classes
                                                            DocEntity docEntBase = entity;
                                                            DocObject docBase = null;
                                                            while(!String.IsNullOrEmpty(docEntBase.BaseDefinition) && mapEntity.TryGetValue(docEntBase.BaseDefinition, out docBase))
                                                            {
                                                                docEntBase = (DocEntity)docBase;
                                                                foreach(DocAttribute docAttrBase in docEntBase.Attributes)
                                                                {
                                                                    if (docAttrBase.Inverse == null && docAttrBase.Derived == null)
                                                                    {
                                                                        sequence++;
                                                                    }
                                                                }
                                                            }

                                                            htmDef.WriteEntityAttributes(entity, entity, views, dictionaryViews, ref sequence);

                                                            htmDef.WriteLine("</table>");

                                                            htmDef.WriteSummaryFooter();
                                                        }

                                                        if (entity.WhereRules != null && entity.WhereRules.Count > 0)
                                                        {
                                                            // avoid attributes without descriptions
                                                            int cDescs = 0;
                                                            foreach (DocWhereRule docAttr in entity.WhereRules)
                                                            {
                                                                if (docAttr.Documentation != null)
                                                                {
                                                                    cDescs++;
                                                                }
                                                            }

                                                            if (cDescs > 0)
                                                            {
                                                                // formal propositions
                                                                htmDef.WriteSummaryHeader("Formal Propositions", true);

                                                                htmDef.WriteLine("<table class=\"propositions\">");
                                                                htmDef.WriteLine("<tr><th>Rule</th><th>Description</th></tr>");
                                                                foreach (DocWhereRule docAttr in entity.WhereRules)
                                                                {
                                                                    htmDef.Write("<tr><td>");
                                                                    htmDef.Write(docAttr.Name);
                                                                    htmDef.Write("</td><td>");
                                                                    if (docAttr.Documentation != null)
                                                                    {
                                                                        htmDef.WriteDocumentationForISO(docAttr.Documentation, entity, Properties.Settings.Default.NoHistory);
                                                                    }
                                                                    htmDef.WriteLine("</td></tr>");
                                                                }
                                                                htmDef.WriteLine("</table>\r\n");

                                                                htmDef.WriteSummaryFooter();
                                                            }
                                                        }
                                                        
                                                        htmDef.WriteLine("</section>");

                                                        htmDef.WriteLine("<section>");
                                                        htmDef.WriteLine("<h5 class=\"num\">Inherited definitions from supertypes</h5>");

                                                        Dictionary<Rectangle, DocEntity> map = new Dictionary<Rectangle, DocEntity>();
                                                        using (Font font = new Font(FontFamily.GenericSansSerif, 8.0f))
                                                        {
                                                            using (Image img = FormatPNG.CreateInheritanceDiagramForEntity(docProject, included, entity, font, map))
                                                            {
                                                                img.Save(path + "\\diagrams\\" + entity.Name.ToLower() + ".png", System.Drawing.Imaging.ImageFormat.Png);
                                                            }
                                                        }

                                                        htmDef.WriteSummaryHeader("Entity inheritance", true);
                                                        htmDef.WriteLine("<img src=\"../../../diagrams/" + entity.Name.ToLower() + ".png\" usemap=\"#f\"/>");

                                                        htmDef.WriteLine("<map name=\"f\">");
                                                        foreach (Rectangle rc in map.Keys)
                                                        {
                                                            DocEntity docEntref = map[rc];
                                                            DocSchema docEntsch = docProject.GetSchemaOfDefinition(docEntref);

                                                            string hyperlink = "../../../schema/" + docEntsch.Name.ToLower() + "/lexical/" + docEntref.Name.ToLower() + ".htm";
                                                            htmDef.WriteLine("<area shape=\"rect\" coords=\"" + rc.Left + "," + rc.Top + "," + rc.Right + "," + rc.Bottom + "\" href=\"" + hyperlink + "\" alt=\"" + docEntref.Name + "\" />");
                                                        }
                                                        htmDef.WriteLine("</map>");
                                                        
                                                        htmDef.WriteSummaryFooter();

                                                        htmDef.WriteSummaryHeader("Attribute inheritance", false);

                                                        htmDef.WriteLine("<table class=\"attributes\">");
                                                        htmDef.Write("<tr><th>#</th><th>Attribute</th><th>Type</th><th>Cardinality</th><th>Description</th>");
                                                        if(views != null)
                                                        {
                                                            foreach(DocModelView docViewHeader in views)
                                                            {
                                                                htmDef.Write("<th>");
                                                                htmDef.Write(docViewHeader.Name.Substring(0, 1));
                                                                htmDef.Write("</th>");
                                                            }
                                                        }
                                                        htmDef.WriteLine("</tr>");

                                                        int sequenceX = 0;
                                                        htmDef.WriteEntityInheritance(entity, entity, views, dictionaryViews, ref sequenceX);

                                                        htmDef.WriteLine("</table>");

                                                        htmDef.WriteSummaryFooter();

                                                        //htmDef.WriteEntityInheritance(entity);

                                                        string conceptdocumentation = FormatEntityConcepts(docProject, entity, mapEntity, mapSchema, included, listFigures, listTables);
                                                        htmDef.WriteDocumentationForISO(conceptdocumentation, entity, Properties.Settings.Default.NoHistory);

                                                        if (docProject.Examples != null)
                                                        {
                                                            List<DocExample> listExample = new List<DocExample>();
                                                            foreach (DocExample docExample in docProject.Examples)
                                                            {
                                                                BuildExampleList(listExample, docExample, entity, included);
                                                            }
                                                            if (listExample.Count > 0)
                                                            {
                                                                htmDef.WriteLine("<section>");
                                                                htmDef.WriteLine("<h5 class=\"num\">Examples</h5>");
                                                                //htmDef.WriteSummaryHeader("Examples", true);
                                                                htmDef.WriteLine("<ul>");
                                                                foreach (DocExample docExample in listExample)
                                                                {
                                                                    if (docExample.Name != null)
                                                                    {
                                                                        htmDef.Write("<li><a href=\"../../../annex/annex-e/");
                                                                        htmDef.Write(docExample.Name.Replace(' ', '-').ToLower());
                                                                        htmDef.Write(".htm\">");
                                                                        htmDef.Write(docExample.Name);
                                                                        htmDef.Write("</a></li>");
                                                                        htmDef.WriteLine("");
                                                                    }
                                                                }
                                                                htmDef.WriteLine("</ul>");
                                                                //htmDef.WriteSummaryFooter();
                                                                htmDef.WriteLine("</section>");
                                                            }
                                                        }

                                                        htmDef.WriteLine("<section>");
                                                        htmDef.WriteLine("<h5 class=\"num\">Formal representations</h5>");

                                                        if (!Properties.Settings.Default.NoXsd)
                                                        {
                                                            htmDef.WriteSummaryHeader("XSD Specification", false);
                                                            htmDef.Write("<div class=\"xsd\"><code class=\"xsd\">");
                                                            htmDef.WriteFormatted(FormatXSD.FormatEntity(entity, mapEntity, included));
                                                            htmDef.Write("</code></div>");
                                                            htmDef.WriteSummaryFooter();
                                                        }

                                                        htmDef.WriteExpressEntityAndDocumentation(entity, Properties.Settings.Default.NoHistory, Properties.Settings.Default.ExpressComments);

                                                        htmDef.WriteLine("</section>");

                                                        // write url for incoming page link
                                                        htmDef.WriteLinkTo(entity);

                                                        htmDef.WriteFooter(Properties.Settings.Default.Footer);
                                                    }
                                                }
                                            }
                                        }

                                        // functions
                                        if (schema.Functions.Count > 0)
                                        {
                                            iSubSection++;

                                            htmTOC.WriteTOC(2, iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + " Functions");
                                            htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">" + iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + " Functions</td></tr>\r\n");
                                            int iEntity = 0;
                                            foreach (DocFunction entity in schema.Functions)
                                            {
                                                if (included == null || included.ContainsKey(entity))
                                                {
                                                    iEntity++;

                                                    string formatnum = iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + "." + iEntity.ToString();
                                                    mapNumber.Add(entity, formatnum);

                                                    htmTOC.WriteTOC(3, "<a class=\"listing-link\" href=\"schema/" + mapSchema[entity.Name].ToLower() + "/lexical/" + entity.Name.ToLower() + ".htm\">" + formatnum + " " + entity.Name + "</a>");
                                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\"><a id=\"" + formatnum + "\">" + iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + "." + iEntity.ToString() + "</a> <a class=\"listing-link\" href=\"" + mapSchema[entity.Name].ToLower() + "/lexical/" + entity.Name.ToLower() + ".htm\" target=\"info\">" + entity.Name + "</a></td></tr>\r\n");

                                                    using (FormatHTM htmDef = new FormatHTM(pathSchema + @"\" + schema.Name.ToLower() + "\\lexical\\" + entity.Name.ToLower() + ".htm", mapEntity, mapSchema, included))
                                                    {
                                                        htmDef.WriteHeader(entity.Name, iSection, iSchema, iSubSection, iEntity, Properties.Settings.Default.Header);
                                                        htmDef.WriteScript(iSection, iSchema, iSubSection, iEntity);

                                                        htmDef.WriteLine("<h4 class=\"num\">" + entity.Name + "</h4>");

                                                        htmDef.WriteLine("<section>");
                                                        htmDef.WriteLine("<h5 class=\"num\">Semantic definitions at the function</h5>");

                                                        htmDef.WriteSummaryHeader("Function Definition", true);
                                                        htmDef.WriteLine("<p>");
                                                        htmDef.WriteDocumentationForISO(entity.Documentation, entity, Properties.Settings.Default.NoHistory);
                                                        htmDef.WriteLine("</p>");
                                                        htmDef.WriteSummaryFooter();

                                                        htmDef.WriteLine("</section>");

                                                        htmDef.WriteLine("<section>");
                                                        htmDef.WriteLine("<h5 class=\"num\">Formal representations</h5>");

                                                        htmDef.WriteSummaryHeader("EXPRESS Specification", true);
                                                        htmDef.WriteLine("<span class=\"express\">\r\n");
                                                        htmDef.WriteExpressFunction(entity);
                                                        htmDef.WriteLine("</span>\r\n");
                                                        htmDef.WriteSummaryFooter();

                                                        htmDef.WriteLine("</section>");

                                                        // write url for incoming page link
                                                        htmDef.WriteLinkTo(entity);

                                                        htmDef.WriteFooter(Properties.Settings.Default.Footer);
                                                    }
                                                }
                                            }
                                        }

                                        // rules
                                        if (schema.GlobalRules.Count > 0)
                                        {
                                            iSubSection++;

                                            htmTOC.WriteTOC(2, iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + " Rules");
                                            htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">" + iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + " Rules</td></tr>\r\n");
                                            int iEntity = 0;
                                            foreach (DocGlobalRule entity in schema.GlobalRules)
                                            {
                                                if (included == null || included.ContainsKey(entity))
                                                {
                                                    iEntity++;

                                                    string formatnum = iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + "." + iEntity.ToString();
                                                    mapNumber.Add(entity, formatnum);

                                                    htmTOC.WriteTOC(3, "<a class=\"listing-link\" href=\"schema/" + mapSchema[entity.Name].ToLower() + "/lexical/" + entity.Name.ToLower() + ".htm\">" + formatnum + " " + entity.Name + "</a>");
                                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\"><a id=\"" + formatnum + "\">" + iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + "." + iEntity.ToString() + "</a> <a href=\"" + mapSchema[entity.Name].ToLower() + "/lexical/" + entity.Name.ToLower() + ".htm\" target=\"info\">" + entity.Name + "</a></td></tr>\r\n");

                                                    using (FormatHTM htmDef = new FormatHTM(pathSchema + @"\" + schema.Name.ToLower() + "\\lexical\\" + entity.Name.ToLower() + ".htm", mapEntity, mapSchema, included))
                                                    {
                                                        htmDef.WriteHeader(entity.Name, iSection, iSchema, iSubSection, iEntity, Properties.Settings.Default.Header);
                                                        htmDef.WriteScript(iSection, iSchema, iSubSection, iEntity);

                                                        htmDef.WriteLine("<h4 class=\"num\">" + entity.Name + "</h4>");

                                                        htmDef.WriteLine("<section>");
                                                        htmDef.WriteLine("<h5 class=\"num\">Semantic definitions at the global rule</h5>");

                                                        htmDef.WriteSummaryHeader("Global Rule Definition", true);
                                                        htmDef.WriteLine("<p>");
                                                        htmDef.WriteDocumentationForISO(entity.Documentation, entity, Properties.Settings.Default.NoHistory);
                                                        htmDef.WriteLine("</p>");
                                                        htmDef.WriteSummaryFooter();

                                                        htmDef.WriteLine("</section>");

                                                        htmDef.WriteLine("<section>");
                                                        htmDef.WriteLine("<h5 class=\"num\">Formal representations</h5>");

                                                        htmDef.WriteSummaryHeader("EXPRESS Specification", true);
                                                        htmDef.WriteLine("<span class=\"express\">\r\n");
                                                        htmDef.WriteExpressGlobalRule(entity);
                                                        htmDef.WriteLine("</span>\r\n");
                                                        htmDef.WriteSummaryFooter();

                                                        htmDef.WriteLine("</section>");

                                                        // write url for incoming page link
                                                        htmDef.WriteLinkTo(entity);

                                                        htmDef.WriteFooter(Properties.Settings.Default.Footer);
                                                    }
                                                }
                                            }
                                        }

                                        // property sets
                                        if (schema.PropertySets.Count > 0 || schema.PropertyEnums.Count > 0)
                                        {
                                            iSubSection++;

                                            htmTOC.WriteTOC(2, iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + " Property Sets");
                                            htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">" + iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + " Property Sets</td></tr>\r\n");
                                            int iPset = 0;
                                            foreach (DocPropertySet entity in schema.PropertySets)
                                            {
                                                if (worker.CancellationPending)
                                                    return;

                                                if (included == null || included.ContainsKey(entity))
                                                {
                                                    iPset++;

                                                    string formatnum = iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + "." + iPset.ToString();
                                                    mapNumber.Add(entity, formatnum);

                                                    htmTOC.WriteTOC(3, "<a class=\"listing-link\" href=\"schema/" + mapSchema[entity.Name].ToLower() + "/pset/" + entity.Name.ToLower() + ".htm\">" + formatnum + " " + entity.Name + "</a>");
                                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\"><a id=\"" + formatnum + "\">" + formatnum + "</a> <a class=\"listing-link\" href=\"" + mapSchema[entity.Name].ToLower() + "/pset/" + entity.Name.ToLower() + ".htm\" target=\"info\">" + entity.Name + "</a></td></tr>\r\n");

                                                    using (FormatHTM htmDef = new FormatHTM(pathSchema + @"\" + schema.Name.ToLower() + "\\pset\\" + entity.Name.ToLower() + ".htm", mapEntity, mapSchema, included))
                                                    {
                                                        htmDef.WriteHeader(entity.Name, iSection, iSchema, iSubSection, iPset, Properties.Settings.Default.Header);
                                                        htmDef.WriteScript(iSection, iSchema, iSubSection, iPset);
                                                        htmDef.WriteLine("<h4 class=\"std\">" + iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + "." + iPset.ToString() + " " + entity.Name + "</h4>");

                                                        if (!String.IsNullOrEmpty(entity.ApplicableType))
                                                        {
                                                            htmDef.Write("<p>");
                                                            htmDef.WriteDefinition(entity.PropertySetType);
                                                            htmDef.WriteLine("/");

                                                            if (entity.ApplicableType != null && entity.ApplicableType.Contains("/"))
                                                            {
                                                                // break out, e.g. "IfcSensor/TEMPERATURESENSOR"
                                                                string[] applicableparts = entity.ApplicableType.Split('/');
                                                                for (int iapppart = 0; iapppart < applicableparts.Length; iapppart++)
                                                                {
                                                                    if (iapppart > 0)
                                                                    {
                                                                        htmDef.Write(" / ");
                                                                    }
                                                                    htmDef.WriteDefinition(applicableparts[iapppart]);
                                                                }
                                                            }
                                                            else
                                                            {
                                                                htmDef.WriteDefinition(entity.ApplicableType);
                                                            }
                                                            htmDef.Write("</p>");
                                                        }

                                                        // english by default
                                                        htmDef.WriteLine("<table>");

                                                        entity.Localization.Sort(); // ensure sorted
                                                        foreach (DocLocalization doclocal in entity.Localization)
                                                        {
                                                            string localname = doclocal.Name;
                                                            string localdesc = doclocal.Documentation;

                                                            string localid = doclocal.Locale.Substring(0, 2).ToLower();

                                                            if (localid.Equals("en", StringComparison.InvariantCultureIgnoreCase) && localdesc == null)
                                                            {
                                                                localdesc = entity.Documentation;
                                                            }

                                                            htmDef.WriteLine("<tr><td><img src=\"../../../img/locale-" + localid + ".png\" /></td><td><b> " + localname + ":</b> " + localdesc + "</td></tr>");
                                                        }

                                                        htmDef.WriteLine("</table>");

                                                        if (!Properties.Settings.Default.NoXml)
                                                        {
                                                            ////htmDef.WriteLine("<p><a href=\"http://lookup.bsdd.buildingsmart.com/api/4.0/IfdPSet/search/" + entity.Name + "\" target=\"ifd\"><img src=\"../../../img/external.png\" title=\"Link to IFD\"/> buildingSMART Data Dictionary</a></p>\r\n");
                                                            //http://lookup.bsdd.buildingsmart.com/api/4.0/IfdPSet/search/Pset_ActionRequest

                                                            // use guid
                                                            string guid = IfcGloballyUniqueId.Format(entity.Uuid);
                                                            htmDef.WriteLine("<p><a href=\"http://lookup.bsdd.buildingsmart.com/api/4.0/IfdPSet/" + guid + "/ifcVersion/2x4\" target=\"ifd\"><img border=\"0\" src=\"../../../img/external.png\" title=\"Link to IFD\"/> buildingSMART Data Dictionary</a></p>\r\n");

                                                            htmDef.WriteLine("<p><a href=\"../../../psd/" + entity.Name + ".xml\"><img border=\"0\" src=\"../../../img/diagram.png\" title=\"Link to PSD-XML\"/> PSD-XML</a></p>\r\n");
                                                        }

                                                        // write diagram if it exists
                                                        htmDef.WriteLine(FormatFigure(docProject, entity, null, entity.Name, listFigures));
                                                        htmDef.WriteProperties(entity.Properties);

                                                        // write url for incoming page link
                                                        htmDef.WriteLinkTo(entity);

                                                        htmDef.WriteFooter(Properties.Settings.Default.Footer);
                                                    }

                                                    // generate PSD listing
                                                    using (FormatXML formatPSD = new FormatXML(path + @"\psd\" + entity.Name + ".xml", typeof(PropertySetDef)))//, PropertySetDef.DefaultNamespace)) // full casing for compatibility with original files
                                                    {
                                                        formatPSD.Instance = Program.ExportPsd(entity, mapPropEnum);
                                                        formatPSD.Save();
                                                    }
                                                }
                                            }

                                            foreach (DocPropertyEnumeration entity in schema.PropertyEnums)
                                            {
                                                if (worker.CancellationPending)
                                                    return;

                                                if (included == null || included.ContainsKey(entity))
                                                {
                                                    iPset++;

                                                    string formatnum = iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + "." + iPset.ToString();
                                                    mapNumber.Add(entity, formatnum);

                                                    htmTOC.WriteTOC(3, "<a class=\"listing-link\" href=\"schema/" + mapSchema[entity.Name].ToLower() + "/pset/" + entity.Name.ToLower() + ".htm\">" + formatnum + " " + entity.Name + "</a>");
                                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\"><a id=\"" + formatnum + "\">" + formatnum + "</a> <a class=\"listing-link\" href=\"" + mapSchema[entity.Name].ToLower() + "/pset/" + entity.Name.ToLower() + ".htm\" target=\"info\">" + entity.Name + "</a></td></tr>\r\n");

                                                    using (FormatHTM htmDef = new FormatHTM(pathSchema + @"\" + schema.Name.ToLower() + "\\pset\\" + entity.Name.ToLower() + ".htm", mapEntity, mapSchema, included))
                                                    {
                                                        htmDef.WriteHeader(entity.Name, iSection, iSchema, iSubSection, iPset, Properties.Settings.Default.Header);
                                                        htmDef.WriteScript(iSection, iSchema, iSubSection, iPset);
                                                        htmDef.WriteLine("<h4 class=\"std\">" + iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + "." + iPset.ToString() + " " + entity.Name + "</h4>");

                                                        // english by default
                                                        htmDef.WriteLine("<table>");

                                                        entity.Localization.Sort(); // ensure sorted
                                                        foreach (DocLocalization doclocal in entity.Localization)
                                                        {
                                                            if (doclocal.Locale != null && doclocal.Locale.Length > 2)
                                                            {
                                                                string localname = doclocal.Name;
                                                                string localdesc = doclocal.Documentation;

                                                                string localid = doclocal.Locale.Substring(0, 2).ToLower();

                                                                if (localid.Equals("en", StringComparison.InvariantCultureIgnoreCase) && localdesc == null)
                                                                {
                                                                    localdesc = entity.Documentation;
                                                                }

                                                                htmDef.WriteLine("<tr><td><img src=\"../../../img/locale-" + localid + ".png\" /></td><td><b> " + localname + ":</b> " + localdesc + "</td></tr>");
                                                            }
                                                        }

                                                        htmDef.WriteLine("</table>");

                                                        htmDef.WriteLine("<table class=\"gridtable\">");
                                                        htmDef.WriteLine("<tr><th>Name</th><th>Description</th></tr>");

                                                        bool showdefaultdesc = true;

                                                        foreach (DocPropertyConstant docprop in entity.Constants)
                                                        {
                                                            htmDef.WriteLine("<tr><td>" + docprop.Name + "</td><td>");

                                                            if (docprop.Localization.Count > 0)
                                                            {
                                                                htmDef.WriteLine("<table class=\"gridtable\">");
                                                                docprop.Localization.Sort();
                                                                foreach (DocLocalization doclocal in docprop.Localization)
                                                                {
                                                                    string localname = doclocal.Name;
                                                                    string localdesc = doclocal.Documentation;

                                                                    string localid = doclocal.Locale.Substring(0, 2).ToLower();

                                                                    if (localid.Equals("en", StringComparison.InvariantCultureIgnoreCase) && localdesc == null)
                                                                    {
                                                                        localdesc = docprop.Documentation;
                                                                        showdefaultdesc = false;
                                                                    }

                                                                    htmDef.WriteLine("<tr><td><img src=\"../../../img/locale-" + localid + ".png\" /></td><td><b>" + localname + "</b></td><td>" + localdesc + "</td></tr>");
                                                                }
                                                                htmDef.WriteLine("</table>");
                                                            }

                                                            if(showdefaultdesc)
                                                            {
                                                                htmDef.WriteLine(docprop.Documentation);
                                                            }

                                                            htmDef.WriteLine("</td></tr>");
                                                        }

                                                        htmDef.WriteLine("</table>");

                                                        // write url for incoming page link
                                                        htmDef.WriteLinkTo(entity);

                                                        htmDef.WriteFooter(Properties.Settings.Default.Footer);
                                                    }
                                                }
                                            }

                                        }


                                        // quantity sets (assume properties always exist for such schemas so always section 4)
                                        if (schema.QuantitySets.Count > 0)
                                        {
                                            iSubSection++;

                                            htmTOC.WriteTOC(2, iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + " Quantity Sets");
                                            htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">" + iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + " Quantity Sets</td></tr>\r\n");
                                            int iPset = 0;
                                            foreach (DocQuantitySet entity in schema.QuantitySets)
                                            {
                                                if (worker.CancellationPending)
                                                    return;

                                                if (included == null || included.ContainsKey(entity))
                                                {
                                                    iPset++;

                                                    string formatnum = iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + "." + iPset.ToString();
                                                    mapNumber.Add(entity, formatnum);

                                                    htmTOC.WriteTOC(3, "<a class=\"listing-link\" href=\"schema/" + mapSchema[entity.Name].ToLower() + "/qset/" + entity.Name.ToLower() + ".htm\">" + formatnum + " " + entity.Name + "</a>");
                                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\"><a id=\"" + formatnum + "\">" + formatnum + "</a> <a class=\"listing-link\" href=\"" + mapSchema[entity.Name].ToLower() + "/qset/" + entity.Name.ToLower() + ".htm\" target=\"info\">" + entity.Name + "</a></td></tr>\r\n");

                                                    using (FormatHTM htmDef = new FormatHTM(pathSchema + @"\" + schema.Name.ToLower() + "\\qset\\" + entity.Name.ToLower() + ".htm", mapEntity, mapSchema, included))
                                                    {
                                                        htmDef.WriteHeader(entity.Name, iSection, iSchema, iSubSection, iPset, Properties.Settings.Default.Header);
                                                        htmDef.WriteScript(iSection, iSchema, iSubSection, iPset);
                                                        htmDef.WriteLine("<h4 class=\"std\">" + iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + "." + iPset.ToString() + " " + entity.Name + "</h4>");

                                                        if (!String.IsNullOrEmpty(entity.ApplicableType))
                                                        {
                                                            htmDef.Write("<p>");

                                                            htmDef.WriteDefinition("QTO_TYPEDRIVENOVERRIDE");
                                                            htmDef.WriteLine("/");
                                                            htmDef.WriteDefinition(entity.ApplicableType);
                                                            htmDef.Write("</p>");
                                                        }

                                                        // english by default
                                                        htmDef.WriteLine("<table>");
                                                        entity.Localization.Sort(); // ensure sorted
                                                        foreach (DocLocalization doclocal in entity.Localization)
                                                        {
                                                            string localname = doclocal.Name;
                                                            string localdesc = doclocal.Documentation;
                                                            string localid = doclocal.Locale.Substring(0, 2).ToLower();

                                                            if (localid.Equals("en", StringComparison.InvariantCultureIgnoreCase) && localdesc == null)
                                                            {
                                                                localdesc = entity.Documentation;
                                                            }

                                                            htmDef.WriteLine("<tr valign=\"top\"><td><img src=\"../../../img/locale-" + localid + ".png\" title=\"Link to XML\"/></td><td><b>" + localname + "</b>: " + localdesc + "</td></tr>");
                                                        }

                                                        htmDef.WriteLine("</table>");

                                                        if (!Properties.Settings.Default.NoXml)
                                                        {
                                                            htmDef.WriteLine("<p><a href=\"../../../qto/" + entity.Name + ".xml\"><img border=\"0\" src=\"../../../img/diagram.png\" title=\"Link to QTO-XML\"/> QTO-XML</a></p>\r\n");
                                                        }

                                                        // write each quantity
                                                        htmDef.WriteLine("<table class=\"gridtable\">");
                                                        htmDef.WriteLine("<tr><th>Name</th><th>Type</th><th>Description</th>");
                                                        foreach (DocQuantity docprop in entity.Quantities)
                                                        {
                                                            htmDef.WriteLine("<tr><td>" + docprop.Name + "</td><td>");
                                                            htmDef.WriteDefinition(docprop.QuantityType.ToString());
                                                            htmDef.WriteLine("</td><td>");

                                                            bool showdefaultdesc = false;
                                                            if(docprop.Localization.Count > 0)
                                                            {
                                                                htmDef.WriteLine("<table class=\"gridtable\">");

                                                                docprop.Localization.Sort();
                                                                foreach (DocLocalization doclocal in docprop.Localization)
                                                                {
                                                                    string localname = doclocal.Name;
                                                                    string localdesc = doclocal.Documentation;

                                                                    string localid = doclocal.Locale.Substring(0, 2).ToLower();

                                                                    if (String.IsNullOrEmpty(localdesc) && localid.Equals("en", StringComparison.InvariantCultureIgnoreCase) && localdesc == null)
                                                                    {
                                                                        localdesc = docprop.Documentation;
                                                                        showdefaultdesc = false;
                                                                    }

                                                                    htmDef.WriteLine("<tr><td><img src=\"../../../img/locale-" + localid + ".png\" /></td><td><b>" + localname + "</b></td><td>" + localdesc + "</td></tr>");
                                                                }
                                                                htmDef.WriteLine("</table>");
                                                            }
                                                            if(showdefaultdesc)
                                                            {
                                                                htmDef.WriteLine(docprop.Documentation);
                                                            }

                                                            htmDef.WriteLine("</td></tr>");
                                                        }
                                                        htmDef.WriteLine("</table>");

                                                        // write url for incoming page link
                                                        htmDef.WriteLinkTo(entity);

                                                        htmDef.WriteFooter(Properties.Settings.Default.Footer);
                                                    }

                                                    // generate PSD listing
                                                    using (FormatXML formatPSD = new FormatXML(path + @"\qto\" + entity.Name + ".xml", typeof(QtoSetDef), QtoSetDef.DefaultNamespace)) // full casing for compatibility with original files
                                                    {
                                                        formatPSD.Instance = Program.ExportQto(entity);
                                                        formatPSD.Save();
                                                    }

                                                }
                                            }
                                        }
                                    }

                                    // v1.8: write links to express-g                                
                                    htmSchema.WriteLine(
                                    "<p><a href=\"../../annex/annex-d/" + MakeLinkName(schema) + "/index.htm\" ><img src=\"../../img/diagram.png\" style=\"border: 0px\" title=\"Link to EXPRESS-G diagram\" alt=\"Link to EXPRESS-G diagram\">&nbsp;EXPRESS-G diagram</a></p>");

                                    // link to this page
                                    htmSchema.WriteLinkTo(schema);

                                    htmSchema.WriteFooter(Properties.Settings.Default.Footer);
                                }
                            }
                        }

                        htmSectionTOC.WriteLine(
                            "</table>\r\n" +
                            "</div>\r\n" +
                            "</body>\r\n" +
                            "</html>\r\n");
                    }
                }

                int iAnnex = 0;
                char chAnnex = 'A';
                foreach (DocAnnex docannex in docProject.Annexes)
                {
                    worker.ReportProgress(++progressCurrent, docannex);

                    iAnnex--;
                    htmTOC.WriteTOC(0, "<a class=\"listing-link\" href=\"annex/annex-" + chAnnex.ToString().ToLower() + ".htm\">Annex " + chAnnex.ToString() + ". " + docannex.Name + "</a>");

                    // write the section page
                    using (FormatHTM htmSection = new FormatHTM(path + @"\annex\annex-" + chAnnex.ToString().ToLower() + @".htm", mapEntity, mapSchema, included))
                    {
                        htmSection.WriteHeader(docannex.Name, iAnnex, 0, 0, 0, Properties.Settings.Default.Header);
                        htmSection.WriteScript(iAnnex, 0, 0, 0);
                        htmSection.WriteLine("<h1 class=\"annex\">Annex " + chAnnex.ToString() + "</h1>");
                        if (chAnnex == 'A')
                        {
                            htmSection.WriteLine("<div align=\"center\">(normative)</div>");
                        }
                        else
                        {
                            htmSection.WriteLine("<div align=\"center\">(informative)</div>");
                        }
                        htmSection.WriteLine("<h1 class=\"annex\">" + docannex.Name + "</h1>");

                        // no numbering for annex currently... docannex.Documentation = UpdateNumbering(section.Documentation, ref iFigure, ref iTable);
                        htmSection.WriteDocumentationForISO(docannex.Documentation, docannex, Properties.Settings.Default.NoHistory);

                        // write listing of schemas
                        if (chAnnex == 'A')
                        {
                            // create page for model view
                            //htmSection.WriteComputerListing("IFC4", "ifc4", 0);

                            /*
                            DoExport(docProject, path + @"\annex\annex-a\default\ifc4.exp", null, null, instances, true);
                            DoExport(docProject, path + @"\annex\annex-a\default\ifcXML4.xsd", null, null, instances, true);
                            DoExport(docProject, path + @"\annex\annex-a\default\ifc4.ifc", null, null, instances, true);
                            DoExport(docProject, path + @"\annex\annex-a\default\ifc4.ifcxml", null, null, instances, true);

                            using (FormatHTM htmExpress = new FormatHTM(path + @"\annex\annex-a\default\ifc4.exp.htm", mapEntity, mapSchema, included))
                            {
                                htmExpress.UseAnchors = true;
                                htmExpress.WriteHeader("EXPRESS", 3);
                                htmExpress.WriteExpressSchema(docProject);
                                htmExpress.WriteFooter("");
                            }

                            using (FormatHTM htmXSD = new FormatHTM(path + @"\annex\annex-a\default\ifcXML4.xsd.htm", mapEntity, mapSchema, included))
                            {
                                string xsdcontent = null;
                                using (System.IO.StreamReader reader = new System.IO.StreamReader(path + @"\annex\annex-a\default\ifcXML4.xsd.txt"))
                                {
                                    xsdcontent = reader.ReadToEnd();
                                }

                                htmXSD.UseAnchors = false;
                                htmXSD.WriteHeader("XSD", 3);
                                htmXSD.Write("<span class=\"express\">");
                                htmXSD.WriteFormatted(xsdcontent);
                                htmXSD.Write("</span>");
                                htmXSD.WriteFooter("");
                            }
                             */
                        }
                        else if(chAnnex == 'C')
                        {
                            htmSection.WriteInheritanceMapping(docProject, views);
                        }

                        htmSection.WriteLinkTo("annex-" + chAnnex.ToString().ToLower(), 1);
                        htmSection.WriteFooter(Properties.Settings.Default.Footer);
                    }

                    using (FormatHTM htmSectionTOC = new FormatHTM(path + @"\annex\toc-" + chAnnex.ToString().ToLower() + ".htm", mapEntity, mapSchema, included))
                    {
                        htmSectionTOC.WriteLine(
                            "<html> \r\n" +
                            "<head> \r\n" +
                            "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"> \r\n" +
                            "<link rel=\"stylesheet\" type=\"text/css\" href=\"../ifc-styles.css\"> \r\n" +
                            "<title>Section Contents</title> \r\n" +
                            "</head> \r\n" +
                            "<body class=\"image\"> \r\n" +
                            "<div class=\"menu\">\r\n" +
                            "<table class=\"menu\" summary=\"Table of Contents\">\r\n");

                        // top level
                        htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">" + chAnnex + ". <a class=\"listing-link\" href=\"annex-" + chAnnex.ToString().ToLower() + ".htm\" target=\"info\" >" + docannex.Name + "</a></td></tr>\r\n");

                        switch (chAnnex)
                        {
                            case 'A':
                                // each MVD has specific schema
                                //if (Properties.Settings.Default.ConceptTables)
                                {
                                    int iCodeView = 0;
                                    foreach (DocModelView docModelView in docProject.ModelViews)
                                    {
                                        if ((included == null || included.ContainsKey(docModelView)) && !String.IsNullOrEmpty(docModelView.Code))
                                        {
                                            iCodeView++;
                                            htmTOC.WriteTOC(1, "<a class=\"listing-link\" href=\"annex/annex-a/" + MakeLinkName(docModelView) + "/index.htm\" >A." + iCodeView.ToString() + " " + docModelView.Name + "</a>");

                                            htmSectionTOC.WriteLine("<tr><td>&nbsp;</td></tr>");
                                            htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">A." + iCodeView.ToString() + " <a href=\"annex-a/" + MakeLinkName(docModelView) + "/index.htm\" target=\"info\" >" + docModelView.Name + "</a></td></tr>");

                                            // create page for model view
                                            string pathRoot = path + @"\annex\annex-a\" + MakeLinkName(docModelView) + @"\index.htm";
                                            using (FormatHTM htmRoot = new FormatHTM(pathRoot, mapEntity, mapSchema, included))
                                            {
                                                htmRoot.WriteComputerListing(docModelView.Name, docModelView.Code, iCodeView);
                                            }

                                            // show filtered schemas for model views only if exchanges defined
                                            if (Properties.Settings.Default.ConceptTables)
                                            {
                                                DocModelView[] modelviews = docProject.GetViewInheritance(docModelView);

                                                DoExport(docProject, path + @"\annex\annex-a\" + MakeLinkName(docModelView) + @"\" + docModelView.Code + ".exp", modelviews, locales, instances);
                                                DoExport(docProject, path + @"\annex\annex-a\" + MakeLinkName(docModelView) + @"\" + docModelView.Code + ".xsd", modelviews, locales, instances);
                                                DoExport(docProject, path + @"\annex\annex-a\" + MakeLinkName(docModelView) + @"\" + docModelView.Code + ".ifc", modelviews, locales, instances);
                                                DoExport(docProject, path + @"\annex\annex-a\" + MakeLinkName(docModelView) + @"\" + docModelView.Code + ".ifcxml", modelviews, locales, instances);
                                                DoExport(docProject, path + @"\annex\annex-a\" + MakeLinkName(docModelView) + @"\" + docModelView.Code + ".xml", modelviews, locales, instances);

                                                using (FormatHTM htmExpress = new FormatHTM(path + @"\annex\annex-a\" + MakeLinkName(docModelView) + @"\" + docModelView.Code + ".exp.htm", mapEntity, mapSchema, included))
                                                {
                                                    htmExpress.UseAnchors = true;
                                                    htmExpress.WriteHeader("EXPRESS", 3);
                                                    htmExpress.WriteExpressSchema(docProject);
                                                    htmExpress.WriteFooter("");
                                                }

                                                // Future: write XSD with html markup...
                                                using (FormatHTM htmXSD = new FormatHTM(path + @"\annex\annex-a\" + MakeLinkName(docModelView) + @"\" + docModelView.Code + ".xsd.htm", mapEntity, mapSchema, included))
                                                {
                                                    string xsdcontent = null;
                                                    using (System.IO.StreamReader reader = new System.IO.StreamReader(path + @"\annex\annex-a\" + MakeLinkName(docModelView) + @"\" + docModelView.Code + ".xsd"))
                                                    {
                                                        xsdcontent = reader.ReadToEnd();
                                                    }

                                                    htmXSD.UseAnchors = false;
                                                    htmXSD.WriteHeader("XSD", 3);
                                                    htmXSD.WriteFormatted(xsdcontent);
                                                    htmXSD.WriteFooter("");
                                                }
                                            }

                                            DoExport(docProject, path + @"\annex\annex-a\" + MakeLinkName(docModelView) + @"\" + docModelView.Code + ".mvdxml", new DocModelView[] { docModelView }, locales, instances);

                                        }
                                    }
                                }
                                break;

                            case 'B':
                                // alphabetical listings
                                htmTOC.WriteTOC(1, "B.1 Definitions");
                                htmSectionTOC.WriteLine("<tr><td>&nbsp;</td></tr>");
                                htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B.1 Definitions</td></tr>");

                                htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/alphabeticalorder_definedtypes.htm\" >B.1.1 Defined types</a>");
                                htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B.1.1 <a href=\"annex-b/alphabeticalorder_definedtypes.htm\" target=\"info\" >Defined types</a></td></tr>");
                                htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/alphabeticalorder_enumtypes.htm\" >B.1.2 Enumeration types</a>");
                                htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B.1.2 <a href=\"annex-b/alphabeticalorder_enumtypes.htm\" target=\"info\" >Enumeration types</a></td></tr>");
                                htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/alphabeticalorder_selecttypes.htm\" >B.1.3 Select types</a>");
                                htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B.1.3 <a href=\"annex-b/alphabeticalorder_selecttypes.htm\" target=\"info\" >Select types</a></td></tr>");
                                htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/alphabeticalorder_entities.htm\" >B.1.4 Entities</a>");
                                htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B.1.4 <a href=\"annex-b/alphabeticalorder_entities.htm\" target=\"info\" >Entities</a></td></tr>");
                                htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/alphabeticalorder_functions.htm\" >B.1.5 Functions</a>");
                                htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B.1.5 <a href=\"annex-b/alphabeticalorder_functions.htm\" target=\"info\" >Functions</a></td></tr>");
                                htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/alphabeticalorder_rules.htm\" >B.1.6 Rules</a>");
                                htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B.1.6 <a href=\"annex-b/alphabeticalorder_rules.htm\" target=\"info\" >Rules</a></td></tr>");
                                htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/alphabeticalorder_psets.htm\" >B.1.7 Property sets</a>");
                                htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B.1.7 <a href=\"annex-b/alphabeticalorder_psets.htm\" target=\"info\" >Property sets</a></td></tr>");
                                htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/alphabeticalorder_qsets.htm\" >B.1.8 Quantity sets</a>");
                                htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B.1.8 <a href=\"annex-b/alphabeticalorder_qsets.htm\" target=\"info\" >Quantity sets</a></td></tr>");

                                htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/alphabeticalorder_psets.htm\" >B.1.9 Individual properties</a>");
                                htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B.1.9 <a href=\"annex-b/alphabeticalorder_properties.htm\" target=\"info\" >Individual properties</a></td></tr>");

                                // locales
                                int indexb = 1;
                                foreach (string locale in listLocale.Keys)
                                {
                                    indexb++;

                                    string localeheader = locale.ToUpper();
                                    if (locale == "zh")
                                    {
                                        localeheader += " [Chinese]"; // no language-generic info available
                                    }
                                    else
                                    {
                                        try
                                        {
                                            System.Globalization.CultureInfo cultureinfo = System.Globalization.CultureInfo.GetCultureInfo(locale);
                                            if (cultureinfo != null)
                                            {
                                                localeheader += " [" + cultureinfo.EnglishName + "]";
                                            }
                                        }
                                        catch
                                        {
                                        }
                                    }

                                    // each locale
                                    htmSectionTOC.WriteLine("<tr><td>&nbsp;</td></tr>");

                                    htmTOC.WriteTOC(1, "B." + indexb.ToString() + " " + localeheader);
                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B." + indexb.ToString() + " " + localeheader + "</td></tr>");

                                    htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/" + locale.ToLower() + "/alphabeticalorder_definedtypes.htm\" >B." + indexb.ToString() + ".1 Defined types</a>");
                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B." + indexb.ToString() + ".1 <a href=\"annex-b/" + locale.ToLower() + "/alphabeticalorder_definedtypes.htm\" target=\"info\" >Defined types</a></td></tr>");
                                    htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/" + locale.ToLower() + "/alphabeticalorder_enumtypes.htm\" >B." + indexb.ToString() + ".2 Enumeration types</a>");
                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B." + indexb.ToString() + ".2 <a href=\"annex-b/" + locale.ToLower() + "/alphabeticalorder_enumtypes.htm\" target=\"info\" >Enumeration types</a></td></tr>");
                                    htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/" + locale.ToLower() + "/alphabeticalorder_selecttypes.htm\" >B." + indexb.ToString() + ".3 Select types</a>");
                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B." + indexb.ToString() + ".3 <a href=\"annex-b/" + locale.ToLower() + "/alphabeticalorder_selecttypes.htm\" target=\"info\" >Select types</a></td></tr>");
                                    htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/" + locale.ToLower() + "/alphabeticalorder_entities.htm\" >B." + indexb.ToString() + ".4 Entities</a>");
                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B." + indexb.ToString() + ".4 <a href=\"annex-b/" + locale.ToLower() + "/alphabeticalorder_entities.htm\" target=\"info\" >Entities</a></td></tr>");
                                    htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/" + locale.ToLower() + "/alphabeticalorder_functions.htm\" >B." + indexb.ToString() + ".5 Functions</a>");
                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B." + indexb.ToString() + ".5 <a href=\"annex-b/" + locale.ToLower() + "/alphabeticalorder_functions.htm\" target=\"info\" >Functions</a></td></tr>");
                                    htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/" + locale.ToLower() + "/alphabeticalorder_rules.htm\" >B." + indexb.ToString() + ".6 Rules</a>");
                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B." + indexb.ToString() + ".6 <a href=\"annex-b/" + locale.ToLower() + "/alphabeticalorder_rules.htm\" target=\"info\" >Rules</a></td></tr>");

                                    /* no translations currently -- enable in future
                                    htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/" + locale.ToLower() + "/alphabeticalorder_psets.htm\" >B." + indexb.ToString() + ".7 Property sets</a>");
                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\"><a href=\"annex-b/" + locale.ToLower() + "/alphabeticalorder_psets.htm\" target=\"info\" >B." + indexb.ToString() + ".7 Property sets</a></td></tr>");
                                    htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/" + locale.ToLower() + "/alphabeticalorder_qsets.htm\" >B." + indexb.ToString() + ".8 Quantity sets</a>");
                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\"><a href=\"annex-b/" + locale.ToLower() + "/alphabeticalorder_qsets.htm\" target=\"info\" >B." + indexb.ToString() + ".8 Quantity sets</a></td></tr>");
                                     */
                                }

                                // generate alphabetical listings
                                using (FormatHTM htmAlpha1 = new FormatHTM(path + "/annex/annex-b/alphabeticalorder_definedtypes.htm", mapEntity, mapSchema, included))
                                {
                                    htmAlpha1.WriteAlphabeticalListing<DocDefined>("Defined Types", path, "definedtypes");
                                }
                                using (FormatHTM htmAlpha1 = new FormatHTM(path + "/annex/annex-b/alphabeticalorder_enumtypes.htm", mapEntity, mapSchema, included))
                                {
                                    htmAlpha1.WriteAlphabeticalListing<DocEnumeration>("Enumeration Types", path, "enumtypes");
                                }
                                using (FormatHTM htmAlpha1 = new FormatHTM(path + "/annex/annex-b/alphabeticalorder_selecttypes.htm", mapEntity, mapSchema, included))
                                {
                                    htmAlpha1.WriteAlphabeticalListing<DocSelect>("Select Types", path, "selecttypes");
                                }
                                using (FormatHTM htmAlpha1 = new FormatHTM(path + "/annex/annex-b/alphabeticalorder_entities.htm", mapEntity, mapSchema, included))
                                {
                                    htmAlpha1.WriteAlphabeticalListing<DocEntity>("Entities", path, "entities");
                                }
                                using (FormatHTM htmAlpha1 = new FormatHTM(path + "/annex/annex-b/alphabeticalorder_functions.htm", mapEntity, mapSchema, included))
                                {
                                    htmAlpha1.WriteAlphabeticalListing<DocFunction>("Functions", path, "functions");
                                }
                                using (FormatHTM htmAlpha1 = new FormatHTM(path + "/annex/annex-b/alphabeticalorder_rules.htm", mapEntity, mapSchema, included))
                                {
                                    htmAlpha1.WriteAlphabeticalListing<DocGlobalRule>("Rules", path, "rules");
                                }
                                // no translations currently -- enable in future
                                using (FormatHTM htmAlpha1 = new FormatHTM(path + "/annex/annex-b/alphabeticalorder_psets.htm", mapEntity, mapSchema, included))
                                {
                                    htmAlpha1.WriteAlphabeticalListing<DocPropertySet>("Property Sets", path, "psets");
                                }
                                using (FormatHTM htmAlpha1 = new FormatHTM(path + "/annex/annex-b/alphabeticalorder_qsets.htm", mapEntity, mapSchema, included))
                                {
                                    htmAlpha1.WriteAlphabeticalListing<DocQuantitySet>("Quantity Sets", path, "qsets");
                                }
                                

                                // generate localized listings
                                foreach (string locale in listLocale.Keys)
                                {
                                    string code = listLocale[locale]; // null for default

                                    using (FormatHTM htmAlpha1 = new FormatHTM(path + "/annex/annex-b/" + locale + "/alphabeticalorder_definedtypes.htm", mapEntity, mapSchema, included))
                                    {
                                        htmAlpha1.WriteLocalizedListing<DocDefined>("Defined Types", code, path, "definedtypes");
                                    }
                                    using (FormatHTM htmAlpha1 = new FormatHTM(path + "/annex/annex-b/" + locale + "/alphabeticalorder_enumtypes.htm", mapEntity, mapSchema, included))
                                    {
                                        htmAlpha1.WriteLocalizedListing<DocEnumeration>("Enumeration Types", code, path, "enumtypes");
                                    }
                                    using (FormatHTM htmAlpha1 = new FormatHTM(path + "/annex/annex-b/" + locale + "/alphabeticalorder_selecttypes.htm", mapEntity, mapSchema, included))
                                    {
                                        htmAlpha1.WriteLocalizedListing<DocSelect>("Select Types", code, path, "selecttypes");
                                    }
                                    using (FormatHTM htmAlpha1 = new FormatHTM(path + "/annex/annex-b/" + locale + "/alphabeticalorder_entities.htm", mapEntity, mapSchema, included))
                                    {
                                        htmAlpha1.WriteLocalizedListing<DocEntity>("Entities", code, path, "entities");
                                    }
                                    using (FormatHTM htmAlpha1 = new FormatHTM(path + "/annex/annex-b/" + locale + "/alphabeticalorder_functions.htm", mapEntity, mapSchema, included))
                                    {
                                        htmAlpha1.WriteLocalizedListing<DocFunction>("Functions", code, path, "functions");
                                    }
                                    using (FormatHTM htmAlpha1 = new FormatHTM(path + "/annex/annex-b/" + locale + "/alphabeticalorder_rules.htm", mapEntity, mapSchema, included))
                                    {
                                        htmAlpha1.WriteLocalizedListing<DocGlobalRule>("Rules", code, path, "rules");
                                    }
                                    using (FormatHTM htmAlpha1 = new FormatHTM(path + "/annex/annex-b/" + locale + "/alphabeticalorder_psets.htm", mapEntity, mapSchema, included))
                                    {
                                        htmAlpha1.WriteLocalizedListing<DocPropertySet>("Property Sets", code, path, "psets");
                                    }
                                    using (FormatHTM htmAlpha1 = new FormatHTM(path + "/annex/annex-b/" + locale + "/alphabeticalorder_qsets.htm", mapEntity, mapSchema, included))
                                    {
                                        htmAlpha1.WriteLocalizedListing<DocQuantitySet>("Quantity Sets", code, path, "qsets");
                                    }

                                }
                                break;

                            case 'C':
                                // Inheritance listings

                                if (docProject.ModelViews != null)
                                {
                                    iView = 0;
                                    foreach (DocModelView docView in docProject.ModelViews)
                                    {
                                        if (included == null || included.ContainsKey(docView))
                                        {
                                            iView++;

                                            htmSectionTOC.WriteLine("<tr><td>&nbsp;</td></tr>");

                                            htmTOC.WriteTOC(1, "<a class=\"listing-link\" href=\"annex/annex-c/" + MakeLinkName(docView) + "/index.htm\" >C." + iView + " " + docView.Name + "</a>");
                                            htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">C." + iView + " <a href=\"annex-c/" + MakeLinkName(docView) + "/index.htm\" target=\"info\" >" + docView.Name + "</a></td></tr>");

                                            // diagram for view
                                            if (!Properties.Settings.Default.SkipDiagrams)
                                            {
                                                Dictionary<DocObject, bool> viewinclude = new Dictionary<DocObject, bool>();
                                                Dictionary<Rectangle, DocEntity> mapRectangle = new Dictionary<Rectangle, DocEntity>();
                                                docProject.RegisterObjectsInScope(docView, viewinclude);
                                                using (Image imgDiagram = FormatPNG.CreateInheritanceDiagram(docProject, viewinclude, docEntityRoot, null, new Font(FontFamily.GenericSansSerif, 8.0f), mapRectangle))
                                                {
                                                    using (FormatHTM htmCover = new FormatHTM(path + @"\annex\annex-c\" + MakeLinkName(docView) + @"\index.htm", mapEntity, mapSchema, included))
                                                    {
                                                        htmCover.WriteHeader(docView.Name, 3);
                                                        htmCover.WriteLine("<h2 class=\"std\">C." + iView + " " + docView.Name + " Inheritance</h2>");
                                                        htmCover.WriteLine("<img src=\"cover.png\" usemap=\"#f\"/>");
                                                        htmCover.WriteLine("<map name=\"f\">");

                                                        foreach (Rectangle rc in mapRectangle.Keys)
                                                        {
                                                            DocEntity docEntref = mapRectangle[rc];
                                                            DocSchema docEntsch = docProject.GetSchemaOfDefinition(docEntref);

                                                            string hyperlink = "../../../schema/" + docEntsch.Name.ToLower() + "/lexical/" + docEntref.Name.ToLower() + ".htm";
                                                            htmCover.WriteLine("<area shape=\"rect\" coords=\"" + rc.Left + "," + rc.Top + "," + rc.Right + "," + rc.Bottom + "\" href=\"" + hyperlink + "\" alt=\"" + docEntref.Name + "\" />");
                                                        }
                                                        htmCover.WriteLine("</map>");
                                                        htmCover.WriteLinkTo("inheritance-" + MakeLinkName(docView), 3);
                                                        htmCover.WriteFooter(String.Empty);

                                                        using (FormatHTM htmLink = new FormatHTM(path + "/link/inheritance-" + MakeLinkName(docView) + ".htm", mapEntity, mapSchema, included))
                                                        {
                                                            htmLink.WriteLinkPage("../annex/annex-c/" + DocumentationISO.MakeLinkName(docView) + "/index.htm");
                                                        }
                                                    }

                                                    // create image after (depends on directory being created first)
                                                    try
                                                    {
                                                        imgDiagram.Save(path + @"\annex\annex-c\" + MakeLinkName(docView) + @"\cover.png");
                                                    }
                                                    catch
                                                    {

                                                    }
                                                }
                                            }

                                                                                            

                                            // all entities
                                            htmTOC.WriteTOC(1, "<a class=\"listing-link\" href=\"annex/annex-c/" + MakeLinkName(docView) + "/all.htm\" >C." + iView + ".1 All entities</a>");
                                            htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">C." + iView + ".1 <a href=\"annex-c/" + MakeLinkName(docView) + "/all.htm\" target=\"info\" >All entities</a></td></tr>");
                                            using (FormatHTM htmInheritAll = new FormatHTM(path + "/annex/annex-c/" + MakeLinkName(docView) + "/all.htm", mapEntity, mapSchema, included))
                                            {
                                                htmInheritAll.WriteInheritanceListing(null, false, "All entities", docView, path, "all");
                                            }

                                            // specific inheritance
                                            htmTOC.WriteTOC(1, "<a class=\"listing-link\" href=\"annex/annex-c/" + MakeLinkName(docView) + "/roots.htm\" >C." + iView + ".2 Rooted entities</a>");
                                            htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">C." + iView + ".2 <a href=\"annex-c/" + MakeLinkName(docView) + "/roots.htm\" target=\"info\" >Rooted entities</a></td></tr>");
                                            using (FormatHTM htmInheritAll = new FormatHTM(path + "/annex/annex-c/" + MakeLinkName(docView) + "/roots.htm", mapEntity, mapSchema, included))
                                            {
                                                htmInheritAll.WriteInheritanceListing("IfcRoot", false, "Rooted entities", docView, path, "roots");
                                            }

                                            htmTOC.WriteTOC(1, "<a class=\"listing-link\" href=\"annex/annex-c/" + MakeLinkName(docView) + "/types.htm\" >C." + iView + ".3 Object types</a>");
                                            htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">C." + iView + ".3 <a href=\"annex-c/" + MakeLinkName(docView) + "/types.htm\" target=\"info\" >Object types</a></td></tr>");
                                            using (FormatHTM htmInheritAll = new FormatHTM(path + "/annex/annex-c/" + MakeLinkName(docView) + "/types.htm", mapEntity, mapSchema, included))
                                            {
                                                htmInheritAll.WriteInheritanceListing("IfcObject", true, "Object types", docView, path, "types");
                                            }

                                            htmSectionTOC.WriteLine("<tr><td>&nbsp;</td></tr>");
                                        
                                        }
                                    }
                                }
                                break;

                            case 'D':
                                // Diagrams

                                // Express-G diagrams
                                htmTOC.WriteTOC(1, "D.1 Schema diagrams");
                                htmSectionTOC.WriteLine("<tr><td>&nbsp;</td></tr>");
                                htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">D.1 Schema diagrams</td></tr>");

                                for (int iSchemaSection = 5; iSchemaSection <= 8; iSchemaSection++)
                                {
                                    DocSection docSection = docProject.Sections[iSchemaSection - 1];

                                    int iDiagramSection = iSchemaSection - 4;

                                    htmTOC.WriteTOC(2, "D.1." + iDiagramSection + " " + docSection.Name);
                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">D.1." + iDiagramSection + " " + docSection.Name + "</td></tr>");


                                    int iSchema = 0;
                                    for (int iSchemaIndex = 1; iSchemaIndex <= docSection.Schemas.Count; iSchemaIndex++)
                                    {
                                        DocSchema docSchema = docSection.Schemas[iSchemaIndex - 1];
                                        if (included == null || included.ContainsKey(docSchema))
                                        {
                                            iSchema++;

                                            htmTOC.WriteTOC(3, "<a class=\"listing-link\" href=\"annex/annex-d/" + MakeLinkName(docSchema) + "/index.htm\" >D.1." + iDiagramSection + "." + iSchema + " " + docSchema.Name + "</a>");
                                            htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">D.1." + iDiagramSection + "." + iSchema + " <a href=\"annex-d/" + MakeLinkName(docSchema) + "/index.htm\" target=\"info\" >" + docSchema.Name + "</a></td></tr>");

                                            // determine number of diagrams
                                            int iLastDiagram = docSchema.GetDiagramCount();

                                            // generate diagrams
                                            if (!Properties.Settings.Default.SkipDiagrams)
                                            {
                                                Image imageSchema = FormatPNG.CreateSchemaDiagram(docSchema, mapEntity);

                                                using (FormatHTM htmSchemaDiagram = new FormatHTM(path + "/annex/annex-d/" + MakeLinkName(docSchema) + "/index.htm", mapEntity, mapSchema, included))
                                                {
                                                    int iSub = 1;

                                                    htmSchemaDiagram.WriteHeader(docSection.Name, 3);
                                                    htmSchemaDiagram.WriteScript(iAnnex, iSub, iSection, 0);
                                                    htmSchemaDiagram.WriteLine("<h4 class=\"std\">D.1." + iDiagramSection + "." + iSchema + " " + docSchema.Name + "</h4>");

                                                    htmSchemaDiagram.WriteLine("<p>");

                                                    // write thumbnail links for each diagram
                                                    for (int iDiagram = 1; iDiagram <= iLastDiagram; iDiagram++)
                                                    {
                                                        string formatnumber = iDiagram.ToString("D4"); // 0001
                                                        htmSchemaDiagram.WriteLine("<a href=\"diagram_" + formatnumber + ".htm\">" +
                                                            "<img src=\"diagram_" + formatnumber + ".png\" width=\"300\" height=\"444\" /></a>"); // width=\"150\" height=\"222\"> 

                                                        // generate EXPRESS-G diagram
                                                        if (docSchema.DiagramPagesHorz != 0)
                                                        {
                                                            int pageY = (iDiagram - 1) / docSchema.DiagramPagesHorz;
                                                            int pageX = (iDiagram - 1) % docSchema.DiagramPagesHorz;
                                                            int pagePixelCX = CtlExpressG.PageX;
                                                            int pagePixelCY = CtlExpressG.PageY;
                                                            using (Image imagePage = new Bitmap(pagePixelCX, pagePixelCY))
                                                            {
                                                                using (Graphics g = Graphics.FromImage(imagePage))
                                                                {
                                                                    g.DrawImage(imageSchema, new Rectangle(0, 0, pagePixelCX, pagePixelCY), new Rectangle(pagePixelCX * pageX, pagePixelCY * pageY, pagePixelCX, pagePixelCY), GraphicsUnit.Pixel);
                                                                }
                                                                imagePage.Save(path + "/annex/annex-d/" + MakeLinkName(docSchema) + "/diagram_" + formatnumber + ".png");
                                                            }
                                                        }
                                                    }

                                                    htmSchemaDiagram.WriteLine("</p>");
                                                    htmSchemaDiagram.WriteFooter(Properties.Settings.Default.Footer);
                                                }


                                                double scale = 0.375; // hard-coded for now -- read from SCHEMATA.scale
                                                double pageCX = 1600; // hard-coded for now -- read from SCHEMATA.settings.page.width
                                                double pageCY = 2370; // hard-coded for now -- read from SCHEMATA.settings.page.height

                                                for (int iDiagram = 1; iDiagram <= iLastDiagram; iDiagram++)
                                                {
                                                    string formatnumber = iDiagram.ToString("D4");
                                                    using (FormatHTM htmSchema = new FormatHTM(path + "/annex/annex-d/" + MakeLinkName(docSchema) + "/diagram_" + formatnumber + ".htm", mapEntity, mapSchema, included))
                                                    {
                                                        htmSchema.WriteHeader(docSchema.Name, 3);
                                                        htmSchema.WriteScript(iAnnex, 1, iDiagramSection, iDiagram);

                                                        htmSchema.WriteLine("<h4 class=\"std\">");
                                                        if (iDiagram > 1)
                                                        {
                                                            htmSchema.Write("<a href=\"diagram_" + (iDiagram - 1).ToString("D4") + ".htm\"><img src=\"../../../img/navleft.png\" style=\"border: 0px\" /></a>");
                                                        }
                                                        else
                                                        {
                                                            // disabled
                                                            htmSchema.Write("<img src=\"../../../img/navleft.png\" style=\"border: 0px\" />");
                                                        }
                                                        if (iDiagram < iLastDiagram)
                                                        {
                                                            htmSchema.Write("<a href=\"diagram_" + (iDiagram + 1).ToString("D4") + ".htm\"><img src=\"../../../img/navright.png\" style=\"border: 0px\" /></a>");
                                                        }
                                                        else
                                                        {
                                                            // disabled
                                                            htmSchema.Write("<img src=\"../../../img/navright.png\" style=\"border: 0px\" />");
                                                        }
                                                        htmSchema.Write(" " + docSchema.Name + " (" + iDiagram + "/" + iLastDiagram + ")");
                                                        htmSchema.WriteLine("</h4>");

                                                        htmSchema.WriteLine("<img src=\"diagram_" + formatnumber + ".png\" usemap=\"#diagram\" >");
                                                        htmSchema.WriteLine("  <map name=\"diagram\" >");
                                                        foreach (DocType docType in docSchema.Types)
                                                        {
                                                            if ((included == null || included.ContainsKey(docType)) && docType.DiagramNumber == iDiagram && docType.DiagramRectangle != null)
                                                            {
                                                                double x0 = docType.DiagramRectangle.X % pageCX * scale;
                                                                double y0 = docType.DiagramRectangle.Y % pageCY * scale;
                                                                double x1 = docType.DiagramRectangle.X % pageCX * scale + docType.DiagramRectangle.Width % pageCX * scale;
                                                                double y1 = docType.DiagramRectangle.Y % pageCY * scale + docType.DiagramRectangle.Height % pageCY * scale;
                                                                string link = "../../../schema/" + mapSchema[docType.Name].ToLower() + "/lexical/" + docType.Name.ToLower() + ".htm";
                                                                htmSchema.WriteLine("    <area shape=\"rect\" coords=\"" + x0 + ", " + y0 + ", " + x1 + ", " + y1 + "\" alt=\"Navigate\" href=\"" + link + "\" />");
                                                            }
                                                        }
                                                        foreach (DocEntity docType in docSchema.Entities)
                                                        {
                                                            if ((included == null || included.ContainsKey(docType)) && docType.DiagramNumber == iDiagram && docType.DiagramRectangle != null)
                                                            {
                                                                double x0 = docType.DiagramRectangle.X % pageCX * scale;
                                                                double y0 = docType.DiagramRectangle.Y % pageCY * scale;
                                                                double x1 = docType.DiagramRectangle.X % pageCX * scale + docType.DiagramRectangle.Width % pageCX * scale;
                                                                double y1 = docType.DiagramRectangle.Y % pageCY * scale + docType.DiagramRectangle.Height % pageCY * scale;
                                                                string link = "../../../schema/" + mapSchema[docType.Name].ToLower() + "/lexical/" + docType.Name.ToLower() + ".htm";
                                                                htmSchema.WriteLine("    <area shape=\"rect\" coords=\"" + x0 + ", " + y0 + ", " + x1 + ", " + y1 + "\" alt=\"Navigate\" href=\"" + link + "\" />");
                                                            }
                                                        }
                                                        if (docSchema.PageTargets != null)
                                                        {
                                                            foreach (DocPageTarget docPageTarget in docSchema.PageTargets)
                                                            {
                                                                foreach (DocPageSource docPageSource in docPageTarget.Sources)
                                                                {
                                                                    if (docPageSource.DiagramNumber == iDiagram && docPageSource.DiagramRectangle != null)
                                                                    {
                                                                        double x0 = docPageSource.DiagramRectangle.X % pageCX * scale;
                                                                        double y0 = docPageSource.DiagramRectangle.Y % pageCY * scale;
                                                                        double x1 = docPageSource.DiagramRectangle.X % pageCX * scale + docPageSource.DiagramRectangle.Width % pageCX * scale;
                                                                        double y1 = docPageSource.DiagramRectangle.Y % pageCY * scale + docPageSource.DiagramRectangle.Height % pageCY * scale;
                                                                        string link = "diagram_" + docPageTarget.DiagramNumber.ToString("D4") + ".htm";
                                                                        htmSchema.WriteLine("    <area shape=\"rect\" coords=\"" + x0 + ", " + y0 + ", " + x1 + ", " + y1 + "\" alt=\"Navigate\" href=\"" + link + "\" />");
                                                                    }
                                                                }
                                                            }
                                                        }
                                                        if (docSchema.SchemaRefs != null)
                                                        {
                                                            foreach (DocSchemaRef docSchemaRef in docSchema.SchemaRefs)
                                                            {
                                                                foreach (DocDefinitionRef docDefinitionRef in docSchemaRef.Definitions)
                                                                {
                                                                    if (docDefinitionRef.DiagramNumber == iDiagram && docDefinitionRef.DiagramRectangle != null)
                                                                    {
                                                                        double x0 = docDefinitionRef.DiagramRectangle.X % pageCX * scale;
                                                                        double y0 = docDefinitionRef.DiagramRectangle.Y % pageCY * scale;
                                                                        double x1 = docDefinitionRef.DiagramRectangle.X % pageCX * scale + docDefinitionRef.DiagramRectangle.Width % pageCX * scale;
                                                                        double y1 = docDefinitionRef.DiagramRectangle.Y % pageCY * scale + docDefinitionRef.DiagramRectangle.Height % pageCY * scale;

                                                                        if (mapSchema.ContainsKey(docDefinitionRef.Name))
                                                                        {
                                                                            DocDefinition docDef = mapEntity[docDefinitionRef.Name] as DocDefinition;
                                                                            if (included == null || included.ContainsKey(docDef))
                                                                            {
                                                                                string link = "../../../schema/" + mapSchema[docDefinitionRef.Name].ToLower() + "/lexical/" + docDefinitionRef.Name.ToLower() + ".htm";
                                                                                htmSchema.WriteLine("    <area shape=\"rect\" coords=\"" + x0 + ", " + y0 + ", " + x1 + ", " + y1 + "\" alt=\"Navigate\" href=\"" + link + "\" />");
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                        htmSchema.WriteLine("  </map>");
                                                        htmSchema.WriteLine("</img>");
                                                        htmSchema.WriteFooter(Properties.Settings.Default.Footer);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }

                                // Instance diagrams
                                htmTOC.WriteTOC(1, "D.2 Instance diagrams");
                                htmSectionTOC.WriteLine("<tr><td>&nbsp;</td></tr>");
                                htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">D.2 Instance diagrams</td></tr>");

                                // D.1 -- schema diagrams - express-G
                                // D.1.1 -- core layer
                                // D.1.2 -- shared layer
                                // D.1.3 -- domain layer
                                // D.1.4 -- resource layer
                                // D.1.4.1~ schema

                                // D.2 -- instance diagrams
                                // D.2.1~  model view
                                // D.2.1.1~  entity

                                if (docProject.ModelViews != null)
                                {
                                    iView = 0;
                                    foreach (DocModelView docView in docProject.ModelViews)
                                    {
                                        if (included == null || included.ContainsKey(docView))
                                        {
                                            iView++;

                                            htmTOC.WriteTOC(2, "D.2." + iView.ToString() + " " + docView.Name);
                                            htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">D.2." + iView.ToString() + "<a href=\"annex-d/" + MakeLinkName(docView) + "/cover.htm\" target=\"info\"> " + docView.Name + "</a></td></tr>");


                                            Dictionary<DocObject, bool> viewinclude = new Dictionary<DocObject, bool>();
                                            Dictionary<Rectangle, DocEntity> mapRectangle = new Dictionary<Rectangle, DocEntity>();
                                            docProject.RegisterObjectsInScope(docView, viewinclude);
                                            using (FormatHTM htmCover = new FormatHTM(path + @"\annex\annex-d\" + MakeLinkName(docView) + @"\cover.htm", mapEntity, mapSchema, included))
                                            {
                                                htmCover.WriteHeader(docView.Name, 3);
                                                htmCover.WriteLine("<h3 class=\"std\">D.2." + iView + " " + docView.Name + " Diagrams</h3>");
                                                htmCover.WriteFooter(String.Empty);
                                            }

                                            // sort by entity name
                                            SortedList<string, DocConceptRoot> listEntity = new SortedList<string, DocConceptRoot>();
                                            foreach (DocConceptRoot docRoot in docView.ConceptRoots)
                                            {
                                                if (docRoot.ApplicableEntity != null)
                                                {
                                                    if (!listEntity.ContainsKey(docRoot.ApplicableEntity.Name)) // only one concept root per entity per view currently supported
                                                    {
                                                        listEntity.Add(docRoot.ApplicableEntity.Name, docRoot);
                                                    }
                                                }
                                            }

                                            // now generate
                                            int iRoot = 0;
                                            foreach (DocConceptRoot docRoot in listEntity.Values)
                                            {
                                                iRoot++;

                                                htmTOC.WriteTOC(3, "<a class=\"listing-link\" href=\"annex/annex-d/" + MakeLinkName(docView) + "/" + MakeLinkName(docRoot.ApplicableEntity) + ".htm\" >D.2." + iView.ToString() + "." + iRoot.ToString() + " " + docRoot.ApplicableEntity.Name + "</a>");
                                                htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">D.2." + iView.ToString() + "." + iRoot.ToString() + " <a href=\"annex-d/" + MakeLinkName(docView) + "/" + MakeLinkName(docRoot.ApplicableEntity) + ".htm\" target=\"info\">" + docRoot.ApplicableEntity.Name + "</a></td></tr>");

                                                string pathRoot = path + @"\annex\annex-d\" + MakeLinkName(docView) + @"\" + MakeLinkName(docRoot.ApplicableEntity) + ".htm";
                                                using (FormatHTM htmRoot = new FormatHTM(pathRoot, mapEntity, mapSchema, included))
                                                {
                                                    htmRoot.WriteHeader(docRoot.ApplicableEntity.Name, iAnnex, 2, 0, iView, Properties.Settings.Default.Header);
                                                    htmRoot.WriteScript(iAnnex, 2, iView, iRoot);
                                                    htmRoot.WriteLine("<h3 class=\"std\">D.2." + iView.ToString() + "." + iRoot.ToString() + " " + docRoot.ApplicableEntity.Name + "</h3>");

                                                    string diagram = FormatDiagram(docProject, docRoot.ApplicableEntity, docView, listFigures, mapEntity, mapSchema);
                                                    htmRoot.WriteLine(diagram);

                                                    htmRoot.WriteFooter(Properties.Settings.Default.Footer);
                                                }

                                            }
                                        }
                                    }
                                }                                
                                break;

                            case 'E':
                                if (docProject.Examples != null)
                                {
                                    List<DocXsdFormat> xsdFormatBase = new List<DocXsdFormat>();
                                    foreach(DocSection docSection in docProject.Sections)
                                    {
                                        foreach(DocSchema docSchema in docSection.Schemas)
                                        {
                                            foreach(DocEntity docEntity in docSchema.Entities)
                                            {
                                                foreach(DocAttribute docAttr in docEntity.Attributes)
                                                {
                                                    if(docAttr.XsdFormat != DocXsdFormatEnum.Default || docAttr.XsdTagless != null)
                                                    {
                                                        DocXsdFormat xsdformat = new DocXsdFormat();
                                                        xsdformat.Entity = docEntity.Name;
                                                        xsdformat.Attribute = docAttr.Name;
                                                        xsdformat.XsdFormat = docAttr.XsdFormat;
                                                        xsdformat.XsdTagless = docAttr.XsdTagless;
                                                        xsdFormatBase.Add(xsdformat);
                                                    }
                                                }
                                            }
                                        }
                                    }

                                    List<int> indexpath = new List<int>();
                                    indexpath.Add(0);
                                    foreach(DocExample docExample in docProject.Examples)
                                    {
                                        Dictionary<string, Type> typemap = new Dictionary<string, Type>();
                                        Compiler compiler = new Compiler(docProject, docExample.Views.ToArray(), null);
                                        System.Reflection.Emit.AssemblyBuilder assembly = compiler.Assembly;
                                        try
                                        {
                                            Type[] types = assembly.GetTypes();
                                            foreach (Type t in types)
                                            {
                                                typemap.Add(t.Name.ToUpper(), t);
                                            }
                                        }
                                        catch
                                        {
                                            // schema could not be compiled according to definition
                                        }

                                        List<DocXsdFormat> listFormats = new List<DocXsdFormat>(xsdFormatBase);
                                        if (docExample.Views.Count > 0)
                                        {
                                            foreach (DocXsdFormat customformat in docExample.Views[0].XsdFormats)
                                            {
                                                listFormats.Add(customformat);
                                            }
                                        }

                                        GenerateExample(docExample, listFormats, path, indexpath, included, mapEntity, mapSchema, typemap, listFigures, listTables, htmTOC, htmSectionTOC);
                                    }
                                }
                                break;

                            case 'F':
                                if (docProject.ChangeSets != null)
                                {
                                    for (int iChangeset = 1; iChangeset <= docProject.ChangeSets.Count; iChangeset++)
                                    {
                                        DocChangeSet docChangeSet = docProject.ChangeSets[iChangeset - 1];

                                        // what's new page
                                        htmTOC.WriteTOC(1, "<a class=\"listing-link\" href=\"annex/annex-f/" + MakeLinkName(docChangeSet) + "/index.htm\" >F." + iChangeset + " " + docChangeSet.Name + "</a>");
                                        htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">F." + iChangeset + " <a href=\"annex-f/" + MakeLinkName(docChangeSet) + "/index.htm\" target=\"info\" >" + docChangeSet.Name + "</a></td></tr>");
                                        using (FormatHTM htmWhatsnew = new FormatHTM(path + @"\annex\annex-f\" + MakeLinkName(docChangeSet) + @"\index.htm", mapEntity, mapSchema, included))
                                        {
                                            htmWhatsnew.WriteHeader(docChangeSet.Name, 3);
                                            htmWhatsnew.WriteScript(iAnnex, iChangeset, 0, 0);
                                            htmWhatsnew.WriteLine("<h4 class=\"std\">F." + iChangeset + " " + docChangeSet.Name + "</h4>");
                                            htmWhatsnew.WriteDocumentationForISO(docChangeSet.Documentation, docChangeSet, false);
                                            htmWhatsnew.WriteLinkTo(MakeLinkName(docChangeSet), 3);
                                            htmWhatsnew.WriteFooter(Properties.Settings.Default.Footer);
                                        }

                                        // change log for entities
                                        htmTOC.WriteTOC(1, "<a class=\"listing-link\" href=\"annex/annex-f/" + MakeLinkName(docChangeSet) + "/changelog.htm\" >F." + iChangeset + ".1 Entities</a>");
                                        htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\"><a href=\"annex-f/" + MakeLinkName(docChangeSet) + "/changelog.htm\" target=\"info\" >F." + iChangeset + ".1 Entities</a></td></tr>");
                                        string pathChange = path + @"\annex\annex-f\" + MakeLinkName(docChangeSet) + @"\changelog.htm";
                                        using (FormatHTM htmChange = new FormatHTM(pathChange, mapEntity, mapSchema, included))
                                        {
                                            htmChange.WriteHeader(docChangeSet.Name, 3);
                                            htmChange.WriteScript(iAnnex, iChangeset, 1, 0);
                                            htmChange.WriteLine("<h4 class=\"std\">F." + iChangeset + ".1 Entities</h4>");

                                            htmChange.WriteLine("<table class=\"gridtable\">");
                                            htmChange.WriteLine("<tr>" +
                                                "<th>Item</th>" +
                                                "<th>SPF</th>" +
                                                "<th>XML</th>" +
                                                "<th>Change</th>" +
                                                "<th>Description</th>" +
                                                "</tr>");

                                            foreach (DocChangeAction docChangeItem in docChangeSet.ChangesEntities)
                                            {
                                                htmChange.WriteChangeItem(docChangeItem, 0);
                                            }

                                            htmChange.WriteLine("</table>");
                                            htmChange.WriteLinkTo(MakeLinkName(docChangeSet) + "-changelog", 3);
                                            htmChange.WriteFooter(Properties.Settings.Default.Footer);
                                        }

                                        // change log for properties
                                        htmTOC.WriteTOC(1, "<a class=\"listing-link\" href=\"annex/annex-f/" + MakeLinkName(docChangeSet) + "/properties.htm\" >F." + iChangeset + ".2 Properties</a>");
                                        htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\"><a href=\"annex-f/" + MakeLinkName(docChangeSet) + "/properties.htm\" target=\"info\" >F." + iChangeset + ".1 Properties</a></td></tr>");
                                        pathChange = path + @"\annex\annex-f\" + MakeLinkName(docChangeSet) + @"\properties.htm";
                                        using (FormatHTM htmChange = new FormatHTM(pathChange, mapEntity, mapSchema, included))
                                        {
                                            htmChange.WriteHeader(docChangeSet.Name, 3);
                                            htmChange.WriteScript(iAnnex, iChangeset, 1, 0);
                                            htmChange.WriteLine("<h4 class=\"std\">F." + iChangeset + ".2 Properties</h4>");

                                            htmChange.WriteLine("<table class=\"gridtable\">");
                                            htmChange.WriteLine("<tr>" +
                                                "<th>Item</th>" +
                                                "<th>SPF</th>" +
                                                "<th>XML</th>" +
                                                "<th>Change</th>" +
                                                "<th>Description</th>" +
                                                "</tr>");

                                            if (docChangeSet.ChangesProperties != null)
                                            {
                                                foreach (DocChangeAction docChangeItem in docChangeSet.ChangesProperties)
                                                {
                                                    htmChange.WriteChangeItem(docChangeItem, 0);
                                                }
                                            }

                                            htmChange.WriteLine("</table>");
                                            htmChange.WriteLinkTo(MakeLinkName(docChangeSet) + "-properties", 3);
                                            htmChange.WriteFooter(Properties.Settings.Default.Footer);
                                        }


                                        // change log for quantities
                                        htmTOC.WriteTOC(1, "<a class=\"listing-link\" href=\"annex/annex-f/" + MakeLinkName(docChangeSet) + "/quantities.htm\" >F." + iChangeset + ".3 Quantities</a>");
                                        htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\"><a href=\"annex-f/" + MakeLinkName(docChangeSet) + "/quantities.htm\" target=\"info\" >F." + iChangeset + ".3 Quantities</a></td></tr>");
                                        pathChange = path + @"\annex\annex-f\" + MakeLinkName(docChangeSet) + @"\quantities.htm";
                                        using (FormatHTM htmChange = new FormatHTM(pathChange, mapEntity, mapSchema, included))
                                        {
                                            htmChange.WriteHeader(docChangeSet.Name, 3);
                                            htmChange.WriteScript(iAnnex, iChangeset, 1, 0);
                                            htmChange.WriteLine("<h4 class=\"std\">F." + iChangeset + ".3 Quantities</h4>");

                                            htmChange.WriteLine("<table class=\"gridtable\">");
                                            htmChange.WriteLine("<tr>" +
                                                "<th>Item</th>" +
                                                "<th>SPF</th>" +
                                                "<th>XML</th>" +
                                                "<th>Change</th>" +
                                                "<th>Description</th>" +
                                                "</tr>");

                                            if (docChangeSet.ChangesQuantities != null)
                                            {
                                                foreach (DocChangeAction docChangeItem in docChangeSet.ChangesQuantities)
                                                {
                                                    htmChange.WriteChangeItem(docChangeItem, 0);
                                                }
                                            }

                                            htmChange.WriteLine("</table>");
                                            htmChange.WriteLinkTo(MakeLinkName(docChangeSet) + "-quantities", 3);
                                            htmChange.WriteFooter(Properties.Settings.Default.Footer);
                                        }

                                    }
                                }
                                break;
                        }

                        htmSectionTOC.WriteLine(
                            "</table>\r\n" +
                            "</div>\r\n" +
                            "</body>\r\n" +
                            "</html>\r\n");
                    }

                    chAnnex++;
                }

                // bibliography
                try
                {
                    using (FormatHTM htmSection = new FormatHTM(path + @"\bibliography.htm", mapEntity, mapSchema, included))
                    {
                        htmSection.WriteHeader("Bibliography", 0);

                        htmSection.Write(
                            "\r\n" +
                            "<script type=\"text/javascript\">\r\n" +
                            "<!--\r\n" +
                            "    parent.index.location.replace(\"blank.htm\");\r\n" +
                            "//-->\r\n" +
                            "</script>\r\n");

                        htmSection.WriteLine("<h1>Bibliography</h1>");

                        htmSection.WriteLine("<dl>");
                        if (docProject.InformativeReferences != null)
                        {
                            foreach (DocReference docRef in docProject.InformativeReferences)
                            {
                                htmSection.WriteLine("<dt class=\"bibliographyreference\"><a id=\"" + MakeLinkName(docRef) + "\" id=\"" + MakeLinkName(docRef) + "\">" + docRef.Name + "</a>, <i>" + docRef.Documentation + "</i></dt>");
                                htmSection.WriteLine("<dd>&nbsp;</dd>");
                            }
                        }
                        htmSection.WriteLine("</dl>");

                        htmSection.WriteFooter(Properties.Settings.Default.Footer);
                    }
                }
                catch
                {
                    htmTOC.ToString();
                }

                htmTOC.WriteLine("</p>");


                // write figures
                htmTOC.WriteLine("<h1 class=\"std\">Figures</h1>");
                htmTOC.WriteLine("<p>");
                htmTOC.WriteContentRefs(listFigures, "Figure");
                htmTOC.WriteLine("</p>");

                htmTOC.WriteLine("<p></p>");

                // write tables
                htmTOC.WriteLine("<h1 class=\"std\">Tables</h1>");
                htmTOC.WriteLine("<p>");
                htmTOC.WriteContentRefs(listTables, "Table");
                htmTOC.WriteLine("</p>");

                htmTOC.WriteFooter(Properties.Settings.Default.Footer);
            }

            worker.ReportProgress(++progressCurrent, "Index");
            if (worker.CancellationPending)
                return;

            // generate index -- takes very long, so only run when changing
            SortedList<string, DocObject> listIndex = new SortedList<string, DocObject>();
            foreach (string key in mapEntity.Keys)
            {
                listIndex.Add(key, mapEntity[key]);
            }

            using (FormatHTM htmIndex = new FormatHTM(path + "/doc_index.htm", mapEntity, mapSchema, included)) // file name "doc_index" required by ISO
            {
                htmIndex.WriteHeader("Index", 0);

                htmIndex.Write(
                    "\r\n" +
                    "<script type=\"text/javascript\">\r\n" +
                    "<!--\r\n" +
                    "    parent.index.location.replace(\"blank.htm\");\r\n" +
                    "//-->\r\n" +
                    "</script>\r\n");

                htmIndex.WriteLine(
                    "<div class=\"not-numbered\">\r\n" +
                    "<h1 class=\"std\">Index</h1>\r\n" +
                    "<p class=\"std\">\r\n");

                foreach (string key in listIndex.Keys)
                {
                    DocObject obj = mapEntity[key];
                    if (included == null || included.ContainsKey(obj))
                    {
                        htmIndex.WriteLine("<b>" + key + "</b> ");

                        // build ordered list of references in documentation
                        SortedDictionary<string, string> mapRefs = new SortedDictionary<string, string>();
                        foreach (string refkey1 in listIndex.Keys)
                        {
                            string doc = mapEntity[refkey1].Documentation;
                            if (doc != null)// && key != refkey) // also include main ref for ISO
                            {
                                if (refkey1 == key || doc.Contains(key))
                                {
                                    DocObject refobj = (DocObject)mapEntity[refkey1];

                                    string refnumber = null;
                                    if (mapNumber != null && mapNumber.TryGetValue(refobj, out refnumber))
                                    {
                                        mapRefs.Add(refnumber, refkey1);
                                    }

                                }
                            }
                        }

                        // search references of terms in documentation
                        string comma = "";
                        foreach (string refnumber in mapRefs.Keys)
                        {
                            string refkey = mapRefs[refnumber];

                            DocObject refobj = (DocObject)mapEntity[refkey];
                            string display = refobj.Name;//refnumber; // new: use names for bSI; numbers for ISO

                            if (refobj is DocPropertySet || refobj is DocPropertyEnumeration)
                            {
                                htmIndex.Write(comma + "<a class=\"listing-link\" title=\"" + refobj.Name + "\" href=\"schema/" + mapSchema[refkey].ToLower() + "/pset/" + refobj.Name.ToLower() + ".htm\">" + display + "</a>");
                            }
                            else if (refobj is DocQuantitySet)
                            {
                                htmIndex.Write(comma + "<a class=\"listing-link\" title=\"" + refobj.Name + "\" href=\"schema/" + mapSchema[refkey].ToLower() + "/qset/" + refobj.Name.ToLower() + ".htm\">" + display + "</a>");
                            }
                            else
                            {
                                htmIndex.Write(comma + "<a class=\"listing-link\" title=\"" + refobj.Name + "\" href=\"schema/" + mapSchema[refkey].ToLower() + "/lexical/" + refobj.Name.ToLower() + ".htm\">" + display + "</a>");
                            }

                            comma = ", ";
                        }

                        htmIndex.WriteLine("<br />\r\n");
                    }
                }

                worker.ReportProgress(++progressCurrent, "Links");
                if (worker.CancellationPending)
                    return;

                // new: incoming links
                foreach(DocSection docLinkSection in docProject.Sections)
                {
                    int iSection = docProject.Sections.IndexOf(docLinkSection) + 1;
                    using (FormatHTM htmLink = new FormatHTM(path + "/link/chapter-" + iSection.ToString() + ".htm", mapEntity, mapSchema, included))
                    {
                        htmLink.WriteLinkPage("../schema/chapter-" + iSection.ToString() + ".htm");
                    }

                    foreach (DocSchema docLinkSchema in docLinkSection.Schemas)
                    {
                        using (FormatHTM htmLink = new FormatHTM(path + "/link/" + MakeLinkName(docLinkSchema) + ".htm", mapEntity, mapSchema, included))
                        {
                            htmLink.WriteLinkPage("../schema/" + docLinkSchema.Name.ToLower() + "/content.htm");
                        }

                        foreach (DocEntity docLinkObj in docLinkSchema.Entities)
                        {
                            if (included == null || included.ContainsKey(docLinkObj))
                            {
                                using (FormatHTM htmLink = new FormatHTM(path + "/link/" + MakeLinkName(docLinkObj) + ".htm", mapEntity, mapSchema, included))
                                {
                                    htmLink.WriteLinkPage("../schema/" + docLinkSchema.Name.ToLower() + "/lexical/" + MakeLinkName(docLinkObj) + ".htm");
                                }
                            }
                        }

                        foreach(DocType docLinkObj in docLinkSchema.Types)
                        {
                            if (included == null || included.ContainsKey(docLinkObj))
                            {
                                using (FormatHTM htmLink = new FormatHTM(path + "/link/" + MakeLinkName(docLinkObj) + ".htm", mapEntity, mapSchema, included))
                                {
                                    htmLink.WriteLinkPage("../schema/" + docLinkSchema.Name.ToLower() + "/lexical/" + MakeLinkName(docLinkObj) + ".htm");
                                }
                            }
                        }

                        foreach (DocFunction docLinkObj in docLinkSchema.Functions)
                        {
                            if (included == null || included.ContainsKey(docLinkObj))
                            {
                                using (FormatHTM htmLink = new FormatHTM(path + "/link/" + MakeLinkName(docLinkObj) + ".htm", mapEntity, mapSchema, included))
                                {
                                    htmLink.WriteLinkPage("../schema/" + docLinkSchema.Name.ToLower() + "/lexical/" + MakeLinkName(docLinkObj) + ".htm");
                                }
                            }
                        }

                        foreach (DocGlobalRule docLinkObj in docLinkSchema.GlobalRules)
                        {
                            if (included == null || included.ContainsKey(docLinkObj))
                            {
                                using (FormatHTM htmLink = new FormatHTM(path + "/link/" + MakeLinkName(docLinkObj) + ".htm", mapEntity, mapSchema, included))
                                {
                                    htmLink.WriteLinkPage("../schema/" + docLinkSchema.Name.ToLower() + "/lexical/" + MakeLinkName(docLinkObj) + ".htm");
                                }
                            }
                        }

                        foreach (DocPropertySet docLinkObj in docLinkSchema.PropertySets)
                        {
                            if (included == null || included.ContainsKey(docLinkObj))
                            {
                                using (FormatHTM htmLink = new FormatHTM(path + "/link/" + MakeLinkName(docLinkObj) + ".htm", mapEntity, mapSchema, included))
                                {
                                    htmLink.WriteLinkPage("../schema/" + docLinkSchema.Name.ToLower() + "/pset/" + MakeLinkName(docLinkObj) + ".htm");
                                }
                            }
                        }

                        foreach (DocPropertyEnumeration docLinkObj in docLinkSchema.PropertyEnums)
                        {
                            if (included == null || included.ContainsKey(docLinkObj))
                            {
                                using (FormatHTM htmLink = new FormatHTM(path + "/link/" + MakeLinkName(docLinkObj) + ".htm", mapEntity, mapSchema, included))
                                {
                                    htmLink.WriteLinkPage("../schema/" + docLinkSchema.Name.ToLower() + "/pset/" + MakeLinkName(docLinkObj) + ".htm");
                                }
                            }
                        }

                        foreach (DocQuantitySet docLinkObj in docLinkSchema.QuantitySets)
                        {
                            if (included == null || included.ContainsKey(docLinkObj))
                            {
                                using (FormatHTM htmLink = new FormatHTM(path + "/link/" + MakeLinkName(docLinkObj) + ".htm", mapEntity, mapSchema, included))
                                {
                                    htmLink.WriteLinkPage("../schema/" + docLinkSchema.Name.ToLower() + "/qset/" + MakeLinkName(docLinkObj) + ".htm");
                                }
                            }
                        }
                    }
                }

                char chAnnex = 'a';
                foreach(DocAnnex docAnnex in docProject.Annexes)
                {
                    using (FormatHTM htmLink = new FormatHTM(path + "/link/annex-" + chAnnex + ".htm", mapEntity, mapSchema, included))
                    {
                        htmLink.WriteLinkPage("../annex/annex-" + chAnnex + ".htm");
                    }

                    chAnnex++;
                }

                foreach(DocAnnotation docAnnot in docProject.Annotations)
                {
                    using (FormatHTM htmLink = new FormatHTM(path + "/link/" + MakeLinkName(docAnnot) + ".htm", mapEntity, mapSchema, included))
                    {
                        htmLink.WriteLinkPage("../" + MakeLinkName(docAnnot) + ".htm");
                    }
                }

                foreach(DocChangeSet docChange in docProject.ChangeSets)
                {
                    using (FormatHTM htmLink = new FormatHTM(path + "/link/" + MakeLinkName(docChange) + ".htm", mapEntity, mapSchema, included))
                    {
                        htmLink.WriteLinkPage("../annex/annex-f/" + MakeLinkName(docChange) + "/index.htm");
                    }
                    using (FormatHTM htmLink = new FormatHTM(path + "/link/" + MakeLinkName(docChange) + "-changelog.htm", mapEntity, mapSchema, included))
                    {
                        htmLink.WriteLinkPage("../annex/annex-f/" + MakeLinkName(docChange) + "/changelog.htm");
                    }
                    using (FormatHTM htmLink = new FormatHTM(path + "/link/" + MakeLinkName(docChange) + "-properties.htm", mapEntity, mapSchema, included))
                    {
                        htmLink.WriteLinkPage("../annex/annex-f/" + MakeLinkName(docChange) + "/properties.htm");
                    }
                    using (FormatHTM htmLink = new FormatHTM(path + "/link/" + MakeLinkName(docChange) + "-quantities.htm", mapEntity, mapSchema, included))
                    {
                        htmLink.WriteLinkPage("../annex/annex-f/" + MakeLinkName(docChange) + "/quantities.htm");
                    }
                }

                foreach(DocModelView docView in docProject.ModelViews)
                {
                    if (docView.Code != null)
                    {
                        using (FormatHTM htmLink = new FormatHTM(path + "/link/listing-" + docView.Code.ToLower() + ".htm", mapEntity, mapSchema, included))
                        {
                            htmLink.WriteLinkPage("../annex/annex-a/" + MakeLinkName(docView) + "/index.htm");
                        }
                    }
                }

#if false
                foreach (string key in listIndex.Keys)
                {
                    DocObject obj = mapEntity[key];
                    if (included == null || included.ContainsKey(obj))
                    {
                        string schemaname = null;
                        if (mapSchema.TryGetValue(obj.Name, out schemaname))
                        {
                            using (FormatHTM htmLink = new FormatHTM(path + "/link/" + MakeLinkName(obj) + ".htm", mapEntity, mapSchema, included))
                            {
                                string linkurl = "../schema/" + schemaname.ToLower() + "/lexical/" + MakeLinkName(obj) + ".htm";
                                if (obj is DocPropertySet || obj is DocPropertyEnumeration)
                                {
                                    linkurl = "../schema/" + schemaname.ToLower() + "/pset/" + MakeLinkName(obj) + ".htm";
                                }
                                else if (obj is DocQuantitySet)
                                {
                                    linkurl = "../schema/" + schemaname.ToLower() + "/qset/" + MakeLinkName(obj) + ".htm";
                                }

                                htmLink.WriteLinkPage(linkurl);
                            }
                        }
                    }
                }
#endif

                // write links for each concept template recursively
                List<DocTemplateDefinition> listLink = new List<DocTemplateDefinition>();
                foreach (DocTemplateDefinition docTemplate in docProject.Templates)
                {
                    listLink.Add(docTemplate);
                    GenerateTemplateLink(listLink, mapEntity, mapSchema, included);
                    listLink.Clear();
                }

                // write links for each example recursively
                List<DocExample> listLinkExample = new List<DocExample>();
                if (docProject.Examples != null)
                {
                    foreach (DocExample docTemplate in docProject.Examples)
                    {
                        listLinkExample.Add(docTemplate);
                        GenerateExampleLink(listLinkExample, mapEntity, mapSchema, included);
                        listLinkExample.Clear();
                    }
                }

                htmIndex.WriteLine("</p>");
                htmIndex.WriteFooter(Properties.Settings.Default.Footer);
            }
        }
Example #45
0
        public void Save()
        {
            string xmlns = "http://www.buildingsmart-tech.org/ifcXML/IFC4/final";

            if (this.m_views != null && this.m_views.Length == 1 && !String.IsNullOrEmpty(this.m_views[0].Code))
            {
                DocModelView docView = this.m_views[0];

                if (!String.IsNullOrEmpty(docView.XsdUri))
                {
                    xmlns = docView.XsdUri;
                }
                else if (!String.IsNullOrEmpty(docView.Code))
                {
                    xmlns = "http://www.buildingsmart-tech.org/ifcXML/MVD4/" + docView.Code;
                }
            }

            // build map of types
            Dictionary <string, DocObject> map = new Dictionary <string, DocObject>();

            foreach (DocSection docSection in this.m_project.Sections)
            {
                foreach (DocSchema docSchema in docSection.Schemas)
                {
                    foreach (DocEntity docEnt in docSchema.Entities)
                    {
                        if (!map.ContainsKey(docEnt.Name))
                        {
                            map.Add(docEnt.Name, docEnt);
                        }
                    }
                    foreach (DocType docType in docSchema.Types)
                    {
                        if (!map.ContainsKey(docType.Name))
                        {
                            map.Add(docType.Name, docType);
                        }
                    }
                }
            }

            SortedList <string, DocDefined>     mapDefined  = new SortedList <string, DocDefined>(this);
            SortedList <string, DocEnumeration> mapEnum     = new SortedList <string, DocEnumeration>(this);
            SortedList <string, DocSelect>      mapSelect   = new SortedList <string, DocSelect>(this);
            SortedList <string, DocEntity>      mapEntity   = new SortedList <string, DocEntity>(this);
            SortedList <string, DocFunction>    mapFunction = new SortedList <string, DocFunction>(this);
            SortedList <string, DocGlobalRule>  mapRule     = new SortedList <string, DocGlobalRule>(this);

            SortedList <string, string> sort = new SortedList <string, string>(new FormatXSD(null));

            foreach (DocSection docSection in this.m_project.Sections)
            {
                foreach (DocSchema docSchema in docSection.Schemas)
                {
                    if (this.m_included == null || this.m_included.ContainsKey(docSchema))
                    {
                        foreach (DocType docType in docSchema.Types)
                        {
                            if (this.m_included == null || this.m_included.ContainsKey(docType))
                            {
                                if (docType is DocDefined)
                                {
                                    if (!mapDefined.ContainsKey(docType.Name))
                                    {
                                        mapDefined.Add(docType.Name, (DocDefined)docType);
                                    }
                                }
                                else if (docType is DocEnumeration)
                                {
                                    mapEnum.Add(docType.Name, (DocEnumeration)docType);
                                }
                                else if (docType is DocSelect)
                                {
                                    mapSelect.Add(docType.Name, (DocSelect)docType);
                                }
                            }
                        }

                        foreach (DocEntity docEnt in docSchema.Entities)
                        {
                            if (this.m_included == null || this.m_included.ContainsKey(docEnt))
                            {
                                if (!mapEntity.ContainsKey(docEnt.Name))
                                {
                                    mapEntity.Add(docEnt.Name, docEnt);
                                }

                                // check for any attributes that are lists of value types requiring wrapper, e.g. IfcTextFontName
                                foreach (DocAttribute docAttr in docEnt.Attributes)
                                {
                                    DocObject docObjRef = null;
                                    if (docAttr.DefinedType != null &&
                                        docAttr.GetAggregation() != DocAggregationEnum.NONE &&
                                        map.TryGetValue(docAttr.DefinedType, out docObjRef) &&
                                        docObjRef is DocDefined &&
                                        docAttr.XsdFormat == DocXsdFormatEnum.Element &&
                                        !(docAttr.XsdTagless == true) &&
                                        !sort.ContainsKey(docAttr.DefinedType))
                                    {
                                        sort.Add(docAttr.DefinedType, docAttr.DefinedType);
                                    }
                                }
                            }
                        }

                        foreach (DocFunction docFunc in docSchema.Functions)
                        {
                            if ((this.m_included == null || this.m_included.ContainsKey(docFunc)) && !mapFunction.ContainsKey(docFunc.Name))
                            {
                                mapFunction.Add(docFunc.Name, docFunc);
                            }
                        }

                        foreach (DocGlobalRule docRule in docSchema.GlobalRules)
                        {
                            if (this.m_included == null || this.m_included.ContainsKey(docRule))
                            {
                                mapRule.Add(docRule.Name, docRule);
                            }
                        }
                    }
                }
            }

            using (System.IO.StreamWriter writer = new System.IO.StreamWriter(this.m_filename))
            {
                writer.WriteLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
                writer.WriteLine("<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" " +
                                 "xmlns:ifc=\"" + xmlns + "\" " +
                                 "targetNamespace=\"" + xmlns + "\" " +
                                 "elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\" >");

                WriteResource(writer, "IfcDoc.xsd1.txt");

                // Entities
                writer.WriteLine("\t<!-- element and complex type declarations (for ENTITY definitions) -->");
                foreach (DocEntity docEntity in mapEntity.Values)
                {
                    writer.Write(FormatEntity(docEntity, map, this.m_included));
                }

                // Selects
                writer.WriteLine("\t<!-- group declarations (for SELECT data type definitions) -->");
                foreach (DocSelect docSelect in mapSelect.Values)
                {
                    writer.Write(FormatSelect(docSelect, map, this.m_included));
                }

                // Enumerations
                writer.WriteLine("\t<!-- enumeration type declarations (for ENUMERATION data type definitions) -->");
                foreach (DocEnumeration docEnum in mapEnum.Values)
                {
                    writer.Write(FormatEnum(docEnum));
                }

                // Defined Types
                writer.WriteLine("\t<!-- simple type declarations (for TYPE defined data type definitions) -->");
                foreach (DocDefined docDefined in mapDefined.Values)
                {
                    writer.Write(FormatDefinedSimple(docDefined));
                }

                WriteResource(writer, "IfcDoc.xsd2.txt");

                // sort selects alphabetically
                Queue <DocSelectItem> queue = new Queue <DocSelectItem>();
                foreach (DocSelect docSelect in mapSelect.Values)
                {
                    foreach (DocSelectItem docSelItem in docSelect.Selects)
                    {
                        queue.Enqueue(docSelItem);
                    }
                }
                List <DocDefined> listWrapper = new List <DocDefined>(); // keep track of wrapped types
                while (queue.Count > 0)
                {
                    DocSelectItem docItem = queue.Dequeue();

                    DocObject mapDef = null;
                    if (map.TryGetValue(docItem.Name, out mapDef))
                    {
                        if (mapDef is DocSelect)
                        {
                            // expand each
                            DocSelect docSub = (DocSelect)mapDef;
                            foreach (DocSelectItem dsi in docSub.Selects)
                            {
                                queue.Enqueue(dsi);
                            }
                        }
                        else if (!sort.ContainsKey(docItem.Name))
                        {
                            if (this.m_included == null || this.m_included.ContainsKey(mapDef))
                            {
                                sort.Add(docItem.Name, docItem.Name);
                            }
                        }
                    }
                }

                writer.WriteLine("\t<!-- base global wrapper declaration for atomic simple types (for embeded base schema definitions) -->");
                foreach (string docItem in sort.Values)
                {
                    DocObject mapDef = null;
                    if (map.TryGetValue(docItem, out mapDef) && mapDef is DocType)
                    {
                        if (this.m_included == null || this.m_included.ContainsKey(mapDef))
                        {
                            writer.Write(FormatTypeWrapper((DocType)mapDef, map));
                        }
                    }
                }

                writer.WriteLine("</xs:schema>");
            }
        }
        /// <summary>
        /// Formats table for single exchange
        /// </summary>
        /// <param name="def"></param>
        /// <returns></returns>
        private static string FormatExchange(DocProject docProject, DocModelView docView, DocExchangeDefinition def, Dictionary<string, DocObject> mapEntity, Dictionary<string, string> mapSchema)
        {
            // format content
            StringBuilder sb = new StringBuilder();

            if(!String.IsNullOrEmpty(def.ExchangeClass))
            {
                sb.AppendLine("<table class=\"gridtable\">");
                sb.AppendLine("<tr><th>Process</th><th>Sender</th><th>Receiver</th></tr>");
                sb.AppendLine("<tr><td>" + def.ExchangeClass + "</td><td>" + def.SenderClass + "</td><td>" + def.ReceiverClass + "</td></tr>");
                sb.AppendLine("</table>");
            }

            // 1. manual content
            sb.Append(def.Documentation);

            // 2. map of entities and templates -- Identity | Template | Import | Export
            sb.AppendLine("<p></p>");//This exchange involves the following entities:</p>");

            SortedList<string, DocConceptRoot> sortlist = new SortedList<string, DocConceptRoot>();

            foreach (DocConceptRoot docRoot in docView.ConceptRoots)
            {
                foreach (DocTemplateUsage docUsage in docRoot.Concepts)
                {
                    foreach (DocExchangeItem docReq in docUsage.Exchanges)
                    {
                        //if (docReq.Exchange == def && docReq.Requirement != DocExchangeRequirementEnum.NotRelevant && docReq.Requirement != DocExchangeRequirementEnum.Excluded && !sortlist.ContainsKey(docRoot.ApplicableEntity.Name))
                        if (docReq.Exchange == def && docReq.Requirement != DocExchangeRequirementEnum.NotRelevant && !sortlist.ContainsKey(docRoot.ApplicableEntity.Name))
                        {
                            sortlist.Add(docRoot.ApplicableEntity.Name, docRoot);
                        }
                    }
                }
            }

            // new style - table
            sb.AppendLine("<table class=\"exchange\">");
            sb.AppendLine("<tr><th colspan=\"5\"><img src=\"../../../img/mvd-" + MakeLinkName(def) + ".png\" />&nbsp; " + def.Name + "</th></tr>");
            sb.AppendLine("<tr><th>Entity/Concept</th><th>Attributes</th><th>Constraints</th><th>I</th><th>E</th></tr>");
            foreach (string ent in sortlist.Keys)
            {
                DocConceptRoot docRoot = sortlist[ent];

                sb.Append("<tr><td colspan=\"5\"><b><i>");
                sb.Append(docRoot.ApplicableEntity.Name);
                sb.AppendLine("</i></b></td></tr>");

                // determine schema
                string schema = mapSchema[ent];

                foreach (DocTemplateUsage docConcept in docRoot.Concepts)
                {
                    if (docConcept.Definition != null)
                    {
                        DocExchangeRequirementEnum reqImport = DocExchangeRequirementEnum.NotRelevant;
                        DocExchangeRequirementEnum reqExport = DocExchangeRequirementEnum.NotRelevant;
                        foreach (DocExchangeItem docReq in docConcept.Exchanges)
                        {
                            if (docReq.Exchange == def)
                            {
                                if (docReq.Applicability == DocExchangeApplicabilityEnum.Export)
                                {
                                    reqExport = docReq.Requirement;
                                }
                                else if (docReq.Applicability == DocExchangeApplicabilityEnum.Import)
                                {
                                    reqImport = docReq.Requirement;
                                }
                            }
                        }

                        if (reqImport != DocExchangeRequirementEnum.NotRelevant || reqExport != DocExchangeRequirementEnum.NotRelevant)
                        {
#if false
                            sb.Append("<tr><td>&nbsp;&nbsp;<a href=\"../../");
                            sb.Append(schema.ToLower());
                            sb.Append("/lexical/");
                            sb.Append(ent.ToLower());
                            sb.Append(".htm#");
                            sb.Append(MakeLinkName(docConcept.Definition));
                            sb.Append("\">");
                            sb.Append(docConcept.Definition.Name);
                            sb.Append("</a></td><td>");
#endif
                            sb.Append("<tr><td>&nbsp;&nbsp;<a href=\"../../templates/");
                            sb.Append(MakeLinkName(docConcept.Definition));
                            sb.Append(".htm\">");
                            sb.Append(docConcept.Definition.Name);
                            sb.Append("</a></td><td>");

                            bool first = true;
                            if (docConcept.Definition.Rules != null)
                            {
                                foreach (DocModelRule docRule in docConcept.Definition.Rules)
                                {
                                    if (!first)
                                    {
                                        sb.Append("<br/>");
                                    }
                                    sb.Append(docRule.Name);
                                    first = false;
                                }
                            }
                            sb.Append("</td><td>");


                            string table = FormatConceptTable(docProject, docView, docRoot.ApplicableEntity, docRoot, docConcept, mapEntity, mapSchema);
                            sb.Append(table);

                            sb.Append("</td><td>");
                            AppendRequirement(sb, reqImport, 3);
                            sb.Append("</td><td>");
                            AppendRequirement(sb, reqExport, 3);
                            sb.AppendLine("</td></tr>");

                        }
                    }
                }

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

            return sb.ToString();
        }