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;
3using System.Reflection;
4using System.Threading.Tasks;
5using System.Xml;
7using Waher.Events;
10
12{
16 public class CodeBlock : BlockElement
17 {
18 private ICodeContent handler;
19 private Type handlerType = null;
20 private readonly string[] rows;
21 private readonly string indentString;
22 private readonly string language;
23 private readonly int start, end, indent;
24
33 public CodeBlock(MarkdownDocument Document, string[] Rows, int Start, int End, int Indent)
34 : this(Document, Rows, Start, End, Indent, null)
35 {
36 }
37
47 public CodeBlock(MarkdownDocument Document, string[] Rows, int Start, int End, int Indent, string Language)
48 : base(Document)
49 {
50 this.rows = Rows;
51 this.start = Start;
52 this.end = End;
53 this.indent = Indent;
54 this.indentString = JSON.IndentString(this.indent);
55 this.language = Language;
56 }
57
61 public string Language => this.language;
62
66 public string[] Rows => this.rows;
67
72 where T : ICodeContentRenderer
73 {
74 if (this.handlerType is null || this.handlerType != typeof(T))
75 {
76 this.handler = GetCodeBlockHandler<T>(this.language, this.Document.Settings.AllowInlineScript);
77 this.handlerType = typeof(T);
78 }
79
80 return (T)this.handler;
81 }
82
83 private static IXmlVisualizer[] xmlVisualizers = null;
84 private readonly static Dictionary<Type, Dictionary<string, ICodeContentRenderer[]>> codeContentHandlers = new Dictionary<Type, Dictionary<string, ICodeContentRenderer[]>>();
85 private readonly static Dictionary<string, IXmlVisualizer[]> xmlVisualizerHandlers = new Dictionary<string, IXmlVisualizer[]>(StringComparer.CurrentCultureIgnoreCase);
86
87 static CodeBlock()
88 {
89 Init();
90 Types.OnInvalidated += (Sender, e) => Init();
91 }
92
93 private static void Init()
94 {
97
99 {
100 ConstructorInfo CI = Types.GetDefaultConstructor(T);
101 if (CI is null)
102 continue;
103
104 try
105 {
107 CodeContents.Add(CodeContent);
108 }
109 catch (Exception ex)
110 {
111 Log.Exception(ex);
112 }
113 }
114
115 foreach (Type T in Types.GetTypesImplementingInterface(typeof(IXmlVisualizer)))
116 {
117 ConstructorInfo CI = Types.GetDefaultConstructor(T);
118 if (CI is null)
119 continue;
120
121 try
122 {
123 IXmlVisualizer XmlVisualizer = (IXmlVisualizer)CI.Invoke(Types.NoParameters);
124 XmlVisualizers.Add(XmlVisualizer);
125 }
126 catch (Exception ex)
127 {
128 Log.Exception(ex);
129 }
130 }
131
132 lock (codeContentHandlers)
133 {
134 codeContentHandlers.Clear();
135 }
136
137 lock (xmlVisualizerHandlers)
138 {
139 xmlVisualizers = XmlVisualizers.ToArray();
140 xmlVisualizerHandlers.Clear();
141 }
142 }
143
144 internal static T GetCodeBlockHandler<T>(string Language, bool AllowScript)
145 where T : ICodeContentRenderer
146 {
147 ICodeContentRenderer[] Handlers;
148
149 if (string.IsNullOrEmpty(Language))
150 return default;
151
152 lock (codeContentHandlers)
153 {
154 if (!codeContentHandlers.TryGetValue(typeof(T), out Dictionary<string, ICodeContentRenderer[]> PerLanguage))
155 {
156 PerLanguage = new Dictionary<string, ICodeContentRenderer[]>();
157 codeContentHandlers[typeof(T)] = PerLanguage;
158 }
159
160 if (!PerLanguage.TryGetValue(Language, out Handlers))
161 {
163
164 foreach (Type T2 in Types.GetTypesImplementingInterface(typeof(T)))
165 {
166 ConstructorInfo CI = Types.GetDefaultConstructor(T2);
167 if (CI is null)
168 continue;
169
170 try
171 {
172 T CodeContent = (T)CI.Invoke(Types.NoParameters);
173 if (CodeContent.Supports(Language) > Grade.NotAtAll)
174 List.Add(CodeContent);
175 }
176 catch (Exception ex)
177 {
178 Log.Exception(ex);
179 }
180 }
181
182 if (List.Count > 0)
183 Handlers = List.ToArray();
184 else
185 Handlers = null;
186
187 PerLanguage[Language] = Handlers;
188 }
189 }
190
191 if (Handlers is null)
192 return default;
193
194 T Best = default;
195 Grade BestGrade = Grade.NotAtAll;
196 Grade ContentGrade;
197
198 foreach (ICodeContentRenderer Content in Handlers)
199 {
200 ContentGrade = Content.Supports(Language);
201 if (ContentGrade > BestGrade && Content is T TypedContent && (AllowScript || !Content.EvaluatesScript))
202 {
203 BestGrade = ContentGrade;
204 Best = TypedContent;
205 }
206 }
207
208 return Best;
209 }
210
216 public static IXmlVisualizer GetXmlVisualizerHandler(XmlDocument Xml)
217 {
218 if (Xml is null || Xml.DocumentElement is null)
219 return null;
220
221 IXmlVisualizer[] Handlers;
222 string Key = Xml.DocumentElement.NamespaceURI + "#" + Xml.DocumentElement.LocalName;
223
224 lock (xmlVisualizerHandlers)
225 {
226 if (!xmlVisualizerHandlers.TryGetValue(Key, out Handlers))
227 {
229
230 foreach (IXmlVisualizer Visualizer in xmlVisualizers)
231 {
232 if (Visualizer.Supports(Xml) > Grade.NotAtAll)
233 List.Add(Visualizer);
234 }
235
236 if (List.Count > 0)
237 Handlers = List.ToArray();
238 else
239 Handlers = null;
240
241 xmlVisualizerHandlers[Key] = Handlers;
242 }
243 }
244
245 if (Handlers is null)
246 return null;
247
248 IXmlVisualizer Best = null;
249 Grade BestGrade = Grade.NotAtAll;
250 Grade VisualizerGrade;
251
252 foreach (IXmlVisualizer Visualizer in Handlers)
253 {
254 VisualizerGrade = Visualizer.Supports(Xml);
255 if (VisualizerGrade > BestGrade)
256 {
257 BestGrade = VisualizerGrade;
258 Best = Visualizer;
259 }
260 }
261
262 return Best;
263 }
264
269 public override Task Render(IRenderer Output) => Output.Render(this);
270
274 public int Indent => this.indent;
275
279 public string IndentString => this.indentString;
280
284 public override bool InlineSpanElement => false;
285
289 public int Start => this.start;
290
294 public int End => this.end;
295
302 public override bool SameMetaData(MarkdownElement E)
303 {
304 return E is CodeBlock x &&
305 this.indent == x.indent &&
306 this.indentString == x.indentString &&
307 this.language == x.language &&
308 AreEqual(this.rows, x.rows) &&
309 base.SameMetaData(E);
310 }
311
317 public override bool Equals(object obj)
318 {
319 return obj is CodeBlock x &&
320 this.indent == x.indent &&
321 this.indentString == x.indentString &&
322 this.language == x.language &&
323 AreEqual(this.rows, x.rows) &&
324 base.Equals(obj);
325 }
326
331 public override int GetHashCode()
332 {
333 int h1 = base.GetHashCode();
334 int h2 = this.indent.GetHashCode();
335
336 h1 = ((h1 << 5) + h1) ^ h2;
337 h2 = this.indentString?.GetHashCode() ?? 0;
338
339 h1 = ((h1 << 5) + h1) ^ h2;
340 h2 = this.language?.GetHashCode() ?? 0;
341
342 h1 = ((h1 << 5) + h1) ^ h2;
343 h2 = GetHashCode(this.rows);
344
345 h1 = ((h1 << 5) + h1) ^ h2;
346
347 return h1;
348 }
349
354 public override void IncrementStatistics(MarkdownStatistics Statistics)
355 {
356 Statistics.NrCodeBlocks++;
357 }
358
359 }
360}
Helps with common JSON-related tasks.
Definition: JSON.cs:16
static string IndentString(int NrTabs)
Gets an indentation string consisting of a number of tab characters. Strings are caches and reused to...
Definition: JSON.cs:780
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:17
string IndentString
String used for indentation.
Definition: CodeBlock.cs:279
CodeBlock(MarkdownDocument Document, string[] Rows, int Start, int End, int Indent, string Language)
Represents a code block in a markdown document.
Definition: CodeBlock.cs:47
override bool InlineSpanElement
If the element is an inline span element.
Definition: CodeBlock.cs:284
override int GetHashCode()
Serves as the default hash function.
Definition: CodeBlock.cs:331
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:302
override bool Equals(object obj)
Determines whether the specified object is equal to the current object.
Definition: CodeBlock.cs:317
static IXmlVisualizer GetXmlVisualizerHandler(XmlDocument Xml)
Gets the best XML Visualizer for a given XML document.
Definition: CodeBlock.cs:216
override void IncrementStatistics(MarkdownStatistics Statistics)
Increments the property or properties in Statistics corresponding to the element.
Definition: CodeBlock.cs:354
CodeBlock(MarkdownDocument Document, string[] Rows, int Start, int End, int Indent)
Represents a code block in a markdown document.
Definition: CodeBlock.cs:33
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:14
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:1657
A chunked list is a linked list of chunks of objects of type T .
Definition: ChunkedList.cs:54
int Count
Number of elements in collection.
Definition: ChunkedList.cs:68
void Add(T Item)
Adds an item to the collection.
Definition: ChunkedList.cs:272
T[] ToArray()
Returns an array containing all elements of the collection.
Static class that dynamically manages types and interfaces available in the runtime environment.
Definition: Types.cs:15
static object[] NoParameters
Contains an empty array of parameter values.
Definition: Types.cs:572
static Type[] GetTypesImplementingInterface(string InterfaceFullName)
Gets all types implementing a given interface.
Definition: Types.cs:85
static ConstructorInfo GetDefaultConstructor(Type Type)
Gets the default constructor of a type, if one exists.
Definition: Types.cs:1742
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 Supports(T Object)
If the interface understands objects such as Object .
Grade
Grade enumeration
Definition: Grade.cs:7