diff --git a/TASVideos.WikiEngine/Builtins.cs b/TASVideos.WikiEngine/Builtins.cs index 869c1f62b..749bdca88 100644 --- a/TASVideos.WikiEngine/Builtins.cs +++ b/TASVideos.WikiEngine/Builtins.cs @@ -3,4 +3,6 @@ public static partial class Builtins { private static KeyValuePair Attr(string name, string value) => new(name, value); + + private static KeyValuePair Attr(string name, ReadOnlySpan value) => Attr(name, value.ToString()); } diff --git a/TASVideos.WikiEngine/MakeBracketed.cs b/TASVideos.WikiEngine/MakeBracketed.cs index 33c708eb4..f843f4e02 100644 --- a/TASVideos.WikiEngine/MakeBracketed.cs +++ b/TASVideos.WikiEngine/MakeBracketed.cs @@ -1,4 +1,5 @@ using TASVideos.Common; +using TASVideos.Extensions; using TASVideos.WikiEngine.AST; namespace TASVideos.WikiEngine; @@ -12,7 +13,7 @@ public static partial class Builtins /// /// Turns text inside [square brackets] into the appropriate thing, usually module or link. Does not handle [if:]. /// - public static IEnumerable MakeBracketed(string text, StringIndices range) + public static IEnumerable MakeBracketed(ReadOnlySpan text, StringIndices range) { if (text.StartsWith("if:")) { @@ -32,7 +33,7 @@ public static IEnumerable MakeBracketed(string text, StringIndices range) return MakeModuleInternal(range, "UserGetWikiName"); } - Match match; + RegexMatchShim match; if ((match = Footnote.Match(text)).Success) { return MakeFootnote(range, match.Groups[1].Value); @@ -51,12 +52,12 @@ public static IEnumerable MakeBracketed(string text, StringIndices range) return MakeLinkOrImage(range, text); } - private static Module[] MakeModuleInternal(StringIndices range, string module) + private static Module[] MakeModuleInternal(StringIndices range, ReadOnlySpan module) { - return [new Module(range, module)]; + return [new Module(range, module.ToString())]; } - private static IEnumerable MakeFootnote(StringIndices range, string n) + private static IEnumerable MakeFootnote(StringIndices range, ReadOnlySpan n) { return [ @@ -67,7 +68,7 @@ private static IEnumerable MakeFootnote(StringIndices range, string n) ]; } - private static Element[] MakeFootnoteLink(StringIndices range, string n) + private static Element[] MakeFootnoteLink(StringIndices range, ReadOnlySpan n) { return [ @@ -88,24 +89,24 @@ private static Element[] MakeFootnoteLink(StringIndices range, string n) // You can always make a wikilink by starting with "[=", and that will accept a wide range of characters // This regex is just for things that we'll make implicit wiki links out of; contents of brackets that don't match any other known pattern private static readonly Regex ImplicitWikiLink = ImplicitWikiLinkRegex(); - private static bool IsLink(string text) + private static bool IsLink(ReadOnlySpan text) { - return LinkPrefixes.Any(text.StartsWith); + return text.StartsWithAny(LinkPrefixes); } - private static bool IsImage(string text) + private static bool IsImage(ReadOnlySpan text) { - return IsLink(text) && ImageSuffixes.Any(text.EndsWith); + return IsLink(text) && text.EndsWithAny(ImageSuffixes); } - private static string NormalizeImageUrl(string text) + private static ReadOnlySpan NormalizeImageUrl(ReadOnlySpan text) { return text[0] == '=' ? text[1] is '/' ? text[1..] : $"/{text[1..]}" : text; } - private static string NormalizeUrl(string text) + private static ReadOnlySpan NormalizeUrl(ReadOnlySpan text) { if (text[0] == '=') { @@ -125,12 +126,12 @@ private static string NormalizeUrl(string text) return text; } - public static string NormalizeInternalLink(string input) + public static string NormalizeInternalLink(ReadOnlySpan input) { var iAnchorSeparator = input.IndexOf('#'); var pathAndQuery = iAnchorSeparator < 0 ? input : input[..iAnchorSeparator]; var anchor = iAnchorSeparator < 0 ? "" : input[(iAnchorSeparator + 1)..]; - var ss = pathAndQuery.TrimEnd('/').Split('/'); + var ss = pathAndQuery.TrimEnd('/').ToString().Split('/'); int skip = -1; if (ss.Length >= 4 && ss[1].Equals("users", StringComparison.OrdinalIgnoreCase) && ss[2].Equals("profile", StringComparison.OrdinalIgnoreCase)) @@ -173,7 +174,7 @@ public static string NormalizeInternalLink(string input) return anchor.Length is 0 ? newText : $"{newText}#{anchor}"; } - private static string DisplayTextForUrl(string text) + private static ReadOnlySpan DisplayTextForUrl(ReadOnlySpan text) { // If users don't like this, they should use links with explicit display text if (text.StartsWith("user:")) @@ -185,9 +186,9 @@ private static string DisplayTextForUrl(string text) return text; } - private static IEnumerable MakeLinkOrImage(StringIndices range, string text) + private static IEnumerable MakeLinkOrImage(StringIndices range, ReadOnlySpan text) { - var pp = text.Split('|'); + var pp = text.ToString().Split('|'); if (pp.Length >= 2 && IsLink(pp[0]) && IsImage(pp[1])) { return [MakeLink(range, pp[0], MakeImage(range, pp.Skip(1), out _))]; @@ -232,7 +233,7 @@ private static IEnumerable MakeLinkOrImage(StringIndices range, string te return [new Text(range, $"[{text}]")]; } - internal static INode MakeLink(StringIndices range, string text, INode child) + internal static INode MakeLink(StringIndices range, ReadOnlySpan text, INode child) { var href = NormalizeUrl(text); var attrs = new List> diff --git a/TASVideos.WikiEngine/NodeImplementations/Text.cs b/TASVideos.WikiEngine/NodeImplementations/Text.cs index ded60984d..ee8612090 100644 --- a/TASVideos.WikiEngine/NodeImplementations/Text.cs +++ b/TASVideos.WikiEngine/NodeImplementations/Text.cs @@ -17,9 +17,15 @@ public int CharEnd set => _charRange.End = value; } + public Text(StringIndices range, ReadOnlySpan content) + : this(range, content.ToString()) { } + public Text(int charStart, string content) : this((charStart, default), content) { } + public Text(int charStart, ReadOnlySpan content) + : this(charStart, content.ToString()) { } + public Task WriteHtmlAsync(TextWriter w, WriterContext ctx) { foreach (var c in Content)