| 0: | // Syntax.cs | |
| 1: | // Copyright (c) 2001 Mike Krueger | |
| 2: | // | |
| 3: | // This program is free software; you can redistribute it and/or modify | |
| 4: | // it under the terms of the GNU General Public License as published by | |
| 5: | // the Free Software Foundation; either version 2 of the License, or | |
| 6: | // (at your option) any later version. | |
| 7: | // | |
| 8: | // This program is distributed in the hope that it will be useful, | |
| 9: | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 10: | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 11: | // GNU General Public License for more details. | |
| 12: | // | |
| 13: | // You should have received a copy of the GNU General Public License | |
| 14: | // along with this program; if not, write to the Free Software | |
| 15: | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 16: | ||
| 17: | using System; | |
| 18: | using System.Drawing; | |
| 19: | using System.Diagnostics; | |
| 20: | using System.Collections.Specialized; | |
| 21: | using System.Collections; | |
| 22: | using System.Globalization; | |
| 23: | using System.IO; | |
| 24: | using System.Reflection; | |
| 25: | using System.Windows.Forms; | |
| 26: | using System.Xml; | |
| 27: | ||
| 28: | using SharpDevelop.Tool.Function; | |
| 29: | ||
| 30: | namespace SharpDevelop.Internal.Text { | |
| 31: | ||
| 32: | public class FontContainer | |
| 33: | { | |
| 34: | static Font defaultfont = null; | |
| 35: | static Font boldfont = null; | |
| 36: | static Font italicfont = null; | |
| 37: | static Font bolditalicfont = null; | |
| 38: | ||
| 39: | public static Font BoldFont { | |
| 40: | get { | |
| 41: | Debug.Assert(boldfont != null, "SharpDevelop.Internal.Text.FontContainer : boldfont == null"); | |
| 42: | return boldfont; | |
| 43: | } | |
| 44: | } | |
| 45: | ||
| 46: | public static Font ItalicFont { | |
| 47: | get { | |
| 48: | Debug.Assert(italicfont != null, "SharpDevelop.Internal.Text.FontContainer : italicfont == null"); | |
| 49: | return italicfont; | |
| 50: | } | |
| 51: | } | |
| 52: | ||
| 53: | public static Font BoldItalicFont { | |
| 54: | get { | |
| 55: | Debug.Assert(bolditalicfont != null, "SharpDevelop.Internal.Text.FontContainer : bolditalicfont == null"); | |
| 56: | return bolditalicfont; | |
| 57: | } | |
| 58: | } | |
| 59: | ||
| 60: | public static Font DefaultFont { | |
| 61: | get { | |
| 62: | if(defaultfont == null) | |
| 63: | DefaultFont = new Font("Courier New", 10); | |
| 64: | ||
| 65: | return defaultfont; | |
| 66: | } | |
| 67: | set { | |
| 68: | defaultfont = value; | |
| 69: | boldfont = new Font(defaultfont, FontStyle.Bold); | |
| 70: | italicfont = new Font(defaultfont, FontStyle.Italic); | |
| 71: | bolditalicfont = new Font(defaultfont, FontStyle.Bold | FontStyle.Italic); | |
| 72: | } | |
| 73: | } | |
| 74: | ||
| 75: | public static void LoadFonts() | |
| 76: | { | |
| 77: | // defaultfont = SharpDevelop.Tool.Data.Option.GetProperty("SharpDevelop.Internal.Text.FontContainer.DefaultFont", new Font("Courier New", 10)); | |
| 78: | } | |
| 79: | } | |
| 80: | ||
| 81: | public class SyntaxColor | |
| 82: | { | |
| 83: | Color color; | |
| 84: | Color backgroundcolor = System.Drawing.Color.WhiteSmoke; | |
| 85: | bool bold = false; | |
| 86: | bool italic = false; | |
| 87: | string name = ""; | |
| 88: | ||
| 89: | public static Color ParseColor(string c) | |
| 90: | { | |
| 91: | int a = 255; | |
| 92: | int offset = 0; | |
| 93: | if (c.Length > 7) { | |
| 94: | offset = 2; | |
| 95: | a = Int32.Parse(c.Substring(1,2), NumberStyles.HexNumber); | |
| 96: | } | |
| 97: | ||
| 98: | int r = Int32.Parse(c.Substring(1 + offset,2), NumberStyles.HexNumber); | |
| 99: | int g = Int32.Parse(c.Substring(3 + offset,2), NumberStyles.HexNumber); | |
| 100: | int b = Int32.Parse(c.Substring(5 + offset,2), NumberStyles.HexNumber); | |
| 101: | return Color.FromArgb(a, r, g, b); | |
| 102: | } | |
| 103: | ||
| 104: | public SyntaxColor(XmlElement el) | |
| 105: | { | |
| 106: | Debug.Assert(el != null, "SharpDevelop.Internal.Text.SyntaxColor(XmlElement el) : el == null"); | |
| 107: | if (el.Attributes["Name"] != null) | |
| 108: | name = el.Attributes["Name"].InnerText; | |
| 109: | ||
| 110: | if (el.Attributes["Bold"] != null) | |
| 111: | bold = Boolean.Parse(el.Attributes["Bold"].InnerText); | |
| 112: | ||
| 113: | if (el.Attributes["Italic"] != null) | |
| 114: | italic = Boolean.Parse(el.Attributes["Italic"].InnerText); | |
| 115: | ||
| 116: | if (el.Attributes["Color"] != null) { | |
| 117: | string c = el.Attributes["Color"].InnerText; | |
| 118: | if (c[0] == '#') { | |
| 119: | color = ParseColor(c); | |
| 120: | } else | |
| 121: | color = (Color)(Color.GetType()).InvokeMember(c, BindingFlags.GetProperty, null, Color, new object[0]); | |
| 122: | } else { | |
| 123: | color = Color.Transparent; // to set it to the default value. | |
| 124: | } | |
| 125: | ||
| 126: | if (el.Attributes["BackgroundColor"] != null) { | |
| 127: | string c = el.Attributes["BackgroundColor"].InnerText; | |
| 128: | if (c[0] == '#') { | |
| 129: | backgroundcolor = ParseColor(c); | |
| 130: | } else { | |
| 131: | backgroundcolor = (Color)(Color.GetType()).InvokeMember(c, BindingFlags.GetProperty, null, Color, new object[0]); | |
| 132: | } | |
| 133: | } | |
| 134: | } | |
| 135: | ||
| 136: | public SyntaxColor(Color color, bool bold, bool italic) | |
| 137: | { | |
| 138: | this.color = color; | |
| 139: | this.bold = bold; | |
| 140: | this.italic = italic; | |
| 141: | } | |
| 142: | ||
| 143: | public string Name { | |
| 144: | get { | |
| 145: | return name; | |
| 146: | } | |
| 147: | } | |
| 148: | ||
| 149: | public bool Bold { | |
| 150: | get { | |
| 151: | return bold; | |
| 152: | } | |
| 153: | set { | |
| 154: | bold = value; | |
| 155: | } | |
| 156: | } | |
| 157: | ||
| 158: | public bool Italic { | |
| 159: | get { | |
| 160: | return italic; | |
| 161: | } | |
| 162: | set { | |
| 163: | italic = value; | |
| 164: | } | |
| 165: | } | |
| 166: | public Color BackgroundColor { | |
| 167: | get { | |
| 168: | return backgroundcolor; | |
| 169: | } | |
| 170: | set { | |
| 171: | backgroundcolor = value; | |
| 172: | } | |
| 173: | } | |
| 174: | public Color Color { | |
| 175: | get { | |
| 176: | return color; | |
| 177: | } | |
| 178: | set { | |
| 179: | color = value; | |
| 180: | } | |
| 181: | } | |
| 182: | ||
| 183: | public Font Font { | |
| 184: | get { | |
| 185: | if (Bold) { | |
| 186: | return Italic ? FontContainer.BoldItalicFont : FontContainer.BoldFont; | |
| 187: | } | |
| 188: | return Italic ? FontContainer.ItalicFont :FontContainer.DefaultFont; | |
| 189: | } | |
| 190: | } | |
| 191: | } | |
| 192: | ||
| 193: | public class Span | |
| 194: | { | |
| 195: | public bool StopEOL; | |
| 196: | public SyntaxColor Color; | |
| 197: | public string Begin = null; | |
| 198: | public string End = null; | |
| 199: | public string Name = null; | |
| 200: | public string Rule = null; | |
| 201: | public bool NoEscapeSequences = false; | |
| 202: | ||
| 203: | public Span(XmlElement span) | |
| 204: | { | |
| 205: | Color = new SyntaxColor(span); | |
| 206: | ||
| 207: | if (span.Attributes["Rule"] != null) { | |
| 208: | Rule = span.Attributes["Rule"].InnerText; | |
| 209: | } | |
| 210: | if (span.Attributes["NoEscapeSequences"] != null) { | |
| 211: | NoEscapeSequences = Boolean.Parse(span.Attributes["NoEscapeSequences"].InnerText); | |
| 212: | } | |
| 213: | ||
| 214: | Name = span.Attributes["Name"].InnerText; | |
| 215: | StopEOL = Boolean.Parse(span.Attributes["StopAtEol"].InnerText); | |
| 216: | Begin = span["Begin"].InnerText; | |
| 217: | if (span["End"] != null) | |
| 218: | End = span["End"].InnerText; | |
| 219: | } | |
| 220: | } | |
| 221: | ||
| 222: | public class PrevMarker | |
| 223: | { | |
| 224: | public string What; | |
| 225: | public SyntaxColor Color; | |
| 226: | public bool MarkMarker = false; | |
| 227: | ||
| 228: | public PrevMarker(XmlElement mark) | |
| 229: | { | |
| 230: | Color = new SyntaxColor(mark); | |
| 231: | What = mark.InnerText; | |
| 232: | if (mark.Attributes["MarkMarker"] != null) { | |
| 233: | MarkMarker = Boolean.Parse(mark.Attributes["MarkMarker"].InnerText); | |
| 234: | } | |
| 235: | } | |
| 236: | } | |
| 237: | ||
| 238: | public class NextMarker | |
| 239: | { | |
| 240: | public string What; | |
| 241: | public SyntaxColor Color; | |
| 242: | public bool MarkMarker = false; | |
| 243: | ||
| 244: | public NextMarker(XmlElement mark) | |
| 245: | { | |
| 246: | Color = new SyntaxColor(mark); | |
| 247: | What = mark.InnerText; | |
| 248: | if (mark.Attributes["MarkMarker"] != null) { | |
| 249: | MarkMarker = Boolean.Parse(mark.Attributes["MarkMarker"].InnerText); | |
| 250: | } | |
| 251: | } | |
| 252: | } | |
| 253: | ||
| 254: | public class RuleSet | |
| 255: | { | |
| 256: | public LookupTable KeyWords; | |
| 257: | public ArrayList Spans = new ArrayList(); | |
| 258: | public LookupTable PrevMarkers; | |
| 259: | public LookupTable NextMarkers; | |
| 260: | public bool NoEscapeSequences = false; | |
| 261: | ||
| 262: | public bool IgnoreCase = false; | |
| 263: | string name = null; | |
| 264: | ||
| 265: | public bool[] Delimeters = new bool[256]; | |
| 266: | ||
| 267: | public string Reference = null; | |
| 268: | ||
| 269: | public string Name { | |
| 270: | get { | |
| 271: | return name; | |
| 272: | } | |
| 273: | set { | |
| 274: | name = value; | |
| 275: | } | |
| 276: | } | |
| 277: | ||
| 278: | public RuleSet(XmlElement el) | |
| 279: | { | |
| 280: | XmlNodeList nodes = el.GetElementsByTagName("KeyWords"); | |
| 281: | ||
| 282: | if (el.Attributes["Name"] != null) | |
| 283: | Name = el.Attributes["Name"].InnerText; | |
| 284: | ||
| 285: | if (el.Attributes["NoEscapeSequences"] != null) { | |
| 286: | NoEscapeSequences = Boolean.Parse(el.Attributes["NoEscapeSequences"].InnerText); | |
| 287: | } | |
| 288: | ||
| 289: | if (el.Attributes["Reference"] != null) | |
| 290: | Reference = el.Attributes["Reference"].InnerText; | |
| 291: | ||
| 292: | if (el.Attributes["IgnoreCase"] != null) | |
| 293: | IgnoreCase = Boolean.Parse(el.Attributes["IgnoreCase"].InnerText); | |
| 294: | ||
| 295: | for (int i = 0; i < Delimeters.Length; ++i) { | |
| 296: | Delimeters[i] = false; | |
| 297: | } | |
| 298: | if (el["Delimeters"] != null) { | |
| 299: | string del = el["Delimeters"].InnerText; | |
| 300: | foreach (char ch in del) { | |
| 301: | Delimeters[(int)ch] = true; | |
| 302: | } | |
| 303: | } | |
| 304: | ||
| 305: | // Spans = new LookupTable(!IgnoreCase); | |
| 306: | ||
| 307: | KeyWords = new LookupTable(!IgnoreCase); | |
| 308: | PrevMarkers = new LookupTable(!IgnoreCase); | |
| 309: | NextMarkers = new LookupTable(!IgnoreCase); | |
| 310: | ||
| 311: | ||
| 312: | foreach (XmlElement el2 in nodes) { | |
| 313: | SyntaxColor color = new SyntaxColor(el2); | |
| 314: | XmlNodeList keys = el2.GetElementsByTagName("Key"); | |
| 315: | foreach (XmlElement node in keys) { | |
| 316: | KeyWords[node.Attributes["Word"].InnerText] = color; | |
| 317: | } | |
| 318: | } | |
| 319: | ||
| 320: | nodes = el.GetElementsByTagName("Span"); | |
| 321: | foreach (XmlElement el2 in nodes) { | |
| 322: | Spans.Add(new Span(el2)); | |
| 323: | /* | |
| 324: | Span span = new Span(el2); | |
| 325: | Spans[span.Begin] = span;*/ | |
| 326: | } | |
| 327: | ||
| 328: | nodes = el.GetElementsByTagName("MarkPrevious"); | |
| 329: | foreach (XmlElement el2 in nodes) { | |
| 330: | PrevMarker prev = new PrevMarker(el2); | |
| 331: | PrevMarkers[prev.What] = prev; | |
| 332: | } | |
| 333: | ||
| 334: | nodes = el.GetElementsByTagName("MarkFollowing"); | |
| 335: | foreach (XmlElement el2 in nodes) { | |
| 336: | NextMarker next = new NextMarker(el2); | |
| 337: | NextMarkers[next.What] = next; | |
| 338: | } | |
| 339: | } | |
| 340: | } | |
| 341: | ||
| 342: | public class Syntax | |
| 343: | { | |
| 344: | public ArrayList Rules = new ArrayList(); | |
| 345: | public Hashtable Properties = new Hashtable(); | |
| 346: | ||
| 347: | public SyntaxColor defaultColor; | |
| 348: | ||
| 349: | public SyntaxColor CaretColor = null; | |
| 350: | public SyntaxColor SelectionColor = null; | |
| 351: | public SyntaxColor HRulerColor = null; | |
| 352: | public SyntaxColor SpaceMarkerColor = null; | |
| 353: | public SyntaxColor TabMarkerColor = null; | |
| 354: | public SyntaxColor InvalidLineColor = null; | |
| 355: | public SyntaxColor LineNumberColor = null; | |
| 356: | public SyntaxColor EolMarkerColor = null; | |
| 357: | public SyntaxColor digitColor = null; | |
| 358: | public SyntaxColor BookmarkColor = null; | |
| 359: | public SyntaxColor CaretmarkerColor = null; | |
| 360: | public SyntaxColor FoldLine = null; | |
| 361: | public SyntaxColor FoldMarker = null; | |
| 362: | ||
| 363: | public Color BackgroundColor; | |
| 364: | public string Name; | |
| 365: | ||
| 366: | public bool DoIndent; | |
| 367: | public string[] Extensions; | |
| 368: | public bool DefaultSyntax = false; | |
| 369: | ||
| 370: | public static Syntax[] SyntaxDefinitions; | |
| 371: | ||
| 372: | public static void LoadSyntaxDefinitions() | |
| 373: |