User:A2569875-bot/Code/WikiUtils.cs

维基百科,自由的百科全书
using System;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using WikiTemplateArgUtil;
namespace System.Linq
{
    public static class StackConvert
    {
        public static void LR_Reduce(this Stack<int> input, int[] queue)
        {
            for (int i = queue.Length - 1; i >= 0; --i) input.Push(queue[i]);
        }
    }
}

namespace DotNetWikiBot
{

    public class cas_checker
    {
        public String cas_no;
        public String cas_ref;
        public String cas_comment;
        public cas_checker(String no_s, String ref_s)
        {
            cas_no = no_s;
            cas_ref = ref_s;
        }
    }

    public class TreeNode<T>
    {
        private readonly T _value;
        private readonly List<TreeNode<T>> _children = new List<TreeNode<T>>();

        public TreeNode(T value)
        {
            _value = value;
        }

        public void ResetParent()
        {
            Stack<TreeNode<T>> TraversalStack = new Stack<TreeNode<T>>();
            TraversalStack.Push(this);
            while (TraversalStack.Any())
            {
                TreeNode<T> temp = TraversalStack.Pop();
                if (temp.Children.Count <= 0)
                {
                    //donothing
                }
                else for (int i = temp.Children.Count() - 1; i >= 0; --i)
                {
                    temp[i].Parent = temp;
                    TraversalStack.Push(temp[i]);
                }
            }
        }

        public TreeNode<T> this[int i]
        {
            get { return _children[i]; }
        }

        public override string ToString()
        {
            return "root: " + _value;
        }

        public TreeNode<T> Parent { get; private set; }

        public T Value { get { return _value; } }

        public System.Collections.ObjectModel.ReadOnlyCollection<TreeNode<T>> Children
        {
            get { return _children.AsReadOnly(); }
        }

        public TreeNode<T> AddChild(T value)
        {
            var node = new TreeNode<T>(value) { Parent = this };
            _children.Add(node);
            return node;
        }

        public TreeNode<T> AddSubtree(TreeNode<T> value)
        {
            value.Parent = this;
            _children.Add(value);
            return value;
        }

        public TreeNode<T> AddSubtreeAt(TreeNode<T> node, TreeNode<T> value)
        {
            value.Parent = this;
            int to_insert = _children.IndexOf(node);
            if(to_insert >= 0 && to_insert < _children.Count)
                _children.Insert(to_insert, value);
            return value;
        }

        public TreeNode<T> AddSubtreeInv(TreeNode<T> value)
        {
            value.Parent = this;
            _children.Insert(0, value);
            return value;
        }

        public TreeNode<T>[] AddChildren(params T[] values)
        {
            return values.Select(AddChild).ToArray();
        }

        public void ClearChildren()
        {
            _children.Clear();
        }

        public bool RemoveChild(TreeNode<T> node)
        {
            return _children.Remove(node);
        }

        public void Traverse(Action<T> action)
        {
            action(Value);
            foreach (var child in _children)
                child.Traverse(action);
        }

        public IEnumerable<T> Flatten()
        {
            return new[] { Value }.Concat(_children.SelectMany(x => x.Flatten()));
        }
    }

    public class template_item
    {
        public String argument;
        public String Value;
        public template_item(String arg, String val)
        {
            argument = arg;
            Value = val;
        }
    }

    public class token_check_stack
    {
        public int iter;
        public string Value;
        public token_check_stack(int num, string str)
        {
            iter = num;
            Value = str;
        }
    }

    public class DinoComparer : IComparer<List<int>>
    {
        public int Compare(List<int> x, List<int> y)
        {
            int x_min = (x.Count > 0 ? x[0] : -1), y_min = (y.Count > 0 ? y[0] : -1);
            foreach (var it in x) if (it < x_min) x_min = it;
            foreach (var it in y) if (it < y_min) y_min = it;
            return ((Int32)(x_min)).CompareTo((Int32)(y_min));
        }
    }

    public class TemplateEntity
    {
        List<template_item> template_struct;
        public string Name;
        public TemplateEntity() { }
        public override string ToString()
        {
            string template_code = "{{" + Name;
            int output_count = 1;
            bool has_complex = false;
            foreach (template_item item in template_struct)
            {
                if (output_count.ToString() == item.argument)
                {
                    template_code += "|" + item.Value;
                }
                else
                {
                    has_complex = true;
                    template_code += "\n| " + item.argument + " = " + item.Value;
                }
            }
            return template_code + (has_complex ? "\n" : "") + "}}";
        }

        public void InsertArg(string at_arg, string arg_name, string arg_value)
        {
            for (int i = 0; i < template_struct.Count; ++i)
            {
                if (arg_name == at_arg)
                {
                    template_struct.Insert(i + 1, new template_item(arg_name, arg_value));
                    break;
                }
            }
        }
        public template_item Argument
        {
            set
            {
                for (int i = 0; i < template_struct.Count; ++i)
                {
                    if (template_struct[i].argument == value.argument)
                    {
                        template_struct[i].Value = value.Value;
                        return;
                    }
                }
                template_struct.Add(value);
            }
        }
        public template_item GetArgumentByName(string name)
        {
            for (int i = 0; i < template_struct.Count; ++i)
            {
                if (template_struct[i].argument == name)
                {
                    return new template_item(template_struct[i].argument, template_struct[i].Value);
                }
            }
            return null;
        }
        public bool Parse(string template_name, string input)
        {
            Name = template_name;
            Regex get_templatestart = new Regex("\\{\\{[\\t\\n\\r ]*(" + template_name +
                //讀到最後
                ")(\\n|[^\\n])*");
            MatchCollection match_lines = get_templatestart.Matches(" " + input + " ");
            bool is_success = false;
            template_struct = new List<template_item>();
            string loadded_template_text = "{{" + template_name;
            bool is_load_arg = true;
            bool is_load_val = false;
            bool is_nowiki = false;
            string arg = "", val = "";
            foreach (Match match_line in match_lines)
            {
                if (match_line.Success)
                {
                    is_success = true;
                    String ready_to_parse = match_line.Value;
                    int template_stack = 1;
                    int un_named_arg_count = 1;
                    for (int i = (2 + template_name.Length); i < ready_to_parse.Length; ++i)
                    {
                        string this_utf8_char = ready_to_parse.Substring(i, 1);
                        string next_utf8_char = (
                            ((i + 1) < ready_to_parse.Length) ?
                            ready_to_parse.Substring(i + 1, 1) :
                            ""
                        );

                        string nowiki_check_utf8_char = (
                            ((i + 8) < ready_to_parse.Length) ?
                            ready_to_parse.Substring(i + 8, 8) :
                            ""
                        );
                        string nowiki_end_check_utf8_char = (
                            ((i + 9) < ready_to_parse.Length) ?
                            ready_to_parse.Substring(i + 9, 9) :
                            ""
                        );
                        if (template_stack <= 0) break;

                        if (is_nowiki)
                        {
                            if (nowiki_end_check_utf8_char == "")
                            {

                            }
                        }

                        if (this_utf8_char == "{" && next_utf8_char == "{")
                        {
                            ++i;
                            ++template_stack;
                            loadded_template_text += "{{";
                            if (template_stack > 1)
                            {
                                if (is_load_arg) arg += "{{";
                                if (is_load_val) val += "{{";
                            }
                            continue;
                        }
                        if (this_utf8_char == "}" && next_utf8_char == "}")
                        {
                            if (template_stack > 1)
                            {
                                if (is_load_arg) arg += "}}";
                                if (is_load_val) val += "}}";
                            }
                            ++i;
                            --template_stack;
                            loadded_template_text += "}}";
                            continue;
                        }
                        if (this_utf8_char == "|" && template_stack <= 1)
                        {
                            loadded_template_text += "|";
                            arg = arg.TrimEnd(' '); arg = arg.TrimEnd('\n'); arg = arg.TrimEnd('\t');
                            arg = arg.Trim(' '); arg = arg.Trim('\n'); arg = arg.Trim('\t');

                            val = val.TrimEnd(' '); val = val.TrimEnd('\n'); val = val.TrimEnd('\t');
                            val = val.Trim(' '); val = val.Trim('\n'); val = val.Trim('\t');

                            if (is_load_val)
                            {
                                if (arg != "" && val != "")
                                {
                                    if (arg == un_named_arg_count.ToString()) ++un_named_arg_count;
                                    template_struct.Add(new template_item(arg, val));
                                }
                            }
                            else
                            {
                                if (val != "")
                                {
                                    template_struct.Add(new template_item(un_named_arg_count.ToString(), arg));
                                    ++un_named_arg_count;
                                }
                            }
                            arg = "";
                            val = "";
                            is_load_val = false;
                            is_load_arg = true;
                            continue;
                        }
                        if (this_utf8_char == "=" && template_stack <= 1)
                        {
                            loadded_template_text += "=";
                            if (is_load_arg)
                            {
                                is_load_arg = false;
                                is_load_val = true;
                            }
                            else
                            {
                                val += "=";
                            }
                            continue;
                        }
                        if (is_load_arg)
                        {
                            if ((this_utf8_char == "\n" || this_utf8_char == "\t") && template_stack <= 1)
                            {
                                arg += " ";
                            }
                            else arg += this_utf8_char;
                        }
                        if (is_load_val)
                        {
                            val += this_utf8_char;
                        }
                        loadded_template_text += this_utf8_char;
                    }
                }
                if (template_struct.Count > 0) break;
            }
            return is_success;
        }

    }

}