public override void Build(FileModel model, IHostService host) { switch (model.Type) { case DocumentType.Article: var restApi = (RestApiRootItemViewModel)model.Content; BuildItem(host, restApi, model); if (restApi.Children != null) { foreach (var item in restApi.Children) { BuildItem(host, item, model); } } if (restApi.Tags != null) { foreach (var tag in restApi.Tags) { BuildTag(host, tag, model); } } break; case DocumentType.Overwrite: BuildItem(host, model); break; default: throw new NotSupportedException(); } }
public override void Build(FileModel model, IHostService host) { var toc = (TocItemViewModel)model.Content; BuildCore(toc, model, host); // todo : metadata. }
private void ValidateToc(TocItemViewModel item, FileModel model, IHostService hostService) { if (!PathUtility.IsRelativePath(item.Href)) return; var file = model.File; var originalFile = model.OriginalFileAndType.File; // Special handle for folder ends with '/' FileAndType originalTocFile = null; string fileName = Path.GetFileName(item.Href); if (string.IsNullOrEmpty(fileName)) { var href = item.Href + "toc.yml"; var absHref = (RelativePath)file + (RelativePath)href; string tocPath = absHref.GetPathFromWorkingFolder(); if (!hostService.SourceFiles.TryGetValue(tocPath, out originalTocFile)) { href = item.Href + "toc.md"; absHref = (RelativePath)file + (RelativePath)href; tocPath = absHref.GetPathFromWorkingFolder(); if (!hostService.SourceFiles.TryGetValue(tocPath, out originalTocFile)) { var error = $"Unable to find either toc.yml or toc.md inside {item.Href}. Make sure the file is included in config file docfx.json!"; Logger.LogError(error, file: model.LocalPathFromRepoRoot); throw new DocumentException(error); } } Logger.LogInfo($"TOC file {href} inside {item.Href} is used", file: model.LocalPathFromRepoRoot); item.Href = href; item.OriginalHref = item.Href; } // Set default homepage SetDefaultHomepage(item, originalTocFile, model); }
public IEnumerable<RestApiTagViewModel> GetTagsFromOverwriteDocument(FileModel overwriteModel, string uid, IHostService host) { return OverwriteDocumentReader.Transform<RestApiTagViewModel>( overwriteModel, uid, s => BuildRestApiDocument.BuildTag(host, s, overwriteModel, content => content != null && content.Trim() == Constants.ContentPlaceholder)); }
private void BuildCore(TocItemViewModel item, FileModel model, IHostService hostService) { if (item == null) { return; } var linkToUids = new HashSet<string>(); var linkToFiles = new HashSet<string>(); if (Utility.IsSupportedRelativeHref(item.Href)) { linkToFiles.Add(ParseFile(item.Href)); } if (Utility.IsSupportedRelativeHref(item.Homepage)) { linkToFiles.Add(ParseFile(item.Homepage)); } if (!string.IsNullOrEmpty(item.TopicUid)) { linkToUids.Add(item.TopicUid); } model.LinkToUids = model.LinkToUids.Union(linkToUids); model.LinkToFiles = model.LinkToFiles.Union(linkToFiles); if (item.Items != null) { foreach (var i in item.Items) { BuildCore(i, model, hostService); } } }
public IEnumerable<ItemViewModel> GetItemsFromOverwriteDocument(FileModel fileModel, string uid, IHostService host) { return OverwriteDocumentReader.Transform<ItemViewModel>( fileModel, uid, s => BuildManagedReferenceDocument.BuildItem(host, s, fileModel, content => content != null && content.Trim() == Constants.ContentPlaceholder)); }
public SaveResult Save(FileModel model) { if (model.Type != DocumentType.Article) { throw new NotSupportedException(); } string path = Path.Combine(model.BaseDir, model.File); try { JsonUtility.Serialize(path, model.Content); } catch (PathTooLongException e) { Logger.LogError($"Path \"{path}\": {e.Message}"); throw; } return new SaveResult { DocumentType = model.DocumentType ?? "Conceptual", ModelFile = model.File, LinkToFiles = model.Properties.LinkToFiles, LinkToUids = model.Properties.LinkToUids, }; }
public override SaveResult Save(FileModel model) { if (model.FileAndType != model.OriginalFileAndType) { var targetFile = Path.Combine(model.BaseDir, model.File); Directory.CreateDirectory(Path.GetDirectoryName(targetFile)); File.Copy( Path.Combine(model.OriginalFileAndType.BaseDir, model.OriginalFileAndType.File), targetFile, true); File.SetAttributes(targetFile, FileAttributes.Normal); } var result = new SaveResult { DocumentType = "Resource", ResourceFile = model.File, }; if (model.Content != null) { // For resources, e.g. image.png, file extension is kept result.FileWithoutExtension = model.File; } return result; }
private void BuildItem(IHostService host, ItemViewModel item, FileModel model) { item.Summary = Markup(host, item.Summary, model); item.Remarks = Markup(host, item.Remarks, model); item.Conceptual = Markup(host, item.Conceptual, model); if (item.Syntax?.Return?.Description != null) { item.Syntax.Return.Description = Markup(host, item.Syntax?.Return?.Description, model); } var parameters = item.Syntax?.Parameters; if (parameters != null) { foreach (var parameter in parameters) { parameter.Description = Markup(host, parameter.Description, model); } } if (item.Exceptions != null) { foreach (var exception in item.Exceptions) { exception.Description = Markup(host, exception.Description, model); } } }
public override SaveResult Save(FileModel model) { return new SaveResult { DocumentType = "Toc", ModelFile = model.File, }; }
public override void Build(FileModel model, IHostService host) { if (model.Type != DocumentType.Article && model.Type != DocumentType.Resource) { throw new NotSupportedException(); } // todo : metadata. }
public SaveResult Save(FileModel model) { return new SaveResult { DocumentType = "Conceptual", ModelFile = model.File, LinkToFiles = linkToFiles.ToImmutableArray(), }; }
private void UpdateRelativePathAndAddTocMap(TocViewModel toc, FileModel model, HashSet<string> links, Dictionary<string, HashSet<string>> tocMap, IHostService hostService) { if (toc == null) return; var file = model.File; var originalFile = model.OriginalFileAndType.File; foreach (var item in toc) { if (PathUtility.IsRelativePath(item.Href)) { // Special handle for folder ends with '/' FileAndType originalTocFile = null; string fileName = Path.GetFileName(item.Href); if (string.IsNullOrEmpty(fileName)) { var href = item.Href + "toc.yml"; var absHref = (RelativePath)file + (RelativePath)href; string tocPath = absHref.GetPathFromWorkingFolder(); if (!hostService.SourceFiles.TryGetValue(tocPath, out originalTocFile)) { href = item.Href + "toc.md"; absHref = (RelativePath)file + (RelativePath)href; tocPath = absHref.GetPathFromWorkingFolder(); if (!hostService.SourceFiles.TryGetValue(tocPath, out originalTocFile)) { var error = $"Unable to find either toc.yml or toc.md inside {item.Href}. Make sure the file is included in config file docfx.json!"; Logger.LogError(error, file: model.LocalPathFromRepoRoot); throw new DocumentException(error); } } Logger.LogInfo($"TOC file {href} inside {item.Href} is used", file: model.LocalPathFromRepoRoot); item.Href = href; item.OriginalHref = item.Href; } // Add toc.yml to tocMap before change item.Href to home page item.Href = ((RelativePath)file + (RelativePath)item.Href).GetPathFromWorkingFolder(); if (item.OriginalHref != null) item.OriginalHref = ((RelativePath)file + (RelativePath)item.OriginalHref).GetPathFromWorkingFolder(); HashSet<string> value; if (tocMap.TryGetValue(item.Href, out value)) { value.Add(originalFile); } else { tocMap[item.Href] = new HashSet<string>(FilePathComparer.OSPlatformSensitiveComparer) { originalFile }; } links.Add(item.Href); SetHomepage(item, originalTocFile, model); } UpdateRelativePathAndAddTocMap(item.Items, model, links, tocMap, hostService); } }
public override SaveResult Save(FileModel model) { return new SaveResult { DocumentType = "Toc", ModelFile = model.File, TocMap = model.Properties.TocMap, LinkToFiles = model.Properties.LinkToFiles }; }
public override SaveResult Save(FileModel model) { return new SaveResult { DocumentType = "Toc", FileWithoutExtension = Path.ChangeExtension(model.File, null), LinkToFiles = model.LinkToFiles.ToImmutableArray(), LinkToUids = model.LinkToUids, }; }
public void Build(FileModel model, IHostService host) { model.File = Path.ChangeExtension(model.File, ".json"); var toc = (TocViewModel)model.Content; HashSet<string> links = new HashSet<string>(); Dictionary<string, HashSet<string>> tocMap = new Dictionary<string, HashSet<string>>(); UpdateRelativePathAndAddTocMap(toc, model, links, tocMap, host); model.Properties.LinkToFiles = links.ToImmutableArray(); model.Properties.TocMap = tocMap.ToImmutableDictionary(); // todo : metadata. }
public SaveResult Save(FileModel model) { HashSet<string> linkToFiles = CollectLinksAndFixDocument(model); return new SaveResult { DocumentType = "Conceptual", ModelFile = model.File, LinkToFiles = linkToFiles.ToImmutableArray(), }; }
private static MergeItem CreateMergeItem(string majorUid, FileModel model, IHostService host) { var vm = (PageViewModel)model.Content; var majorItem = vm.Items.Find(item => item.Uid == majorUid); if (majorItem == null) { host.LogError("Cannot find uid in model.", file: model.File); return null; } return CreateMergeItemCore(majorItem, vm); }
private string Markup(IHostService host, string markdown, FileModel model) { if (string.IsNullOrEmpty(markdown)) { return markdown; } var mr = host.Markup(markdown, model.FileAndType); ((HashSet<string>)model.Properties.LinkToFiles).UnionWith(mr.LinkToFiles); ((HashSet<string>)model.Properties.LinkToUids).UnionWith(mr.LinkToUids); return mr.Html; }
public override void Build(FileModel model, IHostService host) { if (model.Type != DocumentType.Article) { return; } var content = (Dictionary<string, object>)model.Content; var markdown = (string)content[ConceputalKey]; var result = host.Markup(markdown, model.FileAndType); var htmlInfo = SeperateHtml(result.Html); content["title"] = htmlInfo.Title; content["rawTitle"] = htmlInfo.RawTitle; content[ConceputalKey] = htmlInfo.Content; if (result.YamlHeader != null && result.YamlHeader.Count > 0) { foreach (var item in result.YamlHeader) { if (item.Key == "uid") { var uid = item.Value as string; if (!string.IsNullOrWhiteSpace(uid)) { model.Uids = new[] { uid }.ToImmutableArray(); content["uid"] = item.Value; } } else { content[item.Key] = item.Value; if (item.Key == DocumentTypeKey) { model.DocumentType = item.Value as string; } } } } model.Properties.LinkToFiles = result.LinkToFiles; model.Properties.LinkToUids = result.LinkToUids; model.Properties.XrefSpec = null; if (model.Uids.Length > 0) { model.Properties.XrefSpec = new XRefSpec { Uid = model.Uids[0], Name = TitleThumbnail(content["title"].ToString() ?? model.Uids[0], TitleThumbnailMaxLength), Href = ((RelativePath)model.File).GetPathFromWorkingFolder() }; } model.File = Path.ChangeExtension(model.File, ".json"); }
public override void UpdateHref(FileModel model, Func<string, string, string> updater) { if (updater == null) return; var toc = (TocViewModel)model.Content; var path = model.File; if (toc.Count > 0) { foreach (var item in toc) { UpdateTocItemHref(item, path, updater); } } }
public override void Build(FileModel model, IHostService host) { if (model.Type != DocumentType.Article) { return; } if (!host.HasMetadataValidation) { return; } host.ValidateInputMetadata( model.OriginalFileAndType.File, ((Dictionary<string, object>)model.Content).ToImmutableDictionary().Remove(ConceptualKey)); }
public SaveResult Save(FileModel model) { var toc = (TocViewModel)model.Content; var path = (RelativePath)model.OriginalFileAndType.File; JsonUtility.Serialize(Path.Combine(model.BaseDir, model.File), toc); return new SaveResult { DocumentType = "Toc", ModelFile = model.File, TocMap = model.Properties.TocMap, LinkToFiles = model.Properties.LinkToFiles }; }
private void Normalize(TocViewModel toc, FileModel model, IHostService hostService) { if (toc == null) return; foreach (var item in toc) { ValidateToc(item, model, hostService); var relativeToFile = (RelativePath)model.File; item.Href = NormalizeHref(item.Href, relativeToFile); item.OriginalHref = NormalizeHref(item.OriginalHref, relativeToFile); item.Homepage = NormalizeHref(item.Homepage, relativeToFile); Normalize(item.Items, model, hostService); } }
public static RestApiItemViewModelBase BuildItem(IHostService host, RestApiItemViewModelBase item, FileModel model, Func<string, bool> filter = null) { item.Summary = Markup(host, item.Summary, model, filter); item.Description = Markup(host, item.Description, model, filter); if (model.Type != DocumentType.Overwrite) { item.Conceptual = Markup(host, item.Conceptual, model, filter); item.Remarks = Markup(host, item.Remarks, model, filter); } var rootModel = item as RestApiRootItemViewModel; if (rootModel != null) { // Mark up recursively for swagger root except for children and tags foreach (var jToken in rootModel.Metadata.Values.OfType<JToken>()) { MarkupRecursive(jToken, host, model, filter); } } var childModel = item as RestApiChildItemViewModel; if (childModel?.Parameters != null) { foreach (var param in childModel.Parameters) { param.Description = Markup(host, param.Description, model, filter); foreach (var jToken in param.Metadata.Values.OfType<JToken>()) { MarkupRecursive(jToken, host, model, filter); } } } if (childModel?.Responses != null) { foreach (var response in childModel.Responses) { response.Description = Markup(host, response.Description, model, filter); foreach (var jToken in response.Metadata.Values.OfType<JToken>()) { MarkupRecursive(jToken, host, model, filter); } } } return item; }
public override void UpdateHref(FileModel model, IDocumentBuildContext context) { var toc = (TocViewModel)model.Content; var key = model.Key; // Add current folder to the toc mapping, e.g. `a/` maps to `a/toc` var directory = ((RelativePath)key).GetPathFromWorkingFolder().GetDirectoryPath(); context.RegisterToc(key, directory); if (toc.Count > 0) { foreach (var item in toc) { UpdateTocItemHref(item, model, context); } } }
public override void Build(FileModel model, IHostService host) { switch (model.Type) { case DocumentType.Article: var page = (PageViewModel)model.Content; foreach (var item in page.Items) { BuildItem(host, item, model); } break; case DocumentType.Overwrite: BuildItem(host, model); break; default: throw new NotSupportedException(); } }
public FileModel Load(FileAndType file, ImmutableDictionary<string, object> metadata) { switch (file.Type) { case DocumentType.Article: var page = YamlUtility.Deserialize<PageViewModel>(Path.Combine(file.BaseDir, file.File)); if (page.Metadata == null) { page.Metadata = metadata.ToDictionary(p => p.Key, p => p.Value); } else { foreach (var item in metadata) { if (!page.Metadata.ContainsKey(item.Key)) { page.Metadata[item.Key] = item.Value; } } } var result = new FileModel(file, page, serializer: new BinaryFormatter()) { Uids = (from item in page.Items select item.Uid).ToImmutableArray(), }; result.Properties.LinkToFiles = new HashSet<string>(); result.Properties.LinkToUids = new HashSet<string>(); return result; case DocumentType.Override: var overrides = MarkdownReader.ReadMarkdownAsOverride(file.BaseDir, file.File); return new FileModel(file, overrides, serializer: new BinaryFormatter()) { Uids = (from item in overrides select item.Uid).ToImmutableArray(), Properties = { LinkToFiles = new HashSet<string>(), LinkToUids = new HashSet<string>(), } }; default: throw new NotSupportedException(); } }
private void UpdateTocItemHref(TocItemViewModel toc, FileModel model, IDocumentBuildContext context) { ResolveUid(toc, model, context); RegisterTocMap(toc, model.Key, context); if (!string.IsNullOrEmpty(toc.Homepage)) { toc.Href = toc.Homepage; } toc.Href = GetUpdatedHref(toc.Href, model, context); toc.OriginalHref = GetUpdatedHref(toc.OriginalHref, model, context); if (toc.Items != null && toc.Items.Count > 0) { foreach (var item in toc.Items) { UpdateTocItemHref(item, model, context); } } }
private object MergeCore(string majorUid, FileModel model, IEnumerable<FileModel> others, IHostService host) { var item = CreateMergeItem(majorUid, model, host); if (item == null) { return model.Content; } foreach (var other in others) { var otherItem = CreateMergeItem(majorUid, other, host); if (otherItem == null) { continue; } MergeCore(item, otherItem); } return ConvertToVM(item); }