/// <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); }
/// <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); }
/// <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); }
/// <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); }