Get parsing working, and HTML generation from resulting objects

This commit is contained in:
Saphire committed 2022-02-21 02:27:27 +07:00
1 parent a7250ceacf
commit 38f317afd3
9 files changed
+171 -146

No files matched your search

+4 -2
View File
@@ -9,7 +9,7 @@ public record ThreadPost
public string Author { get; set; }
public string Uid { get; set; }
public string RawHtml { get; set; }
public ParsedContent.ParsedContent? ParsedContent { get; set; }
public RootNode? ParsedContent { get; set; }
public string? File { get; set; }
public string? Filename { get; set; }
public string? Title { get; set; }
@@ -18,8 +18,10 @@ public record ThreadPost
[JsonIgnore]
public bool IsChapterAnnounce { get; set; } = false;
[JsonIgnore]
public ChapterMetadata? Chapter { get; set; }
public List<int>? RepliesTo { get; set; }
[JsonIgnore]
public bool AuthorPost { get; set; } = false;
}
public record Metadata
+46 -41
View File
@@ -6,10 +6,28 @@ using System.Web;
namespace QuestReader.Models.ParsedContent;
public class ParsedContent
[JsonConverter(typeof(ContentConverter))]
public abstract class ContentNode
{
public string Type { get => GetType().Name.Replace("Node", ""); }
}
public abstract class ContainerNode : ContentNode
{
public Version Version { get; set; }
public IList<ContentNode> Nodes { get; set; }
public override string ToString() => $"{Type} [ {string.Join(",\n", Nodes)} ]";
public IEnumerable<int> GetReferences()
{
return Nodes.SelectMany(n =>
n is ContainerNode container
? container.GetReferences()
: (
n is ReferenceNode @ref ? new List<int> { @ref.PostId ?? @ref.ThreadId } : Array.Empty<int>()
)
);
}
}
class ContentConverter : JsonConverter<ContentNode>
@@ -28,54 +46,42 @@ class ContentConverter : JsonConverter<ContentNode>
ContentNode value,
JsonSerializerOptions options)
{
switch (value)
{
switch (value) {
case null:
JsonSerializer.Serialize(writer, null as ContentNode, options);
break;
case TextNode textNode:
JsonSerializer.Serialize(writer, textNode.Text, options);
break;
default:
{
if (value is RootNode)
throw new InvalidDataContractException("RootNode must not be used");
var type = value.GetType();
JsonSerializer.Serialize(writer, value, type, options);
break;
}
}
var type = value.GetType();
JsonSerializer.Serialize(writer, value, type, options);
break;
};
}
}
[JsonConverter(typeof(ContentConverter))]
public abstract class ContentNode
public class RootNode : ContainerNode
{
public string Type { get => GetType().Name.Replace("Node", ""); }
public virtual string Render(TemplateModel model)
{
throw new NotImplementedException("Rendering is not supported for this node type");
}
public Version Version { get; set; }
}
public class TextNode : ContentNode
{
public string Text { get; set; }
public override string ToString() => $"\"{Text}\"";
public override string Render(TemplateModel model) => HttpUtility.HtmlEncode(Text);
public override string ToString() => $"{Text}";
}
public class NewlineNode : ContentNode
{
public override string ToString() => $"<br>";
public override string Render(TemplateModel model) => "<br>";
public override string ToString() => $"\n";
}
public class ReferenceNode : ContentNode
{
public int PostId { get; set; }
public int? PostId { get; set; }
public int ThreadId { get; set; }
public ReferenceType ReferenceType { get; set; }
public bool LongReference { get; set; }
@@ -88,20 +94,11 @@ public enum ReferenceType
QuestDiscussion
}
public abstract class ContainerNode : ContentNode
public class YoutubeEmbedNode : ContentNode
{
public IList<ContentNode> Nodes { get; set; }
public override string ToString() => $"{Type} [ {string.Join(",\n", Nodes)} ]";
}
// A temporary container to recursively parse everything of a note before bailing and MUST NOT BE USED NORMALLY
public class RootNode : ContainerNode
{
public override string ToString() => throw new InvalidDataContractException("RootNode must not be used");
public override string Render(TemplateModel model) => throw new InvalidDataContractException("RootNode must not be used");
}
/// <remarks>Todo: Make this a URL</remarks>
public string VideoLink { get; set; }
};
public class QuoteNode : ContainerNode { };
@@ -117,7 +114,15 @@ public class InlineCodeNode : ContainerNode { };
public class UnderlineNode : ContainerNode { };
public class SmallFontNode : ContainerNode { };
public class ColorNode : ContainerNode
{
public string Color { get; set; }
};
public class ExternalLinkNode : ContainerNode
{
/// <remarks>Todo: Make this a URL</remarks>
public string Destination { get; set; }
}
+1 -1
View File
@@ -6,6 +6,6 @@ public class TemplateModel
public DateTime Now { get; set; }
public List<ThreadPost> Posts { get; set; }
public List<ThreadPost> AllPosts { get; set; }
public string BaseUrl { get; set; }
public string AssetsPath { get; set; }
public string ToolVersion { get; set; }
}