public void TestYamlHeaderParser() { // spaces are allowed string input = @" --- uid: abc --- "; var yamlHeaders = YamlHeaderParser.Select(input); Assert.Equal(1, yamlHeaders.Count); Assert.Equal("abc", yamlHeaders[0].Id); // --- Should also work input = @"--- uid: abc --- "; yamlHeaders = YamlHeaderParser.Select(input); Assert.Equal(1, yamlHeaders.Count); Assert.Equal("abc", yamlHeaders[0].Id); // --- should be start with uid input = @" --- id: abc --- "; yamlHeaders = YamlHeaderParser.Select(input); Assert.Equal(0, yamlHeaders.Count); }
private static IEnumerable <T> ReadMarkDownCore <T>(string file) where T : IOverrideDocumentViewModel { var content = File.ReadAllText(file); var repoInfo = GitUtility.GetGitDetail(file); var lineIndex = GetLineIndex(content).ToList(); var yamlDetails = YamlHeaderParser.Select(content); if (yamlDetails == null) { yield break; } var sections = from detail in yamlDetails let id = detail.Id from ms in detail.MatchedSections from location in ms.Value.Locations orderby location.StartLocation descending select new { Detail = detail, Id = id, Location = location }; var currentEnd = Coordinate.GetCoordinate(content); foreach (var item in sections) { if (!string.IsNullOrEmpty(item.Id)) { int start = lineIndex[item.Location.EndLocation.Line] + item.Location.EndLocation.Column + 1; int end = lineIndex[currentEnd.Line] + currentEnd.Column + 1; using (var sw = new StringWriter()) { YamlUtility.Serialize(sw, item.Detail.Properties); using (var sr = new StringReader(sw.ToString())) { var vm = YamlUtility.Deserialize <T>(sr); vm.Conceptual = content.Substring(start, end - start + 1); vm.Documentation = new SourceDetail { Remote = repoInfo, StartLine = item.Location.EndLocation.Line, EndLine = currentEnd.Line }; vm.Uid = item.Id; yield return(vm); } } } currentEnd = item.Location.StartLocation; } }
private static IEnumerable <OverwriteDocumentModel> ReadMarkDownCore(string file) { var content = File.ReadAllText(file); var repoInfo = GitUtility.GetGitDetail(file); var lineIndex = GetLineIndex(content).ToList(); var yamlDetails = YamlHeaderParser.Select(content); var sections = from detail in yamlDetails let id = detail.Id from location in detail.MatchedSection.Locations orderby location.StartLocation descending select new { Detail = detail, Id = id, Location = location }; var currentEnd = Coordinate.GetCoordinate(content); foreach (var item in sections) { if (!string.IsNullOrEmpty(item.Id)) { int start = lineIndex[item.Location.EndLocation.Line] + item.Location.EndLocation.Column + 1; int end = lineIndex[currentEnd.Line] + currentEnd.Column + 1; yield return(new OverwriteDocumentModel { Uid = item.Id, Metadata = item.Detail.Properties, Conceptual = content.Substring(start, end - start + 1), Documentation = new SourceDetail { Remote = repoInfo, StartLine = item.Location.EndLocation.Line, EndLine = currentEnd.Line, Path = Path.GetFullPath(file).ToDisplayPath() } }); } currentEnd = item.Location.StartLocation; } }
public ParseResult Run(MapFileItemViewModel item, IndexerContext context) { var filePath = context.MarkdownFilePath; var content = context.MarkdownContent; var apis = context.ExternalApiIndex; var apiMapFileOutputFolder = context.ApiMapFileOutputFolder; var yamlHeaders = YamlHeaderParser.Select(content); if (yamlHeaders == null || yamlHeaders.Count == 0) { return(new ParseResult(ResultLevel.Info, "No valid yaml header reference found for {0}", filePath)); } if (item.References == null) { item.References = new ReferencesViewModel(); } ReferencesViewModel references = item.References; List <MarkdownSection> sections = SplitToSections(content, yamlHeaders); Dictionary <string, MarkdownSection> validMarkdownSections = new Dictionary <string, MarkdownSection>(); foreach (var markdownSection in sections) { if (!string.IsNullOrEmpty(markdownSection.Id)) { validMarkdownSections[markdownSection.Id] = markdownSection; } } foreach (var yamlHeader in yamlHeaders) { var referenceId = yamlHeader.Id; var apiId = yamlHeader.Id; MetadataItem api; if (apis.TryGetValue(apiId, out api)) { var reference = new MapFileItemViewModel { Id = referenceId, ReferenceKeys = yamlHeader.MatchedSections, Href = api.Href, }; // *DONOT* Add references to Markdown file // references.AddItem(reference); // 2. Write api reference to API's map file MarkdownSection markdownSection; if (!validMarkdownSections.TryGetValue(apiId, out markdownSection)) { continue; } var apiPath = api.Href; var apiIndexPath = context.ApiIndexFilePath; var apiYamlPath = FileExtensions.GetFullPath(Path.GetDirectoryName(apiIndexPath), apiPath); string apiMapFileName = Path.GetFileName(apiPath) + Constants.MapFileExtension; string apiFolder = Path.GetDirectoryName(apiYamlPath); // Use the same folder as api.yaml if the output folder is not set string apiMapFileFolder = (string.IsNullOrEmpty(apiMapFileOutputFolder) ? apiFolder : apiMapFileOutputFolder); string apiMapFileFullPath = FileExtensions.GetFullPath(apiMapFileFolder, apiMapFileName); // Path should be the relative path from .yml to .md var markdownFilePath = context.MarkdownFilePath; var indexFolder = Path.GetDirectoryName(context.ApiIndexFilePath); var apiYamlFilePath = FileExtensions.GetFullPath(indexFolder, api.Href); var relativePath = FileExtensions.MakeRelativePath(Path.GetDirectoryName(apiYamlFilePath), markdownFilePath).BackSlashToForwardSlash(); MapFileItemViewModel apiMapFileSection = new MapFileItemViewModel { Id = apiId, Remote = item.Remote, Href = relativePath, Startline = markdownSection.Location.StartLocation.Line + 1, Endline = markdownSection.Location.EndLocation.Line + 1, // Endline + 1 - 1, +1 for it starts from 0, -1 for it is actually the start line for next charactor, in code snippet, is always a \n References = SelectReferenceSection(references, markdownSection.Location), CustomProperties = yamlHeader.Properties, MapFileType = MapFileType.Yaml }; MapFileViewModel apiMapFile; if (File.Exists(apiMapFileFullPath)) { apiMapFile = JsonUtility.Deserialize <MapFileViewModel>(apiMapFileFullPath); } else { apiMapFile = new MapFileViewModel(); } // Current behavior: Override existing one apiMapFile[apiId] = apiMapFileSection; // Post-process item // if references'/overrides count is 0, set it to null if (apiMapFileSection.References != null && apiMapFileSection.References.Count == 0) { apiMapFileSection.References = null; } if (apiMapFileSection.CustomProperties != null && apiMapFileSection.CustomProperties.Count == 0) { apiMapFileSection.CustomProperties = null; } JsonUtility.Serialize(apiMapFileFullPath, apiMapFile); ParseResult.WriteToConsole(ResultLevel.Success, "Successfully generated {0}.", apiMapFileFullPath); } } // Select references to the indices where DefinedLine is between startline and endline return(new ParseResult(ResultLevel.Success)); }