1 | // Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team |
---|
2 | // |
---|
3 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this |
---|
4 | // software and associated documentation files (the "Software"), to deal in the Software |
---|
5 | // without restriction, including without limitation the rights to use, copy, modify, merge, |
---|
6 | // publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons |
---|
7 | // to whom the Software is furnished to do so, subject to the following conditions: |
---|
8 | // |
---|
9 | // The above copyright notice and this permission notice shall be included in all copies or |
---|
10 | // substantial portions of the Software. |
---|
11 | // |
---|
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, |
---|
13 | // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR |
---|
14 | // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE |
---|
15 | // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR |
---|
16 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
---|
17 | // DEALINGS IN THE SOFTWARE. |
---|
18 | |
---|
19 | using System; |
---|
20 | using System.Linq; |
---|
21 | using System.Xml; |
---|
22 | |
---|
23 | namespace ICSharpCode.AvalonEdit.Highlighting.Xshd |
---|
24 | { |
---|
25 | /// <summary> |
---|
26 | /// Xshd visitor implementation that saves an .xshd file as XML. |
---|
27 | /// </summary> |
---|
28 | public sealed class SaveXshdVisitor : IXshdVisitor |
---|
29 | { |
---|
30 | /// <summary> |
---|
31 | /// XML namespace for XSHD. |
---|
32 | /// </summary> |
---|
33 | public const string Namespace = V2Loader.Namespace; |
---|
34 | |
---|
35 | XmlWriter writer; |
---|
36 | |
---|
37 | /// <summary> |
---|
38 | /// Creates a new SaveXshdVisitor instance. |
---|
39 | /// </summary> |
---|
40 | public SaveXshdVisitor(XmlWriter writer) |
---|
41 | { |
---|
42 | if (writer == null) |
---|
43 | throw new ArgumentNullException("writer"); |
---|
44 | this.writer = writer; |
---|
45 | } |
---|
46 | |
---|
47 | /// <summary> |
---|
48 | /// Writes the specified syntax definition. |
---|
49 | /// </summary> |
---|
50 | public void WriteDefinition(XshdSyntaxDefinition definition) |
---|
51 | { |
---|
52 | if (definition == null) |
---|
53 | throw new ArgumentNullException("definition"); |
---|
54 | writer.WriteStartElement("SyntaxDefinition", Namespace); |
---|
55 | if (definition.Name != null) |
---|
56 | writer.WriteAttributeString("name", definition.Name); |
---|
57 | if (definition.Extensions != null) |
---|
58 | writer.WriteAttributeString("extensions", string.Join(";", definition.Extensions.ToArray())); |
---|
59 | |
---|
60 | definition.AcceptElements(this); |
---|
61 | |
---|
62 | writer.WriteEndElement(); |
---|
63 | } |
---|
64 | |
---|
65 | object IXshdVisitor.VisitRuleSet(XshdRuleSet ruleSet) |
---|
66 | { |
---|
67 | writer.WriteStartElement("RuleSet", Namespace); |
---|
68 | |
---|
69 | if (ruleSet.Name != null) |
---|
70 | writer.WriteAttributeString("name", ruleSet.Name); |
---|
71 | WriteBoolAttribute("ignoreCase", ruleSet.IgnoreCase); |
---|
72 | |
---|
73 | ruleSet.AcceptElements(this); |
---|
74 | |
---|
75 | writer.WriteEndElement(); |
---|
76 | return null; |
---|
77 | } |
---|
78 | |
---|
79 | void WriteBoolAttribute(string attributeName, bool? value) |
---|
80 | { |
---|
81 | if (value != null) { |
---|
82 | writer.WriteAttributeString(attributeName, value.Value ? "true" : "false"); |
---|
83 | } |
---|
84 | } |
---|
85 | |
---|
86 | void WriteRuleSetReference(XshdReference<XshdRuleSet> ruleSetReference) |
---|
87 | { |
---|
88 | if (ruleSetReference.ReferencedElement != null) { |
---|
89 | if (ruleSetReference.ReferencedDefinition != null) |
---|
90 | writer.WriteAttributeString("ruleSet", ruleSetReference.ReferencedDefinition + "/" + ruleSetReference.ReferencedElement); |
---|
91 | else |
---|
92 | writer.WriteAttributeString("ruleSet", ruleSetReference.ReferencedElement); |
---|
93 | } |
---|
94 | } |
---|
95 | |
---|
96 | void WriteColorReference(XshdReference<XshdColor> color) |
---|
97 | { |
---|
98 | if (color.InlineElement != null) { |
---|
99 | WriteColorAttributes(color.InlineElement); |
---|
100 | } else if (color.ReferencedElement != null) { |
---|
101 | if (color.ReferencedDefinition != null) |
---|
102 | writer.WriteAttributeString("color", color.ReferencedDefinition + "/" + color.ReferencedElement); |
---|
103 | else |
---|
104 | writer.WriteAttributeString("color", color.ReferencedElement); |
---|
105 | } |
---|
106 | } |
---|
107 | |
---|
108 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Justification = "The file format requires lowercase, and all possible values are English-only")] |
---|
109 | void WriteColorAttributes(XshdColor color) |
---|
110 | { |
---|
111 | if (color.Foreground != null) |
---|
112 | writer.WriteAttributeString("foreground", color.Foreground.ToString()); |
---|
113 | if (color.Background != null) |
---|
114 | writer.WriteAttributeString("background", color.Background.ToString()); |
---|
115 | if (color.FontWeight != null) |
---|
116 | writer.WriteAttributeString("fontWeight", V2Loader.FontWeightConverter.ConvertToInvariantString(color.FontWeight.Value).ToLowerInvariant()); |
---|
117 | if (color.FontStyle != null) |
---|
118 | writer.WriteAttributeString("fontStyle", V2Loader.FontStyleConverter.ConvertToInvariantString(color.FontStyle.Value).ToLowerInvariant()); |
---|
119 | } |
---|
120 | |
---|
121 | object IXshdVisitor.VisitColor(XshdColor color) |
---|
122 | { |
---|
123 | writer.WriteStartElement("Color", Namespace); |
---|
124 | if (color.Name != null) |
---|
125 | writer.WriteAttributeString("name", color.Name); |
---|
126 | WriteColorAttributes(color); |
---|
127 | if (color.ExampleText != null) |
---|
128 | writer.WriteAttributeString("exampleText", color.ExampleText); |
---|
129 | writer.WriteEndElement(); |
---|
130 | return null; |
---|
131 | } |
---|
132 | |
---|
133 | object IXshdVisitor.VisitKeywords(XshdKeywords keywords) |
---|
134 | { |
---|
135 | writer.WriteStartElement("Keywords", Namespace); |
---|
136 | WriteColorReference(keywords.ColorReference); |
---|
137 | foreach (string word in keywords.Words) { |
---|
138 | writer.WriteElementString("Word", Namespace, word); |
---|
139 | } |
---|
140 | writer.WriteEndElement(); |
---|
141 | return null; |
---|
142 | } |
---|
143 | |
---|
144 | object IXshdVisitor.VisitSpan(XshdSpan span) |
---|
145 | { |
---|
146 | writer.WriteStartElement("Span", Namespace); |
---|
147 | WriteColorReference(span.SpanColorReference); |
---|
148 | if (span.BeginRegexType == XshdRegexType.Default && span.BeginRegex != null) |
---|
149 | writer.WriteAttributeString("begin", span.BeginRegex); |
---|
150 | if (span.EndRegexType == XshdRegexType.Default && span.EndRegex != null) |
---|
151 | writer.WriteAttributeString("end", span.EndRegex); |
---|
152 | WriteRuleSetReference(span.RuleSetReference); |
---|
153 | if (span.Multiline) |
---|
154 | writer.WriteAttributeString("multiline", "true"); |
---|
155 | |
---|
156 | if (span.BeginRegexType == XshdRegexType.IgnorePatternWhitespace) |
---|
157 | WriteBeginEndElement("Begin", span.BeginRegex, span.BeginColorReference); |
---|
158 | if (span.EndRegexType == XshdRegexType.IgnorePatternWhitespace) |
---|
159 | WriteBeginEndElement("End", span.EndRegex, span.EndColorReference); |
---|
160 | |
---|
161 | if (span.RuleSetReference.InlineElement != null) |
---|
162 | span.RuleSetReference.InlineElement.AcceptVisitor(this); |
---|
163 | |
---|
164 | writer.WriteEndElement(); |
---|
165 | return null; |
---|
166 | } |
---|
167 | |
---|
168 | void WriteBeginEndElement(string elementName, string regex, XshdReference<XshdColor> colorReference) |
---|
169 | { |
---|
170 | if (regex != null) { |
---|
171 | writer.WriteStartElement(elementName, Namespace); |
---|
172 | WriteColorReference(colorReference); |
---|
173 | writer.WriteString(regex); |
---|
174 | writer.WriteEndElement(); |
---|
175 | } |
---|
176 | } |
---|
177 | |
---|
178 | object IXshdVisitor.VisitImport(XshdImport import) |
---|
179 | { |
---|
180 | writer.WriteStartElement("Import", Namespace); |
---|
181 | WriteRuleSetReference(import.RuleSetReference); |
---|
182 | writer.WriteEndElement(); |
---|
183 | return null; |
---|
184 | } |
---|
185 | |
---|
186 | object IXshdVisitor.VisitRule(XshdRule rule) |
---|
187 | { |
---|
188 | writer.WriteStartElement("Rule", Namespace); |
---|
189 | WriteColorReference(rule.ColorReference); |
---|
190 | |
---|
191 | writer.WriteString(rule.Regex); |
---|
192 | |
---|
193 | writer.WriteEndElement(); |
---|
194 | return null; |
---|
195 | } |
---|
196 | } |
---|
197 | } |
---|