Пример #1
0
        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);
        }
Пример #2
0
        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);
            }
        }
Пример #3
0
        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);
        }
Пример #4
0
        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);
            }
        }
Пример #5
0
 private void CopyMetadataToToc(TocViewModel vm)
 {
     foreach (var item in vm)
     {
         CopyMetadataToTocItem(item);
         foreach (var childItem in item.Items ?? Enumerable.Empty <TocItemViewModel>())
         {
             CopyMetadataToTocItem(childItem);
         }
     }
 }
Пример #6
0
 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);
 }
Пример #7
0
 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);
 }
Пример #8
0
        public static void DistinctTocItems(TocViewModel model)
        {
            foreach (var item in model)
            {
                if (item.Items != null)
                {
                    DistinctTocItems(item.Items);
                }
            }

            UniqueTocItemsCore(model);
        }
Пример #9
0
        public static void SortTocItems(TocViewModel model)
        {
            foreach (var item in model)
            {
                if (item.Items != null)
                {
                    SortTocItems(item.Items);
                }
            }

            model.Sort(SortByItemsAndName);
        }
Пример #10
0
 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>();
 }
Пример #11
0
        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);
            }
        }
Пример #12
0
        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
            });
        }
Пример #13
0
        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");
        }
Пример #14
0
        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);
        }
Пример #15
0
        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);
            }
        }
Пример #16
0
        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);
        }
Пример #17
0
        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);
            }
        }
Пример #18
0
 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);
     }
 }
Пример #19
0
        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));
        }
Пример #20
0
 public InitialState(string filePath)
 {
     Parents  = new Stack <TocItemViewModel>();
     Root     = new TocViewModel();
     FilePath = filePath;
 }
Пример #21
0
        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})");
        }
Пример #22
0
 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;
 }
Пример #23
0
 public static void SaveToc(string tocPath, TocViewModel model)
 {
     YamlUtility.Serialize(tocPath, model);
 }
Пример #24
0
 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;
 }
Пример #25
0
 protected async override void OnAppearing()
 {
     await TocViewModel.Init();
 }
Пример #26
0
 protected override bool OnBackButtonPressed()
 {
     return(TocViewModel.Back() || base.OnBackButtonPressed());
 }
Пример #27
0
 public InitialState(string filePath)
 {
     Parents = new Stack<TocItemViewModel>();
     Root = new TocViewModel();
     FilePath = filePath;
 }
Пример #28
0
        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);
            }
        }