Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
PlantUml.cs
1using SkiaSharp;
2using System;
4using System.Diagnostics;
5using System.IO;
6using System.Text;
7using System.Threading;
8using System.Threading.Tasks;
9using System.Xml;
20using Waher.Events;
26using Waher.Script;
28using Waher.Security;
29using static System.Environment;
30
32{
33 internal enum ResultType
34 {
35 Svg,
36 Png
37 }
38
39 internal class GraphInfo
40 {
41 public string BaseFileName;
42 public string TxtFileName;
43 public string ImageFileName;
44 public bool ImageExists;
45 public string PlantUmlFolder;
46 public string Title;
47 public string AsyncId;
48 public bool Sent;
49 }
50
56 {
57 private const int chartGenerationTimeout = 30000;
58
59 private static readonly AsyncProcessor<ChartRecord> queue = new AsyncProcessor<ChartRecord>(1, "PlantUML processor");
60 private static readonly Random rnd = new Random();
61 private static Scheduler scheduler = null;
62 private static string jarPath = null;
63 private static string javaPath = null;
64 private static string plantUmlFolder = null;
65 private static string contentRootFolder = null;
66 private static IMarkdownAsynchronousOutput asyncHtmlOutput = null;
67
71 public PlantUml()
72 {
73 }
74
80 public static void Init(string ContentRootFolder)
81 {
82 try
83 {
84 contentRootFolder = ContentRootFolder;
85
86 if (scheduler is null)
87 {
88 if (Types.TryGetModuleParameter("Scheduler", out Scheduler Scheduler))
89 scheduler = Scheduler;
90 else
91 {
92 scheduler = new Scheduler();
93
94 Log.Terminating += (Sender, e) =>
95 {
96 scheduler?.Dispose();
97 scheduler = null;
98 return Task.CompletedTask;
99 };
100 }
101 }
102
103 SearchForInstallationFolder(out string JarPath, out string JavaPath);
104
105 if (string.IsNullOrEmpty(JarPath))
106 Log.Warning("PlantUML not found. PlantUML support will not be available in Markdown.");
107 else if (string.IsNullOrEmpty(JavaPath))
108 Log.Warning("Java not found. PlantUML support will not be available in Markdown.");
109 else
110 {
111 SetPath(JarPath, JavaPath);
112
113 Log.Informational("PlantUML found. Integration with Markdown added.",
114 new KeyValuePair<string, object>("Path", jarPath),
115 new KeyValuePair<string, object>("Java", javaPath));
116
117
119 }
120 }
121 catch (Exception ex)
122 {
123 Log.Exception(ex);
124 }
125 }
126
131 public static async Task Terminate()
132 {
133 try
134 {
135 await queue.CloseForTermination(true, chartGenerationTimeout);
136 await queue.DisposeAsync();
137 }
138 catch (Exception ex)
139 {
140 Log.Exception(ex);
141 }
142 }
143
151 public static void SetPath(string JarPath, string JavaPath)
152 {
153 if (!string.IsNullOrEmpty(jarPath) && JarPath != jarPath)
154 throw new Exception("PlantUML an Java paths have already been set.");
155
156 jarPath = JarPath;
157 javaPath = JavaPath;
158 plantUmlFolder = Path.Combine(contentRootFolder, "PlantUML");
159
160 if (!Directory.Exists(plantUmlFolder))
161 Directory.CreateDirectory(plantUmlFolder);
162
163 DeleteOldFiles(TimeSpan.FromDays(7));
164 }
165
166 private static void DeleteOldFiles(object P)
167 {
168 if (P is TimeSpan MaxAge)
169 DeleteOldFiles(MaxAge, true);
170 }
171
177 public static void DeleteOldFiles(TimeSpan MaxAge, bool Reschedule)
178 {
179 if (string.IsNullOrEmpty(plantUmlFolder))
180 return;
181
182 DateTime Limit = DateTime.Now - MaxAge;
183 int Count = 0;
184
185 DirectoryInfo PlantUmlFolder = new DirectoryInfo(plantUmlFolder);
186 FileInfo[] Files = PlantUmlFolder.GetFiles("*.*");
187
188 foreach (FileInfo FileInfo in Files)
189 {
190 if (FileInfo.LastAccessTime < Limit)
191 {
192 try
193 {
194 File.Delete(FileInfo.FullName);
195 Count++;
196 }
197 catch (Exception ex)
198 {
199 Log.Error("Unable to delete old file: " + ex.Message, FileInfo.FullName);
200 }
201 }
202 }
203
204 if (Count > 0)
205 Log.Informational(Count.ToString() + " old file(s) deleted.", plantUmlFolder);
206
207 if (Reschedule)
208 {
209 lock (rnd)
210 {
211 scheduler.Add(DateTime.Now.AddDays(rnd.NextDouble() * 2), DeleteOldFiles, MaxAge);
212 }
213 }
214 }
215
221 public static void SearchForInstallationFolder(out string JarPath, out string JavaPath)
222 {
224
225 Folders.AddRange(FileSystem.GetFolders(new Environment.SpecialFolder[]
226 {
227 SpecialFolder.ProgramFiles,
228 SpecialFolder.ProgramFilesX86
229 }));
230
231 if (Types.TryGetModuleParameter("Runtime", out string RuntimeFolder))
232 {
233 Folders.Add(Path.Combine(RuntimeFolder, SpecialFolder.ProgramFiles.ToString()));
234 Folders.Add(Path.Combine(RuntimeFolder, SpecialFolder.ProgramFilesX86.ToString()));
235 }
236
237 string PathVar = Environment.GetEnvironmentVariable("PATH");
238 if (!string.IsNullOrEmpty(PathVar))
239 {
240 string[] Paths = PathVar.Split(Path.PathSeparator);
241 Folders.AddRange(Paths);
242 }
243
244 string[] Folders2 = Folders.ToArray();
245
246 JarPath = FileSystem.FindLatestFile(Folders2, "plantuml.jar", 1);
247 JavaPath = FileSystem.FindLatestFile(Folders2, "java" + FileSystem.ExecutableExtension, 3);
248 }
249
255 public Grade Supports(string Language)
256 {
257 if (!string.IsNullOrEmpty(jarPath) && !string.IsNullOrEmpty(javaPath))
258 {
259 int i = Language.IndexOf(':');
260 if (i > 0)
261 Language = Language.Substring(0, i).TrimEnd();
262
263 switch (Language.ToLower())
264 {
265 case "uml": return Grade.Excellent;
266 case "plantuml": return Grade.Perfect;
267 }
268 }
269
270 return Grade.NotAtAll;
271 }
272
276 public bool EvaluatesScript => false;
277
282 public void Register(MarkdownDocument Document)
283 {
284 // Do nothing.
285 }
286
296 public async Task<bool> RenderHtml(HtmlRenderer Renderer, string[] Rows, string Language, int Indent, MarkdownDocument Document)
297 {
298 StringBuilder Output = Renderer.Output;
299 bool GenerateIfNotExists = asyncHtmlOutput is null;
300 GraphInfo Info = await GetGraphInfo(Language, Rows, ResultType.Svg, GenerateIfNotExists);
301
302 if (GenerateIfNotExists || Info.ImageExists)
303 {
304 this.GenerateHTML(Output, Info);
305 return true;
306 }
307
308 Info.AsyncId = await asyncHtmlOutput.GenerateStub(MarkdownOutputType.Html, Output, Info.Title, Document);
309
310 foreach (KeyValuePair<AsyncMarkdownProcessing, object> P in Document.AsyncTasks)
311 {
312 if (P.Value is AsyncState AsyncState && AsyncState.Type == ResultType.Svg && AsyncState.GraphInfos.Count < 10)
313 {
314 AsyncState.GraphInfos.Add(Info);
315 return true;
316 }
317 }
318
319 Document.QueueAsyncTask(this.ExecutePlantUml, new AsyncState(ResultType.Svg, Info));
320
321 return true;
322 }
323
324 private class AsyncState
325 {
326 public readonly ChunkedList<GraphInfo> GraphInfos;
327 public readonly ResultType Type;
328
329 public AsyncState(ResultType Type, GraphInfo Info)
330 {
331 this.Type = Type;
332 this.GraphInfos = new ChunkedList<GraphInfo>()
333 {
334 Info
335 };
336 }
337 }
338
339 private async Task ExecutePlantUml(object State)
340 {
342 {
343 XmlEntitiesOnly = true
344 }))
345 {
346 AsyncState AsyncState = (AsyncState)State;
347
348 try
349 {
350 await ExecutePlantUml(AsyncState.Type, AsyncState.GraphInfos.ToArray());
351
352 foreach (GraphInfo Info in AsyncState.GraphInfos)
353 {
354 Renderer.Clear();
355
356 this.GenerateHTML(Renderer.Output, Info);
357 await asyncHtmlOutput.ReportResult(MarkdownOutputType.Html, Info.AsyncId, Renderer.ToString());
358 Info.Sent = true;
359 }
360 }
361 catch (Exception ex)
362 {
363 Renderer.Clear();
364 await Renderer.RenderObject(ex, true, new Variables());
365
366 string s = Renderer.ToString();
367
368 foreach (GraphInfo Info in AsyncState.GraphInfos)
369 {
370 if (!Info.Sent)
371 await asyncHtmlOutput.ReportResult(MarkdownOutputType.Html, Info.AsyncId, s);
372 }
373 }
374 }
375 }
376
377 private static async Task ExecutePlantUml(ResultType Type, params GraphInfo[] Files)
378 {
379 ChartRecord Rec = new ChartRecord(Type, Files);
380 queue.Queue(Rec);
381
382 if (!await Rec.Wait())
383 throw new Exception("Unable to process PlantUML chart.");
384 }
385
386 private class ChartRecord : IWorkItem
387 {
388 private readonly TaskCompletionSource<bool> result = new TaskCompletionSource<bool>();
389 private readonly ResultType type;
390 private readonly GraphInfo[] files;
391
392 public ChartRecord(ResultType Type, params GraphInfo[] Files)
393 {
394 this.type = Type;
395 this.files = Files;
396 }
397
401 public Task Execute()
402 {
403 return this.Execute(CancellationToken.None);
404 }
405
410 public async Task Execute(CancellationToken Cancel)
411 {
412 StringBuilder Arguments = new StringBuilder();
413 Arguments.Append("-jar \"");
414 Arguments.Append(jarPath);
415 Arguments.Append("\" -quiet -charset UTF-8 -t");
416 Arguments.Append(this.type.ToString().ToLower());
417
418 foreach (GraphInfo Info in this.files)
419 {
420 Arguments.Append(" \"");
421 Arguments.Append(Info.TxtFileName);
422 Arguments.Append('"');
423 }
424
425 ProcessStartInfo ProcessInformation = new ProcessStartInfo()
426 {
427 FileName = javaPath,
428 Arguments = Arguments.ToString(),
429 UseShellExecute = false,
430 RedirectStandardError = true,
431 RedirectStandardOutput = true,
432 RedirectStandardInput = false,
433 WorkingDirectory = this.files[0].PlantUmlFolder,
434 CreateNoWindow = true,
435 WindowStyle = ProcessWindowStyle.Hidden
436 };
437
438 Process P = new Process();
439 TaskCompletionSource<int> ExitSource = new TaskCompletionSource<int>();
440
441 P.Exited += (Sender, e) =>
442 {
443 ExitSource.TrySetResult(P.ExitCode);
444 };
445
446 Task _ = Task.Delay(chartGenerationTimeout).ContinueWith(Prev =>
447 {
448 try
449 {
450 P.Kill();
451
452 foreach (GraphInfo Info in this.files)
453 {
454 if (File.Exists(Info.ImageFileName))
455 File.Delete(Info.ImageFileName);
456 }
457 }
458 catch (Exception ex)
459 {
460 Log.Exception(ex);
461 }
462 finally
463 {
464 ExitSource.TrySetException(new TimeoutException("PlantUML process did not terminate properly."));
465 }
466
467 return Task.CompletedTask;
468 });
469
470 P.StartInfo = ProcessInformation;
471 P.EnableRaisingEvents = true;
472 P.Start();
473
474 int ExitCode = await ExitSource.Task;
475
476 if (ExitCode != 0)
477 {
478 string Error = P.StandardError.ReadToEnd();
479 this.result.TrySetException(new Exception(Error));
480 }
481 }
482
487 public void Processed(bool Result)
488 {
489 this.result.TrySetResult(Result);
490 }
491
496 public Task<bool> Wait()
497 {
498 return this.result.Task;
499 }
500
506 public Task<bool> Wait(CancellationToken Cancel)
507 {
508 if (Cancel.CanBeCanceled)
509 Cancel.Register(() => this.result.TrySetException(new OperationCanceledException(Cancel)));
510
511 return this.result.Task;
512 }
513 }
514
515 private void GenerateHTML(StringBuilder Output, GraphInfo Info)
516 {
517 Info.ImageFileName = Info.ImageFileName.Substring(contentRootFolder.Length).Replace(Path.DirectorySeparatorChar, '/');
518 if (!Info.ImageFileName.StartsWith("/"))
519 Info.ImageFileName = "/" + Info.ImageFileName;
520
521 Output.Append("<figure>");
522 Output.Append("<img src=\"");
523 Output.Append(XML.HtmlAttributeEncode(Info.ImageFileName));
524
525 if (!string.IsNullOrEmpty(Info.Title))
526 {
527 Output.Append("\" alt=\"");
528 Output.Append(XML.HtmlAttributeEncode(Info.Title));
529
530 Output.Append("\" title=\"");
531 Output.Append(XML.HtmlAttributeEncode(Info.Title));
532 }
533 else
534 Output.Append("\" alt=\"PlantUML graph");
535
536 Output.Append("\" class=\"aloneUnsized\"/>");
537
538 if (!string.IsNullOrEmpty(Info.Title))
539 {
540 Output.Append("<figcaption>");
541 Output.Append(XML.HtmlValueEncode(Info.Title));
542 Output.Append("</figcaption>");
543 }
544
545 Output.AppendLine("</figure>");
546 }
547
548 internal static Task<GraphInfo> GetGraphInfo(string Language, string[] Rows, ResultType Type)
549 {
550 return GetGraphInfo(Language, MarkdownDocument.AppendRows(Rows), Type);
551 }
552
553 internal static async Task<GraphInfo> GetGraphInfo(string Language, string Graph, ResultType Type)
554 {
555 string FileName = Hashes.ComputeSHA256HashString(Encoding.UTF8.GetBytes(Graph + Language));
556 string PlantUmlFolder = Path.Combine(contentRootFolder, "PlantUML");
557
558 GraphInfo Result = new GraphInfo()
559 {
560 BaseFileName = Path.Combine(PlantUmlFolder, FileName),
561 PlantUmlFolder = PlantUmlFolder
562 };
563 int i = Language.IndexOf(':');
564
565 if (i > 0)
566 Result.Title = Language.Substring(i + 1).Trim();
567 else
568 Result.Title = string.Empty;
569
570 Result.TxtFileName = Result.BaseFileName + ".txt";
571 if (!File.Exists(Result.TxtFileName))
572 await Files.WriteAllTextAsync(Result.TxtFileName, Graph, Encoding.UTF8);
573
574 switch (Type)
575 {
576 case ResultType.Svg:
577 default:
578 Result.ImageFileName = Result.BaseFileName + "." + ImageCodec.FileExtensionSvg;
579 break;
580
581 case ResultType.Png:
582 Result.ImageFileName = Result.BaseFileName + "." + ImageCodec.FileExtensionPng;
583 break;
584 }
585
586 Result.ImageExists = File.Exists(Result.ImageFileName);
587 if (Result.ImageExists)
588 {
589 FileInfo Info = new FileInfo(Result.ImageFileName);
590 if (Info.Length == 0)
591 Result.ImageExists = false;
592 }
593
594 return Result;
595 }
596
597 internal static Task<GraphInfo> GetGraphInfo(string Language, string[] Rows, ResultType Type, bool GenerateIfNotExists)
598 {
599 return GetGraphInfo(Language, MarkdownDocument.AppendRows(Rows), Type, GenerateIfNotExists);
600 }
601
602 internal static async Task<GraphInfo> GetGraphInfo(string Language, string GraphDefinition, ResultType Type, bool GenerateIfNotExists)
603 {
604 GraphInfo Result = await GetGraphInfo(Language, GraphDefinition, Type);
605
606 if (GenerateIfNotExists && !Result.ImageExists)
607 await ExecutePlantUml(Type, Result);
608
609 return Result;
610 }
611
621 public async Task<bool> RenderMarkdown(MarkdownRenderer Renderer, string[] Rows, string Language, int Indent, MarkdownDocument Document)
622 {
623 GraphInfo Info = await GetGraphInfo(Language, Rows, ResultType.Png, true);
624 if (Info is null)
625 return false;
626
627 return await ImageContent.GenerateMarkdownFromFile(Renderer.Output, Info.ImageFileName, Info.Title);
628 }
629
630
640 public async Task<bool> RenderText(TextRenderer Renderer, string[] Rows, string Language, int Indent, MarkdownDocument Document)
641 {
642 GraphInfo Info = await GetGraphInfo(Language, Rows, ResultType.Svg, true);
643 if (Info is null)
644 return false;
645
646 Renderer.Output.AppendLine(Info.Title);
647
648 return true;
649 }
650
660 public async Task<bool> RenderWpfXaml(WpfXamlRenderer Renderer, string[] Rows, string Language, int Indent, MarkdownDocument Document)
661 {
662 GraphInfo Info = await GetGraphInfo(Language, Rows, ResultType.Png, true);
663 if (Info is null)
664 return false;
665
666 XmlWriter Output = Renderer.XmlOutput;
667
668 Output.WriteStartElement("Image");
669 Output.WriteAttributeString("Source", Info.ImageFileName);
670 Output.WriteAttributeString("Stretch", "None");
671
672 if (!string.IsNullOrEmpty(Info.Title))
673 Output.WriteAttributeString("ToolTip", Info.Title);
674
675 Output.WriteEndElement();
676
677 return true;
678 }
688 public async Task<bool> RenderXamarinFormsXaml(XamarinFormsXamlRenderer Renderer, string[] Rows, string Language, int Indent, MarkdownDocument Document)
689 {
690 GraphInfo Info = await GetGraphInfo(Language, Rows, ResultType.Png, true);
691 if (Info is null)
692 return false;
693
694 XmlWriter Output = Renderer.XmlOutput;
695
696 Output.WriteStartElement("Image");
697 Output.WriteAttributeString("Source", Info.ImageFileName);
698 Output.WriteEndElement();
699
700 return true;
701 }
702
712 public async Task<bool> RenderLatex(LatexRenderer Renderer, string[] Rows, string Language, int Indent, MarkdownDocument Document)
713 {
714 GraphInfo Info = await GetGraphInfo(Language, Rows, ResultType.Png, true);
715 StringBuilder Output = Renderer.Output;
716
717 Output.AppendLine("\\begin{figure}[h]");
718 Output.AppendLine("\\centering");
719
720 Output.Append("\\fbox{\\includegraphics{");
721 Output.Append(Info.ImageFileName.Replace('\\', '/'));
722 Output.AppendLine("}}");
723
724 if (!string.IsNullOrEmpty(Info.Title))
725 {
726 Output.Append("\\caption{");
727 Output.Append(LatexRenderer.EscapeLaTeX(Info.Title));
728 Output.AppendLine("}");
729 }
730
731 Output.AppendLine("\\end{figure}");
732 Output.AppendLine();
733
734 return true;
735 }
736
744 public async Task<PixelInformation> GenerateImage(string[] Rows, string Language, MarkdownDocument Document)
745 {
746 GraphInfo Info = await GetGraphInfo(Language, Rows, ResultType.Png, true);
747 if (Info is null)
748 return null;
749
750 byte[] Data = await Runtime.IO.Files.ReadAllBytesAsync(Info.ImageFileName);
751
752 using (SKBitmap Bitmap = SKBitmap.Decode(Data))
753 {
754 return new PixelInformationPng(Data, Bitmap.Width, Bitmap.Height);
755 }
756 }
757
767 public async Task<bool> RenderContractXml(ContractsRenderer Renderer, string[] Rows, string Language, int Indent, MarkdownDocument Document)
768 {
769 try
770 {
771 GraphInfo Info = await GetGraphInfo(Language, Rows, ResultType.Png, true);
772 if (Info is null)
773 return false;
774
775 byte[] Data = await Runtime.IO.Files.ReadAllBytesAsync(Info.ImageFileName);
776 string ContentType = ImageCodec.ContentTypePng;
777 ContentResponse Content = await InternetContent.DecodeAsync(ContentType, Data, null);
778
779 if (Content.HasError || !(Content.Decoded is SKImage Image))
780 return false;
781
782 XmlWriter Output = Renderer.XmlOutput;
783 int Width = Image.Width;
784 int Height = Image.Height;
785
786 Output.WriteStartElement("imageStandalone");
787
788 Output.WriteAttributeString("contentType", ContentType);
789 Output.WriteAttributeString("width", Width.ToString());
790 Output.WriteAttributeString("height", Height.ToString());
791
792 Output.WriteStartElement("binary");
793 Output.WriteValue(Convert.ToBase64String(Data));
794 Output.WriteEndElement();
795
796 Output.WriteStartElement("caption");
797 if (string.IsNullOrEmpty(Info.Title))
798 Output.WriteElementString("text", "Graph");
799 else
800 Output.WriteElementString("text", Info.Title);
801
802 Output.WriteEndElement();
803 Output.WriteEndElement();
804
805 return true;
806 }
807 catch (Exception ex)
808 {
809 Log.Exception(ex);
810 return false;
811 }
812 }
813 }
814}
Contains information about a response to a content request.
bool HasError
If an error occurred.
object Decoded
Decoded object.
Image encoder/decoder.
Definition: ImageCodec.cs:14
const string FileExtensionPng
png
Definition: ImageCodec.cs:75
const string ContentTypePng
image/png
Definition: ImageCodec.cs:30
const string FileExtensionSvg
svg
Definition: ImageCodec.cs:120
Static class managing encoding and decoding of internet content.
static Task< ContentResponse > DecodeAsync(string ContentType, byte[] Data, Encoding Encoding, KeyValuePair< string, string >[] Fields, Uri BaseUri)
Decodes an object.
Renders Contracts XML from a Markdown document.
Renders LaTeX from a Markdown document.
static string EscapeLaTeX(string s)
Escapes text for output in a LaTeX document.
Contains a markdown document. This markdown document class supports original markdown,...
static string AppendRows(string[] Rows)
Appends a set of rows into a single string with newlines between rows.
static async Task< bool > GenerateMarkdownFromFile(StringBuilder Output, string FileName, string Title)
Generates Markdown embedding an image available in a file.
Definition: ImageContent.cs:56
Class managing PlantUML integration into Markdown documents.
Definition: PlantUml.cs:56
async Task< PixelInformation > GenerateImage(string[] Rows, string Language, MarkdownDocument Document)
Generates an image of the contents.
Definition: PlantUml.cs:744
Grade Supports(string Language)
Checks how well the handler supports multimedia content of a given type.
Definition: PlantUml.cs:255
async Task< bool > RenderMarkdown(MarkdownRenderer Renderer, string[] Rows, string Language, int Indent, MarkdownDocument Document)
Generates Markdown for the code content.
Definition: PlantUml.cs:621
static void DeleteOldFiles(TimeSpan MaxAge, bool Reschedule)
Deletes generated files older than MaxAge .
Definition: PlantUml.cs:177
static void Init(string ContentRootFolder)
Initializes the PlantUML-Markdown integration.
Definition: PlantUml.cs:80
static void SetPath(string JarPath, string JavaPath)
Sets the full path of PlantUML.
Definition: PlantUml.cs:151
async Task< bool > RenderWpfXaml(WpfXamlRenderer Renderer, string[] Rows, string Language, int Indent, MarkdownDocument Document)
Generates WPF XAML for the code content.
Definition: PlantUml.cs:660
async Task< bool > RenderXamarinFormsXaml(XamarinFormsXamlRenderer Renderer, string[] Rows, string Language, int Indent, MarkdownDocument Document)
Generates Xamarin.Forms XAML for the code content.
Definition: PlantUml.cs:688
async Task< bool > RenderHtml(HtmlRenderer Renderer, string[] Rows, string Language, int Indent, MarkdownDocument Document)
Generates HTML for the code content.
Definition: PlantUml.cs:296
static async Task Terminate()
Terminates PlantUML processing.
Definition: PlantUml.cs:131
async Task< bool > RenderText(TextRenderer Renderer, string[] Rows, string Language, int Indent, MarkdownDocument Document)
Generates plain text for the code content.
Definition: PlantUml.cs:640
bool EvaluatesScript
If script is evaluated for this type of code block.
Definition: PlantUml.cs:276
async Task< bool > RenderLatex(LatexRenderer Renderer, string[] Rows, string Language, int Indent, MarkdownDocument Document)
Generates LaTeX for the code content.
Definition: PlantUml.cs:712
static void SearchForInstallationFolder(out string JarPath, out string JavaPath)
Searches for the installation folder on the local machine.
Definition: PlantUml.cs:221
void Register(MarkdownDocument Document)
Is called on the object when an instance of the element has been created in a document.
Definition: PlantUml.cs:282
PlantUml()
Class managing PlantUML integration into Markdown documents.
Definition: PlantUml.cs:71
async Task< bool > RenderContractXml(ContractsRenderer Renderer, string[] Rows, string Language, int Indent, MarkdownDocument Document)
Generates smart contract XML for the code content.
Definition: PlantUml.cs:767
Renders HTML from a Markdown document.
Definition: HtmlRenderer.cs:25
Contains settings that the HTML export uses to customize HTML output.
Definition: HtmlSettings.cs:7
Renders portable Markdown from a Markdown document.
Abstract base class for Markdown renderers.
Definition: Renderer.cs:15
readonly StringBuilder Output
Renderer output.
Definition: Renderer.cs:19
void Clear()
Clears the underlying StringBuilder.
Definition: Renderer.cs:138
override string ToString()
Returns the renderer output.
Definition: Renderer.cs:130
Renders plain text from a Markdown document.
Definition: TextRenderer.cs:18
Renders XAML (WPF flavour) from a Markdown document.
Renders XAML (Xamarin.Forms flavour) from a Markdown document.
Static class helping modules to find files installed on the system.
Definition: FileSystem.cs:12
static string[] GetFolders(Environment.SpecialFolder[] Folders, params string[] AppendWith)
Gets the physical locations of special folders.
Definition: FileSystem.cs:126
static string ExecutableExtension
Extension used by executable files on the platform.
Definition: FileSystem.cs:231
static string FindLatestFile(Environment.SpecialFolder[] Folders, string Pattern, bool IncludeSubfolders)
Finds the latest file matching a search pattern, by searching in a set of folders,...
Definition: FileSystem.cs:179
Helps with common XML-related tasks.
Definition: XML.cs:21
static string HtmlValueEncode(string s)
Differs from Encode(String), in that it does not encode the aposotrophe or the quote.
Definition: XML.cs:211
static string HtmlAttributeEncode(string s)
Differs from Encode(String), in that it does not encode the aposotrophe.
Definition: XML.cs:121
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
static void Warning(string Message, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, string StackTrace, params KeyValuePair< string, object >[] Tags)
Logs a warning event.
Definition: Log.cs:576
static void Error(string Message, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, string StackTrace, params KeyValuePair< string, object >[] Tags)
Logs an error event.
Definition: Log.cs:692
static void Informational(string Message, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, string StackTrace, params KeyValuePair< string, object >[] Tags)
Logs an informational event.
Definition: Log.cs:344
A chunked list is a linked list of chunks of objects of type T .
Definition: ChunkedList.cs:54
void AddRange(IEnumerable< T > Collection)
Adds a range of elements (last) to the list.
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.
Contains static methods
Definition: Files.cs:14
static Task WriteAllTextAsync(string FileName, string Text)
Creates a text file asynchronously.
Definition: Files.cs:95
Static class that dynamically manages types and interfaces available in the runtime environment.
Definition: Types.cs:15
static bool TryGetModuleParameter(string Name, out object Value)
Tries to get a module parameter value.
Definition: Types.cs:607
Processes work tasks, in an asynchronous manner.
Class that can be used to schedule events in time. It uses a timer to execute tasks at the appointed ...
Definition: Scheduler.cs:14
void Dispose()
IDisposable.Dispose
Definition: Scheduler.cs:34
DateTime Add(DateTime When, Action< object > Callback, object State)
Adds an event.
Definition: Scheduler.cs:54
Base class for graphs.
Definition: Graph.cs:88
Contains pixel information in PNG format
Collection of variables.
Definition: Variables.cs:25
Contains methods for simple hash calculations.
Definition: Hashes.cs:57
static string ComputeSHA256HashString(byte[] Data)
Computes the SHA-256 hash of a block of binary data.
Definition: Hashes.cs:449
Interface for classes that help output asynchronous markdown output.
Task< string > GenerateStub(MarkdownOutputType Type, StringBuilder Output, string Title, MarkdownDocument Document)
Generates a stub in the output, that will be filled with the asynchronously generated content,...
Task ReportResult(MarkdownOutputType Type, string Id, string Result)
Method called when asynchronous result has been generated in a Markdown document.
Interface for all markdown handlers of code content that generates an image output.
Interface for code content plain text renderers.
Interface for code content WPF XAML renderers.
Interface for asynchronous operations.
Definition: IWorkItem.cs:10
Definition: ImplTypes.g.cs:58
ResultType
Image types supported by GraphViz
Definition: GraphViz.cs:35
MarkdownOutputType
Markdown output type.
Grade
Grade enumeration
Definition: Grade.cs:7