using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text.RegularExpressions;
using System.Diagnostics;
using System.Reflection;
namespace X03.PageElements.Notations
{
abstract public class NotNestable : PageElements.Notation, Plugin.PageElement
{
public List<PageElements.Plains.Plaintext> ChildrenAsPlaintext
{
get
{
return this.Children.Cast<PageElements.Plains.Plaintext>().ToList();
}
protected set
{
this.Children = value.Cast<PageElement>().ToList();
}
}
new static public IEnumerable<Type> GetPluginClasses()
{
return Utils.GetPluginClasses(typeof(PageElements.Notations.NotNestable));
}
private static PageElement createNotNestableElement(Type notationClass, PageElement parent, List<PageElements.Plains.Plaintext> children)
{
return (PageElement)Assembly.GetAssembly(notationClass).CreateInstance(notationClass.FullName, false, BindingFlags.CreateInstance, null, new object[] { parent, children }, null, null);
}
public static List<PageElement> Generate(Type notationClass, PageElement parent, List<PageElement> elements, HashSet<Type> targetClasses)
{
var ret = new List<PageElement>(elements);
var pattern = notationClass.GetField("Pattern", BindingFlags.Static | BindingFlags.Public).GetValue(null) as string;
if (pattern == null)
return ret;
PageElement mergeTarget = null;
Match m = null;
var idx = 0;
while (idx <= ret.Count - 1)
{
if (ret[idx] is PageElements.Wikitext)
{
PageElements.Wikitext wikitext = ret[idx] as PageElements.Wikitext;
m = Regex.Match(wikitext.ToWikitext(), pattern, RegexOptions.Singleline | RegexOptions.IgnoreCase);
if (m.Success)
{
var subs = new string[] {
wikitext.ToWikitext().Substring(0, (m.Index + 1) - 1),
m.Value,
wikitext.ToWikitext().Substring(m.Index + m.Length)
};
var additions = new List<PageElement>();
if (subs[0].Length > 0)
additions.Add(new PageElements.Wikitext(subs[0]));
// create PageElement
if (notationClass.GetMethod("Merge") != null)
{
// 連結可能Notation
Debug.Assert(notationClass.Name != null);
if (m.Index == 0 && mergeTarget != null && mergeTarget.GetType().Name == notationClass.Name)
{
// 連結(既存インスタンスと統合)。新しいインスタンスは生成しない。
notationClass.GetMethod("Merge").Invoke(null, new object[] { parent, new List<PageElements.Plains.Plaintext>() { new PageElements.Plains.Plaintext(parent, subs[1]) }, mergeTarget });
}
else
{
mergeTarget = createNotNestableElement(notationClass, parent, new List<PageElements.Plains.Plaintext>() { new PageElements.Plains.Plaintext(parent, subs[1]) });
additions.Add(mergeTarget);
}
}
else
{
// 連結しないNotation
// 子Elementを持たないのでTokenize不要
additions.Add(createNotNestableElement(notationClass, parent, new List<PageElements.Plains.Plaintext>() { new PageElements.Plains.Plaintext(parent, subs[1]) }));
}
if (subs[2].Length > 0)
additions.Add(new PageElements.Wikitext(subs[2]));
ret.RemoveAt(idx);
ret.InsertRange(idx, additions);
idx += additions.Count - 1 - 1; // 追加された最後の要素を指すように、直後に実行されるidx++に合わせて調整
break;
}
}
else
{
}
idx++;
}
return ret;
}
public static string Pattern;
public NotNestable(PageElement parent, List<PageElements.Plains.Plaintext> children)
: this(parent, children.Cast<PageElement>().ToList())
{
}
public NotNestable(PageElement parent, List<PageElement> children)
: base(parent, children)
{
}
}
}