Exemplo n.º 1
0
        private void BuildCore(FileModel model, IHostService host)
        {
            var markdownService = (MarkdigMarkdownService)model.MarkdownFragmentsModel.Properties.MarkdigMarkdownService;
            var overwriteDocumentModelCreater = new OverwriteDocumentModelCreater(model.MarkdownFragmentsModel.OriginalFileAndType.File);
            var overwriteApplier = new OverwriteApplier(host, OverwriteModelType.MarkdownFragments);
            var schema           = model.Properties.Schema as DocumentSchema;
            List <OverwriteDocumentModel> overwriteDocumentModels;

            // 1. string => AST(MarkdownDocument)
            var ast = markdownService.Parse((string)model.MarkdownFragmentsModel.Content, model.MarkdownFragmentsModel.OriginalFileAndType.File);

            // 2 AST(MarkdownDocument) => MarkdownFragmentModel
            var fragments = new MarkdownFragmentsCreater().Create(ast).ToList();

            // 3. MarkdownFragmentModel => OverwriteDocument
            overwriteDocumentModels = fragments.Select(overwriteDocumentModelCreater.Create).ToList();
            model.MarkdownFragmentsModel.Content = overwriteDocumentModels;

            // Validate here as OverwriteDocumentModelCreater already filtered some invalid cases, e.g. duplicated H2
            ValidateWithSchema(fragments, model);

            // 4. Apply schema to OverwriteDocument, and merge with skeyleton YAML object
            foreach (var overwriteDocumentModel in overwriteDocumentModels)
            {
                var uidDefinitons = model.Uids.Where(s => s.Name == overwriteDocumentModel.Uid).ToList();
                if (uidDefinitons.Count == 0)
                {
                    Logger.LogWarning(
                        $"Unable to find UidDefinition for Uid: { overwriteDocumentModel.Uid}",
                        code: WarningCodes.Overwrite.InvalidMarkdownFragments);
                    continue;
                }
                if (uidDefinitons.Count > 1)
                {
                    Logger.LogWarning($"There are more than one UidDefinitions found for Uid {overwriteDocumentModel.Uid} in lines {string.Join(", ", uidDefinitons.Select(uid => uid.Line).ToList())}");
                }

                var ud                  = uidDefinitons[0];
                var jsonPointer         = new JsonPointer(ud.Path).GetParentPointer();
                var schemaForCurrentUid = jsonPointer.FindSchema(schema);
                var source              = jsonPointer.GetValue(model.Content);
                var overwriteObject     = overwriteApplier.BuildOverwriteWithSchema(model.MarkdownFragmentsModel, overwriteDocumentModel, schema);
                overwriteApplier.MergeContentWithOverwrite(ref source, overwriteObject, ud.Name, string.Empty, schemaForCurrentUid);
            }

            // 5. Validate schema after the merge
            using (new LoggerFileScope(model.LocalPathFromRoot))
            {
                ((SchemaDrivenDocumentProcessor)host.Processor).SchemaValidator.Validate(model.Content);
            }

            // 6. Re-export xrefspec after the merge
            overwriteApplier.UpdateXrefSpec(model, schema);

            model.LinkToUids      = model.LinkToUids.Union(model.MarkdownFragmentsModel.LinkToUids);
            model.LinkToFiles     = model.LinkToFiles.Union(model.MarkdownFragmentsModel.LinkToFiles);
            model.FileLinkSources = model.FileLinkSources.Merge(model.MarkdownFragmentsModel.FileLinkSources);
            model.UidLinkSources  = model.UidLinkSources.Merge(model.MarkdownFragmentsModel.UidLinkSources);
            model.MarkdownFragmentsModel.Content = overwriteDocumentModels;
        }
Exemplo n.º 2
0
        private void ApplyOverwriteToModel(OverwriteApplier overwriteApplier, string uid, IHostService host)
        {
            var ms       = host.LookupByUid(uid);
            var ods      = ms.Where(m => m.Type == DocumentType.Overwrite).ToList();
            var articles = ms.Except(ods).ToList();

            if (articles.Count == 0 || ods.Count == 0)
            {
                return;
            }

            if (articles.Count > 1)
            {
                throw new DocumentException($"{uid} is defined in multiple articles {articles.Select(s => s.LocalPathFromRoot).ToDelimitedString()}");
            }

            var model  = articles[0];
            var schema = model.Properties.Schema as DocumentSchema;

            using (new LoggerFileScope(model.LocalPathFromRoot))
            {
                var uidDefiniton = model.Uids.Where(s => s.Name == uid).ToList();
                if (uidDefiniton.Count == 0)
                {
                    throw new DocfxException($"Unable to find UidDefinition for Uid {uid}");
                }

                try
                {
                    foreach (var ud in uidDefiniton)
                    {
                        var jsonPointer         = new JsonPointer(ud.Path).GetParentPointer();
                        var schemaForCurrentUid = jsonPointer.FindSchema(schema);
                        var source = jsonPointer.GetValue(model.Content);

                        foreach (var od in ods)
                        {
                            using (new LoggerFileScope(od.LocalPathFromRoot))
                            {
                                foreach (var fm in ((IEnumerable <OverwriteDocumentModel>)od.Content).Where(s => s.Uid == uid))
                                {
                                    // Suppose that BuildOverwriteWithSchema do the validation of the overwrite object
                                    var overwriteObject = overwriteApplier.BuildOverwriteWithSchema(od, fm, schemaForCurrentUid);
                                    overwriteApplier.MergeContentWithOverwrite(ref source, overwriteObject, ud.Name, string.Empty, schemaForCurrentUid);

                                    model.LinkToUids      = model.LinkToUids.Union(od.LinkToUids);
                                    model.LinkToFiles     = model.LinkToFiles.Union(od.LinkToFiles);
                                    model.FileLinkSources = model.FileLinkSources.Merge(od.FileLinkSources);
                                    model.UidLinkSources  = model.UidLinkSources.Merge(od.UidLinkSources);
                                }
                            }
                        }
                    }

                    // 1. Validate schema after the merge
                    // TODO: Issue exists - however unable to identify which overwrite document the issue is from
                    ((SchemaDrivenDocumentProcessor)host.Processor).SchemaValidator.Validate(model.Content);

                    // 2. Re-export xrefspec after the merge
                    overwriteApplier.UpdateXrefSpec(model, schema);
                }
                catch (DocumentException e)
                {
                    // Log error here to preserve file info
                    Logger.LogError(e.Message);
                    throw;
                }
            }
        }
Exemplo n.º 3
0
        public override void Postbuild(ImmutableList<FileModel> models, IHostService host)
        {
            foreach (var uid in host.GetAllUids())
            {
                var ms = host.LookupByUid(uid);
                var ods = ms.Where(m => m.Type == DocumentType.Overwrite).ToList();
                var articles = ms.Except(ods).ToList();
                if (articles.Count == 0 || ods.Count == 0)
                {
                    continue;
                }

                if (articles.Count > 1)
                {
                    throw new DocumentException($"{uid} is defined in multiple articles {articles.Select(s => s.LocalPathFromRoot).ToDelimitedString()}");
                }

                var model = articles[0];
                var schema = model.Properties.Schema as DocumentSchema;
                using (new LoggerFileScope(model.LocalPathFromRoot))
                {
                    var uidDefiniton = model.Uids.Where(s => s.Name == uid).ToList();
                    if (uidDefiniton.Count == 0)
                    {
                        throw new DocfxException($"Unable to find UidDefinition for Uid {uid}");
                    }

                    foreach (var ud in uidDefiniton)
                    {
                        var jsonPointer = new JsonPointer(ud.Path).GetParentPointer();
                        var schemaForCurrentUid = jsonPointer.FindSchema(schema);
                        var source = jsonPointer.GetValue(model.Content);

                        foreach (var od in ods)
                        {
                            using (new LoggerFileScope(od.LocalPathFromRoot))
                            {
                                foreach (var fm in ((IEnumerable<OverwriteDocumentModel>)od.Content).Where(s => s.Uid == uid))
                                {
                                    // Suppose that BuildOverwriteWithSchema do the validation of the overwrite object
                                    var overwriteObject = BuildOverwriteWithSchema(od, fm, host, schemaForCurrentUid);
                                    _merger.Merge(ref source, overwriteObject, ud.Name, string.Empty, schemaForCurrentUid);

                                    model.LinkToUids = model.LinkToUids.Union(od.LinkToUids);
                                    model.LinkToFiles = model.LinkToFiles.Union(od.LinkToFiles);
                                    model.FileLinkSources = model.FileLinkSources.Merge(od.FileLinkSources);
                                    model.UidLinkSources = model.UidLinkSources.Merge(od.UidLinkSources);
                                }
                            }
                        }
                    }

                    // 1. Validate schema after the merge
                    ((SchemaDrivenDocumentProcessor)host.Processor).SchemaValidator.Validate(model.Content);

                    // 2. Re-export xrefspec after the merge
                    var context = new ProcessContext(host, model);
                    _xrefSpecUpdater.Process(model.Content, schema, context);

                    UpdateXRefSpecs((List<XRefSpec>)model.Properties.XRefSpecs, context.XRefSpecs);
                    UpdateXRefSpecs((List<XRefSpec>)model.Properties.ExternalXRefSpecs, context.ExternalXRefSpecs);
                }
            }
        }