public DictionaryMetaObject(string DictName, string DictDescript, string DictPrefix, string DictContents) { DictionaryName = DictName; DictionaryDescription = DictDescript; DictionaryRawText = DictContents; DictionaryCategoryPrefix = DictPrefix; UseDictionary = true; DictData = new DictionaryData(); }
public Payload RunPlugin(Payload Input, int ThreadsAvailable) { DictionaryData ParsedDict = new DictionaryData(); try { DictParser DP = new DictParser(); ParsedDict = DP.ParseDict(DictDataRawMeta); } catch { MessageBox.Show("There was an error trying to parse your dictionary file. Please make sure that your dictionary file is correctly formatted.", "Error Parsing Dictionary", MessageBoxButtons.OK, MessageBoxIcon.Error); return(new Payload()); } //ParsedDict.FullDictionary structure //--"Wildcards" //----int Word Count //--------Words //----------categories[] //--"Standards" //----int Word Count //--------Words //----------categories[] NumCats = ParsedDict.NumCats; uint WordsProcessed = 0; TimeSpan reportPeriod = TimeSpan.FromMinutes(0.01); using (new System.Threading.Timer( _ => SetUpdate(WordsProcessed), null, reportPeriod, reportPeriod)) { try { using (ThreadsafeOutputWriter OutputWriter = new ThreadsafeOutputWriter(OutputLocation, Encoding.GetEncoding(SelectedEncoding.ToString()), FileMode.Create)) { #region set up and write the header string[] header; if (CSVStyle == "Poster") { header = ParsedDict.CatNames; } else { header = new string[ParsedDict.NumCats + 1]; header[0] = "Entry"; for (int i = 0; i < ParsedDict.NumCats; i++) { header[i + 1] = ParsedDict.CatNames[i]; } } for (int i = 0; i < header.Length; i++) { header[i] = Quote + header[i] + Quote; } OutputWriter.WriteString(String.Join(Delimiter, header)); #endregion if (CSVStyle == "Poster") { #region write poster style csv Dictionary <string, int> CatIndices = new Dictionary <string, int>(); //for (int i = 0; i < ParsedDict.CatValues.Length; i++) CatIndices.Add(ParsedDict.CatValues[i], i); for (int i = 0; i < ParsedDict.CatValues.Length; i++) { //we have to make sure that the category mapped key doesn't already exist in the CatIndices variable //otherwise, a person can accidentally re-use the same category number (e.g., 10) for multiple categories, //which will screw things up if (!CatIndices.ContainsKey(ParsedDict.CatValues[i])) { CatIndices.Add(ParsedDict.CatValues[i], i); } else { MessageBox.Show("Your dictionary file appears to use the same code to refer to muliple categories (" + ParsedDict.CatValues[i] + "). All categories that use this code will be omitted, except for the first category that used this code.", "Dictionary Formatting Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } //initialize our word map List <List <string> > WordMap = new List <List <string> >(); for (int i = 0; i < NumCats; i++) { WordMap.Add(new List <string>()); } if (ParsedDict.FullDictionary.ContainsKey("Wildcards")) { foreach (int wordcount in ParsedDict.FullDictionary["Wildcards"].Keys) { foreach (string word in ParsedDict.FullDictionary["Wildcards"][wordcount].Keys) { for (int i = 0; i < ParsedDict.FullDictionary["Wildcards"][wordcount][word].Length; i++) { if (CatIndices.ContainsKey(ParsedDict.FullDictionary["Wildcards"][wordcount][word][i])) { WordMap[CatIndices[ParsedDict.FullDictionary["Wildcards"][wordcount][word][i]]].Add(Quote + word.Replace(Quote, Quote + Quote) + Quote); } } WordsProcessed++; } } } if (ParsedDict.FullDictionary.ContainsKey("Standards")) { foreach (int wordcount in ParsedDict.FullDictionary["Standards"].Keys) { foreach (string word in ParsedDict.FullDictionary["Standards"][wordcount].Keys) { for (int i = 0; i < ParsedDict.FullDictionary["Standards"][wordcount][word].Length; i++) { if (CatIndices.ContainsKey(ParsedDict.FullDictionary["Standards"][wordcount][word][i])) { WordMap[CatIndices[ParsedDict.FullDictionary["Standards"][wordcount][word][i]]].Add(Quote + word.Replace(Quote, Quote + Quote) + Quote); } } WordsProcessed++; } } } //now that we've populated the word map, we can clean some things up //first, wipe out the parseddict ParsedDict = new DictionaryData(); //now we sort the word lists and figure out our array size that we're going to write int MaxWords = 0; for (int i = 0; i < NumCats; i++) { WordMap[i].Sort(); int wordCount = WordMap[i].Count; if (wordCount > MaxWords) { MaxWords = wordCount; } } //OutputArray[Cols,Rows] string[][] OutputArray = new string[MaxWords][]; //initialize array with empty strings for (int i = 0; i < MaxWords; i++) { OutputArray[i] = new string[NumCats]; for (int j = 0; j < NumCats; j++) { OutputArray[i][j] = ""; } } //now we populate the array with the words from the word map for (int i = 0; i < NumCats; i++) { for (int j = 0; j < WordMap[i].Count; j++) { OutputArray[j][i] = WordMap[i][j]; } } WordMap.Clear(); //finally, write the data for (int i = 0; i < MaxWords; i++) { OutputWriter.WriteString(String.Join(Delimiter, OutputArray[i])); } #endregion } else { #region write table style csv //set up a dictionary to track which columns the output gets written to Dictionary <string, int> CatIndices = new Dictionary <string, int>(); for (int i = 0; i < ParsedDict.CatValues.Length; i++) { //we have to make sure that the category mapped key doesn't already exist in the CatIndices variable //otherwise, a person can accidentally re-use the same category number (e.g., 10) for multiple categories, //which will screw things up if (!CatIndices.ContainsKey(ParsedDict.CatValues[i])) { CatIndices.Add(ParsedDict.CatValues[i], i + 1); } else { MessageBox.Show("Your dictionary file appears to use the same code to refer to muliple categories (" + ParsedDict.CatValues[i] + "). All categories that use this code will be omitted, except for the first category that used this code.", "Dictionary Formatting Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } List <string> WordList = new List <string>(); Dictionary <string, string[]> WordListUnpacked = new Dictionary <string, string[]>(); #region deconstruct dictionary object //it's kind of taking the long way around to basically read in the dictionary, parse it out into its own object, //then deconstruct that object into additional lists/dictionaries. I might change this in the future, however, I //currently feel that this is a fairly robust way to make sure that everything is parsed out properly before //trying to reassemble into a table. Inefficient? Yes, but it allows me to recycle a lot of other code that I've written foreach (int wordcount in ParsedDict.FullDictionary["Wildcards"].Keys) { foreach (string word in ParsedDict.FullDictionary["Wildcards"][wordcount].Keys) { WordList.Add(word); WordListUnpacked.Add(word, ParsedDict.FullDictionary["Wildcards"][wordcount][word]); WordsProcessed++; } } foreach (int wordcount in ParsedDict.FullDictionary["Standards"].Keys) { foreach (string word in ParsedDict.FullDictionary["Standards"][wordcount].Keys) { WordList.Add(word); WordListUnpacked.Add(word, ParsedDict.FullDictionary["Standards"][wordcount][word]); WordsProcessed++; } } //we can wipe this out now that we're done with it ParsedDict = new DictionaryData(); #endregion WordList.Sort(); //now we go back and iterate over everything to write it out as a table for (int i = 0; i < WordList.Count; i++) { string word = WordList[i]; //initialize new array with empty strings string[] RowToWrite = new string[NumCats + 1]; for (int j = 0; j < NumCats + 1; j++) { RowToWrite[j] = ""; } RowToWrite[0] = Quote + word.Replace(Quote, Quote + Quote) + Quote; for (int j = 0; j < WordListUnpacked[word].Length; j++) { if (CatIndices.ContainsKey(WordListUnpacked[word][j])) { RowToWrite[CatIndices[WordListUnpacked[word][j]]] = "X"; } } OutputWriter.WriteString(String.Join(Delimiter, RowToWrite)); } #endregion } } } catch { MessageBox.Show("There was a problem writing your dictionary to a CSV file. Is your CSV file currently open in another application?", "CSV Write Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } return(new Payload()); }
public DictionaryData ParseDict(DictionaryMetaObject DictionaryToParse) { DictionaryData DictData = DictionaryToParse.DictData; // ____ _ _ ____ _ _ ____ _ ___ _ _ _ // | _ \ ___ _ __ _ _| | __ _| |_ ___ | _ \(_) ___| |_| _ \ __ _| |_ __ _ / _ \| |__ (_) ___ ___| |_ // | |_) / _ \| '_ \| | | | |/ _` | __/ _ \ | | | | |/ __| __| | | |/ _` | __/ _` | | | | | '_ \| |/ _ \/ __| __| // | __/ (_) | |_) | |_| | | (_| | || __/ | |_| | | (__| |_| |_| | (_| | || (_| | | |_| | |_) | | __/ (__| |_ // |_| \___/| .__/ \__,_|_|\__,_|\__\___| |____/|_|\___|\__|____/ \__,_|\__\__,_| \___/|_.__// |\___|\___|\__| // |_| |__/ //parse out the the dictionary file DictData.MaxWords = 0; //yeah, there's levels to this thing DictData.FullDictionary = new Dictionary <string, Dictionary <int, Dictionary <string, string[]> > >(); DictData.FullDictionary.Add("Wildcards", new Dictionary <int, Dictionary <string, string[]> >()); DictData.FullDictionary.Add("Standards", new Dictionary <int, Dictionary <string, string[]> >()); DictData.WildCardArrays = new Dictionary <int, string[]>(); DictData.PrecompiledWildcards = new Dictionary <string, Regex>(); Dictionary <int, List <string> > WildCardLists = new Dictionary <int, List <string> >(); string[] DicSplit = DictionaryToParse.DictionaryRawText.Split(new char[] { '%' }, 3, StringSplitOptions.None); string[] HeaderLines = DicSplit[1].Trim().Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries); string[] EntryLines = DicSplit[2].Trim().Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries); DictData.NumCats = HeaderLines.Length; //now that we know the number of categories, we can fill out the arrays DictData.CatNames = new string[DictData.NumCats]; DictData.CatValues = new string[DictData.NumCats]; //Map Out the Categories for (int i = 0; i < DictData.NumCats; i++) { string[] HeaderRow = HeaderLines[i].Trim().Split(new char[] { '\t' }, 2); DictData.CatValues[i] = HeaderRow[0]; DictData.CatNames[i] = HeaderRow[1]; } //Map out the dictionary entries for (int i = 0; i < EntryLines.Length; i++) { string EntryLine = EntryLines[i].Trim(); while (EntryLine.Contains(" ")) { EntryLine.Replace(" ", " "); } string[] EntryRow = EntryLine.Trim().Split(new char[] { '\t' }, StringSplitOptions.RemoveEmptyEntries); if (EntryRow.Length > 1 && !String.IsNullOrWhiteSpace(EntryRow[0])) { int Words_In_Entry = EntryRow[0].Split(' ').Length; if (Words_In_Entry > DictData.MaxWords) { DictData.MaxWords = Words_In_Entry; } if (EntryRow[0].Contains("*")) { if (DictData.FullDictionary["Wildcards"].ContainsKey(Words_In_Entry)) { if (!DictData.FullDictionary["Wildcards"][Words_In_Entry].ContainsKey(EntryRow[0].ToLower())) { DictData.FullDictionary["Wildcards"][Words_In_Entry].Add(EntryRow[0].ToLower(), EntryRow.Skip(1).ToArray()); WildCardLists[Words_In_Entry].Add(EntryRow[0].ToLower()); DictData.PrecompiledWildcards.Add(EntryRow[0].ToLower(), new Regex("^" + Regex.Escape(EntryRow[0].ToLower()).Replace("\\*", ".*") + "$", RegexOptions.Compiled)); } } else { DictData.FullDictionary["Wildcards"].Add(Words_In_Entry, new Dictionary <string, string[]> { { EntryRow[0].ToLower(), EntryRow.Skip(1).ToArray() } }); WildCardLists.Add(Words_In_Entry, new List <string>(new string[] { EntryRow[0].ToLower() })); DictData.PrecompiledWildcards.Add(EntryRow[0].ToLower(), new Regex("^" + Regex.Escape(EntryRow[0].ToLower()).Replace("\\*", ".*") + "$", RegexOptions.Compiled)); } } else { if (DictData.FullDictionary["Standards"].ContainsKey(Words_In_Entry)) { if (!DictData.FullDictionary["Standards"][Words_In_Entry].ContainsKey(EntryRow[0].ToLower())) { DictData.FullDictionary["Standards"][Words_In_Entry].Add(EntryRow[0].ToLower(), EntryRow.Skip(1).ToArray()); } } else { DictData.FullDictionary["Standards"].Add(Words_In_Entry, new Dictionary <string, string[]> { { EntryRow[0].ToLower(), EntryRow.Skip(1).ToArray() } }); } } } } for (int i = DictData.MaxWords; i > 0; i--) { if (WildCardLists.ContainsKey(i)) { DictData.WildCardArrays.Add(i, WildCardLists[i].ToArray()); } } WildCardLists.Clear(); DictData.DictionaryLoaded = true; //MessageBox.Show("Your dictionary has been successfully loaded.", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information); return(DictData); }