1
0
Fork 0
mirror of https://github.com/Nioux/AideDeJeu.git synced 2025-10-31 15:36:07 +00:00
AideDeJeu/AideDeJeu/AideDeJeu/ViewModels/StoreViewModel.cs
2018-09-16 23:10:24 +02:00

386 lines
13 KiB
C#

using AideDeJeu.Tools;
using AideDeJeuLib;
using Markdig;
using Markdig.Parsers;
using Markdig.Syntax;
using Markdig.Syntax.Inlines;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace AideDeJeu.ViewModels
{
public class StoreViewModel : BaseViewModel
{
public Item ToItem(string source, string md)
{
var pipeline = new MarkdownPipelineBuilder().UsePipeTables().Build();
var document = MarkdownParser.Parse(md, pipeline);
var enumerator = document.GetEnumerator();
try
{
enumerator.MoveNext();
while (enumerator.Current != null)
{
var block = enumerator.Current;
if (block is HtmlBlock)
{
if (IsNewItem(block))
{
var item = ParseItem(source, ref enumerator);
return item;
}
}
enumerator.MoveNext();
}
}
finally
{
enumerator.Dispose();
}
return null;
}
public Item ParseItem(string source, ref ContainerBlock.Enumerator enumerator)
{
var currentItem = GetNewItem(enumerator.Current);
if (currentItem != null)
{
enumerator.MoveNext();
while (enumerator.Current != null)
{
var block = enumerator.Current;
if (block is HtmlBlock)
{
if (IsClosingItem(block))
{
currentItem.Id = GetNewAnchorId(source, currentItem.Name);
if (currentItem.Id != null)
{
_AllItems[currentItem.Id] = currentItem;
}
return currentItem;
}
else if (IsNewItem(block))
{
var subItem = ParseItem(source, ref enumerator);
var propertyName = subItem.GetType().Name;
if (currentItem.GetType().GetProperty(propertyName) != null)
{
PropertyInfo prop = currentItem.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance);
if (null != prop && prop.CanWrite)
{
prop.SetValue(currentItem, subItem, null);
}
}
else //if (currentItem is Items)
{
var items = currentItem; // as Items;
items.AddChild(subItem);
}
enumerator.MoveNext();
}
else
{
currentItem.Markdown += enumerator.Current.ToMarkdownString();
enumerator.MoveNext();
}
}
else
{
ParseItemProperties(source, currentItem, block);
currentItem.Markdown += enumerator.Current.ToMarkdownString();
enumerator.MoveNext();
}
}
currentItem.Id = GetNewAnchorId(source, currentItem.Name);
_AllItems[currentItem.Id] = currentItem;
}
return currentItem;
}
public bool ParseItemProperties(string source, Item item, Block block)
{
switch (block)
{
case Markdig.Extensions.Tables.Table table:
return ParseItemProperties(source, item, table);
case ContainerBlock blocks:
return ParseItemProperties(source, item, blocks);
case LeafBlock leaf:
bool isname = ParseItemProperties(source, item, leaf.Inline);
if(isname)
{
if(leaf is HeadingBlock)
{
var headingBlock = leaf as HeadingBlock;
item.NameLevel = headingBlock.Level;
}
}
return isname;
}
return false;
}
public bool ParseItemProperties(string source, Item item, ContainerBlock blocks)
{
bool isname = false;
foreach (var block in blocks)
{
isname |= ParseItemProperties(source, item, block);
}
return isname;
}
public bool ParseItemProperties(string source, Item item, ContainerInline inlines)
{
bool isname = false;
if (inlines == null)
{
return isname;
}
PropertyInfo prop = null;
foreach (var inline in inlines)
{
if (inline is HtmlInline)
{
var tag = (inline as HtmlInline).Tag;
if (tag == "<!--br-->" || tag == "<br>")
{
}
else if (tag.StartsWith("<!--/"))
{
prop = null;
}
else if (tag.StartsWith("<!--") && !tag.StartsWith("<!--/"))
{
var propertyName = tag.Substring(4, tag.Length - 7);
if(propertyName == "Name")
{
isname = true;
}
prop = item.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance);
}
}
else
{
if (null != prop && prop.CanWrite)
{
prop.SetValue(item, inline.ToMarkdownString(), null);
}
}
}
return isname;
}
public bool IsNewItem(Block block)
{
var htmlBlock = block as HtmlBlock;
if (htmlBlock.Type == HtmlBlockType.Comment)
{
var tag = htmlBlock.Lines.Lines.FirstOrDefault().Slice.ToString();
if (!string.IsNullOrEmpty(tag) && tag != "<!--br-->" && tag != "<br>")
{
if (tag.StartsWith("<!--") && !tag.StartsWith("<!--/"))
{
var name = $"AideDeJeuLib.{tag.Substring(4, tag.Length - 7)}, AideDeJeu";
var type = Type.GetType(name);
if (type != null)
{
return true;
}
}
}
}
return false;
}
public bool IsClosingItem(Block block)
{
var htmlBlock = block as HtmlBlock;
if (htmlBlock.Type == HtmlBlockType.Comment)
{
var tag = htmlBlock.Lines.Lines.FirstOrDefault().Slice.ToString();
if (!string.IsNullOrEmpty(tag) && tag != "<!--br-->" && tag != "<br>")
{
if (tag.StartsWith("<!--/"))
{
return true;
}
}
}
return false;
}
public Item GetNewItem(Block block)
{
var htmlBlock = block as HtmlBlock;
if (htmlBlock.Type == HtmlBlockType.Comment)
{
var tag = htmlBlock.Lines.Lines.FirstOrDefault().Slice.ToString();
if (!string.IsNullOrEmpty(tag) && tag != "<!--br-->" && tag != "<br>")
{
if (tag.StartsWith("<!--") && !tag.StartsWith("<!--/"))
{
var name = $"AideDeJeuLib.{tag.Substring(4, tag.Length - 7)}, AideDeJeu";
var type = Type.GetType(name);
if (type != null)
{
var instance = Activator.CreateInstance(type) as Item;
return instance;
}
}
}
}
return null;
}
public string GetNewAnchorId(string source, string name)
{
if (name != null)
{
var baseid = Helpers.IdFromName(name);
var id = $"{source}.md#{baseid}";
int index = 0;
while (true)
{
if (!_AllItems.ContainsKey(name))
{
return id;
}
index++;
name = $"{source}.md#{baseid}{index}";
}
}
return null;
}
/*
void AddAnchor(string source, Dictionary<string, Item> anchors, Item item)
{
if (item != null && item.Name != null)
{
var basename = Helpers.IdFromName(item.Name);
var name = $"{source}.md#{basename}";
//var name = $"{basename}";
int index = 0;
while (true)
{
if (!anchors.ContainsKey(name))
{
item.Id = name;
anchors.Add(name, item);
return;
}
index++;
name = $"{source}.md#{basename}{index}";
//name = $"{basename}{index}";
}
}
}
void MakeAnchors(string source, Dictionary<string, Item> anchors, Item baseItem)
{
AddAnchor(source, anchors, baseItem);
if (baseItem is Items)
{
foreach (var item in (baseItem as Items))
{
MakeAnchors(source, anchors, item);
}
}
}
public class ItemWithAnchors
{
public Item Item { get; set; }
public Dictionary<string, Item> Anchors { get; set; } = new Dictionary<string, Item>();
}
*/
public Dictionary<string, Item> _AllItems = new Dictionary<string, Item>();
public async Task PreloadAllItemsAsync()
{
foreach (var resourceName in Tools.Helpers.GetResourceNames())
{
var regex = new Regex(@"AideDeJeu\.Data\.(?<name>.*?)\.md");
var match = regex.Match(resourceName);
var source = match.Groups["name"].Value;
if (!string.IsNullOrEmpty(source))
{
if (!_AllItems.ContainsKey(source))
{
var md = await Tools.Helpers.GetResourceStringAsync(resourceName);
if (md != null)
{
var item = ToItem(source, md);
if (item != null)
{
var anchors = new Dictionary<string, Item>();
//MakeAnchors(source, anchors, item);
_AllItems[source] = item;
}
}
}
}
}
}
public async Task<Item> GetItemFromDataAsync(string source, string anchor)
{
var id = $"{source}.md#{anchor}";
//await Task.Delay(3000);
if (!_AllItems.ContainsKey(id) && !_AllItems.ContainsKey(source))
{
//var md = await Tools.Helpers.GetStringFromUrl($"https://raw.githubusercontent.com/Nioux/AideDeJeu/master/Data/{source}.md");
var md = await Tools.Helpers.GetResourceStringAsync($"AideDeJeu.Data.{source}.md");
if (md != null)
{
var item = ToItem(source, md);
if (item != null)
{
var anchors = new Dictionary<string, Item>();
//MakeAnchors(source, anchors, item);
_AllItems[source] = item;
}
else
{
return null;
}
}
else
{
return null;
}
}
if (_AllItems.ContainsKey(id))
{
return _AllItems[id];
}
else if (_AllItems.ContainsKey(source))
{
return _AllItems[source];
}
return null;
}
}
}