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); }
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); }
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)); }
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); }
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)); } }
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; }
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))); }