Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
CodeBlock.cs
1using System;
2using System.Collections.Generic;
3using System.Reflection;
4using System.Threading.Tasks;
5using System.Xml;
7using Waher.Events;
9
11{
15 public class CodeBlock : BlockElement
16 {
17 private ICodeContent handler;
18 private Type handlerType = null;
19 private readonly string[] rows;
20 private readonly string indentString;
21 private readonly string language;
22 private readonly int start, end, indent;
23
32 public CodeBlock(MarkdownDocument Document, string[] Rows, int Start, int End, int Indent)
33 : this(Document, Rows, Start, End, Indent, null)
34 {
35 }
36
46 public CodeBlock(MarkdownDocument Document, string[] Rows, int Start, int End, int Indent, string Language)
47 : base(Document)
48 {
49 this.rows = Rows;
50 this.start = Start;
51 this.end = End;
52 this.indent = Indent;
53 this.indentString = this.indent <= 0 ? string.Empty : new string('\t', this.indent);
54 this.language = Language;
55 }
56
60 public string Language => this.language;
61
65 public string[] Rows => this.rows;
66
71 where T : ICodeContentRenderer
72 {
73 if (this.handlerType is null || this.handlerType != typeof(T))
74 {
75 this.handler = GetCodeBlockHandler<T>(this.language, this.Document.Settings.AllowInlineScript);
76 this.handlerType = typeof(T);
77 }
78
79 return (T)this.handler;
80 }
81
82 private static IXmlVisualizer[] xmlVisualizers = null;
83 private readonly static Dictionary<Type, Dictionary<string, ICodeContentRenderer[]>> codeContentHandlers = new Dictionary<Type, Dictionary<string, ICodeContentRenderer[]>>();
84 private readonly static Dictionary<string, IXmlVisualizer[]> xmlVisualizerHandlers = new Dictionary<string, IXmlVisualizer[]>(StringComparer.CurrentCultureIgnoreCase);
85
86 static CodeBlock()
87 {
88 Init();
89 Types.OnInvalidated += (Sender, e) => Init();
90 }
91
92 private static void Init()
93 {
94 List<ICodeContentRenderer> CodeContents = new List<ICodeContentRenderer>();
95 List<IXmlVisualizer> XmlVisualizers = new List<IXmlVisualizer>();
96
98 {
99 ConstructorInfo CI = Types.GetDefaultConstructor(T);
100 if (CI is null)
101 continue;
102
103 try
104 {
106 CodeContents.Add(CodeContent);
107 }
108 catch (Exception ex)
109 {
110 Log.Exception(ex);
111 }
112 }
113
114 foreach (Type T in Types.GetTypesImplementingInterface(typeof(IXmlVisualizer)))
115 {
116 ConstructorInfo CI = Types.GetDefaultConstructor(T);
117 if (CI is null)
118 continue;
119
120 try
121 {
122 IXmlVisualizer XmlVisualizer = (IXmlVisualizer)CI.Invoke(Types.NoParameters);
123 XmlVisualizers.Add(XmlVisualizer);
124 }
125 catch (Exception ex)
126 {
127 Log.Exception(ex);
128 }
129 }
130
131 lock (codeContentHandlers)
132 {
133 codeContentHandlers.Clear();
134 }
135
136 lock (xmlVisualizerHandlers)
137 {
138 xmlVisualizers = XmlVisualizers.ToArray();
139 xmlVisualizerHandlers.Clear();
140 }
141 }
142
143 internal static T GetCodeBlockHandler<T>(string Language, bool AllowScript)
144 where T : ICodeContentRenderer
145 {
146 ICodeContentRenderer[] Handlers;
147
148 if (string.IsNullOrEmpty(Language))
149 return default;
150
151 lock (codeContentHandlers)
152 {
153 if (!codeContentHandlers.TryGetValue(typeof(T), out Dictionary<string, ICodeContentRenderer[]> PerLanguage))
154 {
155 PerLanguage = new Dictionary<string, ICodeContentRenderer[]>();
156 codeContentHandlers[typeof(T)] = PerLanguage;
157 }
158
159 if (!PerLanguage.TryGetValue(Language, out Handlers))
160 {
161 List<ICodeContentRenderer> List = new List<ICodeContentRenderer>();
162
163 foreach (Type T2 in Types.GetTypesImplementingInterface(typeof(T)))
164 {
165 ConstructorInfo CI = Types.GetDefaultConstructor(T2);
166 if (CI is null)
167 continue;
168
169 try
170 {
171 T CodeContent = (T)CI.Invoke(Types.NoParameters);
172 if (CodeContent.Supports(Language) > Grade.NotAtAll)
173 List.Add(CodeContent);
174 }
175 catch (Exception ex)
176 {
177 Log.Exception(ex);
178 }
179 }
180
181 if (List.Count > 0)
182 Handlers = List.ToArray();
183 else
184 Handlers = null;
185
186 PerLanguage[Language] = Handlers;
187 }
188 }
189
190 if (Handlers is null)
191 return default;
192
193 T Best = default;
194 Grade BestGrade = Grade.NotAtAll;
195 Grade ContentGrade;
196
197 foreach (ICodeContentRenderer Content in Handlers)
198 {
199 ContentGrade = Content.Supports(Language);
200 if (ContentGrade > BestGrade && Content is T TypedContent && (AllowScript || !Content.EvaluatesScript))
201 {
202 BestGrade = ContentGrade;
203 Best = TypedContent;
204 }
205 }
206
207 return Best;
208 }
209
210 internal static IXmlVisualizer GetXmlVisualizerHandler(XmlDocument Xml)
211 {
212 if (Xml is null || Xml.DocumentElement is null)
213 return null;
214
215 IXmlVisualizer[] Handlers;
216 string Key = Xml.DocumentElement.NamespaceURI + "#" + Xml.DocumentElement.LocalName;
217
218 lock (xmlVisualizerHandlers)
219 {
220 if (!xmlVisualizerHandlers.TryGetValue(Key, out Handlers))
221 {
222 List<IXmlVisualizer> List = new List<IXmlVisualizer>();
223
224 foreach (IXmlVisualizer Visualizer in xmlVisualizers)
225 {
226 if (Visualizer.Supports(Xml) > Grade.NotAtAll)
227 List.Add(Visualizer);
228 }
229
230 if (List.Count > 0)
231 Handlers = List.ToArray();
232 else
233 Handlers = null;
234
235 xmlVisualizerHandlers[Key] = Handlers;
236 }
237 }
238
239 if (Handlers is null)
240 return null;
241
242 IXmlVisualizer Best = null;
243 Grade BestGrade = Grade.NotAtAll;
244 Grade VisualizerGrade;
245
246 foreach (IXmlVisualizer Visualizer in Handlers)
247 {
248 VisualizerGrade = Visualizer.Supports(Xml);
249 if (VisualizerGrade > BestGrade)
250 {
251 BestGrade = VisualizerGrade;
252 Best = Visualizer;
253 }
254 }
255
256 return Best;
257 }
258
263 public override Task Render(IRenderer Output) => Output.Render(this);
264
268 public int Indent => this.indent;
269
273 public string IndentString => this.indentString;
274
278 public override bool InlineSpanElement => false;
279
283 public int Start => this.start;
284
288 public int End => this.end;
289
296 public override bool SameMetaData(MarkdownElement E)
297 {
298 return E is CodeBlock x &&
299 this.indent == x.indent &&
300 this.indentString == x.indentString &&
301 this.language == x.language &&
302 AreEqual(this.rows, x.rows) &&
303 base.SameMetaData(E);
304 }
305
311 public override bool Equals(object obj)
312 {
313 return obj is CodeBlock x &&
314 this.indent == x.indent &&
315 this.indentString == x.indentString &&
316 this.language == x.language &&
317 AreEqual(this.rows, x.rows) &&
318 base.Equals(obj);
319 }
320
325 public override int GetHashCode()
326 {
327 int h1 = base.GetHashCode();
328 int h2 = this.indent.GetHashCode();
329
330 h1 = ((h1 << 5) + h1) ^ h2;
331 h2 = this.indentString?.GetHashCode() ?? 0;
332
333 h1 = ((h1 << 5) + h1) ^ h2;
334 h2 = this.language?.GetHashCode() ?? 0;
335
336 h1 = ((h1 << 5) + h1) ^ h2;
337 h2 = GetHashCode(this.rows);
338
339 h1 = ((h1 << 5) + h1) ^ h2;
340
341 return h1;
342 }
343
348 public override void IncrementStatistics(MarkdownStatistics Statistics)
349 {
350 Statistics.NrCodeBlocks++;
351 }
352
353 }
354}
Contains a markdown document. This markdown document class supports original markdown,...
MarkdownSettings Settings
Markdown settings.
bool AllowInlineScript
If inline script is allowed embedded in the Markdown.
Contains some basic statistical information about a Markdown document.
Abstract base class for block elements.
Definition: BlockElement.cs:7
Represents a code block in a markdown document.
Definition: CodeBlock.cs:16
string IndentString
String used for indentation.
Definition: CodeBlock.cs:273
CodeBlock(MarkdownDocument Document, string[] Rows, int Start, int End, int Indent, string Language)
Represents a code block in a markdown document.
Definition: CodeBlock.cs:46
override bool InlineSpanElement
If the element is an inline span element.
Definition: CodeBlock.cs:278
override int GetHashCode()
Serves as the default hash function.
Definition: CodeBlock.cs:325
override Task Render(IRenderer Output)
Renders the element.
override bool SameMetaData(MarkdownElement E)
If the current object has same meta-data as E (but not necessarily same content).
Definition: CodeBlock.cs:296
override bool Equals(object obj)
Determines whether the specified object is equal to the current object.
Definition: CodeBlock.cs:311
override void IncrementStatistics(MarkdownStatistics Statistics)
Increments the property or properties in Statistics corresponding to the element.
Definition: CodeBlock.cs:348
CodeBlock(MarkdownDocument Document, string[] Rows, int Start, int End, int Indent)
Represents a code block in a markdown document.
Definition: CodeBlock.cs:32
Abstract base class for all markdown elements.
MarkdownDocument Document
Markdown document.
static bool AreEqual(Array Items1, Array Items2)
Checks if two typed arrays are equal
Static class managing the application event log. Applications and services log events on this static ...
Definition: Log.cs:13
static void Exception(Exception Exception, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, params KeyValuePair< string, object >[] Tags)
Logs an exception. Event type will be determined by the severity of the exception.
Definition: Log.cs:1647
Static class that dynamically manages types and interfaces available in the runtime environment.
Definition: Types.cs:14
static object[] NoParameters
Contains an empty array of parameter values.
Definition: Types.cs:548
static Type[] GetTypesImplementingInterface(string InterfaceFullName)
Gets all types implementing a given interface.
Definition: Types.cs:84
static ConstructorInfo GetDefaultConstructor(Type Type)
Gets the default constructor of a type, if one exists.
Definition: Types.cs:1630
Interface for all markdown handlers of code content.
Definition: ICodeContent.cs:9
bool EvaluatesScript
If script is evaluated for this type of code block.
Definition: ICodeContent.cs:20
Grade Supports(string Language)
Checks how well the handler supports code content of a given type.
Interface for all XML visalizers.
Interface for Markdown renderers.
Definition: IRenderer.cs:12
Grade
Grade enumeration
Definition: Grade.cs:7