Example #1
0
        static IEnumerable <WikiElement> Parse(CustomElementArgs args)
        {
            WikiPage page = args.Page;

            lastCat    = 0;
            currentCat = 0;

            var def = page.Def as ThingDef;

            str.Clear();
            str.AppendLine("<color=cyan><b>Important stats:</b></color>");

            ShowStat("Market value", GetStat(def, "MarketValue") * 0.01f, null, '$');
            currentCat++;

            ShowStat("Armor (sharp)", GetStat(def, "StuffPower_Armor_Sharp"), 1f, '%');
            ShowStat("Armor (blunt)", GetStat(def, "StuffPower_Armor_Blunt"), 1f, '%');
            ShowStat("Armor (heat)", GetStat(def, "StuffPower_Armor_Heat"), 1f, '%');
            currentCat++;

            ShowStat("Melee sharp damage", GetStat(def, "SharpDamageMultiplier"), 1f, '%');
            ShowStat("Melee attack cooldown", GetStuffStat(def, "MeleeWeapon_CooldownMultiplier"), 1f, '%', true);
            ShowStat("Melee blunt damage", GetStat(def, "BluntDamageMultiplier"), 1f, '%');
            currentCat++;

            ShowStat("Max hit points", GetStuffStat(def, "MaxHitPoints"), 1f, '%');
            ShowStat("Beauty", GetStuffStat(def, "Beauty"), 1f, '%');
            currentCat++;

            ShowStat("Work to make (items)", GetStuffStat(def, "WorkToMake"), 1f, '%', true);
            ShowStat("Work to build", GetStuffStat(def, "WorkToBuild"), 1f, '%', true);

            yield return(WikiElement.Create(str.ToString()));

            if (def.defName == "RF_Copper" || def.defName == "RF_Tin")
            {
                yield break;
            }

            yield return(WikiElement.Create("This is a metal alloy that can be created at the Forge:"));

            yield return(new WikiElement()
            {
                DefForIconAndLabel = RFDefOf.RF_Forge
            });
        }
Example #2
0
        private static string ExtractNoFormattingElements(string text, Dictionary<string, WikiElement> elementSubstitutions)
        {
            StringBuilder result = new StringBuilder();
            // Explanation of the groups following regex:
            // It searches for an opening tag, which is either an <element attr="value" (/)> or a <!--comment
            // (?<!^=+.*)           Excludes any element that starts with a repetition of '='
            // (?!.*=+$)            Excludes any element that ends with a repetition of '='
            // Together, these first and last part of the regex are used to exclude elements within a header.
            // ({0})                Contains the name of the no-formatting elements.
            // (\\s+[^>]*?|\\s*?)   Follows the initial tag with either spaces + content, spaces or nothing.
            // (/?>)                The end of the opening tag, which could be a closing as well.
            //  |                   OR
            // (!--)                A comment.
            string elementStart = string.Format(@"(?<!^=+.*)<({0})(\s+[^>]*?|\s*?)(/?>)(?!.*=+$)|<(!--)", ELEMENTS_WITH_NO_FORMATTING);
            string elementEnd = string.Empty;
            Regex elementStartRegex = new Regex(elementStart, RegexOptions.IgnoreCase | RegexOptions.Multiline);
            while (text.Length > 0)
            {
                string element = string.Empty;      // The name of the element.
                string attributes = string.Empty;   // The attributes of the element (as text).
                string close = string.Empty;        // The closing character(s) of the opening tag.
                string inside = string.Empty;       // The content following the opening tag of the element that is yet to be analyzed.
                string content = string.Empty;      // The content of the element.
                string tail = string.Empty;         // The closing tag of the element.

                string[] textParts = elementStartRegex.Split(text, 2, 0);

                // Everything before the non-formatting elements is appended as-is.
                result.Append(textParts[0]);

                if (textParts.Length == 5)
                {
                    // Element + any Attributes.
                    element = textParts[1];
                    attributes = textParts[2];
                    close = textParts[3];
                    inside = textParts[4];
                }
                else if (textParts.Length == 3)
                {
                    // Comment.
                    element = textParts[1];
                    inside = textParts[2];
                }
                else
                {
                    break;
                }

                if (close == "/>")
                {
                    // Empty <tag />
                    text = inside;
                }
                else
                {
                    // Starting at 1 representing the current element opened.
                    int stack = 1;
                    if (element == "!--")
                    {
                        // Comment.
                        elementStart = "<!--";
                        elementEnd = "-->";
                        // Setting the stack to 0 will skip the search loop for a closing tag of same depth.
                        // The first closing tag found will be taken to close the element.
                        stack = 0;
                    }
                    else
                    {
                        elementStart = string.Format(@"<{0}(\s+[^/]*?)?>", element);
                        elementEnd = string.Format("<\\/{0}\\s*>", element);
                    }

                    Regex openingsRegex = new Regex(elementStart, RegexOptions.IgnoreCase);
                    Regex closingsRegex = new Regex(elementEnd, RegexOptions.IgnoreCase);
                    MatchCollection openings = openingsRegex.Matches(inside, 0);
                    MatchCollection closings = closingsRegex.Matches(inside, 0);
                    int i = 0, j = 0;
                    // This loop looks for the j index of a matching closing tag for the current element.
                    // Any new opening tag will increase the stack and require an additional closing tag.
                    while (stack > 0)
                    {
                        if (j == closings.Count)
                        {
                            // No more closing tags => needless to keep counting.
                            break;
                        }

                        if (i < openings.Count && openings[i].Index < closings[j].Index)
                        {
                            // We found another opening before a closing. Increase the stack.
                            stack++;
                            i++;
                        }
                        else
                        {
                            // We found a closing element. Decrease the stack.
                            if (--stack == 0)
                                break;  // Bingo.
                            else
                                j++;
                        }
                    }
                    // At this point, we know we can substring from 0 to the index of the closing tag OR to the end.
                    if (j == closings.Count)
                    {
                        // No end tag - let it run out to the end of the text.
                        content = inside.Substring(0, inside.Length);
                        tail = string.Empty;
                        text = string.Empty;
                    }
                    else
                    {
                        content = inside.Substring(0, closings[j].Index);
                        tail = closings[j].Value;
                        text = inside.Substring(closings[j].Index + closings[j].Length);
                    }
                }

                // Substitute the occurences of the non-formatting elements and their content by a GUID.
                // The substitution can later be reversed to retrieve the content untouched.
                string elementGUID = Tools.GetRandomGUID();
                if (element == "!--")
                    result.Append("<!-- " + elementGUID + " -->"); // The original tags are used in subsequent methods below.
                else
                    if (element == "pre" || element == "code" || element == "sql")
                    result.AppendFormat("<{0}{1}>{2}</{0}>", element, attributes, elementGUID); // The original tags are used in subsequent methods below.
                else
                    result.Append(elementGUID);

                WikiElement substitutedElement = new WikiElement(element, content, WikiAttributes.ParseAttributes(attributes));
                elementSubstitutions.Add(elementGUID, substitutedElement);
            }

            return result.ToString();
        }
Example #3
0
 internal void SetParent(WikiElement parent)
 {
     _parent = parent;
 }