public Dictionary <string, DfmTagNameResolveResult> GetAll(string[] lines) { if (lines == null) { throw new ArgumentNullException(nameof(lines)); } var snippetTags = ResolveCodeSnippetTags(lines); var snippetTagGroups = from tag in snippetTags group tag by tag.Name; var excludedLines = new HashSet <int>(from tagGroup in snippetTagGroups from tag in tagGroup select tag.Line); var result = new Dictionary <string, DfmTagNameResolveResult>(); foreach (var snippetTagGroup in snippetTagGroups) { var tagResolveResult = new DfmTagNameResolveResult(); string tagName = snippetTagGroup.Key; var startTags = (from tag in snippetTagGroup where tag.Type == CodeSnippetTagType.Start select tag.Line).ToList(); var endTags = (from tag in snippetTagGroup where tag.Type == CodeSnippetTagType.End select tag.Line).ToList(); if (startTags.Count == 1 && endTags.Count == 1) { int startLine = startTags[0]; int endLine = endTags[0]; if (startLine < endLine) { tagResolveResult.IsSuccessful = true; tagResolveResult.StartLine = startLine + 1; tagResolveResult.EndLine = endLine - 1; tagResolveResult.ExcludesLines = excludedLines; tagResolveResult.IndentLength = DfmCodeExtractorHelper.GetIndentLength(lines[startLine - 1]); } else { tagResolveResult.IsSuccessful = false; tagResolveResult.ErrorMessage = $"Tag {tagName}'s start line '{startLine}' should be less than end line '{endLine}'"; } } else { tagResolveResult.IsSuccessful = false; tagResolveResult.ErrorMessage = $"Tag {tagName} is not paired or occurred just more than once, details: ({startTags.Count} start lines, {endTags.Count} end lines)"; } result.Add(tagName, tagResolveResult); } return(result); }
public DfmExtractCodeResult ExtractFencesCode(DfmFencesBlockToken token, string fencesPath) { if (token == null) { throw new ArgumentNullException(nameof(token)); } if (string.IsNullOrEmpty(fencesPath)) { throw new ArgumentNullException(nameof(fencesPath)); } var fencesCode = File.ReadAllLines(fencesPath); // NOTE: Parsing language and removing comment lines only do for tag name representation if (token.PathQueryOption?.TagName != null) { var lang = GetCodeLanguageOrExtension(token); List <ICodeSnippetExtractor> extractors; if (!CodeLanguageExtractors.TryGetValue(lang, out extractors)) { string errorMessage = $"{lang} is not supported languaging name, alias or extension for parsing code snippet with tag name, you can use line numbers instead"; Logger.LogError(errorMessage); return(new DfmExtractCodeResult { IsSuccessful = false, ErrorMessage = errorMessage, FencesCodeLines = fencesCode }); } var resolveResult = ResolveTagNamesFromPath(fencesPath, fencesCode, token.PathQueryOption.TagName, extractors); if (!resolveResult.IsSuccessful) { Logger.LogError(resolveResult.ErrorMessage); return(new DfmExtractCodeResult { IsSuccessful = false, ErrorMessage = resolveResult.ErrorMessage, FencesCodeLines = fencesCode }); } return(GetFencesCodeCore(fencesCode, resolveResult.StartLine, resolveResult.EndLine, resolveResult.IndentLength, resolveResult.ExcludesLines)); } else { // line range check only need to be done for line number representation string errorMessage; if (!CheckLineRange(fencesCode.Length, token.PathQueryOption?.StartLine, token.PathQueryOption?.EndLine, out errorMessage)) { Logger.LogError(errorMessage); return(new DfmExtractCodeResult { IsSuccessful = false, ErrorMessage = errorMessage, FencesCodeLines = fencesCode }); } int startLine = token.PathQueryOption?.StartLine ?? 1; int endLine = token.PathQueryOption?.EndLine ?? fencesCode.Length; int indentLength = (from line in fencesCode.Skip(startLine - 1).Take(endLine - startLine + 1) where !string.IsNullOrEmpty(line) && !string.IsNullOrWhiteSpace(line) select(int?) DfmCodeExtractorHelper.GetIndentLength(line)).Min() ?? 0; return(GetFencesCodeCore(fencesCode, startLine, endLine, indentLength)); } }
public DfmExtractCodeResult ExtractFencesCode(DfmFencesToken token, string fencesPath) { if (token == null) { throw new ArgumentNullException(nameof(token)); } if (string.IsNullOrEmpty(fencesPath)) { throw new ArgumentNullException(nameof(fencesPath)); } using (new LoggerPhaseScope("Extract Dfm Code")) { var fencesCode = EnvironmentContext.FileAbstractLayer.ReadAllLines(fencesPath); if (token.PathQueryOption == null) { // Add the full file when no query option is given return(new DfmExtractCodeResult { IsSuccessful = true, FencesCodeLines = fencesCode }); } if (!token.PathQueryOption.ValidateAndPrepare(fencesCode, token)) { Logger.LogError(GenerateErrorMessage(token), line: token.SourceInfo.LineNumber.ToString()); return(new DfmExtractCodeResult { IsSuccessful = false, ErrorMessage = token.PathQueryOption.ErrorMessage, FencesCodeLines = fencesCode }); } if (!string.IsNullOrEmpty(token.PathQueryOption.ErrorMessage)) { Logger.LogWarning(GenerateErrorMessage(token), line: token.SourceInfo.LineNumber.ToString()); } var includedLines = new List <string>(); foreach (var line in token.PathQueryOption.GetQueryLines(fencesCode)) { includedLines.Add(line); } if (!token.PathQueryOption.ValidateHighlightLinesAndDedentLength(includedLines.Count)) { Logger.LogWarning(GenerateErrorMessage(token), line: token.SourceInfo.LineNumber.ToString()); } var dedentLength = token.PathQueryOption.DedentLength ?? (from line in includedLines where !string.IsNullOrEmpty(line) && !string.IsNullOrWhiteSpace(line) select(int?) DfmCodeExtractorHelper.GetIndentLength(line)).Min() ?? 0; return(new DfmExtractCodeResult { IsSuccessful = true, ErrorMessage = token.PathQueryOption.ErrorMessage, FencesCodeLines = (dedentLength == 0 ? includedLines : includedLines.Select(s => Regex.Replace(s, string.Format(RemoveIndentSpacesRegexString, dedentLength), string.Empty))).ToArray() }); } }
private static string[] Dedent(IEnumerable <string> lines, int?dedentLength = null) { var length = dedentLength ?? (from line in lines where !string.IsNullOrWhiteSpace(line) select(int?) DfmCodeExtractorHelper.GetIndentLength(line)).Min() ?? 0; var normalizedLines = (length == 0 ? lines : lines.Select(s => Regex.Replace(s, string.Format(RemoveIndentSpacesRegexString, length), string.Empty))).ToArray(); return(normalizedLines); }