Example #1
0
 protected void AddStringToTranslationCache(string sKey, ElementString zElementString)
 {
     if (m_dictionaryElementStringCache.ContainsKey(sKey))
     {
         m_dictionaryElementStringCache.Remove(sKey);
         //Logger.AddLogLine("String Cache: Replace?!");
     }
     m_dictionaryElementStringCache.Add(sKey, zElementString);
 }
Example #2
0
        [TestMethod] public void ConvertNonNullToString()
        {
            // Arrange
            var contents = "Niobium (Nb)";
            var concept  = new ElementString(contents);

            // Act
            var conversion = (string)concept !;

            // Assert
            conversion.Should().Be(contents);
        }
Example #3
0
        [TestMethod] public void ConvertNonNullToCharSpan()
        {
            // Arrange
            var contents = "Oxygen (O)";
            var concept  = new ElementString(contents);

            // Act
            var conversion = ((ReadOnlySpan <char>)concept).ToString();

            // Assert
            conversion.Should().Be(contents);
        }
Example #4
0
        [TestMethod] public void Stringification()
        {
            // Arrange
            var contents = "Beryllium (Be)";
            var concept  = new ElementString(contents);

            // Act
            var toString = concept.ToString();

            // Assert
            toString.Should().Be(contents);
        }
Example #5
0
        [TestMethod] public void IndexTooLarge()
        {
            // Arrange
            var contents = "Dysprosium (Dy)";
            var concept  = new ElementString(contents);
            var index    = contents.Length + 13;

            // Act
            Func <char> action = () => concept[index];

            // Assert
            action.Should().ThrowExactly <IndexOutOfRangeException>().WithAnyMessage();
        }
Example #6
0
        [TestMethod] public void SusbtringEndOutOfRange()
        {
            // Arrange
            var contents = "Tungsten (W)";
            var concept  = new ElementString(contents);
            var range    = new Range(4, 109);

            // Act
            Func <string> action = () => concept[range].ToString();

            // Assert
            action.Should().ThrowExactly <ArgumentOutOfRangeException>().WithAnyMessage();
        }
Example #7
0
        [TestMethod] public void Length()
        {
            // Arrange
            var contents = "Hydrogen (H)";
            var concept  = new ElementString(contents);

            // Act
            var length   = concept.Length;
            var expected = contents.Length;

            // Assert
            length.Should().Be(expected);
        }
Example #8
0
        [TestMethod] public void View()
        {
            // Arrange
            var contents = "Chlorine (Cl)";
            var concept  = new ElementString(contents);

            // Act
            var view     = concept.View;
            var expected = contents.AsSpan();

            // Assert
            view.ToString().Should().Be(expected.ToString());
        }
Example #9
0
        [TestMethod] public void IndexTooSmall()
        {
            // Arrange
            var contents = "Selenium (Se)";
            var concept  = new ElementString(contents);
            var index    = -8;

            // Act
            Func <char> action = () => concept[index];

            // Assert
            action.Should().ThrowExactly <IndexOutOfRangeException>().WithAnyMessage();
        }
Example #10
0
        [TestMethod] public void SubstringInRange()
        {
            // Arrange
            var contents = "Livermorium (Lv)";
            var concept  = new ElementString(contents);
            var range    = new Range(2, 9);

            // Act
            var substring = concept[range].ToString();
            var expected  = contents[range];

            // Assert
            substring.Should().Be(expected);
        }
Example #11
0
        [TestMethod] public void IndexInRange()
        {
            // Arrange
            var contents = "Cadmium (Cd)";
            var concept  = new ElementString(contents);
            var index    = 4;

            // Act
            var character = concept[index];
            var expected  = contents[index];

            // Assert
            character.Should().Be(expected);
        }
Example #12
0
        [TestMethod] public void WeakEquality()
        {
            // Arrange
            var    mercury    = new ElementString("Mercury (Hg)");
            var    nonElement = "Mercury (Hg)";
            object?nll        = null;

            // Act
            var areNotEqual     = FullCheck.ExpectNotEqual <object>(mercury, nonElement);
            var nullAreNotEqual = FullCheck.ExpectNotEqual(mercury, nll);

            // Assert
            areNotEqual.Should().NotHaveValue();
            nullAreNotEqual.Should().NotHaveValue();
        }
Example #13
0
        [TestMethod] public void WeakIteration()
        {
            // Arrange
            var contents = "Gold (Au)";
            var concept  = new ElementString(contents);

            // Act
            var fromIteration = string.Empty;

            foreach (var c in (IEnumerable)concept)
            {
                fromIteration += (char)c;
            }

            // Assert
            fromIteration.Should().Be(contents);
        }
Example #14
0
        [TestMethod] public void StrongIteration()
        {
            // Arrange
            var contents = "Silver (Ag)";
            var concept  = new ElementString(contents);

            // Act
            var fromIteration = string.Empty;

            foreach (var c in concept)
            {
                fromIteration += c;
            }

            // Assert
            fromIteration.Should().Be(contents);
        }
Example #15
0
        [TestMethod] public void StrictTotalOrder()
        {
            // Arrange
            var           dubnium     = new ElementString("Dubnium (Db)");
            var           einsteinium = new ElementString("Einsteinium (Es)");
            ElementString?nll         = null;

            // Act
            var nonEquiv     = FullCheck.ExpectLessThan(dubnium, einsteinium);
            var equiv        = FullCheck.ExpectEquivalent(dubnium, dubnium);
            var nullNonEquiv = FullCheck.ExpectLessThan(nll, einsteinium);
            var nullEquiv    = FullCheck.ExpectEquivalent(nll, nll);

            // Assert
            nonEquiv.Should().NotHaveValue();
            equiv.Should().NotHaveValue();
            nullNonEquiv.Should().NotHaveValue();
            nullEquiv.Should().NotHaveValue();
        }
Example #16
0
        [TestMethod] public void StrongEquality()
        {
            // Arrange
            var           nickel = new ElementString("Nickel (Ni)");
            var           copper = new ElementString("Copper (Cu)");
            ElementString?nll    = null;

            // Act
            var areEqual        = FullCheck.ExpectEqual(nickel, nickel);
            var areNotEqual     = FullCheck.ExpectNotEqual(nickel, copper);
            var nullAreEqual    = FullCheck.ExpectEqual(nll, nll);
            var nullAreNotEqual = FullCheck.ExpectNotEqual(copper, nll);

            // Assert
            areEqual.Should().NotHaveValue();
            areNotEqual.Should().NotHaveValue();
            nullAreEqual.Should().NotHaveValue();
            nullAreNotEqual.Should().NotHaveValue();
        }
Example #17
0
 protected void AddStringToTranslationCache(string sKey, ElementString zElementString)
 {
     if (m_dictionaryElementStringCache.ContainsKey(sKey))
     {
         m_dictionaryElementStringCache.Remove(sKey);
         //Logger.AddLogLine("String Cache: Replace?!");
     }
     m_dictionaryElementStringCache.Add(sKey, zElementString);
 }
Example #18
0
        /// <summary>
        /// Translates the string representing the element. (also handles any nodraw text input)
        /// </summary>
        /// <param name="sRawString"></param>
        /// <param name="nCardIndex"></param>
        /// <param name="zDeckLine"></param>
        /// <param name="zElement"></param>
        /// <returns></returns>
        protected override ElementString TranslateToElementString(string sRawString, int nCardIndex, DeckLine zDeckLine, ProjectLayoutElement zElement)
        {
            List <string> listLine = zDeckLine.LineColumns;

            string sOutput = sRawString;

            sOutput = sOutput.Replace("#empty", string.Empty);

            var zElementString = new ElementString();

            // TODO: maybe move these into classes so this isn't one mammoth blob

            LogTranslation(zElement, sOutput);

            // Translate card variables (non-reference information
            // Groups
            //     1    2    3   4   5
            // @"(.*)(!\[)(.+?)(\])(.*)"
            sOutput = LoopTranslateRegex(s_regexCardVariable, sOutput, zElement,
                                         (zMatch =>
            {
                string sDefineValue;
                var sKey = zMatch.Groups[3].ToString().ToLower();

                // NOTE: if this expands into more variables move all this into some other method and use a dictionary lookup
                if (sKey.Equals("cardindex"))
                {
                    sDefineValue = (nCardIndex + 1).ToString();
                }
                else if (sKey.Equals("deckindex"))
                {
                    sDefineValue = (zDeckLine.RowSubIndex + 1).ToString();
                }
                else
                {
                    IssueManager.Instance.FireAddIssueEvent("Bad card variable: " + sKey);
                    sDefineValue = "[BAD NAME: " + sKey + "]";
                }

                return(zMatch.Groups[1] + sDefineValue + zMatch.Groups[5]);
            }
                                         ));

            // Translate named items (column names / defines)
            //Groups
            //    1    2    3   4   5
            //@"(.*)(@\[)(.+?)(\])(.*)"
            sOutput = LoopTranslateRegex(s_regexColumnVariable, sOutput, zElement,
                                         (zMatch =>
            {
                int nIndex;
                string sDefineValue;
                var sKey = zMatch.Groups[3].ToString();

                // check the key for untranslated components
                var arrayParams = sKey.Split(new char[] { ',' });
                if (arrayParams.Length > 1)
                {
                    sKey = arrayParams[0];
                }

                sKey = sKey.ToLower();

                if (DictionaryDefines.TryGetValue(sKey, out sDefineValue))
                {
                }
                else if (DictionaryColumnNameToIndex.TryGetValue(sKey, out nIndex))
                {
                    sDefineValue = (nIndex >= listLine.Count ? string.Empty : (listLine[nIndex] ?? "").Trim());
                }
                else
                {
                    IssueManager.Instance.FireAddIssueEvent("Bad reference name: " + sKey);
                    sDefineValue = "[BAD NAME: " + sKey + "]";
                }
                if (arrayParams.Length > 1)
                {
                    for (int nIdx = 1; nIdx < arrayParams.Length; nIdx++)
                    {
                        sDefineValue = sDefineValue.Replace("{" + nIdx + "}", arrayParams[nIdx]);
                    }
                }
                return(zMatch.Groups[1] + sDefineValue + zMatch.Groups[5]);
            }
                                         ));

            // Translate card counter/index
            // Groups
            //     1   2    3  4    5  6    7  8   9
            //(@"(.*)(##)(\d+)(;)(\d+)(;)(\d+)(#)(.*)");
            sOutput = LoopTranslateRegex(s_regexCardCounter, sOutput, zElement,
                                         (zMatch =>
            {
                var nStart = Int32.Parse(zMatch.Groups[3].ToString());
                var nChange = Int32.Parse(zMatch.Groups[5].ToString());
                var nLeftPad = Int32.Parse(zMatch.Groups[7].ToString());

                return(zMatch.Groups[1] +
                       // nIndex is left as is (not adding 1)
                       (nStart + (nCardIndex * nChange)).ToString(CultureInfo.InvariantCulture).PadLeft(nLeftPad, '0') +
                       zMatch.Groups[9]);
            }));

            // Translate sub card counter/index
            // Groups
            //     1   2    3  4    5  6    7  8   9
            //(@"(.*)(#sc;)(\d+)(;)(\d+)(;)(\d+)(#)(.*)");
            sOutput = LoopTranslateRegex(s_regexSubCardCounter, sOutput, zElement,
                                         (zMatch =>
            {
                var nStart = Int32.Parse(zMatch.Groups[3].ToString());
                var nChange = Int32.Parse(zMatch.Groups[5].ToString());
                var nLeftPad = Int32.Parse(zMatch.Groups[7].ToString());

                var nIndex = zDeckLine.RowSubIndex;

                return(zMatch.Groups[1] +
                       // nIndex is left as is (not adding 1)
                       (nStart + (nIndex * nChange)).ToString(CultureInfo.InvariantCulture).PadLeft(nLeftPad, '0') +
                       zMatch.Groups[9]);
            }));

            // TODO: run these in a loop seeking out the furthest logic in the string

            // Translate If Logic
            //Groups
            //    1     2    3    4   5
            //@"(.*)(#\()(if.+)(\)#)(.*)");
            Func <Match, string> funcIfProcessor =
                (match =>
            {
                var sLogicResult = TranslateIfLogic(match.Groups[3].ToString());
                return(match.Groups[1] +
                       sLogicResult +
                       match.Groups[5]);
            });

            // Translate Switch Logic
            //Groups
            //    1    2         3    4   5
            //@"(.*)(#\()(switch.+)(\)#)(.*)");
            Func <Match, string> funcSwitchProcessor =
                match =>
            {
                var sLogicResult = TranslateSwitchLogic(match.Groups[3].ToString());
                return(match.Groups[1] +
                       sLogicResult +
                       match.Groups[5]);
            };

            var nTranslationLoopCount = 0;

            while (true)
            {
                if (nTranslationLoopCount > MAX_TRANSLATION_LOOP_COUNT)
                {
                    Logger.AddLogLine("Distrupting traslation loop. It appears to be an endless loop.");
                    break;
                }

                var zIfMatch     = s_regexIfLogic.Match(sOutput);
                var zSwitchMatch = s_regexSwitchLogic.Match(sOutput);

                Func <Match, string> funcProcessor;
                Match zMatchToTranslate;

                // pick the furthest logic item in the string (if or switch)
                if (zIfMatch.Success && zSwitchMatch.Success)
                {
                    // group 2 is the first of the groups that has the actual logic
                    int iflastIdx     = zIfMatch.Groups[2].Index;
                    int switchlastidx = zSwitchMatch.Groups[2].Index;

                    if (iflastIdx > switchlastidx)
                    {
                        zMatchToTranslate = zIfMatch;
                        funcProcessor     = funcIfProcessor;
                    }
                    else
                    {
                        zMatchToTranslate = zSwitchMatch;
                        funcProcessor     = funcSwitchProcessor;
                    }
                }
                else if (zIfMatch.Success)
                {
                    zMatchToTranslate = zIfMatch;
                    funcProcessor     = funcIfProcessor;
                }
                else if (zSwitchMatch.Success)
                {
                    zMatchToTranslate = zSwitchMatch;
                    funcProcessor     = funcSwitchProcessor;
                }
                else
                {
                    break;
                }

                sOutput = TranslateMatch(zMatchToTranslate, zElement, funcProcessor);
                nTranslationLoopCount++;
            }

            zElementString.String = sOutput;

            return(zElementString);
        }
Example #19
0
        /// <summary>
        /// Translates the string representing the element. (also handles any nodraw text input)
        /// </summary>
        /// <param name="sRawString"></param>
        /// <param name="nCardIndex"></param>
        /// <param name="zDeckLine"></param>
        /// <param name="zElement"></param>
        /// <returns></returns>
        protected override ElementString TranslateToElementString(string sRawString, int nCardIndex, DeckLine zDeckLine, ProjectLayoutElement zElement)
        {
#warning Investigate using method references instead of anonymous methods (optimization/code easier to read)

            var listLine = zDeckLine.LineColumns;
            var nTranslationLoopCount = 0;
            var sOutput = sRawString;

            sOutput = sOutput.Replace("#empty", string.Empty);

            var zElementString = new ElementString();

            // TODO: maybe move these into classes so this isn't one mammoth blob

            LogTranslation(zElement, sOutput);

            // Translate card variables (non-reference information
            // Groups
            //     1    2    3   4   5
            // @"(.*)(!\[)(.+?)(\])(.*)"
            Func <Match, string> funcCardVariableProcessor =
                (zMatch =>
            {
                string sDefineValue;
                var sKey = zMatch.Groups[3].ToString().ToLower();

                // NOTE: if this expands into more variables move all this into some other method and use a dictionary lookup
                if (sKey.Equals("cardindex"))
                {
                    sDefineValue = (nCardIndex + 1).ToString();
                }
                else if (sKey.Equals("deckindex"))
                {
                    sDefineValue = (zDeckLine.RowSubIndex + 1).ToString();
                }
                else if (sKey.Equals("cardcount"))
                {
                    sDefineValue = LayoutManager.Instance.ActiveDeck.CardCount.ToString();
                }
                else if (sKey.Equals("elementname"))
                {
                    sDefineValue = zElement.name;
                }
                else
                {
                    IssueManager.Instance.FireAddIssueEvent("Bad card variable: " + sKey);
                    sDefineValue = "[BAD NAME: " + sKey + "]";
                }

                return(zMatch.Groups[1] + sDefineValue + zMatch.Groups[5]);
            });

            // Translate named items (column names / defines)
            //Groups
            //    1    2    3   4   5
            //@"(.*)(@\[)(.+?)(\])(.*)"
            Func <Match, string> funcDefineProcessor =
                zMatch =>
            {
                int    nIndex;
                string sDefineValue;
                var    sKey = zMatch.Groups[3].ToString();

                // check the key for define parameters
                var arrayParams = sKey.Split(new char[] { ',' });
                if (arrayParams.Length > 1)
                {
                    sKey = arrayParams[0];
                }

                sKey = sKey.ToLower();

                if (DictionaryDefines.TryGetValue(sKey, out sDefineValue))
                {
                }
                else if (DictionaryColumnNameToIndex.TryGetValue(sKey, out nIndex))
                {
                    sDefineValue = (nIndex >= listLine.Count ? string.Empty : (listLine[nIndex] ?? "").Trim());
                }
                else
                {
                    IssueManager.Instance.FireAddIssueEvent("Bad reference name: " + sKey);
                    sDefineValue = "[BAD NAME: " + sKey + "]";
                }
                if (arrayParams.Length > 1)
                {
                    for (int nIdx = 1; nIdx < arrayParams.Length; nIdx++)
                    {
                        sDefineValue = sDefineValue.Replace("{" + nIdx + "}", arrayParams[nIdx]);
                    }
                }
                var result = zMatch.Groups[1] + sDefineValue + zMatch.Groups[5];
                // perform the #empty replace every time a define is unwrapped
                return(result.Replace("#empty", string.Empty));
            };

            // Translate substrings (column names / defines)
            //Groups
            //    1  2    3    4  5    6  7    8   9
            //@"(.*)(%\[)(.+?)(,)(\d+)(,)(\d+)(\])(.*)
            Func <Match, string> funcDefineSubstringProcessor =
                zMatch =>
            {
                var sValue = zMatch.Groups[3].ToString();
                int nStartIdx;
                int nLength;
                if (!int.TryParse(zMatch.Groups[5].ToString(), out nStartIdx) ||
                    !int.TryParse(zMatch.Groups[7].ToString(), out nLength))
                {
                    sValue = "[Invalid substring parameters]";
                }
                else
                {
                    sValue = sValue.Length >= nStartIdx + nLength
                            ? sValue.Substring(nStartIdx, nLength)
                            : "[Invalid substring requested]";
                }


                var result = zMatch.Groups[1] + sValue + zMatch.Groups[9];
                // perform the #empty replace every time a define is unwrapped
                return(result.Replace("#empty", string.Empty));
            };

            // define and define substring processing
            sOutput = LoopTranslationMatchMap(sOutput, zElement,
                                              new Dictionary <Regex, Func <Match, string> >
            {
                { s_regexColumnVariable, funcDefineProcessor },
                { s_regexColumnVariableSubstring, funcDefineSubstringProcessor },
                { s_regexCardVariable, funcCardVariableProcessor }
            });


            // Translate card counter/index
            // Groups
            //     1   2    3  4    5  6    7  8   9
            //(@"(.*)(##)(\d+)(;)(\d+)(;)(\d+)(#)(.*)");
            sOutput = LoopTranslateRegex(s_regexCardCounter, sOutput, zElement,
                                         (zMatch =>
            {
                var nStart = Int32.Parse(zMatch.Groups[3].ToString());
                var nChange = Int32.Parse(zMatch.Groups[5].ToString());
                var nLeftPad = Int32.Parse(zMatch.Groups[7].ToString());

                return(zMatch.Groups[1] +
                       // nIndex is left as is (not adding 1)
                       (nStart + (nCardIndex * nChange)).ToString(CultureInfo.InvariantCulture).PadLeft(nLeftPad, '0') +
                       zMatch.Groups[9]);
            }));

            // Translate sub card counter/index
            // Groups
            //     1   2    3  4    5  6    7  8   9
            //(@"(.*)(#sc;)(\d+)(;)(\d+)(;)(\d+)(#)(.*)");
            sOutput = LoopTranslateRegex(s_regexSubCardCounter, sOutput, zElement,
                                         (zMatch =>
            {
                var nStart = Int32.Parse(zMatch.Groups[3].ToString());
                var nChange = Int32.Parse(zMatch.Groups[5].ToString());
                var nLeftPad = Int32.Parse(zMatch.Groups[7].ToString());

                var nIndex = zDeckLine.RowSubIndex;

                return(zMatch.Groups[1] +
                       // nIndex is left as is (not adding 1)
                       (nStart + (nIndex * nChange)).ToString(CultureInfo.InvariantCulture).PadLeft(nLeftPad, '0') +
                       zMatch.Groups[9]);
            }));

            // Translate random number
            // Groups
            //    1  2         3      4  5      6  7
            //@"(.*)(#random;)(-?\d+)(;)(-?\d+)(#)(.*)"
            sOutput = LoopTranslateRegex(s_regexRandomNumber, sOutput, zElement,
                                         (zMatch =>
            {
                int nMin;
                int nMax;

                if (!int.TryParse(zMatch.Groups[3].ToString(), out nMin) ||
                    !int.TryParse(zMatch.Groups[5].ToString(), out nMax))
                {
                    return("Failed to parse random min/max");
                }

                if (nMin >= nMax)
                {
                    return("Invalid random specified. Min >= Max");
                }

                // max is not inclusive
                return(zMatch.Groups[1] + CardMakerInstance.Random.Next(nMin, nMax + 1).ToString() + zMatch.Groups[9]);
            }));


            // Translate repeat
            // Groups
            //    1  2         3    4  5    6  7
            //@"(.*)(#repeat;)(\d+)(;)(.+?)(#)(.*)"
            sOutput = LoopTranslateRegex(s_regexRepeat, sOutput, zElement,
                                         (zMatch =>
            {
                int nRepeatCount;
                var zBuilder = new StringBuilder();
                if (int.TryParse(zMatch.Groups[3].ToString(), out nRepeatCount))
                {
                    for (var nIdx = 0; nIdx < nRepeatCount; nIdx++)
                    {
                        zBuilder.Append(zMatch.Groups[5].ToString());
                    }
                }
                else
                {
                    Logger.AddLogLine("Unable to parse repeat count: " + zMatch.Groups[3].ToString());
                }

                return(zMatch.Groups[1] + zBuilder.ToString() + zMatch.Groups[7]);
            }));
#if false // may drop this completely...
            // Translate random pool
            // Groups
            //    1  2             3    4  5
            //@"(.*)(#randompool;)(.*?)(#)(.*)"
            sOutput = LoopTranslateRegex(s_regexRandomPool, sOutput, zElement,
                                         (zMatch =>
            {
                string poolName = zMatch.Groups[3].ToString();

                // max is not inclusive
                return(zMatch.Groups[1] + LayoutManager.Instance.ActiveDeck.GetRandomPoolValue(poolName) + zMatch.Groups[5]);
            }));
#endif

            // Translate If Logic
            //Groups
            //    1     2    3    4   5
            //@"(.*)(#\()(if.+)(\)#)(.*)");
            Func <Match, string> funcIfProcessor =
                (match =>
            {
                var sLogicResult = TranslateIfLogic(match.Groups[3].ToString());
                return(match.Groups[1] +
                       sLogicResult +
                       match.Groups[5]);
            });

            // Translate Switch Logic
            //Groups
            //    1    2         3    4   5
            //@"(.*)(#\()(switch.+)(\)#)(.*)");
            Func <Match, string> funcSwitchProcessor =
                match =>
            {
                var sLogicResult = TranslateSwitchLogic(match.Groups[3].ToString());
                return(match.Groups[1] +
                       sLogicResult +
                       match.Groups[5]);
            };

            // if / switch processor
            sOutput = LoopTranslationMatchMap(sOutput, zElement,
                                              new Dictionary <Regex, Func <Match, string> >
            {
                { s_regexIfLogic, funcIfProcessor },
                { s_regexSwitchLogic, funcSwitchProcessor }
            });

            var dictionaryOverrideFieldToValue = new Dictionary <string, string>();
            // Override evaluation:
            // Translate card variables (non-reference information
            // Groups
            //     1     2    3    4    5   6
            // @"(.*)(\$\[)(.+?):(.+?)(\])(.*)
            sOutput = LoopTranslateRegex(s_regexElementOverride, sOutput, zElement,
                                         (zMatch =>
            {
                var sField = zMatch.Groups[3].ToString().ToLower();
                var sValue = zMatch.Groups[4].ToString();

                if (!s_setDisallowedOverrideFields.Contains(sField))
                {
                    // empty override values are discarded (matches reference overrides)
                    if (!string.IsNullOrWhiteSpace(sValue))
                    {
                        dictionaryOverrideFieldToValue[sField] = sValue;
                    }
                }
                else
                {
                    Logger.AddLogLine("[{1}] override not allowed on element: [{0}]".FormatString(zElement.name, sField));
                }

                return(zMatch.Groups[1].Value + zMatch.Groups[6].Value);
            }
                                         ));

            zElementString.String = sOutput;
            zElementString.OverrideFieldToValueDictionary = dictionaryOverrideFieldToValue == null
                ? null
                : dictionaryOverrideFieldToValue;
            return(zElementString);
        }
Example #20
0
        /// <summary>
        /// Translates the string representing the element. (also handles any nodraw text input)
        /// </summary>
        /// <param name="zDeck"></param>
        /// <param name="sRawString"></param>
        /// <param name="nCardIndex"></param>
        /// <param name="zDeckLine"></param>
        /// <param name="zElement"></param>
        /// <returns></returns>
        protected override ElementString TranslateToElementString(Deck zDeck, string sRawString, int nCardIndex, DeckLine zDeckLine, ProjectLayoutElement zElement)
        {
#warning Investigate using method references instead of anonymous methods (optimization/code easier to read)

            var listLine = zDeckLine.LineColumns;
            var sOutput  = sRawString;

            sOutput = sOutput.Replace("#empty", string.Empty);

            var zElementString = new ElementString();

            // TODO: maybe move these into classes so this isn't one mammoth blob

            LogTranslation(zElement, sOutput);

            // Translate card variables (non-reference information
            // Groups
            //     1    2    3   4   5
            // @"(.*)(!\[)(.+?)(\])(.*)"
            Func <Match, string> funcCardVariableProcessor =
                (zMatch =>
            {
                string sDefineValue;
                var sKey = zMatch.Groups[3].ToString().ToLower();

                // NOTE: if this expands into more variables move all this into some other method and use a dictionary lookup
                if (sKey.Equals("cardindex"))
                {
                    sDefineValue = (nCardIndex + 1).ToString();
                }
                else if (sKey.Equals("deckindex"))
                {
                    sDefineValue = (zDeckLine.RowSubIndex + 1).ToString();
                }
                else if (sKey.Equals("cardcount"))
                {
                    sDefineValue = zDeck.CardCount.ToString();
                }
                else if (sKey.Equals("elementname"))
                {
                    sDefineValue = zElement.name;
                }
                else
                {
                    IssueManager.Instance.FireAddIssueEvent("Bad card variable: " + sKey);
                    sDefineValue = "[BAD NAME: " + sKey + "]";
                }

                return(zMatch.Groups[1] + sDefineValue + zMatch.Groups[5]);
            });

            // Translate named items (column names / defines)
            //Groups
            //    1    2    3   4   5
            //@"(.*)(@\[)(.+?)(\])(.*)"
            Func <Match, string> funcDefineProcessor =
                zMatch =>
            {
                int    nIndex;
                string sDefineValue;
                var    sKey = zMatch.Groups[3].ToString();

                // check the key for define parameters
                var arrayParams = sKey.Split(new char[] { ',' });
                if (arrayParams.Length > 1)
                {
                    sKey = arrayParams[0];
                }

                sKey = sKey.ToLower();

                if (DictionaryDefines.TryGetValue(sKey, out sDefineValue))
                {
                }
                else if (DictionaryColumnNameToIndex.TryGetValue(sKey, out nIndex))
                {
                    sDefineValue = (nIndex >= listLine.Count ? string.Empty : (listLine[nIndex] ?? "").Trim());
                }
                else
                {
                    IssueManager.Instance.FireAddIssueEvent("Bad reference name: " + sKey);
                    sDefineValue = "[BAD NAME: " + sKey + "]";
                }
                if (arrayParams.Length > 1)
                {
                    for (int nIdx = 1; nIdx < arrayParams.Length; nIdx++)
                    {
                        sDefineValue = sDefineValue.Replace("{" + nIdx + "}", arrayParams[nIdx]);
                    }
                }
                var result = zMatch.Groups[1] + sDefineValue + zMatch.Groups[5];
                // perform the #empty replace every time a define is unwrapped
                return(result.Replace("#empty", string.Empty));
            };

            // Translate substrings (column names / defines)
            //Groups
            //    1  2    3    4  5    6  7    8   9
            //@"(.*)(%\[)(.+?)(,)(\d+)(,)(\d+)(\])(.*)
            Func <Match, string> funcDefineSubstringProcessor =
                zMatch =>
            {
                var sValue = zMatch.Groups[3].ToString();
                int nStartIdx;
                int nLength;
                if (!int.TryParse(zMatch.Groups[5].ToString(), out nStartIdx) ||
                    !int.TryParse(zMatch.Groups[7].ToString(), out nLength))
                {
                    sValue = "[Invalid substring parameters]";
                }
                else
                {
                    sValue = sValue.Length >= nStartIdx + nLength
                            ? sValue.Substring(nStartIdx, nLength)
                            : string.Empty;
                }


                var result = zMatch.Groups[1] + sValue + zMatch.Groups[9];
                // perform the #empty replace every time a define is unwrapped
                return(result.Replace("#empty", string.Empty));
            };

            // define and define substring processing
            sOutput = LoopTranslationMatchMap(sOutput, zElement,
                                              new Dictionary <Regex, Func <Match, string> >
            {
                { s_regexColumnVariable, funcDefineProcessor },
                { s_regexColumnVariableSubstring, funcDefineSubstringProcessor },
                { s_regexCardVariable, funcCardVariableProcessor }
            });


            // Translate card counter/index
            // Groups
            //     1   2    3  4    5  6    7  8   9
            //(@"(.*)(##)(\d+)(;)(\d+)(;)(\d+)(#)(.*)");
            sOutput = LoopTranslateRegex(s_regexCardCounter, sOutput, zElement,
                                         (zMatch =>
            {
                var nStart = Int32.Parse(zMatch.Groups[3].ToString());
                var nChange = Int32.Parse(zMatch.Groups[5].ToString());
                var nLeftPad = Int32.Parse(zMatch.Groups[7].ToString());

                return(zMatch.Groups[1] +
                       // nIndex is left as is (not adding 1)
                       (nStart + (nCardIndex * nChange)).ToString(CultureInfo.InvariantCulture)
                       .PadLeft(nLeftPad, '0') +
                       zMatch.Groups[9]);
            }));

            // Translate sub card counter/index
            // Groups
            //     1   2    3  4    5  6    7  8   9
            //(@"(.*)(#sc;)(\d+)(;)(\d+)(;)(\d+)(#)(.*)");
            sOutput = LoopTranslateRegex(s_regexSubCardCounter, sOutput, zElement,
                                         (zMatch =>
            {
                var nStart = Int32.Parse(zMatch.Groups[3].ToString());
                var nChange = Int32.Parse(zMatch.Groups[5].ToString());
                var nLeftPad = Int32.Parse(zMatch.Groups[7].ToString());

                var nIndex = zDeckLine.RowSubIndex;

                return(zMatch.Groups[1] +
                       // nIndex is left as is (not adding 1)
                       (nStart + (nIndex * nChange)).ToString(CultureInfo.InvariantCulture).PadLeft(nLeftPad, '0') +
                       zMatch.Groups[9]);
            }));

            // Translate random number
            // Groups
            //    1  2         3      4  5      6  7
            //@"(.*)(#random;)(-?\d+)(;)(-?\d+)(#)(.*)"
            sOutput = LoopTranslateRegex(s_regexRandomNumber, sOutput, zElement,
                                         (zMatch =>
            {
                int nMin;
                int nMax;

                if (!int.TryParse(zMatch.Groups[3].ToString(), out nMin) ||
                    !int.TryParse(zMatch.Groups[5].ToString(), out nMax))
                {
                    return("Failed to parse random min/max");
                }

                if (nMin >= nMax)
                {
                    return("Invalid random specified. Min >= Max");
                }

                // max is not inclusive
                return(zMatch.Groups[1] + CardMakerInstance.Random.Next(nMin, nMax + 1).ToString() +
                       zMatch.Groups[7]);
            }));

            // Translate math (float support)
            // https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings
            // Groups
            //   1   2            3                  4         5                           6    7  8
            //@"(.*)(#math;)([+-]?[0-9]*[.,]?[0-9]+)([+\-*/%])([+-]?[0-9]*[.,]?[0-9]+)[;]?(.*?)(#)(.*)"
            sOutput = LoopTranslateRegex(s_regexMath, sOutput, zElement,
                                         (zMatch =>
            {
                var sResult = "";
                if (ParseUtil.ParseFloat(zMatch.Groups[3].ToString(), out var fAValue) &&
                    ParseUtil.ParseFloat(zMatch.Groups[5].ToString(), out var fBValue))
                {
                    try
                    {
                        var sFormat = zMatch.Groups[6].ToString();
                        var bUseFormat = !string.IsNullOrWhiteSpace(sFormat);
                        float fResult = 0;
                        switch (zMatch.Groups[4].ToString()[0])
                        {
                        case '+':
                            fResult = fAValue + fBValue;
                            break;

                        case '-':
                            fResult = fAValue - fBValue;
                            break;

                        case '*':
                            fResult = fAValue * fBValue;
                            break;

                        case '/':
                            if (fBValue == 0)
                            {
                                throw new Exception("Cannot divide by zero.");
                            }
                            fResult = fAValue / fBValue;
                            break;

                        case '%':
                            fResult = fAValue % fBValue;
                            break;
                        }

                        sResult = bUseFormat
                                ? fResult.ToString(sFormat)
                                : fResult.ToString();
                    }
                    catch (Exception e)
                    {
                        Logger.AddLogLine("Math float translator failed: {0}".FormatString(e));
                    }
                }
                return(zMatch.Groups[1] + sResult + zMatch.Groups[8]);
            }));


            // Translate repeat
            // Groups
            //    1  2         3    4  5    6  7
            //@"(.*)(#repeat;)(\d+)(;)(.+?)(#)(.*)"
            sOutput = LoopTranslateRegex(s_regexRepeat, sOutput, zElement,
                                         (zMatch =>
            {
                int nRepeatCount;
                var zBuilder = new StringBuilder();
                if (int.TryParse(zMatch.Groups[3].ToString(), out nRepeatCount))
                {
                    for (var nIdx = 0; nIdx < nRepeatCount; nIdx++)
                    {
                        zBuilder.Append(zMatch.Groups[5].ToString());
                    }
                }
                else
                {
                    Logger.AddLogLine("Unable to parse repeat count: " + zMatch.Groups[3].ToString());
                }

                return(zMatch.Groups[1] + zBuilder.ToString() + zMatch.Groups[7]);
            }));

            // Translate If Logic
            //Groups
            //    1     2    3    4   5
            //@"(.*)(#\()(if.+)(\)#)(.*)");
            Func <Match, string> funcIfProcessor =
                (match =>
            {
                var sLogicResult = TranslateIfLogic(match.Groups[3].ToString());
                return(match.Groups[1] +
                       sLogicResult +
                       match.Groups[5]);
            });

            // Translate Switch Logic
            //Groups
            //    1    2         3    4   5
            //@"(.*)(#\()(switch.+)(\)#)(.*)");
            Func <Match, string> funcSwitchProcessor =
                match =>
            {
                var sLogicResult = TranslateSwitchLogic(match.Groups[3].ToString());
                return(match.Groups[1] +
                       sLogicResult +
                       match.Groups[5]);
            };

            // if / switch processor
            sOutput = LoopTranslationMatchMap(sOutput, zElement,
                                              new Dictionary <Regex, Func <Match, string> >
            {
                { s_regexIfLogic, funcIfProcessor },
                { s_regexSwitchLogic, funcSwitchProcessor }
            });

            var dictionaryOverrideFieldToValue = new Dictionary <string, string>();
            // Override evaluation:
            // Translate card variables (non-reference information
            // Groups
            //     1     2    3    4    5   6
            // @"(.*)(\$\[)(.+?):(.+?)(\])(.*)
            sOutput = LoopTranslateRegex(s_regexElementOverride, sOutput, zElement,
                                         (zMatch =>
            {
                var sField = zMatch.Groups[3].ToString().ToLower();
                var sValue = zMatch.Groups[4].ToString();

                if (IsDisallowedOverrideField(sField))
                {
                    Logger.AddLogLine(
                        "[{1}] override not allowed on element: [{0}]".FormatString(zElement.name, sField));
                }
                // empty override values are discarded (matches reference overrides)
                else if (!string.IsNullOrWhiteSpace(sValue))
                {
                    dictionaryOverrideFieldToValue[sField] = sValue;
                }

                return(zMatch.Groups[1].Value + zMatch.Groups[6].Value);
            }
                                         ));

            zElementString.String = sOutput;
            zElementString.OverrideFieldToValueDictionary = dictionaryOverrideFieldToValue == null
                ? null
                : dictionaryOverrideFieldToValue;
            return(zElementString);
        }
Example #21
0
        /// <summary>
        /// Translates the string representing the element. (also handles any nodraw text input)
        /// </summary>
        /// <param name="sRawString"></param>
        /// <param name="nCardIndex"></param>
        /// <param name="zDeckLine"></param>
        /// <param name="zElement"></param>
        /// <returns></returns>
        protected override ElementString TranslateToElementString(string sRawString, int nCardIndex, DeckLine zDeckLine, ProjectLayoutElement zElement)
        {
            List <string> listLine = zDeckLine.LineColumns;

            string sOutput = sRawString;

            sOutput = sOutput.Replace("#empty", string.Empty);

            var zElementString = new ElementString();

            // Translate card variables (non-reference information
            // Groups
            //     1    2    3   4   5
            // @"(.*)(!\[)(.+?)(\])(.*)"
            Match zMatch;

            while (s_regexCardVariable.IsMatch(sOutput))
            {
                zMatch = s_regexCardVariable.Match(sOutput);
                string sDefineValue;
                var    sKey = zMatch.Groups[3].ToString().ToLower();

                // NOTE: if this expands into more variables move all this into some other method and use a dictionary lookup
                if (sKey.Equals("cardindex"))
                {
                    sDefineValue = (nCardIndex + 1).ToString();
                }
                else if (sKey.Equals("deckindex"))
                {
                    sDefineValue = (zDeckLine.RowSubIndex + 1).ToString();
                }
                else
                {
                    IssueManager.Instance.FireAddIssueEvent("Bad card variable: " + sKey);
                    sDefineValue = "[BAD NAME: " + sKey + "]";
                }

                sOutput = zMatch.Groups[1] + sDefineValue + zMatch.Groups[5];
            }

            // Translate named items (column names / defines)
            //Groups
            //    1    2    3   4   5
            //@"(.*)(@\[)(.+?)(\])(.*)"
            while (s_regexColumnVariable.IsMatch(sOutput))
            {
                zMatch = s_regexColumnVariable.Match(sOutput);
                int    nIndex;
                string sDefineValue;
                var    sKey = zMatch.Groups[3].ToString().ToLower();

                // check the key for untranslated components
                var arrayParams = sKey.Split(new char[] { ',' });
                if (arrayParams.Length > 1)
                {
                    sKey = arrayParams[0];
                }

                if (DictionaryDefines.TryGetValue(sKey, out sDefineValue))
                {
                }
                else if (DictionaryColumnNameToIndex.TryGetValue(sKey, out nIndex))
                {
                    sDefineValue = (nIndex >= listLine.Count ? string.Empty : (listLine[nIndex] ?? "").Trim());
                }
                else
                {
                    IssueManager.Instance.FireAddIssueEvent("Bad reference name: " + sKey);
                    sDefineValue = "[BAD NAME: " + sKey + "]";
                }
                if (arrayParams.Length > 1)
                {
                    for (int nIdx = 1; nIdx < arrayParams.Length; nIdx++)
                    {
                        sDefineValue = sDefineValue.Replace("{" + nIdx + "}", arrayParams[nIdx]);
                    }
                }
                sOutput = zMatch.Groups[1] + sDefineValue + zMatch.Groups[5];
            }

            // Translate card counter/index
            // Groups
            //     1   2    3  4    5  6    7  8   9
            //(@"(.*)(##)(\d+)(;)(\d+)(;)(\d+)(#)(.*)");
            while (s_regexCardCounter.IsMatch(sOutput))
            {
                zMatch = s_regexCardCounter.Match(sOutput);
                var nStart   = Int32.Parse(zMatch.Groups[3].ToString());
                var nChange  = Int32.Parse(zMatch.Groups[5].ToString());
                var nLeftPad = Int32.Parse(zMatch.Groups[7].ToString());

                sOutput = zMatch.Groups[1] +
                          // nIndex is left as is (not adding 1)
                          (nStart + (nCardIndex * nChange)).ToString(CultureInfo.InvariantCulture).PadLeft(nLeftPad, '0') +
                          zMatch.Groups[9];
            }

            // Translate sub card counter/index
            // Groups
            //     1   2    3  4    5  6    7  8   9
            //(@"(.*)(#sc;)(\d+)(;)(\d+)(;)(\d+)(#)(.*)");
            while (s_regexSubCardCounter.IsMatch(sOutput))
            {
                zMatch = s_regexSubCardCounter.Match(sOutput);
                var nStart   = Int32.Parse(zMatch.Groups[3].ToString());
                var nChange  = Int32.Parse(zMatch.Groups[5].ToString());
                var nLeftPad = Int32.Parse(zMatch.Groups[7].ToString());

                var nIndex = zDeckLine.RowSubIndex;

                sOutput = zMatch.Groups[1] +
                          // nIndex is left as is (not adding 1)
                          (nStart + (nIndex * nChange)).ToString(CultureInfo.InvariantCulture).PadLeft(nLeftPad, '0') +
                          zMatch.Groups[9];
            }

            // Translate If Logic
            //Groups
            //    1     2    3    4   5
            //@"(.*)(#\()(if.+)(\)#)(.*)");
            while (s_regexIfLogic.IsMatch(sOutput))
            {
                zMatch = s_regexIfLogic.Match(sOutput);
                string sLogicResult = TranslateIfLogic(zMatch.Groups[3].ToString());
                sOutput = zMatch.Groups[1] +
                          sLogicResult +
                          zMatch.Groups[5];
            }

            // Translate Switch Logic
            //Groups
            //    1     2        3    4   5
            //@"(.*)(#\()(switch.+)(\)#)(.*)");
            while (s_regexSwitchLogic.IsMatch(sOutput))
            {
                zMatch = s_regexSwitchLogic.Match(sOutput);
                string sLogicResult = TranslateSwitchLogic(zMatch.Groups[3].ToString());
                sOutput = zMatch.Groups[1] +
                          sLogicResult +
                          zMatch.Groups[5];
            }

            zElementString.String = sOutput;

            return(zElementString);
        }
Example #22
0
        /// <summary>
        /// Translates the string representing the element. (also handles any nodraw text input)
        /// </summary>
        /// <param name="sRawString"></param>
        /// <param name="zDeckLine"></param>
        /// <param name="zElement"></param>
        /// <param name="sCacheSuffix"></param>
        /// <returns></returns>
        protected override ElementString TranslateToElementString(string sRawString, int nCardIndex, DeckLine zDeckLine, ProjectLayoutElement zElement)
        {
            List<string> listLine = zDeckLine.LineColumns;

            string sOutput = sRawString;

            sOutput = sOutput.Replace("#empty", String.Empty);

            var zElementString = new ElementString();

            // Translate card variables (non-reference information
            // Groups
            //     1    2    3   4   5
            // @"(.*)(!\[)(.+?)(\])(.*)"
            Match zMatch;
            while (s_regexCardVariable.IsMatch(sOutput))
            {
                zMatch = s_regexCardVariable.Match(sOutput);
                string sDefineValue;
                var sKey = zMatch.Groups[3].ToString().ToLower();

                // NOTE: if this expands into more variables move all this into some other method and use a dictionary lookup
                if (sKey.Equals("cardindex"))
                {
                    sDefineValue = (nCardIndex + 1).ToString();
                }
                else if (sKey.Equals("deckindex"))
                {
                    sDefineValue = (zDeckLine.RowSubIndex + 1).ToString();
                }
                else
                {
                    IssueManager.Instance.FireAddIssueEvent("Bad card variable: " + sKey);
                    sDefineValue = "[BAD NAME: " + sKey + "]";
                }

                sOutput = zMatch.Groups[1] + sDefineValue + zMatch.Groups[5];
            }

            // Translate named items (column names / defines)
            //Groups
            //    1    2    3   4   5
            //@"(.*)(@\[)(.+?)(\])(.*)"
            while (s_regexColumnVariable.IsMatch(sOutput))
            {
                zMatch = s_regexColumnVariable.Match(sOutput);
                int nIndex;
                string sDefineValue;
                var sKey = zMatch.Groups[3].ToString().ToLower();

                // check the key for untranslated components
                var arrayParams = sKey.Split(new char[] { ',' });
                if (arrayParams.Length > 1)
                {
                    sKey = arrayParams[0];
                }

                if (DictionaryDefines.TryGetValue(sKey, out sDefineValue))
                {
                }
                else if (DictionaryColumnNameToIndex.TryGetValue(sKey, out nIndex))
                {
                    sDefineValue = (nIndex >= listLine.Count ? String.Empty : listLine[nIndex].Trim());
                }
                else
                {
                    IssueManager.Instance.FireAddIssueEvent("Bad reference name: " + sKey);
                    sDefineValue = "[BAD NAME: " + sKey + "]";
                }
                if (arrayParams.Length > 1)
                {
                    for (int nIdx = 1; nIdx < arrayParams.Length; nIdx++)
                    {
                        sDefineValue = sDefineValue.Replace("{" + nIdx + "}", arrayParams[nIdx]);
                    }
                }
                sOutput = zMatch.Groups[1] + sDefineValue + zMatch.Groups[5];
            }

            // Translate card counter/index
            // Groups                 
            //     1   2    3  4    5  6    7  8   9
            //(@"(.*)(##)(\d+)(;)(\d+)(;)(\d+)(#)(.*)");
            while (s_regexCardCounter.IsMatch(sOutput))
            {
                zMatch = s_regexCardCounter.Match(sOutput);
                var nStart = Int32.Parse(zMatch.Groups[3].ToString());
                var nChange = Int32.Parse(zMatch.Groups[5].ToString());
                var nLeftPad = Int32.Parse(zMatch.Groups[7].ToString());

                sOutput = zMatch.Groups[1] +
                    // nIndex is left as is (not adding 1)
                    (nStart + (nCardIndex * nChange)).ToString(CultureInfo.InvariantCulture).PadLeft(nLeftPad, '0') +
                    zMatch.Groups[9];
            }

            // Translate sub card counter/index
            // Groups                 
            //     1   2    3  4    5  6    7  8   9
            //(@"(.*)(#sc;)(\d+)(;)(\d+)(;)(\d+)(#)(.*)");
            while (s_regexSubCardCounter.IsMatch(sOutput))
            {
                zMatch = s_regexSubCardCounter.Match(sOutput);
                var nStart = Int32.Parse(zMatch.Groups[3].ToString());
                var nChange = Int32.Parse(zMatch.Groups[5].ToString());
                var nLeftPad = Int32.Parse(zMatch.Groups[7].ToString());

                var nIndex = zDeckLine.RowSubIndex;

                sOutput = zMatch.Groups[1] +
                    // nIndex is left as is (not adding 1)
                    (nStart + (nIndex * nChange)).ToString(CultureInfo.InvariantCulture).PadLeft(nLeftPad, '0') +
                    zMatch.Groups[9];
            }

            // Translate If Logic
            //Groups
            //    1     2    3    4   5 
            //@"(.*)(#\()(if.+)(\)#)(.*)");
            while (s_regexIfLogic.IsMatch(sOutput))
            {
                zMatch = s_regexIfLogic.Match(sOutput);
                string sLogicResult = TranslateIfLogic(zMatch.Groups[3].ToString());
                sOutput = zMatch.Groups[1] +
                    sLogicResult +
                    zMatch.Groups[5];
            }

            // Translate Switch Logic
            //Groups                  
            //    1     2        3    4   5 
            //@"(.*)(#\()(switch.+)(\)#)(.*)");
            while (s_regexSwitchLogic.IsMatch(sOutput))
            {
                zMatch = s_regexSwitchLogic.Match(sOutput);
                string sLogicResult = TranslateSwitchLogic(zMatch.Groups[3].ToString());
                sOutput = zMatch.Groups[1] +
                    sLogicResult +
                    zMatch.Groups[5];
            }

            zElementString.String = sOutput;

            return zElementString;
        }