Update emoji support

* Add constants for emojis
* Move emoji shortcode rendering to Markup
* Add documentation
* Add example
* Add tests
This commit is contained in:
Patrik Svensson
2020-09-18 01:58:55 +02:00
committed by Patrik Svensson
parent 090b30f731
commit eeb3f967b6
38 changed files with 17680 additions and 1878 deletions

View File

@ -1,14 +1,20 @@
namespace Docs
namespace Docs
{
public static class Constants
{
public const string NoContainer = nameof(NoContainer);
public const string NoSidebar = nameof(NoSidebar);
public const string NoLink = nameof(NoLink);
public const string Topic = nameof(Topic);
public const string EditLink = nameof(EditLink);
public const string Description = nameof(Description);
public const string Hidden = nameof(Hidden);
public static class Emojis
{
public const string Root = "EMOJIS_ROOT";
}
public static class Colors
{
public const string Url = "https://raw.githubusercontent.com/spectresystems/spectre.console/main/resources/scripts/Generator/Data/colors.json";

7946
docs/src/Data/emojis.json Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
using Statiq.Common;
using Statiq.Common;
using System.Collections.Generic;
using System.Linq;
@ -16,6 +16,11 @@ namespace Docs
return !document.GetBool(Constants.Hidden, false);
}
public static bool ShowLink(this IDocument document)
{
return !document.GetBool(Constants.NoLink, false);
}
public static IEnumerable<IDocument> OnlyVisible(this IEnumerable<IDocument> source)
{
return source.Where(x => x.IsVisible());

20
docs/src/Models/Emoji.cs Normal file
View File

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json;
namespace Docs.Models
{
public sealed class Emoji
{
public string Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Code { get; set; }
public static List<Emoji> Parse(string json)
{
return JsonConvert.DeserializeObject<List<Emoji>>(json);
}
}
}

View File

@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Statiq.Common;
namespace Docs.Modules
{
public sealed class ReadEmbedded : Module
{
private readonly System.Reflection.Assembly _assembly;
private readonly string _resource;
public ReadEmbedded(System.Reflection.Assembly assembly, string resource)
{
_assembly = assembly ?? throw new ArgumentNullException(nameof(assembly));
_resource = resource ?? throw new ArgumentNullException(nameof(resource));
}
protected override Task<IEnumerable<IDocument>> ExecuteContextAsync(IExecutionContext context)
{
return Task.FromResult((IEnumerable<IDocument>)new[]
{
context.CreateDocument(ReadResource()),
});
}
private Stream ReadResource()
{
var resourceName = _resource.Replace("/", ".");
var stream = _assembly.GetManifestResourceStream(resourceName);
if (stream == null)
{
throw new InvalidOperationException("Could not load manifest resource stream.");
}
return stream;
}
}
}

View File

@ -26,13 +26,8 @@ namespace Docs.Pipelines
new ExecuteConfig(
Config.FromDocument(async (doc, ctx) =>
{
var colors = Color.Parse(await doc.GetContentStringAsync()).ToList();
var definitions = new List<IDocument> { colors.ToDocument(Constants.Colors.Root) };
return doc.Clone(new MetadataDictionary
{
[Constants.Colors.Root] = definitions
});
var data = Color.Parse(await doc.GetContentStringAsync()).ToList();
return data.ToDocument(Constants.Colors.Root);
}))
};
}

View File

@ -0,0 +1,34 @@
using System.Collections.Generic;
using Docs.Models;
using Docs.Modules;
using Statiq.Common;
using Statiq.Core;
namespace Docs.Pipelines
{
public class EmojiPipeline : Pipeline
{
public EmojiPipeline()
{
InputModules = new ModuleList
{
new ExecuteConfig(
Config.FromContext(ctx => {
return new ReadEmbedded(
typeof(EmojiPipeline).Assembly,
"Docs/src/Data/emojis.json");
}))
};
ProcessModules = new ModuleList
{
new ExecuteConfig(
Config.FromDocument(async (doc, ctx) =>
{
var data = Emoji.Parse(await doc.GetContentStringAsync());
return data.ToDocument(Constants.Emojis.Root);
}))
};
}
}
}

View File

@ -17,11 +17,10 @@ namespace Docs.Shortcodes
// Get the definition.
var colors = context.Outputs
.FromPipeline(nameof(ColorsPipeline))
.First()
.GetChildren(Constants.Colors.Root)
.OfType<ObjectDocument<List<Color>>>()
.First().Object;
// Headers
var table = new XElement("table", new XAttribute("class", "table"));
var header = new XElement("tr", new XAttribute("class", "color-row"));
header.Add(new XElement("th", ""));

View File

@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Statiq.Common;
using System.Xml.Linq;
using Docs.Pipelines;
using Docs.Models;
namespace Docs.Shortcodes
{
public class EmojiTableShortcode : SyncShortcode
{
public override ShortcodeResult Execute(KeyValuePair<string, string>[] args, string content, IDocument document, IExecutionContext context)
{
var emojis = context.Outputs
.FromPipeline(nameof(EmojiPipeline))
.OfType<ObjectDocument<List<Emoji>>>()
.First().Object;
// Headers
var table = new XElement("table", new XAttribute("class", "table"));
var header = new XElement("tr", new XAttribute("class", "emoji-row"));
header.Add(new XElement("th", ""));
header.Add(new XElement("th", "Markup"));
header.Add(new XElement("th", "Constant"));
table.Add(header);
foreach (var emoji in emojis)
{
var code = emoji.Code.Replace("U+0000", "U+").Replace("U+000", "U+");
var icon = string.Format("&#x{0};", emoji.Code.Replace("U+", string.Empty));
var row = new XElement("tr");
row.Add(new XElement("td", icon));
row.Add(new XElement("td", new XElement("code", $":{emoji.Id}:")));
row.Add(new XElement("td", new XElement("code", emoji.Name)));
table.Add(row);
}
return table.ToString()
.Replace("&amp;#x", "&#x");
}
}
}