private string LoadCore(IMarkdownRenderer adapter, string currentPath, string raw, SourceInfo sourceInfo, IMarkdownContext context, DfmEngine engine)
        {
            try
            {
                if (!PathUtility.IsRelativePath(currentPath))
                {
                    return(GenerateErrorNodeWithCommentWrapper("INCLUDE", $"Absolute path \"{currentPath}\" is not supported.", raw, sourceInfo));
                }

                // Always report original include file dependency
                var originalRelativePath = currentPath;
                context.ReportDependency(currentPath);

                var    parents = context.GetFilePathStack();
                string parent  = string.Empty;
                if (parents == null)
                {
                    parents = ImmutableStack <string> .Empty;
                }

                // Update currentPath to be referencing to sourcePath
                else if (!parents.IsEmpty)
                {
                    parent      = parents.Peek();
                    currentPath = ((RelativePath)currentPath).BasedOn((RelativePath)parent);
                }

                if (parents.Contains(currentPath, FilePathComparer.OSPlatformSensitiveComparer))
                {
                    return(GenerateErrorNodeWithCommentWrapper("INCLUDE", $"Unable to resolve {raw}: Circular dependency found in \"{parent}\"", raw, sourceInfo));
                }

                // Add current file path to chain when entering recursion
                parents = parents.Push(currentPath);
                string           result;
                HashSet <string> dependency;
                if (!_dependencyCache.TryGetValue(currentPath, out dependency) ||
                    !_cache.TryGet(currentPath, out result))
                {
                    var filePathWithStatus = DfmFallbackHelper.GetFilePathWithFallback(originalRelativePath, context);
                    var src = File.ReadAllText(filePathWithStatus.Item1);
                    dependency = new HashSet <string>();
                    src        = engine.InternalMarkup(src, context.SetFilePathStack(parents).SetDependency(dependency).SetIsInclude());

                    result = UpdateToHrefFromWorkingFolder(src, currentPath);
                    result = GenerateNodeWithCommentWrapper("INCLUDE", $"Include content from \"{currentPath}\"", result);
                    _cache.Add(currentPath, result);
                    _dependencyCache[currentPath] = dependency;
                }
                context.ReportDependency(
                    from d in dependency
                    select(string)((RelativePath)currentPath + (RelativePath)d - (RelativePath)parent));
                return(result);
            }
            catch (Exception e)
            {
                return(GenerateErrorNodeWithCommentWrapper("INCLUDE", $"Unable to resolve {raw}:{e.Message}", raw, sourceInfo));
            }
        }
Exemple #2
0
 internal string InternalMarkup(string src, IMarkdownContext context) =>
 Mark(
     SourceInfo.Create(
         Normalize(src),
         context.GetFilePathStack().Peek()
         ),
     context
     ).ToString();
        /// <summary>
        /// Get file path with fallback
        /// </summary>
        /// <param name="relativePath">original relative path in markdown.</param>
        /// <param name="context">markdown context</param>
        /// <returns>item1: acutal file path. item: true if it hit fallback file. Otherwise false</returns>
        public static Tuple <string, bool> GetFilePathWithFallback(string relativePath, IMarkdownContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (relativePath == null)
            {
                throw new ArgumentNullException(nameof(relativePath));
                throw new FileNotFoundException($"Couldn't resolve path {relativePath}.");
            }

            // var currentFileFolder = Path.Combine(context.GetBaseFolder(), Path.Combine(context.GetFilePathStack().Select(path => Path.GetDirectoryName(path)).ToArray()));
            // var originalFilePath = Path.Combine(context.GetBaseFolder(),  orginalRelativePath);
            var    filePathToDocset            = relativePath;
            string parentFileDirectoryToDocset = context.GetBaseFolder();
            var    parents = context.GetFilePathStack();

            if (parents != null)
            {
                var parent = parents.Peek();
                filePathToDocset            = (RelativePath)parent + (RelativePath)filePathToDocset;
                parentFileDirectoryToDocset = Path.GetDirectoryName(Path.Combine(context.GetBaseFolder(), parent));
            }

            var  originalFilePath = Path.Combine(context.GetBaseFolder(), filePathToDocset);
            var  actualFilePath   = originalFilePath;
            bool hitFallback      = false;

            if (!File.Exists(originalFilePath))
            {
                var fallbackFolders = context.GetFallbackFolders();
                foreach (var folder in fallbackFolders)
                {
                    var fallbackFilePath         = Path.Combine(folder, filePathToDocset);
                    var fallbackFileRelativePath = PathUtility.MakeRelativePath(parentFileDirectoryToDocset, fallbackFilePath);
                    context.ReportDependency(fallbackFileRelativePath); // All the high priority fallback files should be reported to the dependency.
                    if (File.Exists(fallbackFilePath))
                    {
                        actualFilePath = fallbackFilePath;
                        hitFallback    = true;
                        break;
                    }
                }

                if (!hitFallback)
                {
                    if (fallbackFolders.Count > 0)
                    {
                        throw new FileNotFoundException($"Couldn't find file {filePathToDocset}. Fallback folders: {string.Join(",", fallbackFolders)}", filePathToDocset);
                    }
                    throw new FileNotFoundException($"Couldn't find file {filePathToDocset}.", originalFilePath);
                }
            }

            return(Tuple.Create(actualFilePath, hitFallback));
        }
Exemple #4
0
        /// <summary>
        /// Get file path with fallback
        /// </summary>
        /// <param name="relativePath">original relative path in markdown.</param>
        /// <param name="context">markdown context</param>
        /// <returns>item1: acutal file path. item: true if it hit fallback file. Otherwise false</returns>
        public static Tuple<string, bool> GetFilePathWithFallback(string relativePath, IMarkdownContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (relativePath == null)
            {
                throw new ArgumentNullException(nameof(relativePath));
                throw new FileNotFoundException($"Couldn't resolve path {relativePath}.");
            }

            // var currentFileFolder = Path.Combine(context.GetBaseFolder(), Path.Combine(context.GetFilePathStack().Select(path => Path.GetDirectoryName(path)).ToArray()));
            // var originalFilePath = Path.Combine(context.GetBaseFolder(),  orginalRelativePath);
            var filePathToDocset = relativePath;
            string parentFileDirectoryToDocset = context.GetBaseFolder();
            var parents = context.GetFilePathStack();
            if(parents != null)
            {
                var parent = parents.Peek();
                filePathToDocset = (RelativePath)parent + (RelativePath)filePathToDocset;
                parentFileDirectoryToDocset = Path.GetDirectoryName(Path.Combine(context.GetBaseFolder(), parent));
            }

            var originalFilePath = Path.Combine(context.GetBaseFolder(), filePathToDocset);
            var actualFilePath = originalFilePath;
            bool hitFallback = false;
            if (!File.Exists(originalFilePath))
            {
                var fallbackFolders = context.GetFallbackFolders();
                foreach (var folder in fallbackFolders)
                {
                    var fallbackFilePath = Path.Combine(folder, filePathToDocset);
                    var fallbackFileRelativePath = PathUtility.MakeRelativePath(parentFileDirectoryToDocset, fallbackFilePath);
                    context.ReportDependency(fallbackFileRelativePath); // All the high priority fallback files should be reported to the dependency.
                    if (File.Exists(fallbackFilePath))
                    {
                        actualFilePath = fallbackFilePath;
                        hitFallback = true;
                        break;
                    }
                }

                if (!hitFallback)
                {
                    if (fallbackFolders.Count > 0)
                    {
                        throw new FileNotFoundException($"Couldn't find file {filePathToDocset}. Fallback folders: {string.Join(",", fallbackFolders)}", filePathToDocset);
                    }
                    throw new FileNotFoundException($"Couldn't find file {filePathToDocset}.", originalFilePath);
                }
            }

            return Tuple.Create(actualFilePath, hitFallback);
        }
        private string LoadCore(IMarkdownRenderer adapter, string currentPath, string raw, SourceInfo sourceInfo, IMarkdownContext context, DfmEngine engine)
        {
            try
            {
                if (!PathUtility.IsRelativePath(currentPath))
                {
                    return GenerateErrorNodeWithCommentWrapper("INCLUDE", $"Absolute path \"{currentPath}\" is not supported.", raw, sourceInfo);
                }

                // Always report original include file dependency
                var originalRelativePath = currentPath;
                context.ReportDependency(currentPath);

                var parents = context.GetFilePathStack();
                string parent = string.Empty;
                if (parents == null) parents = ImmutableStack<string>.Empty;

                // Update currentPath to be referencing to sourcePath
                else if (!parents.IsEmpty)
                {
                    parent = parents.Peek();
                    currentPath = ((RelativePath)currentPath).BasedOn((RelativePath)parent);
                }

                if (parents.Contains(currentPath, FilePathComparer.OSPlatformSensitiveComparer))
                {
                    return GenerateErrorNodeWithCommentWrapper("INCLUDE", $"Unable to resolve {raw}: Circular dependency found in \"{parent}\"", raw, sourceInfo);
                }

                // Add current file path to chain when entering recursion
                parents = parents.Push(currentPath);
                string result;
                HashSet<string> dependency;
                if (!_dependencyCache.TryGetValue(currentPath, out dependency) ||
                    !_cache.TryGet(currentPath, out result))
                {
                    var filePathWithStatus = DfmFallbackHelper.GetFilePathWithFallback(originalRelativePath, context);
                    var src = File.ReadAllText(filePathWithStatus.Item1);
                    dependency = new HashSet<string>();
                    src = engine.InternalMarkup(src, context.SetFilePathStack(parents).SetDependency(dependency).SetIsInclude());

                    result = UpdateToHrefFromWorkingFolder(src, currentPath);
                    result = GenerateNodeWithCommentWrapper("INCLUDE", $"Include content from \"{currentPath}\"", result);
                    _cache.Add(currentPath, result);
                    _dependencyCache[currentPath] = dependency;
                }
                context.ReportDependency(
                    from d in dependency
                    select (string)((RelativePath)currentPath + (RelativePath)d - (RelativePath)parent));
                return result;
            }
            catch (Exception e)
            {
                return GenerateErrorNodeWithCommentWrapper("INCLUDE", $"Unable to resolve {raw}:{e.Message}", raw, sourceInfo);
            }
        }
        private string LoadCore(IMarkdownRenderer adapter, string currentPath, string raw, IMarkdownContext context, Func <string, IMarkdownContext, string> resolver)
        {
            try
            {
                if (!PathUtility.IsRelativePath(currentPath))
                {
                    return(GenerateErrorNodeWithCommentWrapper("INCLUDE", $"Absolute path \"{currentPath}\" is not supported.", raw));
                }

                var    parents      = context.GetFilePathStack();
                var    originalPath = currentPath;
                string parent       = string.Empty;
                if (parents == null)
                {
                    parents = ImmutableStack <string> .Empty;
                }

                // Update currentPath to be referencing to sourcePath
                else if (!parents.IsEmpty)
                {
                    parent      = parents.Peek();
                    currentPath = ((RelativePath)currentPath).BasedOn((RelativePath)parent);
                }

                if (parents.Contains(currentPath, FilePathComparer.OSPlatformSensitiveComparer))
                {
                    return(GenerateErrorNodeWithCommentWrapper("INCLUDE", $"Unable to resolve {raw}: Circular dependency found in \"{parent}\"", raw));
                }

                // Add current file path to chain when entering recursion
                parents = parents.Push(currentPath);
                string result;
                if (!_cache.TryGet(currentPath, out result))
                {
                    var src = File.ReadAllText(Path.Combine(context.GetBaseFolder(), currentPath));

                    src = resolver(src, context.SetFilePathStack(parents));

                    result = UpdateToHrefFromWorkingFolder(src, currentPath);
                    result = GenerateNodeWithCommentWrapper("INCLUDE", $"Include content from \"{currentPath}\"", result);

                    _cache.Add(currentPath, result);
                }

                return(result);
            }
            catch (Exception e)
            {
                return(GenerateErrorNodeWithCommentWrapper("INCLUDE", $"Unable to resolve {raw}:{e.Message}", raw));
            }
        }
Exemple #7
0
        /// <summary>
        /// Get file path with fallback
        /// </summary>
        /// <param name="relativePath">original relative path in markdown.</param>
        /// <param name="context">markdown context</param>
        /// <returns>item1: acutal file path. item: true if it hit fallback file. Otherwise false</returns>
        public static Tuple <string, bool> GetFilePathWithFallback(string relativePath, IMarkdownContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (relativePath == null)
            {
                throw new ArgumentNullException(nameof(relativePath));
            }

            // var currentFileFolder = Path.Combine(context.GetBaseFolder(), Path.Combine(context.GetFilePathStack().Select(path => Path.GetDirectoryName(path)).ToArray()));
            // var originalFilePath = Path.Combine(context.GetBaseFolder(),  orginalRelativePath);
            RelativePath filePathToDocset            = null;
            string       parentFileDirectoryToDocset = context.GetBaseFolder();
            var          parents = context.GetFilePathStack();

            if (parents != null)
            {
                var parent = parents.Peek();
                filePathToDocset            = ((RelativePath)parent + (RelativePath)relativePath).RemoveWorkingFolder();
                parentFileDirectoryToDocset = Path.GetDirectoryName(Path.Combine(context.GetBaseFolder(), parent));
            }
            else
            {
                filePathToDocset = ((RelativePath)relativePath).RemoveWorkingFolder();
            }

            var originalFullPath = Path.Combine(context.GetBaseFolder(), filePathToDocset);

            if (EnvironmentContext.FileAbstractLayer.Exists(filePathToDocset))
            {
                return(Tuple.Create((string)filePathToDocset, false));
            }
            else
            {
                return(FindInFallbackFolders(
                           context,
                           filePathToDocset,
                           parentFileDirectoryToDocset,
                           originalFullPath));
            }
        }
Exemple #8
0
 internal string InternalMarkup(string src, IMarkdownContext context)
 {
     int lineNumber = 1;
     var normalized = Normalize(src);
     string file = context.GetFilePathStack().Peek();
     if (context.GetIsInclude())
     {
         var match = DfmYamlHeaderBlockRule.YamlHeaderRegex.Match(normalized);
         if (match.Length > 0)
         {
             lineNumber += normalized.Take(match.Length).Count(ch => ch == '\n');
             Logger.LogInfo("Remove yaml header for include file.", file: file);
             normalized = normalized.Substring(match.Length);
         }
     }
     return Mark(
         SourceInfo.Create(normalized, file, lineNumber),
         context
     ).ToString();
 }
Exemple #9
0
        internal string InternalMarkup(string src, IMarkdownContext context)
        {
            int    lineNumber = 1;
            var    normalized = Normalize(src);
            string file       = context.GetFilePathStack().Peek();

            if (context.GetIsInclude())
            {
                var match = DfmYamlHeaderBlockRule.YamlHeaderRegex.Match(normalized);
                if (match.Length > 0)
                {
                    lineNumber += normalized.Take(match.Length).Count(ch => ch == '\n');
                    Logger.LogInfo("Remove yaml header for include file.", file: file);
                    normalized = normalized.Substring(match.Length);
                }
            }
            return(Mark(
                       SourceInfo.Create(normalized, file, lineNumber),
                       context
                       ).ToString());
        }
Exemple #10
0
        public virtual StringBuffer Render(IMarkdownRenderer renderer, DfmFencesToken token, IMarkdownContext context)
        {
            if (!PathUtility.IsRelativePath(token.Path))
            {
                string errorMessage = $"Code absolute path: {token.Path} is not supported in file {context.GetFilePathStack().Peek()}";
                Logger.LogError(errorMessage);
                return(DfmFencesBlockHelper.GetRenderedFencesBlockString(token, renderer.Options, errorMessage));
            }

            try
            {
                // Always report original dependency
                context.ReportDependency(token.Path);
                var filePathWithStatus = DfmFallbackHelper.GetFilePathWithFallback(token.Path, context);
                var extractResult      = _dfmCodeExtractor.ExtractFencesCode(token, filePathWithStatus.Item1);
                var result             = DfmFencesBlockHelper.GetRenderedFencesBlockString(token, renderer.Options, extractResult.ErrorMessage, extractResult.FencesCodeLines);
                return(result);
            }
            catch (DirectoryNotFoundException)
            {
                return(DfmFencesBlockHelper.GenerateReferenceNotFoundErrorMessage(renderer, token));
            }
            catch (FileNotFoundException)
            {
                return(DfmFencesBlockHelper.GenerateReferenceNotFoundErrorMessage(renderer, token));
            }
        }
Exemple #11
0
        public virtual StringBuffer Render(IMarkdownRenderer renderer, DfmFencesToken token, IMarkdownContext context)
        {
            if (!PathUtility.IsRelativePath(token.Path))
            {
                string errorMessage = $"Code absolute path: {token.Path} is not supported in file {context.GetFilePathStack().Peek()}";
                Logger.LogError(errorMessage);
                return(RenderFencesCode(token, renderer.Options, errorMessage));
            }

            try
            {
                // Always report original dependency
                context.ReportDependency(token.Path);
                var filePath = FindFile(token, context);
                var code     = ExtractCode(token, filePath);
                return(RenderFencesCode(token, renderer.Options, code.ErrorMessage, code.CodeLines));
            }
            catch (DirectoryNotFoundException)
            {
                return(RenderReferenceNotFoundErrorMessage(renderer, token));
            }
            catch (FileNotFoundException)
            {
                return(RenderReferenceNotFoundErrorMessage(renderer, token));
            }
        }
        private string LoadCore(IMarkdownRenderer adapter, string currentPath, string raw, IMarkdownContext context, Func <string, IMarkdownContext, string> resolver)
        {
            if (!PathUtility.IsRelativePath(currentPath))
            {
                if (!Path.IsPathRooted(currentPath))
                {
                    return(GenerateNodeWithCommentWrapper("ERROR INCLUDE", $"Absolute path \"{currentPath}\" is not supported.", raw));
                }
                else
                {
                    currentPath = PathUtility.MakeRelativePath(Environment.CurrentDirectory, currentPath);
                }
            }
            var    parents      = context.GetFilePathStack();
            var    originalPath = currentPath;
            string parent       = string.Empty;

            if (parents == null)
            {
                parents = ImmutableStack <string> .Empty;
            }

            // Update currentPath to be referencing to sourcePath
            else if (!parents.IsEmpty)
            {
                parent      = parents.Peek();
                currentPath = ((RelativePath)currentPath).BasedOn((RelativePath)parent);
            }

            if (parents.Contains(currentPath, FilePathComparer.OSPlatformSensitiveComparer))
            {
                return(GenerateNodeWithCommentWrapper("ERROR INCLUDE", $"Unable to resolve {raw}: Circular dependency found in \"{parent}\"", raw));
            }

            string result = string.Empty;

            // Add current file path to chain when entering recursion
            parents = parents.Push(currentPath);
            try
            {
                if (!_cache.TryGet(currentPath, out result))
                {
                    var src = File.ReadAllText(currentPath);

                    src = resolver(src, context.SetFilePathStack(parents));

                    HtmlDocument htmlDoc = new HtmlDocument();
                    htmlDoc.LoadHtml(src);
                    var node = htmlDoc.DocumentNode;

                    // If current content is not the root one, update href to root
                    if (parents.Count() > 1)
                    {
                        UpdateHref(node, originalPath);
                    }

                    result = node.WriteTo();
                    result = GenerateNodeWithCommentWrapper("INCLUDE", $"Include content from \"{currentPath}\"", result);
                }
            }
            catch (Exception e)
            {
                result = GenerateNodeWithCommentWrapper("ERROR INCLUDE", $"Unable to resolve {raw}:{e.Message}", raw);
            }

            _cache.Add(currentPath, result);

            return(result);
        }
        private string LoadCore(IMarkdownRenderer adapter, string currentPath, string raw, IMarkdownContext context, Func<string, IMarkdownContext, string> resolver)
        {
            if (!PathUtility.IsRelativePath(currentPath))
            {
                if (!Path.IsPathRooted(currentPath))
                {
                    return GenerateNodeWithCommentWrapper("ERROR INCLUDE", $"Absolute path \"{currentPath}\" is not supported.", raw);
                }
                else
                    currentPath = PathUtility.MakeRelativePath(Environment.CurrentDirectory, currentPath);
            }
            var parents = context.GetFilePathStack();
            var originalPath = currentPath;
            string parent = string.Empty;
            if (parents == null) parents = ImmutableStack<string>.Empty;

            // Update currentPath to be referencing to sourcePath
            else if (!parents.IsEmpty)
            {
                parent = parents.Peek();
                currentPath = ((RelativePath)currentPath).BasedOn((RelativePath)parent);
            }

            if (parents.Contains(currentPath, FilePathComparer.OSPlatformSensitiveComparer))
            {
                return GenerateNodeWithCommentWrapper("ERROR INCLUDE", $"Unable to resolve {raw}: Circular dependency found in \"{parent}\"", raw);
            }

            string result = string.Empty;

            // Add current file path to chain when entering recursion
            parents = parents.Push(currentPath);
            try
            {
                if (!_cache.TryGet(currentPath, out result))
                {
                    var src = File.ReadAllText(currentPath);

                    src = resolver(src, context.SetFilePathStack(parents));

                    HtmlDocument htmlDoc = new HtmlDocument();
                    htmlDoc.LoadHtml(src);
                    var node = htmlDoc.DocumentNode;

                    // If current content is not the root one, update href to root
                    if (parents.Count() > 1)
                        UpdateHref(node, originalPath);

                    result = node.WriteTo();
                    result = GenerateNodeWithCommentWrapper("INCLUDE", $"Include content from \"{currentPath}\"", result);
                }
            }
            catch (Exception e)
            {
                result = GenerateNodeWithCommentWrapper("ERROR INCLUDE", $"Unable to resolve {raw}:{e.Message}", raw);
            }

            _cache.Add(currentPath, result);

            return result;
        }
Exemple #14
0
        public virtual StringBuffer Render(IMarkdownRenderer renderer, DfmFencesToken token, IMarkdownContext context)
        {
            if (!TypeForwardedToPathUtility.IsRelativePath(token.Path))
            {
                string errorMessage = $"Code absolute path: {token.Path} is not supported in file {context.GetFilePathStack().Peek()}";
                Logger.LogError(errorMessage);
                return DfmFencesBlockHelper.GetRenderedFencesBlockString(token, renderer.Options, errorMessage);
            }

            try
            {
                // Always report original dependency
                context.ReportDependency(token.Path);
                var filePathWithStatus = DfmFallbackHelper.GetFilePathWithFallback(token.Path, context);
                var extractResult = _dfmCodeExtractor.ExtractFencesCode(token, filePathWithStatus.Item1);
                var result = DfmFencesBlockHelper.GetRenderedFencesBlockString(token, renderer.Options, extractResult.ErrorMessage, extractResult.FencesCodeLines);
                return result;
            }
            catch (DirectoryNotFoundException)
            {
                return DfmFencesBlockHelper.GenerateReferenceNotFoundErrorMessage(renderer, token);
            }
            catch (FileNotFoundException)
            {
                return DfmFencesBlockHelper.GenerateReferenceNotFoundErrorMessage(renderer, token);
            }
        }
Exemple #15
0
        public virtual StringBuffer Render(IMarkdownRenderer renderer, DfmFencesToken token, IMarkdownContext context)
        {
            if (!PathUtility.IsRelativePath(token.Path))
            {
                string errorMessage = $"Code absolute path: {token.Path} is not supported in file {context.GetFilePathStack().Peek()}";
                Logger.LogError(errorMessage);
                return(RenderFencesCode(token, renderer.Options, errorMessage));
            }

            try
            {
                // Always report original dependency when path is valid
                if (PathUtility.IsVaildFilePath(token.Path))
                {
                    context.ReportDependency(token.Path);
                }

                var pathQueryOption =
                    !string.IsNullOrEmpty(token.QueryStringAndFragment) ?
                    _dfmCodeExtractor.ParsePathQueryString(token.QueryStringAndFragment) :
                    null;
                var filePath = FindFile(token, context);
                var code     = ExtractCode(token, filePath, pathQueryOption);
                return(RenderFencesCode(token, renderer.Options, code.ErrorMessage, code.CodeLines, pathQueryOption));
            }
            catch (DirectoryNotFoundException)
            {
                return(RenderReferenceNotFoundErrorMessage(renderer, token));
            }
            catch (FileNotFoundException)
            {
                return(RenderReferenceNotFoundErrorMessage(renderer, token));
            }
        }