Beispiel #1
0
        protected override void HandleCore(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 nocheck = node.GetAttributeValue("nocheck", null)
                               where !"bookmark".Equals(nocheck, StringComparison.OrdinalIgnoreCase)
                               let link = node.GetAttributeValue("href", null)
                                          let bookmark = UriUtility.GetFragment(link).TrimStart('#')
                                                         let decodedLink = RelativePath.TryParse(HttpUtility.UrlDecode(UriUtility.GetPath(link)))
                                                                           where !string.IsNullOrEmpty(bookmark) && !WhiteList.Contains(bookmark)
                                                                           where decodedLink != null
                                                                           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);
        }
Beispiel #2
0
            private string GetHrefFromRoot(string originalHref, HandleModelAttributesContext context)
            {
                if (context.FileAndType == null || string.IsNullOrEmpty(originalHref) || !RelativePath.IsRelativePath(originalHref))
                {
                    return(originalHref);
                }

                var result = originalHref;
                var ft     = context.FileAndType;
                var path   = (RelativePath)ft.File + (RelativePath)UriUtility.GetPath(originalHref);
                var file   = path.GetPathFromWorkingFolder().UrlDecode();

                if (context.Host.SourceFiles.ContainsKey(file))
                {
                    result = file.UrlEncode().ToString() + UriUtility.GetQueryStringAndFragment(originalHref);
                }

                List <LinkSourceInfo> sources;

                if (!context.FileLinkSources.TryGetValue(file, out sources))
                {
                    sources = new List <LinkSourceInfo>();
                    context.FileLinkSources[file] = sources;
                }
                sources.Add(new LinkSourceInfo
                {
                    Target     = file,
                    Anchor     = UriUtility.GetFragment(originalHref),
                    SourceFile = ft.File,
                });
                context.LinkToFiles.Add(file);

                return(result);
            }
Beispiel #3
0
 public void TestUriUtility(string input, string path, string queryString, string fragment, string queryStringAndFragment, string nonFragment)
 {
     Assert.Equal(path, UriUtility.GetPath(input));
     Assert.Equal(queryString, UriUtility.GetQueryString(input));
     Assert.Equal(fragment, UriUtility.GetFragment(input));
     Assert.Equal(queryStringAndFragment, UriUtility.GetQueryStringAndFragment(input));
     Assert.Equal(nonFragment, UriUtility.GetNonFragment(input));
 }
Beispiel #4
0
        public object Interpret(BaseSchema schema, object value, IProcessContext context, string path)
        {
            if (value == null || !CanInterpret(schema))
            {
                return(value);
            }

            if (!(value is string val))
            {
                throw new ArgumentException($"{value.GetType()} is not supported type string.");
            }

            if (!Uri.TryCreate(val, UriKind.RelativeOrAbsolute, out Uri uri))
            {
                var message = $"{val} is not a valid href";
                Logger.LogError(message, code: ErrorCodes.Build.InvalidHref);
                throw new DocumentException(message);
            }

            // "/" is also considered as absolute to us
            if (uri.IsAbsoluteUri || val.StartsWith("/", StringComparison.Ordinal))
            {
                return(Helper.RemoveHostName(val, _siteHostName));
            }

            // sample value: a/b/c?hello
            var filePath  = UriUtility.GetPath(val);
            var fragments = UriUtility.GetQueryStringAndFragment(val);
            var relPath   = RelativePath.TryParse(filePath);

            if (relPath != null)
            {
                var originalFile = context.GetOriginalContentFile(path);
                var currentFile  = (RelativePath)originalFile.File;
                relPath = (currentFile + relPath.UrlDecode()).GetPathFromWorkingFolder();
                if (_exportFileLink)
                {
                    (context.FileLinkSources).AddFileLinkSource(new LinkSourceInfo
                    {
                        Target     = relPath,
                        Anchor     = UriUtility.GetFragment(val),
                        SourceFile = originalFile.File
                    });
                }

                if (_updateValue && context.BuildContext != null)
                {
                    var resolved = (RelativePath)context.BuildContext.GetFilePath(relPath);
                    if (resolved != null)
                    {
                        val = resolved.MakeRelativeTo(((RelativePath)context.FileAndType.File).GetPathFromWorkingFolder()).UrlEncode() + fragments;
                    }
                }
            }

            return(val);
        }
Beispiel #5
0
        public object Interpret(BaseSchema schema, object value, IProcessContext context, string path)
        {
            if (value == null || !CanInterpret(schema))
            {
                return(value);
            }

            if (!(value is string val))
            {
                throw new ArgumentException($"{value.GetType()} is not supported type string.");
            }

            if (!Uri.TryCreate(val, UriKind.RelativeOrAbsolute, out Uri uri))
            {
                throw new DocumentException($"{val} is not a valid href");
            }

            // "/" is also considered as absolute to us
            if (uri.IsAbsoluteUri || val.StartsWith("/"))
            {
                return(value);
            }

            // sample value: a/b/c?hello
            var filePath  = UriUtility.GetPath(val);
            var fragments = UriUtility.GetQueryStringAndFragment(val);
            var relPath   = RelativePath.TryParse(filePath);

            if (relPath != null)
            {
                var currentFile = (RelativePath)context.Model.OriginalFileAndType.File;
                relPath = (currentFile + relPath.UrlDecode()).GetPathFromWorkingFolder();
                if (_exportFileLink)
                {
                    ((Dictionary <string, List <LinkSourceInfo> >)context.Properties.FileLinkSources).AddFileLinkSource(new LinkSourceInfo
                    {
                        Target     = relPath,
                        Anchor     = UriUtility.GetFragment(val),
                        SourceFile = context.Model.OriginalFileAndType.File
                    });
                }

                if (_updateValue && context.BuildContext != null)
                {
                    var resolved = (RelativePath)context.BuildContext.GetFilePath(relPath);
                    if (resolved != null)
                    {
                        val = resolved.MakeRelativeTo(((RelativePath)context.Model.File).GetPathFromWorkingFolder()).UrlEncode() + fragments;
                    }
                }
            }

            return(val);
        }
        private void BuildCore(TocItemViewModel item, FileModel model, IHostService hostService, string includedFrom = null)
        {
            if (item == null)
            {
                return;
            }

            var linkToUids      = new HashSet <string>();
            var linkToFiles     = new HashSet <string>();
            var uidLinkSources  = new Dictionary <string, ImmutableList <LinkSourceInfo> >();
            var fileLinkSources = new Dictionary <string, ImmutableList <LinkSourceInfo> >();

            if (Utility.IsSupportedRelativeHref(item.Href))
            {
                UpdateDependencies(linkToFiles, fileLinkSources, item.Href);
            }
            if (Utility.IsSupportedRelativeHref(item.Homepage))
            {
                UpdateDependencies(linkToFiles, fileLinkSources, item.Homepage);
            }
            if (!string.IsNullOrEmpty(item.TopicUid))
            {
                UpdateDependencies(linkToUids, uidLinkSources, item.TopicUid);
            }

            model.LinkToUids      = model.LinkToUids.Union(linkToUids);
            model.LinkToFiles     = model.LinkToFiles.Union(linkToFiles);
            model.UidLinkSources  = model.UidLinkSources.Merge(uidLinkSources);
            model.FileLinkSources = model.FileLinkSources.Merge(fileLinkSources);

            includedFrom = item.IncludedFrom ?? includedFrom;
            if (item.Items != null)
            {
                foreach (var i in item.Items)
                {
                    BuildCore(i, model, hostService, includedFrom);
                }
            }

            void UpdateDependencies(HashSet <string> linkTos, Dictionary <string, ImmutableList <LinkSourceInfo> > linkSources, string link)
            {
                var path   = UriUtility.GetPath(link);
                var anchor = UriUtility.GetFragment(link);

                linkTos.Add(path);
                AddOrUpdate(linkSources, path, GetLinkSourceInfo(path, anchor, model.File, includedFrom));
            }
        }
Beispiel #7
0
        public void ApplyXrefSpec(XRefSpec spec)
        {
            if (spec == null)
            {
                return;
            }

            // TODO: What if href is not html?
            if (!string.IsNullOrEmpty(spec.Href))
            {
                Href = UriUtility.GetNonFragment(spec.Href);
                if (string.IsNullOrEmpty(Anchor))
                {
                    Anchor = UriUtility.GetFragment(spec.Href);
                }
            }
            Spec = spec;
        }
Beispiel #8
0
            private async Task <List <XRefSpec> > HandleCoreAsync(Task <List <XRefSpec> > task, string name, string value)
            {
                var list = await task;

                foreach (var item in list)
                {
                    if (string.IsNullOrEmpty(item.Href))
                    {
                        continue;
                    }
                    var mvc = HttpUtility.ParseQueryString(UriUtility.GetQueryString(item.Href));
                    mvc[name] = value;
                    item.Href = UriUtility.GetPath(item.Href) +
                                "?" + mvc.ToString() +
                                UriUtility.GetFragment(item.Href);
                }
                return(list);
            }
        private void UpdateHref(HtmlAgilityPack.HtmlNode link, string attribute, IDocumentBuildContext context, string sourceFilePath, string destFilePath)
        {
            var originalHref = link.GetAttributeValue(attribute, null);
            var anchor       = link.GetAttributeValue("anchor", null);

            link.Attributes.Remove("anchor");
            var originalPath = UriUtility.GetPath(originalHref);
            var path         = RelativePath.TryParse(originalPath);

            if (path == null)
            {
                return;
            }

            var fli = new FileLinkInfo
            {
                FromFileInSource = sourceFilePath,
                FromFileInDest   = destFilePath,
            };

            if (path.IsFromWorkingFolder())
            {
                var targetInSource = path.UrlDecode();
                fli.ToFileInSource   = targetInSource.RemoveWorkingFolder();
                fli.ToFileInDest     = RelativePath.GetPathWithoutWorkingFolderChar(context.GetFilePath(targetInSource));
                fli.FileLinkInSource = targetInSource - (RelativePath)sourceFilePath;
                if (fli.ToFileInDest != null)
                {
                    var resolved = (RelativePath)fli.ToFileInDest - (RelativePath)destFilePath;
                    fli.FileLinkInDest = resolved;
                    fli.Href           = resolved.UrlEncode();
                }
                else
                {
                    fli.Href = (targetInSource.RemoveWorkingFolder() - ((RelativePath)sourceFilePath).RemoveWorkingFolder()).UrlEncode();
                }
            }
            else
            {
                fli.FileLinkInSource = path.UrlDecode();
                fli.ToFileInSource   = ((RelativePath)sourceFilePath + path).RemoveWorkingFolder();
                fli.FileLinkInDest   = fli.FileLinkInSource;
                fli.Href             = originalPath;
            }
            var href = _settings.HrefGenerator?.GenerateHref(fli) ?? fli.Href;

            link.SetAttributeValue(attribute, href + UriUtility.GetQueryString(originalHref) + (anchor ?? UriUtility.GetFragment(originalHref)));
        }
        /// <summary>
        /// Export xref map file.
        /// </summary>
        private static string ExportXRefMap(DocumentBuildParameters parameters, DocumentBuildContext context)
        {
            Logger.LogVerbose("Exporting xref map...");
            var xrefMap = new XRefMap();

            xrefMap.References =
                (from xref in context.XRefSpecMap.Values.AsParallel().WithDegreeOfParallelism(parameters.MaxParallelism)
                 select new XRefSpec(xref)
            {
                Href = ((RelativePath)context.GetFilePath(UriUtility.GetNonFragment(xref.Href))).RemoveWorkingFolder() + UriUtility.GetFragment(xref.Href)
            }).ToList();
            xrefMap.Sort();
            string xrefMapFileNameWithVersion = string.IsNullOrEmpty(parameters.VersionName) ?
                                                XRefMapFileName :
                                                parameters.VersionName + "." + XRefMapFileName;

            YamlUtility.Serialize(
                xrefMapFileNameWithVersion,
                xrefMap,
                YamlMime.XRefMap);
            Logger.LogInfo("XRef map exported.");
            return(xrefMapFileNameWithVersion);
        }
        private void UpdateHref(HtmlNode link, string attribute, IDocumentBuildContext context, string sourceFilePath, string destFilePath)
        {
            var originalHref = link.GetAttributeValue(attribute, null);
            var anchor       = link.GetAttributeValue("anchor", null);

            link.Attributes.Remove("anchor");
            var originalPath = UriUtility.GetPath(originalHref);
            var path         = RelativePath.TryParse(originalPath);

            if (path == null)
            {
                if (!string.IsNullOrEmpty(anchor))
                {
                    link.SetAttributeValue(attribute, originalHref + anchor);
                }

                return;
            }

            var fli  = FileLinkInfo.Create(sourceFilePath, destFilePath, originalPath, context);
            var href = _settings.HrefGenerator?.GenerateHref(fli) ?? fli.Href;

            link.SetAttributeValue(attribute, href + UriUtility.GetQueryString(originalHref) + (anchor ?? UriUtility.GetFragment(originalHref)));
        }