-
Notifications
You must be signed in to change notification settings - Fork 236
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6907139
commit c3aac82
Showing
11 changed files
with
634 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
using System; | ||
using System.Collections.Immutable; | ||
using System.Linq; | ||
using Statiq.Common; | ||
|
||
namespace Statiq.Web | ||
{ | ||
public static class IExecutionContextXrefExtensions | ||
{ | ||
public static bool TryGetXrefDocument(this IExecutionContext context, string xref, out IDocument document) | ||
{ | ||
_ = context ?? throw new ArgumentNullException(nameof(context)); | ||
|
||
ImmutableArray<IDocument> matches = context.Outputs[nameof(Pipelines.Content)].Flatten() | ||
.Where(x => x.GetString(WebKeys.Xref)?.Equals(xref, StringComparison.OrdinalIgnoreCase) == true) | ||
.ToImmutableDocumentArray(); | ||
if (matches.Length > 1) | ||
{ | ||
throw new ExecutionException($"Multiple ambiguous matching documents found for xref \"{xref}\""); | ||
} | ||
if (matches.Length == 1) | ||
{ | ||
document = matches[0]; | ||
return true; | ||
} | ||
document = default; | ||
return false; | ||
} | ||
|
||
public static IDocument GetXrefDocument(this IExecutionContext context, string xref) => | ||
context.TryGetXrefDocument(xref, out IDocument document) ? document : throw new ExecutionException($"Couldn't find document with xref \"{xref}\""); | ||
|
||
public static bool TryGetXrefLink(this IExecutionContext context, string xref, out string link) => | ||
context.TryGetXrefLink(xref, false, out link); | ||
|
||
public static bool TryGetXrefLink(this IExecutionContext context, string xref, bool includeHost, out string link) | ||
{ | ||
if (context.TryGetXrefDocument(xref, out IDocument document)) | ||
{ | ||
link = document.GetLink(includeHost); | ||
return link != null; | ||
} | ||
link = default; | ||
return false; | ||
} | ||
|
||
public static string GetXrefLink(this IExecutionContext context, string xref, bool includeHost = false) => | ||
context.TryGetXrefLink(xref, includeHost, out string link) ? link : throw new ExecutionException($"Couldn't get link for document with xref \"{xref}\""); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,4 +21,4 @@ public ProcessMetadata() | |
{ | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using AngleSharp.Dom; | ||
using AngleSharp.Dom.Html; | ||
using AngleSharp.Parser.Html; | ||
using Statiq.Common; | ||
using Statiq.Html; | ||
|
||
namespace Statiq.Web.Modules | ||
{ | ||
public class ResolveXrefs : ParallelModule | ||
{ | ||
private static readonly HtmlParser HtmlParser = new HtmlParser(); | ||
|
||
protected override async Task<IEnumerable<Common.IDocument>> ExecuteInputAsync(Common.IDocument input, IExecutionContext context) | ||
{ | ||
IHtmlDocument htmlDocument = await input.ParseHtmlAsync(context, HtmlParser); | ||
if (htmlDocument != null) | ||
{ | ||
// Find and replace "xref:" in links | ||
bool modifiedDocument = false; | ||
foreach (IElement element in htmlDocument | ||
.GetElementsByTagName("a") | ||
.Where(x => x.HasAttribute("href"))) | ||
{ | ||
string href = element.GetAttribute("href"); | ||
if (href.StartsWith("xref:") && href.Length > 5) | ||
{ | ||
string xref = href.Substring(5); | ||
string queryAndFragment = string.Empty; | ||
int queryAndFragmentIndex = xref.IndexOfAny(new[] { '#', '?' }); | ||
if (queryAndFragmentIndex > 0) | ||
{ | ||
queryAndFragment = xref.Substring(queryAndFragmentIndex); | ||
xref = xref.Substring(0, queryAndFragmentIndex); | ||
} | ||
element.Attributes["href"].Value = context.GetXrefLink(xref) + queryAndFragment; | ||
modifiedDocument = true; | ||
} | ||
} | ||
|
||
// Return a new document with the replacements if we performed any | ||
if (modifiedDocument) | ||
{ | ||
using (Stream contentStream = await context.GetContentStreamAsync()) | ||
{ | ||
using (StreamWriter writer = contentStream.GetWriter()) | ||
{ | ||
htmlDocument.ToHtml(writer, ProcessingInstructionFormatter.Instance); | ||
writer.Flush(); | ||
return input.Clone(context.GetContentProvider(contentStream, MediaTypes.Html)).Yield(); | ||
} | ||
} | ||
} | ||
} | ||
|
||
return input.Yield(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
using AngleSharp; | ||
using AngleSharp.Dom; | ||
using AngleSharp.Html; | ||
|
||
namespace Statiq.Web | ||
{ | ||
/// <summary> | ||
/// This uncomments shortcode processing instructions which currently get parsed as comments | ||
/// in AngleSharp. See https://github.com/Wyamio/Statiq/issues/784. | ||
/// This can be removed once https://github.com/AngleSharp/AngleSharp/pull/762 is merged. | ||
/// </summary> | ||
internal class ProcessingInstructionFormatter : IMarkupFormatter | ||
{ | ||
private static readonly IMarkupFormatter Formatter = HtmlMarkupFormatter.Instance; | ||
|
||
public static readonly IMarkupFormatter Instance = new ProcessingInstructionFormatter(); | ||
|
||
public string Attribute(IAttr attribute) => Formatter.Attribute(attribute); | ||
|
||
public string CloseTag(IElement element, bool selfClosing) => Formatter.CloseTag(element, selfClosing); | ||
|
||
public string Doctype(IDocumentType doctype) => Formatter.Doctype(doctype); | ||
|
||
public string OpenTag(IElement element, bool selfClosing) => Formatter.OpenTag(element, selfClosing); | ||
|
||
public string Text(string text) => Formatter.Text(text); | ||
|
||
public string Processing(IProcessingInstruction processing) => Formatter.Processing(processing); | ||
|
||
public string Comment(IComment comment) | ||
{ | ||
if (comment.Data.StartsWith("?") && comment.Data.EndsWith("?")) | ||
{ | ||
// This was probably a shortcode, so uncomment it | ||
return $"<{comment.Data}>"; | ||
} | ||
return Formatter.Comment(comment); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.