IsRelativePath() public static method

public static IsRelativePath ( string path ) : bool
path string
return bool
Example #1
0
        private ImmutableDictionary <string, ImmutableList <LinkSourceInfo> > GetFileLinkSource(FileAndType ft, HtmlDocument doc)
        {
            var fileLinkSources = new Dictionary <string, List <LinkSourceInfo> >();

            foreach (var pair in (from n in doc.DocumentNode.Descendants()
                                  where !string.Equals(n.Name, "xref", StringComparison.OrdinalIgnoreCase)
                                  from attr in n.Attributes
                                  where string.Equals(attr.Name, "src", StringComparison.OrdinalIgnoreCase) ||
                                  string.Equals(attr.Name, "href", StringComparison.OrdinalIgnoreCase)
                                  where !string.IsNullOrWhiteSpace(attr.Value)
                                  select new { Node = n, Attr = attr }).ToList())
            {
                string linkFile;
                string anchor = null;
                var    link   = pair.Attr;
                if (TypeForwardedToPathUtility.IsRelativePath(link.Value))
                {
                    var index = link.Value.IndexOfAny(UriFragmentOrQueryString);
                    if (index == -1)
                    {
                        linkFile = link.Value;
                    }
                    else if (index == 0)
                    {
                        continue;
                    }
                    else
                    {
                        linkFile = link.Value.Remove(index);
                        anchor   = link.Value.Substring(index);
                    }
                    var    path = (TypeForwardedToRelativePath)ft.File + (TypeForwardedToRelativePath)linkFile;
                    string file = path.GetPathFromWorkingFolder().UrlDecode();
                    if (SourceFiles.ContainsKey(file))
                    {
                        link.Value = file;
                        if (!string.IsNullOrEmpty(anchor) &&
                            string.Equals(link.Name, "href", StringComparison.OrdinalIgnoreCase))
                        {
                            pair.Node.SetAttributeValue("anchor", anchor);
                        }
                    }

                    List <LinkSourceInfo> sources;
                    if (!fileLinkSources.TryGetValue(file, out sources))
                    {
                        sources = new List <LinkSourceInfo>();
                        fileLinkSources[file] = sources;
                    }
                    sources.Add(new LinkSourceInfo
                    {
                        Target     = file,
                        Anchor     = anchor,
                        SourceFile = pair.Node.GetAttributeValue("sourceFile", null),
                        LineNumber = pair.Node.GetAttributeValue("sourceStartLineNumber", 0),
                    });
                }
            }
            return(fileLinkSources.ToImmutableDictionary(x => x.Key, x => x.Value.ToImmutableList()));
        }
Example #2
0
        private static ChangeList ParseCore(string tsvFile, string baseDir)
        {
            var  result   = new ChangeList();
            bool hasError = false;

            foreach (var line in File.ReadLines(tsvFile))
            {
                if (string.IsNullOrWhiteSpace(line))
                {
                    continue;
                }
                var columns = line.Split('\t');
                if (columns.Length >= 2)
                {
                    if (string.Equals(columns[0], "<from>", StringComparison.OrdinalIgnoreCase))
                    {
                        result.From = columns[1];
                        continue;
                    }
                    if (string.Equals(columns[0], "<to>", StringComparison.OrdinalIgnoreCase))
                    {
                        result.To = columns[1];
                        continue;
                    }
                    string path;
                    if (TypeForwardedToPathUtility.IsRelativePath(columns[0]))
                    {
                        path = columns[0];
                    }
                    else
                    {
                        path = TypeForwardedToPathUtility.MakeRelativePath(baseDir, columns[0]);
                    }
                    if (path != null)
                    {
                        ChangeKind kind;
                        if (Enum.TryParse(columns[1], true, out kind))
                        {
                            if (kind != ChangeKind.Deleted)
                            {
                                if (!File.Exists(Path.Combine(baseDir, path)))
                                {
                                    Logger.LogError($"File:{path} not existed.");
                                    hasError = true;
                                    continue;
                                }
                            }
                            result.Add(path, kind);
                            continue;
                        }
                    }
                }
                Logger.LogWarning($"Ignore unknown line: {line}");
            }
            if (hasError)
            {
                throw new DocfxException($"Some error ocurred while parsing changelist file: {tsvFile}.");
            }
            return(result);
        }
Example #3
0
        private void WriteLine(ILogItem item)
        {
            if (item == null)
            {
                throw new ArgumentNullException(nameof(item));
            }
            if (item.File == null)
            {
                return;
            }
            string fileFromWorkingDir = TypeForwardedToStringExtension.BackSlashToForwardSlash(item.File);

            if (!TypeForwardedToPathUtility.IsRelativePath(item.File))
            {
                fileFromWorkingDir = TypeForwardedToPathUtility.MakeRelativePath(EnvironmentContext.BaseDirectory, item.File);
            }
            List <LogItem> logsPerFile;

            if (!_logs.TryGetValue(fileFromWorkingDir, out logsPerFile))
            {
                logsPerFile = _logs[fileFromWorkingDir] = new List <LogItem>();
            }
            logsPerFile.Add(new LogItem
            {
                File     = TypeForwardedToStringExtension.BackSlashToForwardSlash(item.File),
                Line     = item.Line,
                LogLevel = item.LogLevel,
                Message  = item.Message,
                Phase    = item.Phase,
            });
        }
        /// <summary>
        /// Append default extension to href by condition
        /// </summary>
        /// <param name="href">original href string</param>
        /// <param name="defaultExtension">default extension to append</param>
        /// <returns>Href with default extension appended</returns>
        private AppendDefaultExtensionResult AppendDefaultExtension(string href, string defaultExtension, IMarkdownContext context, string rawMarkdown, string line)
        {
            // If the context doesn't have necessary info, return the original href
            if (!context.Variables.ContainsKey("path"))
            {
                return(new AppendDefaultExtensionResult(false, href, null));
            }
            var currentFilePath = (string)context.Variables["path"];

            try
            {
                if (!TypeForwardedToPathUtility.IsRelativePath(href))
                {
                    return(new AppendDefaultExtensionResult(false, href, null));
                }
            }
            catch (ArgumentException)
            {
                Logger.LogWarning($"Invalid reference {href} in file: {currentFilePath}. Raw: {rawMarkdown}", null, currentFilePath, line);
                return(new AppendDefaultExtensionResult(false, href, null));
            }

            var index = href.IndexOf('#');

            if (index == -1)
            {
                href = href.TrimEnd('/');
                var extension = Path.GetExtension(href);

                // Regard all the relative path with no extension as markdown file that missing .md
                if (string.IsNullOrEmpty(extension))
                {
                    return(new AppendDefaultExtensionResult(true, $"{href}{defaultExtension}", true));
                }
                else
                {
                    bool isMarkdownFile = extension.Equals(MarkdownExtension, StringComparison.OrdinalIgnoreCase);
                    return(new AppendDefaultExtensionResult(true, href, isMarkdownFile));
                }
            }
            else if (index == 0)
            {
                return(new AppendDefaultExtensionResult(true, href, false));
            }
            else
            {
                var hrefWithoutAnchor = href.Remove(index).TrimEnd('/');
                var anchor            = href.Substring(index);
                var extension         = Path.GetExtension(hrefWithoutAnchor);
                if (string.IsNullOrEmpty(extension))
                {
                    return(new AppendDefaultExtensionResult(true, $"{hrefWithoutAnchor}{defaultExtension}{anchor}", true));
                }
                else
                {
                    bool isMarkdownFile = extension.Equals(MarkdownExtension, StringComparison.OrdinalIgnoreCase);
                    return(new AppendDefaultExtensionResult(true, $"{hrefWithoutAnchor}{anchor}", isMarkdownFile));
                }
            }
        }
Example #5
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));
            }
        }
Example #6
0
        public string ResolveSourceRelativePath(string originPath, string currentFileOutputPath)
        {
            if (string.IsNullOrEmpty(originPath) || !TypeForwardedToPathUtility.IsRelativePath(originPath))
            {
                return(originPath);
            }

            var origin = (TypeForwardedToRelativePath)originPath;

            if (origin == null)
            {
                return(originPath);
            }

            var destPath = _context.GetFilePath(origin.GetPathFromWorkingFolder().ToString());

            if (destPath != null)
            {
                return(((TypeForwardedToRelativePath)destPath - ((TypeForwardedToRelativePath)currentFileOutputPath).GetPathFromWorkingFolder()).ToString());
            }
            else
            {
                Logger.LogWarning($"Can't find output file for {originPath}");
                return(originPath);
            }
        }
Example #7
0
        public static HrefType GetHrefType(string href)
        {
            if (!TypeForwardedToPathUtility.IsRelativePath(href))
            {
                return(HrefType.AbsolutePath);
            }
            var fileName = Path.GetFileName(href);

            if (string.IsNullOrEmpty(fileName))
            {
                return(HrefType.RelativeFolder);
            }

            var tocFileType = GetTocFileType(href);

            if (tocFileType == TocFileType.Markdown)
            {
                return(HrefType.MarkdownTocFile);
            }

            if (tocFileType == TocFileType.Yaml)
            {
                return(HrefType.YamlTocFile);
            }

            return(HrefType.RelativeFile);
        }
Example #8
0
        private string LoadCore(IMarkdownRenderer adapter, string currentPath, string raw, SourceInfo sourceInfo, IMarkdownContext context, DfmEngine engine)
        {
            try
            {
                if (!TypeForwardedToPathUtility.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 = ((TypeForwardedToRelativePath)currentPath).BasedOn((TypeForwardedToRelativePath)parent);
                }

                if (parents.Contains(currentPath, TypeForwardedToFilePathComparer.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)((TypeForwardedToRelativePath)currentPath + (TypeForwardedToRelativePath)d - (TypeForwardedToRelativePath)parent));
                return(result);
            }
            catch (Exception e)
            {
                return(GenerateErrorNodeWithCommentWrapper("INCLUDE", $"Unable to resolve {raw}:{e.Message}", raw, sourceInfo));
            }
        }
Example #9
0
 private static void UpdateToHrefFromWorkingFolder(HtmlNode html, string filePath)
 {
     foreach (var pair in GetHrefNodes(html))
     {
         var link = pair.Attr;
         if (TypeForwardedToPathUtility.IsRelativePath(link.Value) && !TypeForwardedToRelativePath.IsPathFromWorkingFolder(link.Value) && !link.Value.StartsWith("#"))
         {
             link.Value = ((TypeForwardedToRelativePath)filePath + (TypeForwardedToRelativePath)link.Value).GetPathFromWorkingFolder();
         }
     }
 }
Example #10
0
        /// <summary>
        /// Append default extension to href by condition
        /// </summary>
        /// <param name="href">original href string</param>
        /// <param name="defaultExtension">default extension to append</param>
        /// <param name="isHrefRelativeNonMdFile">true if it is a relative path and not a markdown file. Otherwise false</param>
        /// <returns>Href with default extension appended</returns>
        private string AppendDefaultExtension(string href, string defaultExtension, out bool isHrefRelativeNonMdFile)
        {
            isHrefRelativeNonMdFile = false;
            if (!TypeForwardedToPathUtility.IsRelativePath(href))
            {
                return(href);
            }

            var index = href.IndexOf('#');

            if (index == -1)
            {
                href = href.TrimEnd('/');
                var extension = Path.GetExtension(href);

                // Regard all the relative path with no extension as markdown file that missing .md
                if (string.IsNullOrEmpty(extension))
                {
                    return($"{href}{defaultExtension}");
                }
                else
                {
                    if (!extension.Equals(MarkdownExtension, StringComparison.OrdinalIgnoreCase))
                    {
                        isHrefRelativeNonMdFile = true;
                    }
                    return(href);
                }
            }
            else if (index == 0)
            {
                return(href);
            }
            else
            {
                var hrefWithoutAnchor = href.Remove(index).TrimEnd('/');
                var anchor            = href.Substring(index);
                var extension         = Path.GetExtension(hrefWithoutAnchor);
                if (string.IsNullOrEmpty(extension))
                {
                    return($"{hrefWithoutAnchor}{defaultExtension}{anchor}");
                }
                else
                {
                    if (!extension.Equals(MarkdownExtension, StringComparison.OrdinalIgnoreCase))
                    {
                        isHrefRelativeNonMdFile = true;
                    }
                    return($"{hrefWithoutAnchor}{anchor}");
                }
            }
        }
Example #11
0
 public void Add(string filePath, ChangeKind kind)
 {
     if (filePath == null)
     {
         throw new ArgumentNullException(nameof(filePath));
     }
     if (filePath.Length == 0)
     {
         throw new ArgumentException("File path cannot be empty", nameof(filePath));
     }
     if (!TypeForwardedToPathUtility.IsRelativePath(filePath))
     {
         throw new ArgumentException("Expect relative path.", nameof(filePath));
     }
     AddCore(filePath, kind);
 }
Example #12
0
 // TODO: use this method instead of directly accessing UidMap
 public void RegisterInternalXrefSpec(XRefSpec xrefSpec)
 {
     if (xrefSpec == null)
     {
         throw new ArgumentNullException(nameof(xrefSpec));
     }
     if (string.IsNullOrEmpty(xrefSpec.Href))
     {
         throw new ArgumentException("Href for xref spec must contain value");
     }
     if (!TypeForwardedToPathUtility.IsRelativePath(xrefSpec.Href))
     {
         throw new ArgumentException("Only relative href path is supported");
     }
     XRefSpecMap[xrefSpec.Uid] = xrefSpec;
 }
Example #13
0
        public IMarkdownToken TryMatch(IMarkdownParser engine, IMarkdownParsingContext context)
        {
            var match = AzureIncludeRegex.Match(context.CurrentMarkdown);

            if (match.Length == 0)
            {
                return(null);
            }
            var sourceInfo = context.Consume(match.Length);

            // [!azure.include[title](path "optionalTitle")]
            // 1. Get include file path
            var path = match.Groups[2].Value;

            // 2. Get title
            var value = match.Groups[1].Value;
            var title = match.Groups[4].Value;

            if (!TypeForwardedToPathUtility.IsRelativePath(path))
            {
                Logger.LogWarning($"Azure inline include path {path} is not a relative path, can't expand it");
                return(new MarkdownTextToken(this, engine.Context, match.Value, sourceInfo));
            }

            // 3. Apply inline rules to the included content
            object currentFilePath;

            if (!engine.Context.Variables.TryGetValue("path", out currentFilePath))
            {
                Logger.LogWarning($"Can't get path for the file that ref azure inline include file, return MarkdownTextToken. Raw: {match.Value}");
                return(new MarkdownTextToken(this, engine.Context, match.Value, sourceInfo));
            }

            var includeFilePath = TypeForwardedToPathUtility.NormalizePath(Path.Combine(Path.GetDirectoryName(currentFilePath.ToString()), path));

            if (!File.Exists(includeFilePath))
            {
                Logger.LogWarning($"Can't get include file path {includeFilePath} in the file {currentFilePath}, return MarkdownTextToken. Raw: {match.Value}");
                return(new MarkdownTextToken(this, engine.Context, match.Value, sourceInfo));
            }

            return(new TwoPhaseBlockToken(this, engine.Context, sourceInfo, (p, t) =>
            {
                var inlineTokens = p.Tokenize(SourceInfo.Create(MarkdownEngine.Normalize(File.ReadAllText(includeFilePath)), includeFilePath));
                return new AzureIncludeInlineToken(t.Rule, t.Context, path, value, title, inlineTokens, match.Groups[0].Value, t.SourceInfo);
            }));
        }
        private string CheckNonMdRelativeFileHref(string nonMdHref, IMarkdownContext context, string rawMarkdown, string line)
        {
            // If the context doesn't have necessary info or nonMdHref is not a relative path, return the original href
            if (!context.Variables.ContainsKey("path") || !TypeForwardedToPathUtility.IsRelativePath(nonMdHref))
            {
                return(nonMdHref);
            }

            var currentFilePath   = (string)context.Variables["path"];
            var currentFolderPath = Path.GetDirectoryName(currentFilePath);

            var nonMdExpectedPath = Path.Combine(currentFolderPath, nonMdHref);

            if (!File.Exists(nonMdExpectedPath))
            {
                Logger.LogWarning($"Can't find resource reference: {nonMdHref}. Raw: {rawMarkdown}.", null, currentFilePath, line);
            }
            return(nonMdHref);
        }
Example #15
0
        public override void UpdateHref(FileModel model, IDocumentBuildContext context)
        {
            var toc = (TocItemViewModel)model.Content;
            var key = model.Key;

            // Add current folder to the toc mapping, e.g. `a/` maps to `a/toc`
            var directory = ((TypeForwardedToRelativePath)key).GetPathFromWorkingFolder().GetDirectoryPath();

            context.RegisterToc(key, directory);
            UpdateTocItemHref(toc, model, context);
            var tocInfo = new TocInfo(key);

            if (toc.Homepage != null)
            {
                if (TypeForwardedToPathUtility.IsRelativePath(toc.Homepage))
                {
                    var pathToRoot = ((TypeForwardedToRelativePath)model.File + (TypeForwardedToRelativePath)toc.Homepage).GetPathFromWorkingFolder();
                    tocInfo.Homepage = pathToRoot;
                }
            }

            context.RegisterTocInfo(tocInfo);
        }
Example #16
0
        private static void MergeOptionsToConfig(BuildCommandOptions options, BuildJsonConfig config)
        {
            // base directory for content from command line is current directory
            // e.g. C:\folder1>docfx build folder2\docfx.json --content "*.cs"
            // for `--content "*.cs*`, base directory should be `C:\folder1`
            string optionsBaseDirectory = Directory.GetCurrentDirectory();

            config.OutputFolder = options.OutputFolder;

            // Override config file with options from command line
            if (options.Templates != null && options.Templates.Count > 0)
            {
                config.Templates = new ListWithStringFallback(options.Templates);
            }

            if (options.PostProcessors != null && options.PostProcessors.Count > 0)
            {
                config.PostProcessors = new ListWithStringFallback(options.PostProcessors);
            }

            if (options.Themes != null && options.Themes.Count > 0)
            {
                config.Themes = new ListWithStringFallback(options.Themes);
            }
            if (!string.IsNullOrEmpty(options.OutputFolder))
            {
                config.Destination = Path.GetFullPath(Path.Combine(options.OutputFolder, config.Destination ?? string.Empty));
            }
            if (options.Content != null)
            {
                if (config.Content == null)
                {
                    config.Content = new FileMapping(new FileMappingItem());
                }
                config.Content.Add(
                    new FileMappingItem
                {
                    Files        = new FileItems(options.Content),
                    SourceFolder = optionsBaseDirectory,
                });
            }
            if (options.Resource != null)
            {
                if (config.Resource == null)
                {
                    config.Resource = new FileMapping(new FileMappingItem());
                }
                config.Resource.Add(
                    new FileMappingItem
                {
                    Files        = new FileItems(options.Resource),
                    SourceFolder = optionsBaseDirectory,
                });
            }
            if (options.Overwrite != null)
            {
                if (config.Overwrite == null)
                {
                    config.Overwrite = new FileMapping(new FileMappingItem());
                }
                config.Overwrite.Add(
                    new FileMappingItem
                {
                    Files        = new FileItems(options.Overwrite),
                    SourceFolder = optionsBaseDirectory,
                });
            }
            if (options.ExternalReference != null)
            {
                if (config.ExternalReference == null)
                {
                    config.ExternalReference = new FileMapping(new FileMappingItem());
                }
                config.ExternalReference.Add(
                    new FileMappingItem
                {
                    Files        = new FileItems(options.ExternalReference),
                    SourceFolder = optionsBaseDirectory,
                });
            }

            if (options.XRefMaps != null)
            {
                config.XRefMaps =
                    new ListWithStringFallback(
                        (config.XRefMaps ?? new ListWithStringFallback())
                        .Concat(options.XRefMaps)
                        .Where(x => !string.IsNullOrWhiteSpace(x))
                        .Distinct());
            }

            //to-do: get changelist from options

            if (options.Serve)
            {
                config.Serve = options.Serve;
            }
            if (options.Port.HasValue)
            {
                config.Port = options.Port.Value.ToString();
            }
            config.Force           |= options.ForceRebuild;
            config.ExportRawModel  |= options.ExportRawModel;
            config.ExportViewModel |= options.ExportViewModel;
            if (!string.IsNullOrEmpty(options.RawModelOutputFolder))
            {
                config.RawModelOutputFolder = Path.GetFullPath(options.RawModelOutputFolder);
            }
            if (!string.IsNullOrEmpty(options.ViewModelOutputFolder))
            {
                config.ViewModelOutputFolder = Path.GetFullPath(options.ViewModelOutputFolder);
            }
            config.DryRun |= options.DryRun;
            if (options.MaxParallelism != null)
            {
                config.MaxParallelism = options.MaxParallelism;
            }
            if (options.MarkdownEngineName != null)
            {
                config.MarkdownEngineName = options.MarkdownEngineName;
            }
            if (options.MarkdownEngineProperties != null)
            {
                config.MarkdownEngineProperties =
                    JsonConvert.DeserializeObject <Dictionary <string, object> >(
                        options.MarkdownEngineProperties,
                        new JsonSerializerSettings
                {
                    Converters =
                    {
                        new JObjectDictionaryToObjectDictionaryConverter()
                    }
                });
            }
            if (options.NoLangKeyword != null)
            {
                config.NoLangKeyword = options.NoLangKeyword.Value;
            }
            if (options.IntermediateFolder != null)
            {
                config.IntermediateFolder = options.IntermediateFolder;
            }
            if (options.ChangesFile != null)
            {
                config.ChangesFile = options.ChangesFile;
            }
            if (options.GlobalMetadataFilePaths != null && options.GlobalMetadataFilePaths.Any())
            {
                config.GlobalMetadataFilePaths.AddRange(options.GlobalMetadataFilePaths);
            }

            config.GlobalMetadataFilePaths =
                new ListWithStringFallback(config.GlobalMetadataFilePaths.Select(
                                               path => TypeForwardedToPathUtility.IsRelativePath(path) ? Path.Combine(config.BaseDirectory, path) : path).Reverse());

            if (options.FileMetadataFilePaths != null && options.FileMetadataFilePaths.Any())
            {
                config.FileMetadataFilePaths.AddRange(options.FileMetadataFilePaths);
            }

            config.FileMetadataFilePaths =
                new ListWithStringFallback(config.FileMetadataFilePaths.Select(
                                               path => TypeForwardedToPathUtility.IsRelativePath(path) ? Path.Combine(config.BaseDirectory, path) : path).Reverse());

            config.FileMetadata   = GetFileMetadataFromOption(config.FileMetadata, options.FileMetadataFilePath, config.FileMetadataFilePaths);
            config.GlobalMetadata = GetGlobalMetadataFromOption(config.GlobalMetadata, options.GlobalMetadataFilePath, config.GlobalMetadataFilePaths, options.GlobalMetadata);
        }
        private string GenerateAzureLinkHref(IMarkdownContext context, string href, string rawMarkdown, string line)
        {
            if (string.IsNullOrEmpty(href))
            {
                return(string.Empty);
            }

            StringBuffer content = StringBuffer.Empty;

            // If the context doesn't have necessary info, return the original href
            if (!context.Variables.ContainsKey("path") || !context.Variables.ContainsKey("azureMarkdownFileInfoMapping"))
            {
                return(href);
            }

            // if the href is not relative path, return it. Add try catch to keep this method safe.
            try
            {
                if (!TypeForwardedToPathUtility.IsRelativePath(href))
                {
                    return(href);
                }
            }
            catch (ArgumentException)
            {
                Logger.LogWarning($"Invalid reference {href} in file: {(string)context.Variables["path"]}. Raw: {rawMarkdown}", null, (string)context.Variables["path"], line);
                return(href);
            }

            // deal with bookmark. Get file name and anchor
            string hrefFileName = string.Empty;
            string anchor       = string.Empty;
            var    index        = href.IndexOf('#');

            if (index == -1)
            {
                hrefFileName = Path.GetFileName(href);
            }
            else if (index == 0)
            {
                return(href);
            }
            else
            {
                hrefFileName = Path.GetFileName(href.Remove(index));
                anchor       = href.Substring(index);
            }

            // deal with different kinds of relative paths
            var currentFilePath = (string)context.Variables["path"];
            var azureMarkdownFileInfoMapping = (IReadOnlyDictionary <string, AzureFileInfo>)context.Variables["azureMarkdownFileInfoMapping"];

            if (azureMarkdownFileInfoMapping == null || !azureMarkdownFileInfoMapping.ContainsKey(hrefFileName))
            {
                Logger.LogWarning($"Can't find markdown reference: {href}. Raw: {rawMarkdown}.", null, currentFilePath, line);
                return(href);
            }

            string azureHref    = null;
            var    hrefFileInfo = azureMarkdownFileInfoMapping[hrefFileName];

            azureHref = string.Format("{0}{1}", TypeForwardedToPathUtility.MakeRelativePath(Path.GetDirectoryName(currentFilePath), hrefFileInfo.FilePath), anchor);

            return(azureHref);
        }
Example #18
0
        private string FixNonMdRelativeFileHref(string nonMdHref, IMarkdownContext context, string rawMarkdown)
        {
            // If the context doesn't have necessary info or nonMdHref is not a relative path, return the original href
            if (!context.Variables.ContainsKey("path") || !TypeForwardedToPathUtility.IsRelativePath(nonMdHref))
            {
                return(nonMdHref);
            }

            var currentFilePath   = (string)context.Variables["path"];
            var currentFolderPath = Path.GetDirectoryName(currentFilePath);

            try
            {
                // if the relative path (not from azure resource file info mapping) is under docset. Just return it.
                var nonMdHrefFullPath = Path.GetFullPath(Path.Combine(currentFolderPath, nonMdHref));
                if (TypeForwardedToPathUtility.IsPathUnderSpecificFolder(nonMdHrefFullPath, currentFolderPath))
                {
                    return(nonMdHref);
                }
                else
                {
                    Logger.LogVerbose($"Relative path:{nonMdHref} is not under {currentFolderPath} of file {currentFilePath}. Use ex_resource to replace the link.");
                }

                // if azure resource file info doesn't exist, log warning and return
                if (!context.Variables.ContainsKey("azureResourceFileInfoMapping"))
                {
                    Logger.LogWarning($"Can't find azure resource file info mapping. Couldn't fix href: {nonMdHref} in file {currentFilePath}. raw: {rawMarkdown}");
                    return(nonMdHref);
                }

                var           nonMdHrefFileName            = Path.GetFileName(nonMdHref);
                var           azureResourceFileInfoMapping = (Dictionary <string, AzureFileInfo>)context.Variables["azureResourceFileInfoMapping"];
                AzureFileInfo azureResourceFileInfo;
                if (!azureResourceFileInfoMapping.TryGetValue(nonMdHrefFileName, out azureResourceFileInfo))
                {
                    Logger.LogWarning($"Can't find info for file name {nonMdHrefFileName} in azure resource file info mapping. Couldn't fix href: {nonMdHref} in file {currentFilePath}. raw: {rawMarkdown}");
                    return(nonMdHref);
                }

                // If the nonMdHref is under same docset with current file. No need to fix that.
                if (TypeForwardedToPathUtility.IsPathUnderSpecificFolder(azureResourceFileInfo.FilePath, currentFolderPath))
                {
                    return(nonMdHref);
                }

                // If the nonMdHref is under different docset with current file but not exists. Then log warning and won't fix.
                if (!File.Exists(azureResourceFileInfo.FilePath))
                {
                    Logger.LogWarning($"{nonMdHref} refer by {currentFilePath} doesn't exists. Won't do link fix. raw: {rawMarkdown}");
                    return(nonMdHref);
                }

                // If the nonMdHref is under different docset with current file and also exists, then fix the link.
                // 1. copy the external file to ex_resource folder. 2. Return new href path to the file under external folder
                var exResourceDir = Directory.CreateDirectory(Path.Combine(currentFolderPath, ExternalResourceFolderName));
                var resDestPath   = Path.Combine(exResourceDir.FullName, Path.GetFileName(azureResourceFileInfo.FilePath));
                File.Copy(azureResourceFileInfo.FilePath, resDestPath, true);
                return(TypeForwardedToPathUtility.MakeRelativePath(currentFolderPath, resDestPath));
            }
            catch (NotSupportedException nse)
            {
                Logger.LogWarning($"Warning: FixNonMdRelativeFileHref can't be apply on reference: {nonMdHref}. Exception: {nse.Message}");
                return(nonMdHref);
            }
        }
Example #19
0
        private string GenerateAzureLinkHref(IMarkdownContext context, string href, string rawMarkdown)
        {
            StringBuffer content = StringBuffer.Empty;

            // If the context doesn't have necessary info, return the original href
            if (!context.Variables.ContainsKey("path") || !context.Variables.ContainsKey("azureMarkdownFileInfoMapping"))
            {
                return(href);
            }

            // if the href is not relative path, return it
            if (!TypeForwardedToPathUtility.IsRelativePath(href))
            {
                return(href);
            }

            // deal with bookmark. Get file name and anchor
            string hrefFileName = string.Empty;
            string anchor       = string.Empty;
            var    index        = href.IndexOf('#');

            if (index == -1)
            {
                hrefFileName = Path.GetFileName(href);
            }
            else if (index == 0)
            {
                return(href);
            }
            else
            {
                hrefFileName = Path.GetFileName(href.Remove(index));
                anchor       = href.Substring(index);
            }

            // deal with different kinds of relative paths
            var currentFilePath = (string)context.Variables["path"];
            var azureMarkdownFileInfoMapping = (IReadOnlyDictionary <string, AzureFileInfo>)context.Variables["azureMarkdownFileInfoMapping"];

            if (azureMarkdownFileInfoMapping == null || !azureMarkdownFileInfoMapping.ContainsKey(hrefFileName))
            {
                Logger.LogWarning($"Can't fild reference file: {href} in azure file system for file {currentFilePath}. Raw: {rawMarkdown}");
                return(href);
            }

            string azureHref    = null;
            var    hrefFileInfo = azureMarkdownFileInfoMapping[hrefFileName];

            // Not in docsets and transform to azure external link
            if (hrefFileInfo.NeedTransformToAzureExternalLink)
            {
                azureHref = $"{hrefFileInfo.UriPrefix}/{Path.GetFileNameWithoutExtension(hrefFileName)}{anchor}";
            }
            else
            {
                var hrefPath = hrefFileInfo.FilePath;

                // It is correct for Azure strucuture. Azure articles are all under same folder
                var isHrefInsameDocset = TypeForwardedToPathUtility.IsPathUnderSpecificFolder(hrefPath, Path.GetDirectoryName(currentFilePath));

                // In same docset with current file, use relative path. Otherwise, use docset link prefix
                if (isHrefInsameDocset)
                {
                    azureHref = string.Format("{0}{1}", TypeForwardedToPathUtility.MakeRelativePath(Path.GetDirectoryName(currentFilePath), hrefFileInfo.FilePath), anchor);
                }
                else
                {
                    // If the file is in different docset, then append the absolute path prefix. .html should be remove as docs also don't need it now.
                    azureHref = $"{hrefFileInfo.UriPrefix}/{Path.GetFileNameWithoutExtension(hrefFileName)}{anchor}";
                }
            }

            return(azureHref);
        }
Example #20
0
        public override void Handle(HtmlDocument document, ManifestItem manifestItem, string inputFile, string outputFile)
        {
            _fileMapping[outputFile] = inputFile;

            // RFC 3986: relative-ref = relative-part [ "?" query ] [ "#" fragment ]
            _linksWithBookmark[outputFile] =
                (from node in GetNodesWithAttribute(document, "href")
                 let link = node.GetAttributeValue("href", null)
                            let bookmarkIndex = link.IndexOf("#")
                                                where bookmarkIndex != -1
                                                let bookmark = link.Substring(bookmarkIndex + 1)
                                                               let index = link.IndexOfAny(new[] { '?', '#' })
                                                                           let decodedLink = HttpUtility.UrlDecode(link.Remove(index))
                                                                                             where !WhiteList.Contains(bookmark) && TypeForwardedToPathUtility.IsRelativePath(decodedLink)
                                                                                             select new LinkItem
            {
                Title = node.InnerText,
                Href = TransformPath(outputFile, decodedLink),
                Bookmark = bookmark,
                SourceFragment = WebUtility.HtmlDecode(node.GetAttributeValue("data-raw-source", null)),
                SourceFile = WebUtility.HtmlDecode(node.GetAttributeValue("sourceFile", null)),
                SourceLineNumber = node.GetAttributeValue("sourceStartLineNumber", 0),
                TargetLineNumber = node.Line
            }).ToList();
            var anchors = GetNodeAttribute(document, "id").Concat(GetNodeAttribute(document, "name"));

            _registeredBookmarks[outputFile] = new HashSet <string>(anchors);
        }