public void Do(TextReader sr, bool doColour, bool resolveReferences, TextWriter writer) { if (doColour) { tb = svc.tb; this.doColour = doColour; } bool generateOutput = false; if (writer != null) { // if we are generating output, then force references to be resolved resolveReferences = true; generateOutput = true; } while ((line = sr.ReadLine()) != null) { linenum++; // syntax colour comments int commentidx = line.IndexOf(';'); if (commentidx >= 0) { if (doColour) tb.GetRange(new Place(commentidx, linenum), new Place(line.Length, linenum)).SetStyle(svc.commentStyle); line = line.Substring(0, commentidx); } // trim line TrimLine(true); // if nothing left, skip line if (line.Length == 0) continue; // termination if (IsCommand("$end", svc.preprocStyle)) { // terminate further processing and colour as a comment if (doColour) tb.GetRange(new Place(linestart, linenum), tb.Range.End).SetStyle(svc.commentStyle); break; } // include file if (IsCommand("$include", svc.preprocStyle)) { ColourToEnd(0, svc.linkStyle); if (resolveReferences) { string filename = svc.ResolveIncludeFile(line); if (filename == null) { // doesn't exist ColourToEnd(0, svc.wavyError); } else { // open included file and process it var psub = new Processing(svc); psub.processingFilename = filename; using (var subreader = new StreamReader(filename)) { psub.Do(subreader, false, true, writer); } } } continue; } // print line if (IsCommand("$print", svc.preprocStyle)) { if (generateOutput) writer.WriteLine(line); continue; } // tlpd line if (line.StartsWith("[tlpd#")) { int endidx; TlpdEntity entity = Tlpd.Parse(line, false, out endidx); if (endidx > 0) { ColourLength(0, endidx, svc.linkTlpdStyle); if (!entity.IsValid || string.IsNullOrWhiteSpace(entity.Name)) ColourLength(0, endidx, svc.wavyError); switch (entity.Type) { case TlpdEntityType.Map: svc.maps[entity.Name] = entity; break; case TlpdEntityType.Player: svc.players[entity.Name] = entity; break; } } if (endidx < line.Length) Colour(endidx, line.Length, svc.wavyError); continue; } // map line if (IsCommand("$map", svc.entityStyle)) { if (!line.Contains("=")) { ErrorLine("Syntax error: Try '$map name = [tlpd#maps#000#db]' instead."); continue; } // $map Name = [tlpd#] int equalsidx = line.IndexOf("="); string name = line.Substring(0, equalsidx); string tlpd = line.Substring(equalsidx + 1); int namestart, nameend; name = name.Trim(out namestart, out nameend); if (resolveReferences) { if (svc.maps.ContainsKey(name)) Colour(namestart, nameend, svc.wavyRedefined); } int tlpdstart, tlpdend; tlpd = tlpd.Trim(out tlpdstart, out tlpdend); int endidx; TlpdEntity entity = Tlpd.Parse(tlpd, true, out endidx); if (endidx > 0) { ColourLength(equalsidx + 1 + tlpdstart, endidx, svc.linkTlpdStyle); if (entity.Type == TlpdEntityType.Map) { entity.Name = name; svc.maps[entity.Name] = entity; } else { ColourLength(equalsidx + 1 + tlpdstart, endidx, svc.wavyError); } } if (endidx < line.Length) Colour(equalsidx + 1 + tlpdstart + endidx, line.Length - 1, svc.wavyError); //if (resolveReferences) //{ // svc.maps[name] = Tlpd.Parse(tlpd); // Colour(namestart, nameend, svc.mapStyle); //} continue; } // player line if (IsCommand("$player", svc.entityStyle)) { if (!line.Contains("=")) { ErrorLine("Syntax error: Try '$player name = [tlpd#players#0#T#db]' instead."); continue; } // $map Name = [tlpd#] int equalsidx = line.IndexOf("="); string name = line.Substring(0, equalsidx); string tlpd = line.Substring(equalsidx + 1); int namestart, nameend; name = name.Trim(out namestart, out nameend); if (resolveReferences) { if (svc.players.ContainsKey(name)) Colour(namestart, nameend, svc.wavyRedefined); } int tlpdstart, tlpdend; tlpd = tlpd.Trim(out tlpdstart, out tlpdend); int endidx; TlpdEntity entity = Tlpd.Parse(tlpd, true, out endidx); if (endidx > 0) { ColourLength(equalsidx + 1 + tlpdstart, endidx, svc.linkTlpdStyle); if (entity.Type == TlpdEntityType.Player) { entity.Name = name; svc.players[entity.Name] = entity; } else { ColourLength(equalsidx + 1 + tlpdstart, endidx, svc.wavyError); } } if (endidx < line.Length) Colour(equalsidx + 1 + tlpdstart + endidx, line.Length - 1, svc.wavyError); //if (resolveReferences) //{ // svc.players[name] = Tlpd.Parse(tlpd); // Colour(namestart, nameend, ColourPlayer(svc.players[name])); //} continue; } // series line if (IsCommand("$series", svc.seriesStyle)) { svc.seriesOrder.Clear(); int startidx = 0; while (startidx < line.Length) { int idx = line.IndexOf(",", startidx); if (idx < 0) idx = line.Length; string map = line.Substring(startidx, idx - startidx); int mapstart, mapend; map = map.Trim(out mapstart, out mapend); svc.seriesOrder.Add(map); if (resolveReferences) { if (!svc.maps.ContainsKey(map)) Colour(startidx + mapstart, startidx + mapend, svc.wavyUndefined); else Colour(startidx + mapstart, startidx + mapend, svc.mapStyle); } startidx = idx + 1; } continue; } // winner > loser : map // winner < loser : map if (line.Contains(":")) { int colonidx = line.IndexOf(":"); string players = line.Substring(0, colonidx); string map = line.Substring(colonidx + 1); Colour(colonidx, colonidx, svc.operatorStyle); int mapstart, mapend; map = map.Trim(out mapstart, out mapend); if (resolveReferences) { if (!svc.maps.ContainsKey(map)) Colour(colonidx + 1 + mapstart, colonidx + 1 + mapend, svc.wavyUndefined); else Colour(colonidx + 1 + mapstart, colonidx + 1 + mapend, svc.mapStyle); } int playersstart, playersend; players = players.Trim(out playersstart, out playersend); int arrowidx = 0; bool leftwinner; if (players.Contains(">")) { arrowidx = players.IndexOf(">"); leftwinner = true; } else if (players.Contains("<")) { arrowidx = players.IndexOf("<"); leftwinner = false; } else { Error(playersstart, playersend, "No winner specified."); continue; } string left = players.Substring(0, arrowidx); string right = players.Substring(arrowidx + 1); Colour(arrowidx, arrowidx, svc.operatorStyle); int leftstart, leftend; left = left.Trim(out leftstart, out leftend); if (resolveReferences) { if (!svc.players.ContainsKey(left)) Colour(leftstart, leftend, svc.wavyUndefined); else Colour(leftstart, leftend, ColourPlayer(svc.players[left])); } int rightstart, rightend; right = right.Trim(out rightstart, out rightend); if (resolveReferences) { if (!svc.players.ContainsKey(right)) Colour(arrowidx + 1 + rightstart, arrowidx + 1 + rightend, svc.wavyUndefined); else Colour(arrowidx + 1 + rightstart, arrowidx + 1 + rightend, ColourPlayer(svc.players[right])); } if (generateOutput) WriteGame(writer, left, right, map, leftwinner); continue; } // map @ winner loser if (line.Contains("@")) { int atidx = line.IndexOf("@"); string map = line.Substring(0, atidx); string players = line.Substring(atidx + 1); Colour(atidx, atidx, svc.operatorStyle); int mapstart, mapend; map = map.Trim(out mapstart, out mapend); if (resolveReferences) { if (!svc.maps.ContainsKey(map)) Colour(mapstart, mapend, svc.wavyUndefined); else Colour(mapstart, mapend, svc.mapStyle); } int playersstart, playersend; players = players.Trim(out playersstart, out playersend); line = line.Substring(atidx + 1 + playersstart); linestart += atidx + 1 + playersstart; int spaceidx = players.IndexOf(" "); if (spaceidx < 0) { Error(playersstart, playersend, "No winner specified."); continue; } string left = players.Substring(0, spaceidx); string right = players.Substring(spaceidx + 1); int leftstart, leftend; left = left.Trim(out leftstart, out leftend); if (resolveReferences) { if (!svc.players.ContainsKey(left)) Colour(leftstart, leftend, svc.wavyUndefined); else Colour(leftstart, leftend, ColourPlayer(svc.players[left])); } int rightstart, rightend; right = right.Trim(out rightstart, out rightend); if (resolveReferences) { if (!svc.players.ContainsKey(right)) Colour(spaceidx + 1 + rightstart, spaceidx + 1 + rightend, svc.wavyUndefined); else Colour(spaceidx + 1 + rightstart, spaceidx + 1 + rightend, ColourPlayer(svc.players[right])); } if (generateOutput) WriteGame(writer, left, right, map); continue; } // 2-0 left right if (line.Contains("-")) { int atidx = line.IndexOf(" "); if (atidx < 0) { ErrorLine("Syntax error"); continue; } string score = line.Substring(0, atidx); string players = line.Substring(atidx + 1); Colour(atidx, atidx, svc.operatorStyle); int scorestart, scoreend; score = score.Trim(out scorestart, out scoreend); // parse scores int dashidx = score.IndexOf("-"); if (dashidx < 0) { ErrorLine("Syntax error"); continue; } int scoreleft, scoreright; bool errorfree = true; if (!int.TryParse(score.Substring(0, dashidx), out scoreleft)) { Error(scorestart, scorestart + dashidx - 1, "Error"); errorfree = false; } if (!int.TryParse(score.Substring(dashidx + 1), out scoreright)) { Error(scorestart + dashidx + 1, scoreend, "Error"); errorfree = false; } Colour(scorestart + dashidx, scorestart + dashidx, svc.operatorStyle); if (errorfree) { Colour(scorestart, scorestart + dashidx - 1, (scoreleft > scoreright) ? svc.winnerStyle : svc.loserStyle); Colour(scorestart + dashidx + 1, scoreend, (scoreleft < scoreright) ? svc.winnerStyle : svc.loserStyle); } // parse players int playersstart, playersend; players = players.Trim(out playersstart, out playersend); line = line.Substring(atidx + 1 + playersstart); linestart += atidx + 1 + playersstart; int spaceidx = players.IndexOf(" "); if (spaceidx < 0) { Error(playersstart, playersend, "No winner specified."); continue; } string left = players.Substring(0, spaceidx); string right = players.Substring(spaceidx + 1); int leftstart, leftend; left = left.Trim(out leftstart, out leftend); if (resolveReferences) { if (!svc.players.ContainsKey(left)) Colour(leftstart, leftend, svc.wavyUndefined); else Colour(leftstart, leftend, ColourPlayer(svc.players[left])); } int rightstart, rightend; right = right.Trim(out rightstart, out rightend); if (resolveReferences) { if (!svc.players.ContainsKey(right)) Colour(spaceidx + 1 + rightstart, spaceidx + 1 + rightend, svc.wavyUndefined); else Colour(spaceidx + 1 + rightstart, spaceidx + 1 + rightend, ColourPlayer(svc.players[right])); } if (generateOutput) { bool alternate = (scoreleft > scoreright); int mapsdone = 0; while (scoreleft + scoreright > 0) { bool leftwinner = true; if (alternate) leftwinner = (scoreleft > 0); else leftwinner = !(scoreright > 0); alternate = !alternate; if (leftwinner) scoreleft--; else scoreright--; string map = ""; if (mapsdone < svc.seriesOrder.Count) map = svc.seriesOrder[mapsdone]; mapsdone++; WriteGame(writer, left, right, map, leftwinner); } } continue; } // wlw winner loser int satidx = line.IndexOf(" "); if (satidx >= 0) { string score = line.Substring(0, satidx); string players = line.Substring(satidx + 1); int scorestart, scoreend; score = score.Trim(out scorestart, out scoreend); // parse scores bool[] leftwinner = new bool[score.Length]; bool errorfree = true; for (int i = 0; i < score.Length; i++) { char c = score[i]; if (c == 'w' || c == 'W') { leftwinner[i] = true; } else if (c == 'l' || c == 'L') { leftwinner[i] = false; } else { errorfree = false; break; } } if (!errorfree) { ErrorLine("Syntax error"); continue; } for (int i = 0; i < score.Length; i++) { ColourLength(scorestart + i, 1, leftwinner[i] ? svc.winnerStyle : svc.loserStyle); } // parse players int playersstart, playersend; players = players.Trim(out playersstart, out playersend); line = line.Substring(satidx + 1 + playersstart); linestart += satidx + 1 + playersstart; int spaceidx = players.IndexOf(" "); if (spaceidx < 0) { Error(playersstart, playersend, "No winner specified."); continue; } string left = players.Substring(0, spaceidx); string right = players.Substring(spaceidx + 1); int leftstart, leftend; left = left.Trim(out leftstart, out leftend); if (resolveReferences) { if (!svc.players.ContainsKey(left)) Colour(leftstart, leftend, svc.wavyUndefined); else Colour(leftstart, leftend, ColourPlayer(svc.players[left])); } int rightstart, rightend; right = right.Trim(out rightstart, out rightend); if (resolveReferences) { if (!svc.players.ContainsKey(right)) Colour(spaceidx + 1 + rightstart, spaceidx + 1 + rightend, svc.wavyUndefined); else Colour(spaceidx + 1 + rightstart, spaceidx + 1 + rightend, ColourPlayer(svc.players[right])); } if (generateOutput) { int mapsdone = 0; for (int i = 0; i < leftwinner.Length; i++) { string map = ""; if (mapsdone < svc.seriesOrder.Count) map = svc.seriesOrder[mapsdone]; mapsdone++; WriteGame(writer, left, right, map, leftwinner[i]); } } continue; } // unrecognised line ErrorLine("unrecognised command"); } }
public void Colourize(bool resolveReferences) { if (resolveReferences) tb.ClearStyle(FastColoredTextBoxNS.StyleIndex.All); else tb.ClearStyle(tb.GetStyleIndexMask(new Style[] { preprocStyle, linkStyle, commentStyle })); players.Clear(); maps.Clear(); seriesOrder.Clear(); var p = new Processing(this); using (var sr = new StringReader(tb.Text)) { p.Do(sr, true, resolveReferences, null); } }
public string Process() { players.Clear(); maps.Clear(); unknownPlayers.Clear(); unknownMaps.Clear(); seriesOrder.Clear(); var p = new Processing(this); using (var sr = new StringReader(tb.Text)) using (var sw = new StringWriter()) { p.Do(sr, false, true, sw); using (var headerWriter = new StringWriter()) { if (unknownMaps.Count > 0) { headerWriter.WriteLine("; unknown maps"); int maxlength = (from map in unknownMaps select map.Length).Max(); foreach (string map in unknownMaps) headerWriter.WriteLine("$map {0} = {1}", map.PadRight(maxlength, ' '), map); headerWriter.WriteLine(); } if (unknownPlayers.Count > 0) { headerWriter.WriteLine("; unknown players"); int maxlength = (from player in unknownPlayers select player.Length).Max(); foreach (string player in unknownPlayers) headerWriter.WriteLine("$player {0} = {1}", player.PadRight(maxlength, ' '), player); headerWriter.WriteLine(); } headerWriter.WriteLine(sw.ToString()); return headerWriter.ToString(); } } }