public void AddObject(ItemViewModel obj) { //try to find object type TOC entry TocViewModel tocTypeEntry = null; string objectTypeUid = UidHelpers.GetObjectTypeGroupUid(ProjectUid, obj.Type); if (this.tocObjectTypesLevel.ContainsKey(objectTypeUid)) { tocTypeEntry = this.tocObjectTypesLevel[objectTypeUid]; } else { tocTypeEntry = new TocViewModel(); tocTypeEntry.Uid = objectTypeUid; tocTypeEntry.Name = obj.Type + "s"; tocTypeEntry.Items = new List <TocViewModel>(); TOCRoot.Items.Add(tocTypeEntry); tocObjectTypesLevel.Add(tocTypeEntry.Uid, tocTypeEntry); } TocViewModel tocDocElement = new TocViewModel(); tocDocElement.Uid = obj.Uid; tocDocElement.Name = obj.Name; tocTypeEntry.Items.Add(tocDocElement); objectCache.Add(obj.Uid, obj); }
private static void UniqueTocItemsCore(TocViewModel model) { var count = model.Count(); var i = 0; var j = 1; while (j < count) { if (string.Equals(model[i].Name, model[j].Name)) { model[i].Items.AddRange(model[j].Items); model[i].Items.Sort(SortByItemsAndName); j++; } else { i++; model[i] = model[j]; j++; } } if (i < count) { model.RemoveRange(i + 1, count - i - 1); } }
protected ItemViewModel BuildObjectTypePage(TocViewModel tocObjectType) { //build object type item ItemViewModel objectTypeItem = new ItemViewModel(); objectTypeItem.Uid = tocObjectType.Uid; objectTypeItem.Name = tocObjectType.Name; objectTypeItem.ItemType = ItemType.Group; objectTypeItem.Items = new List <ItemViewModel>(); //add items foreach (TocViewModel tocObj in tocObjectType.Items) { ItemViewModel obj = new ItemViewModel(); obj.Uid = tocObj.Uid; obj.Name = tocObj.Name; obj.ItemType = ItemType.Object; if (objectCache.ContainsKey(tocObj.Uid)) { ItemViewModel srcObj = objectCache[tocObj.Uid]; obj.ItemType = srcObj.ItemType; obj.ObjectId = srcObj.ObjectId; obj.Summary = srcObj.Summary; } objectTypeItem.Items.Add(obj); } return(objectTypeItem); }
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); } }
private void CopyMetadataToToc(TocViewModel vm) { foreach (var item in vm) { CopyMetadataToTocItem(item); foreach (var childItem in item.Items ?? Enumerable.Empty <TocItemViewModel>()) { CopyMetadataToTocItem(childItem); } } }
private string GetDefaultHomepage(TocViewModel toc) { foreach (var item in toc) { var href = TreeIterator.PreorderFirstOrDefault(item, s => s.Items, s => IsValidHomepageLink(s.Href)); if (href != null) { return(href.Href); } } return(null); }
private TocItemViewModel GetDefaultHomepageItem(TocViewModel toc) { foreach (var item in toc) { var tocItem = TreeIterator.PreorderFirstOrDefault(item, s => s.Items, s => IsValidHomepageLink(s)); if (tocItem != null) { return(tocItem); } } return(null); }
public static void DistinctTocItems(TocViewModel model) { foreach (var item in model) { if (item.Items != null) { DistinctTocItems(item.Items); } } UniqueTocItemsCore(model); }
public static void SortTocItems(TocViewModel model) { foreach (var item in model) { if (item.Items != null) { SortTocItems(item.Items); } } model.Sort(SortByItemsAndName); }
public void CreateTOC() { //create TOC structure this.TOCStructure = new List <TocViewModel>(); //create TOC root TOCRoot = new TocViewModel(); this.TOCStructure.Add(TOCRoot); TOCRoot.Uid = ProjectUid; TOCRoot.Name = ProjectCaption; TOCRoot.Items = new List <TocViewModel>(); //create TOC object type level cache tocObjectTypesLevel = new Dictionary <string, TocViewModel>(); }
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 override FileModel Load(FileAndType file, ImmutableDictionary <string, object> metadata) { var filePath = Path.Combine(file.BaseDir, file.File); TocViewModel toc = LoadSingleToc(filePath); var repoDetail = GitUtility.GetGitDetail(filePath); // todo : metadata. return(new FileModel(file, toc) { Uids = new[] { file.File }.ToImmutableArray(), LocalPathFromRepoRoot = repoDetail?.RelativePath }); }
static void Main(string[] args) { var items = new List <TocItemViewModel>(); foreach (var file in args) { var toc = YamlUtility.Deserialize <TocViewModel>(file); items.AddRange(toc); } var combined = new TocViewModel(); combined.AddRange(items.OrderBy(item => item.Name)); YamlUtility.Serialize(Console.Out, combined, "YamlMime:TableOfContent"); }
private static IList <string> ResolveAndExportYamlMetadata( Dictionary <string, MetadataItem> allMembers, Dictionary <string, ReferenceItem> allReferences, string folder, string indexFileName, string tocFileName, string apiFolder, bool preserveRawInlineComments, IEnumerable <string> externalReferencePackages) { var outputFiles = new List <string>(); var model = YamlMetadataResolver.ResolveMetadata(allMembers, allReferences, apiFolder, preserveRawInlineComments, externalReferencePackages); // 1. generate toc.yml outputFiles.Add(tocFileName); model.TocYamlViewModel.Type = MemberType.Toc; // TOC do not change var tocViewModel = TocViewModel.FromModel(model.TocYamlViewModel); string tocFilePath = Path.Combine(folder, tocFileName); YamlUtility.Serialize(tocFilePath, tocViewModel); ApiReferenceViewModel indexer = new ApiReferenceViewModel(); // 2. generate each item's yaml var members = model.Members; foreach (var memberModel in members) { var outputPath = memberModel.Name + Constants.YamlExtension; outputFiles.Add(Path.Combine(apiFolder, outputPath)); string itemFilePath = Path.Combine(folder, apiFolder, outputPath); Directory.CreateDirectory(Path.GetDirectoryName(itemFilePath)); var memberViewModel = PageViewModel.FromModel(memberModel); YamlUtility.Serialize(itemFilePath, memberViewModel); Logger.Log(LogLevel.Verbose, $"Metadata file for {memberModel.Name} is saved to {itemFilePath}."); AddMemberToIndexer(memberModel, outputPath, indexer); } // 3. generate manifest file outputFiles.Add(indexFileName); string indexFilePath = Path.Combine(folder, indexFileName); JsonUtility.Serialize(indexFilePath, indexer); return(outputFiles); }
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); } }
private TocViewModel UpdateOriginalHref(TocViewModel toc, RelativePath relativePath) { if (toc == null || relativePath.SubdirectoryCount == 0) { return(toc); } foreach (var item in toc) { item.OriginalHomepage = GetRelativePath(item.OriginalHomepage, relativePath); item.OriginalHref = GetRelativePath(item.OriginalHref, relativePath); item.OriginalTocHref = GetRelativePath(item.OriginalTocHref, relativePath); item.OriginalTopicHref = GetRelativePath(item.OriginalTopicHref, relativePath); item.Items = UpdateOriginalHref(item.Items, relativePath); } return(toc); }
public static void ResolveHref(string tocPath, TocViewModel model) { if (model == null) { return; } if (string.IsNullOrEmpty(tocPath)) { return; } var baseDir = Path.GetDirectoryName(tocPath); foreach (var item in model) { ResolveHref(baseDir, item); } }
private static void WriteTocModelToFile(TocViewModel tocModel, StreamWriter writer, int level) { if (tocModel == null) { return; } foreach (var item in tocModel) { if (!string.IsNullOrEmpty(item.Href)) { writer.WriteLine($"{new string('#', level)} [{item.Name}]({item.Href})"); } else { writer.WriteLine($"{new string('#', level)} {item.Name}"); } WriteTocModelToFile(item.Items, writer, level + 1); } }
private static ParseResult ResolveAndExportYamlMetadata(Dictionary <string, MetadataItem> allMembers, string folder, string indexFileName, string tocFileName, string apiFolder) { var model = YamlMetadataResolver.ResolveMetadata(allMembers, apiFolder); // 1. generate toc.yml model.TocYamlViewModel.Href = tocFileName; model.TocYamlViewModel.Type = MemberType.Toc; // TOC do not change var tocViewModel = TocViewModel.Convert(model.TocYamlViewModel); string tocFilePath = Path.Combine(folder, tocFileName); using (StreamWriter sw = new StreamWriter(tocFilePath)) { YamlUtility.Serialize(sw, tocViewModel); } // 2. generate api.yml string indexFilePath = Path.Combine(folder, indexFileName); using (StreamWriter sw = new StreamWriter(indexFilePath)) { YamlUtility.Serialize(sw, model.Indexer); } // 3. generate each item's yaml var members = model.Members; foreach (var memberModel in members) { string itemFilepath = Path.Combine(folder, apiFolder, memberModel.Href); Directory.CreateDirectory(Path.GetDirectoryName(itemFilepath)); using (StreamWriter sw = new StreamWriter(itemFilepath)) { var memberViewModel = OnePageViewModel.Convert(memberModel); YamlUtility.Serialize(sw, memberViewModel); ParseResult.WriteToConsole(ResultLevel.Success, "Metadata file for {0} is saved to {1}", memberModel.Name, itemFilepath); } } return(new ParseResult(ResultLevel.Success)); }
public InitialState(string filePath) { Parents = new Stack <TocItemViewModel>(); Root = new TocViewModel(); FilePath = filePath; }
private static void SplitToc(string originalTocPath) { if (!Path.IsPathRooted(originalTocPath)) { originalTocPath = Path.GetFullPath(originalTocPath); } if (!File.Exists(originalTocPath)) { throw new FileNotFoundException($"The path of toc file: {originalTocPath} can't be found"); } var originalTocDir = Path.GetDirectoryName(originalTocPath); if (originalTocDir == null) { throw new Exception($"The directory of {originalTocPath} can't be null"); } TocViewModel tocModel; using (var stream = File.OpenRead(originalTocPath)) using (var reader = new StreamReader(stream)) { try { tocModel = YamlUtility.Deserialize <TocViewModel>(reader); } catch (YamlException ex) { Console.WriteLine($"Error occurs while parsing toc {originalTocPath}, please check if the format is correct. {ex.Message}"); throw; } } if (tocModel == null) { Console.WriteLine($"No toc model parsed for {originalTocPath}."); return; } var mergedTocModel = new TocViewModel(); foreach (var ns in tocModel) { var splittedTocPath = Path.Combine(originalTocDir, "_splitted", ns.Uid, "toc.yml"); var splittedTocRelativePath = PathUtility.MakeRelativePath(originalTocDir, splittedTocPath); var reversedRelativePath = PathUtility.MakeRelativePath(Path.GetDirectoryName(splittedTocPath), originalTocDir); ProcessHref(ns, reversedRelativePath.Replace('\\', '/')); var splittedTocDir = Path.GetDirectoryName(splittedTocPath); if (splittedTocDir == null) { throw new Exception($"The directory of {splittedTocPath} can't be null"); } if (!Directory.Exists(splittedTocDir)) { Directory.CreateDirectory(splittedTocDir); } var splittedTocItem = new TocItemViewModel { Uid = ns.Uid, Name = ns.Name, Items = ns.Items }; if (ns.Metadata != null) { splittedTocItem.Metadata = ns.Metadata; } var splittedTocModel = new TocViewModel(new List <TocItemViewModel> { splittedTocItem }); YamlUtility.Serialize(splittedTocPath, splittedTocModel); Console.WriteLine($"Create new splitted toc ({splittedTocPath})"); var mergedTocItem = new TocItemViewModel { Uid = ns.Uid, Name = ns.Name, Href = Path.GetDirectoryName(splittedTocRelativePath).Replace('\\', '/') + "/" }; mergedTocModel.Add(mergedTocItem); } YamlUtility.Serialize(originalTocPath, mergedTocModel); Console.WriteLine($"Rewrite original toc file ({originalTocPath})"); }
private string GetDefaultHomepage(TocViewModel toc) { foreach (var item in toc) { var href = TreeIterator.PreorderFirstOrDefault(item, s => s.Items, s => IsValidHomepageLink(s.Href)); if (href != null) { return href.Href; } } return null; }
public static void SaveToc(string tocPath, TocViewModel model) { YamlUtility.Serialize(tocPath, model); }
private TocItemViewModel GetDefaultHomepageItem(TocViewModel toc) { foreach (var item in toc) { var tocItem = TreeIterator.PreorderFirstOrDefault(item, s => s.Items, s => IsValidHomepageLink(s)); if (tocItem != null) { return tocItem; } } return null; }
protected async override void OnAppearing() { await TocViewModel.Init(); }
protected override bool OnBackButtonPressed() { return(TocViewModel.Back() || base.OnBackButtonPressed()); }
public InitialState(string filePath) { Parents = new Stack<TocItemViewModel>(); Root = new TocViewModel(); FilePath = filePath; }
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); } }