} // if userinput gave a search // keywrods is x:y:z // public StringSearchTerms(string userinput, string keywords) { if (userinput.HasChars()) { Names = (":" + keywords).Split(":"); // 0 is default Terms = new string[Names.Length]; // all null to start StringParser sp = new StringParser(userinput); while (!sp.IsEOL) { string nextword = sp.NextWord(": "); // stop on next : or space int term; if (sp.IsCharMoveOn(':') && (term = Names.IndexOf(nextword, StringComparison.InvariantCultureIgnoreCase)) > 0) // if :, and it matches nextword { string search = sp.NextQuotedWord(" "); // next quoted word if (search != null) { Terms[term] = search; Enabled = true; } } else { if (Terms[0] == null) { Terms[0] = ""; } Terms[0] = Terms[0].AppendPrePad(nextword, " "); Enabled = true; } } } }
public void ParseGroup(StringParser sp) // parse until stopchar. WordLists has all the word combinations { WordLists = new List <List <string> >(); int list = 0; bool addedempty = false; while (!sp.IsEOL && sp.PeekChar() != groupchar) { bool bracketed = sp.IsCharMoveOn(openbracketchar); string p = sp.NextQuotedWord(bracketed ? stopwordinbracket : stopword); // get the quoted item. stop on right point if (p == null || (bracketed && !sp.IsCharMoveOn(closebracketchar))) // nothing, stop, EOL after bracket. Or bracketed but no bracket { break; } if (WordLists.Count <= list) // do we need another list.. { WordLists.Add(new List <string>()); addedempty = false; } WordLists.Last().Add(p); // add it, even if empty if (bracketed && p.Length > 0 && addedempty == false) { WordLists.Last().Add(""); // add an empty entry addedempty = true; // only add one please } if (!sp.IsCharMoveOn(orchar)) // if |, stay on same list, else move to next { list++; } } }
public IEnumerable <List <List <string> > > ParseGroup(string s) // parse whole string, return one after one the word list for each subsection separ by stopchar { StringParser sp = new StringParser(s); while (!sp.IsEOL) { ParseGroup(sp); yield return(WordLists); if (!sp.IsCharMoveOn(groupchar)) { break; } } }
// Make a tree of splitters, controlled by the string in sp static public SplitContainer SplitterTreeMakeFromCtrlString(BaseUtils.StringParser sp, Func <Orientation, int, SplitContainer> MakeSC, Func <string, Control> MakeNode, int lvl) { char tomake; if (sp.SkipUntil(new char[] { 'H', 'V', 'U' }) && (tomake = sp.GetChar()) != 'U') { sp.IsCharMoveOn('('); // ignore ( SplitContainer sc = MakeSC(tomake == 'H' ? Orientation.Horizontal : Orientation.Vertical, lvl); double percent = sp.NextDouble(",") ?? 0.5; sc.SplitterDistance(percent); SplitContainer one = SplitterTreeMakeFromCtrlString(sp, MakeSC, MakeNode, lvl + 1); if (one == null) { string para = sp.PeekChar() == '\'' ? sp.NextQuotedWord() : ""; sc.Panel1.Controls.Add(MakeNode(para)); } else { sc.Panel1.Controls.Add(one); } SplitContainer two = SplitterTreeMakeFromCtrlString(sp, MakeSC, MakeNode, lvl + 1); if (two == null) { string para = sp.PeekChar() == '\'' ? sp.NextQuotedWord() : ""; sc.Panel2.Controls.Add(MakeNode(para)); } else { sc.Panel2.Controls.Add(two); } return(sc); } else { return(null); } }
public bool ParseString(string s) // process the whole string, generate all the Permutations.. { StringParser sp = new StringParser(s); while (!sp.IsEOL) { ParseGroup(sp); CalculatePermutations(); if (!sp.IsCharMoveOn(groupchar)) { break; } } return(sp.IsEOL); }
public string Read(string line) // decode a set of multi conditions (<cond> Or <cond>) Outer (<cond> And <cond>) etc { StringParser sp = new StringParser(line); bool multi = false; string delimchars = " "; if (sp.IsCharMoveOn('(')) { multi = true; delimchars = ") "; } List <Condition> cllist = new List <Condition>(); ConditionEntry.LogicalCondition outercond = ConditionEntry.LogicalCondition.Or; // first outer condition is ignored in a list. Or is the default. while (true) { Condition c = new Condition(); string err = c.Read(sp, delimchars: delimchars); if (err.Length > 0) { return(err); } c.outercondition = outercond; cllist.Add(c); // add.. if (sp.IsCharMoveOn(')')) // if closing bracket.. { if (!multi) { return("Closing condition bracket found but no opening bracket present"); } if (sp.IsEOL) // EOL, end of (cond..cond) outercond ( cond cond) { conditionlist = cllist; return(null); } else { err = ConditionEntry.GetLogicalCondition(sp, delimchars, out outercond); if (err.Length > 0) { return(err + " for outer condition"); } if (!sp.IsCharMoveOn('(')) // must have another ( { return("Missing opening bracket in multiple condition list after " + outercond.ToString()); } } } else if (sp.IsEOL) // last condition { if (multi) { return("Missing closing braket in multiple condition list"); } conditionlist = cllist; return(null); } else { return("Extra characters beyond expression"); } } }
} // debug // You can call this multiple times if required for debugging purposes public void LoadTranslation(string language, CultureInfo uicurrent, string[] txfolders, int includesearchupdepth, string logdir, string includefolderreject = "\\bin", // use to reject include files in specific locations - for debugging bool loadorgenglish = false, // optional load original english and store bool loadfile = false // remember file where it came from ) { #if DEBUG if (logger != null) { logger.Dispose(); } logger = new LogToFile(); logger.SetFile(logdir, "translator-ids.log", false); #endif translations = null; // forget any originalenglish = null; originalfile = null; List <Tuple <string, string> > languages = EnumerateLanguages(txfolders); // uicurrent = CultureInfo.CreateSpecificCulture("it"); // debug Tuple <string, string> langsel = null; if (language == "Auto") { langsel = FindISOLanguage(languages, uicurrent.Name); if (langsel == null) { langsel = FindISOLanguage(languages, uicurrent.TwoLetterISOLanguageName); } } else { langsel = languages.Find(x => Path.GetFileNameWithoutExtension(x.Item2).Equals(language, StringComparison.InvariantCultureIgnoreCase)); } if (langsel == null) { return; } System.Diagnostics.Debug.WriteLine("Load Language " + langsel.Item2); logger?.WriteLine("Read " + langsel.Item2 + " from " + langsel.Item1); using (LineReader lr = new LineReader()) { string tlffile = Path.Combine(langsel.Item1, langsel.Item2); if (lr.Open(tlffile)) { translations = new Dictionary <string, string>(); originalenglish = new Dictionary <string, string>(); originalfile = new Dictionary <string, string>(); string prefix = ""; string line = null; while ((line = lr.ReadLine()) != null) { line = line.Trim(); if (line.StartsWith("Include", StringComparison.InvariantCultureIgnoreCase)) { line = line.Mid(7).Trim(); DirectoryInfo di = new DirectoryInfo(Path.GetDirectoryName(tlffile)); string filename = null; string fileinroot = Path.Combine(di.FullName, line); if (File.Exists(fileinroot)) // first we prefer files in the same folder.. { filename = fileinroot; } else { di = di.GetDirectoryAbove(includesearchupdepth); // then search the tree, first jump up search depth amount try { FileInfo[] allFiles = Directory.EnumerateFiles(di.FullName, line, SearchOption.AllDirectories).Select(f => new FileInfo(f)).OrderBy(p => p.LastWriteTime).ToArray(); if (allFiles.Length > 0) { var selected = allFiles.Where((x) => !x.DirectoryName.Contains(includefolderreject)); // reject folders with this pattern..files if (selected.Count() > 0) { filename = selected.First().FullName; } } } catch { } } if (filename == null || !lr.Open(filename)) // if no file found, or can't open.. { logger?.WriteLine(string.Format("*** Cannot include {0}", line)); } else { logger?.WriteLine("Read " + filename); } } else if (line.Length > 0 && !line.StartsWith("//")) { StringParser s = new StringParser(line); string id = s.NextWord(" :"); if (id.Equals("SECTION")) { prefix = s.NextQuotedWord(" /"); } else { if (id.StartsWith(".") && prefix.HasChars()) { id = prefix + id; } else { prefix = id.Word(new char[] { '.' }); } if (s.IsCharMoveOn(':')) { string orgenglish = s.NextQuotedWord(replaceescape: true); // first is the original english version string foreign = null; bool err = false; if (s.IsStringMoveOn("=>")) { foreign = s.NextQuotedWord(replaceescape: true); err = foreign == null; } else if (s.IsCharMoveOn('@')) { foreign = null; } else { err = false; } if (err == true) { logger?.WriteLine(string.Format("*** Translator ID but no translation {0}", id)); System.Diagnostics.Debug.WriteLine("*** Translator ID but no translation {0}", id); } else { if (!translations.ContainsKey(id)) { //logger?.WriteLine(string.Format("New {0}: \"{1}\" => \"{2}\"", id, english, foreign)); translations[id] = foreign; if (loadorgenglish) { originalenglish[id] = orgenglish; } if (loadfile) { originalfile[id] = lr.CurrentFile; } } else { logger?.WriteLine(string.Format("*** Translator Repeat {0}", id)); } } } } } } } } }
// You can call this multiple times if required for debugging purposes public void LoadTranslation(string language, CultureInfo uicurrent, string writabletxfolder1, string txfolder2) { #if DEBUG if (logger != null) { logger.Dispose(); } logger = new LogToFile(); logger.SetFile(writabletxfolder1, "ids.txt", false); #endif translations = null; // forget any List <string> languagesfolder1 = Languages(writabletxfolder1, false); // full paths List <string> languagesfolder2 = Languages(txfolder2, false); // uicurrent = CultureInfo.CreateSpecificCulture("es"); // debug string langfile = null; if (language == "Auto") { langfile = FindLanguage(languagesfolder1, uicurrent.Name); if (langfile == null) { langfile = FindLanguage(languagesfolder2, uicurrent.Name); } if (language == null) { langfile = FindLanguage(languagesfolder1, uicurrent.TwoLetterISOLanguageName); } if (language == null) { langfile = FindLanguage(languagesfolder2, uicurrent.TwoLetterISOLanguageName); } if (langfile == null) { return; } } else { langfile = Path.Combine(writabletxfolder1, language + ".tlf"); if (!File.Exists(langfile)) { langfile = Path.Combine(txfolder2, language + ".tlf"); if (!File.Exists(langfile)) { return; } } } System.Diagnostics.Debug.WriteLine("Load Language " + langfile); logger?.WriteLine("Read " + langfile); try { var utc8nobom = new UTF8Encoding(false); // give it the default UTF8 no BOM encoding, it will detect BOM or UCS-2 automatically StreamReader sr = new StreamReader(langfile, utc8nobom); translations = new Dictionary <string, string>(); string prefix = ""; string line = null; while ((line = sr.ReadLine()) != null) { line = line.Trim(); if (line.Length > 0 && !line.StartsWith("//")) { StringParser s = new StringParser(line); string id = s.NextWord(" :"); if (id.StartsWith(".") && prefix.HasChars()) { id = prefix + id; } else { prefix = id.Word(new char[] { '.' }); } if (s.IsCharMoveOn(':')) { s.NextQuotedWord(replaceescape: true); // ignore the english for ref purposes only string foreign = null; bool err = false; if (s.IsStringMoveOn("=>")) { foreign = s.NextQuotedWord(replaceescape: true); err = foreign == null; } else if (s.IsCharMoveOn('@')) { foreign = null; } else { err = false; } if (err == true) { logger?.WriteLine(string.Format("*** Translator ID but no translation {0}", id)); System.Diagnostics.Debug.WriteLine("*** Translator ID but no translation {0}", id); } else { if (!translations.ContainsKey(id)) { //logger?.WriteLine(string.Format("New {0}: \"{1}\" => \"{2}\"", id, english, foreign)); translations[id] = foreign; } else { logger?.WriteLine(string.Format("*** Translator Repeat {0}", id)); } } } } } } catch { } }
// You can call this multiple times if required for debugging purposes public void LoadTranslation(string language, CultureInfo uicurrent, string txfolder1, string txfolder2, int includesearchupdepth, string logdir) { #if DEBUG if (logger != null) { logger.Dispose(); } logger = new LogToFile(); logger.SetFile(logdir, "translator-ids.log", false); #endif translations = null; // forget any List <string> languagesfolder1 = Languages(txfolder1, false); // full paths List <string> languagesfolder2 = Languages(txfolder2, false); // uicurrent = CultureInfo.CreateSpecificCulture("es"); // debug string langfile = null; if (language == "Auto") { langfile = FindLanguage(languagesfolder1, uicurrent.Name); if (langfile == null) { langfile = FindLanguage(languagesfolder2, uicurrent.Name); } if (language == null) { langfile = FindLanguage(languagesfolder1, uicurrent.TwoLetterISOLanguageName); } if (language == null) { langfile = FindLanguage(languagesfolder2, uicurrent.TwoLetterISOLanguageName); } if (langfile == null) { return; } } else { langfile = Path.Combine(txfolder1, language + ".tlf"); if (!File.Exists(langfile)) { langfile = Path.Combine(txfolder2, language + ".tlf"); if (!File.Exists(langfile)) { return; } } } System.Diagnostics.Debug.WriteLine("Load Language " + langfile); logger?.WriteLine("Read " + langfile); using (LineReader lr = new LineReader()) { if (lr.Open(langfile)) { translations = new Dictionary <string, string>(); string prefix = ""; string line = null; while ((line = lr.ReadLine()) != null) { line = line.Trim(); if (line.StartsWith("Include", StringComparison.InvariantCultureIgnoreCase)) { line = line.Mid(7).Trim(); DirectoryInfo di = new DirectoryInfo(Path.GetDirectoryName(langfile)); string filename = null; if (File.Exists(Path.Combine(di.FullName, line))) // first we prefer files in the same folder.. { filename = Path.Combine(di.FullName, line); } else { di = di.GetDirectoryAbove(includesearchupdepth); // then search the tree, first jump up search depth amount try { FileInfo[] allFiles = Directory.EnumerateFiles(di.FullName, line, SearchOption.AllDirectories).Select(f => new FileInfo(f)).OrderBy(p => p.LastWriteTime).ToArray(); if (allFiles.Length == 1) { filename = allFiles[0].FullName; } } catch { } } if (filename == null || !lr.Open(filename)) // if no file found, or can't open.. { logger?.WriteLine(string.Format("*** Cannot include {0}", line)); } else { logger?.WriteLine("Read " + filename); } } else if (line.Length > 0 && !line.StartsWith("//")) { StringParser s = new StringParser(line); string id = s.NextWord(" :"); if (id.StartsWith(".") && prefix.HasChars()) { id = prefix + id; } else { prefix = id.Word(new char[] { '.' }); } if (s.IsCharMoveOn(':')) { s.NextQuotedWord(replaceescape: true); // ignore the english for ref purposes only string foreign = null; bool err = false; if (s.IsStringMoveOn("=>")) { foreign = s.NextQuotedWord(replaceescape: true); err = foreign == null; } else if (s.IsCharMoveOn('@')) { foreign = null; } else { err = false; } if (err == true) { logger?.WriteLine(string.Format("*** Translator ID but no translation {0}", id)); System.Diagnostics.Debug.WriteLine("*** Translator ID but no translation {0}", id); } else { if (!translations.ContainsKey(id)) { //logger?.WriteLine(string.Format("New {0}: \"{1}\" => \"{2}\"", id, english, foreign)); translations[id] = foreign; } else { logger?.WriteLine(string.Format("*** Translator Repeat {0}", id)); } } } } } } } }