Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
JavaScriptRenderer.cs
1using SkiaSharp;
2using System;
4using System.IO;
5using System.Text;
6using System.Threading.Tasks;
7using System.Xml;
14using Waher.Events;
16using Waher.Script;
20
22{
27 {
31 public readonly HtmlSettings htmlSettings;
32
38 : base()
39 {
40 this.htmlSettings = HtmlSettings;
41 }
42
49 : base(Output)
50 {
51 this.htmlSettings = HtmlSettings;
52 }
53
60 : base(Document)
61 {
62 this.htmlSettings = HtmlSettings;
63 }
64
72 : base(Output, Document)
73 {
74 this.htmlSettings = HtmlSettings;
75 }
76
80 public override Task RenderDocumentHeader()
81 {
82 string FileName = Path.GetFileName(this.Document.FileName);
83 bool LetterOrUnderscore = false;
84 StringBuilder sb = new StringBuilder();
85
86 foreach (char ch in Path.ChangeExtension(FileName, null))
87 {
88 if (char.IsLetter(ch) || ch == '_')
89 {
90 sb.Append(ch);
91 LetterOrUnderscore = true;
92 }
93 else if (char.IsDigit(ch))
94 {
95 if (!LetterOrUnderscore)
96 {
97 sb.Append('_');
98 LetterOrUnderscore = true;
99 }
100
101 sb.Append(ch);
102 }
103 else
104 {
105 sb.Append('_');
106 LetterOrUnderscore = true;
107 }
108 }
109
110 string Name = sb.ToString();
111
112 this.Output.Append("function CreateInnerHTML");
113 this.Output.Append(Name);
114 this.Output.AppendLine("(ElementId, Args)");
115 this.Output.AppendLine("{");
116 this.Output.AppendLine("\tvar Element = document.getElementById(ElementId);");
117 this.Output.AppendLine("\tif (Element)");
118 this.Output.Append("\t\tElement.innerHTML = CreateHTML");
119 this.Output.Append(Name);
120 this.Output.AppendLine("(Args);");
121 this.Output.AppendLine("}");
122 this.Output.AppendLine();
123 this.Output.Append("function CreateHTML");
124 this.Output.Append(Name);
125 this.Output.AppendLine("(Args)");
126 this.Output.AppendLine("{");
127 this.Output.Append("\tvar Segments = [");
128
129 this.firstSegment = true;
130
131 return Task.CompletedTask;
132 }
133
134 private bool firstSegment;
135
136 private void AppendHtml(string Html)
137 {
138 this.AppendHtml(Html, false, false);
139 }
140
141 private void AppendHtml(string Html, bool Script, bool AppendNewLine)
142 {
143 if (this.firstSegment)
144 this.firstSegment = false;
145 else
146 this.Output.Append(',');
147
148 this.Output.AppendLine();
149 this.Output.Append("\t\t");
150
151 if (Script)
152 this.Output.Append(Html);
153 else
154 {
155 this.Output.Append('"');
156 this.Output.Append(JSON.Encode(Html));
157
158 if (AppendNewLine)
159 this.Output.Append(jsonEncodedNewLine);
160
161 this.Output.Append('"');
162 }
163 }
164
165 private void AppendHtmlLine()
166 {
167 this.AppendHtml(string.Empty, false, true);
168 }
169
170 private void AppendHtmlLine(string Html)
171 {
172 this.AppendHtml(Html, false, true);
173 }
174
175 private static readonly string jsonEncodedNewLine = JSON.Encode(Environment.NewLine);
176
180 public override async Task RenderFootnotes()
181 {
182 this.AppendHtmlLine("<div class=\"footnotes\">");
183 this.AppendHtmlLine("<hr />");
184 this.AppendHtmlLine("<ol>");
185
186 foreach (string Key in this.Document.FootnoteOrder)
187 {
188 if ((this.Document?.TryGetFootnoteNumber(Key, out int Nr) ?? false) &&
189 (this.Document?.TryGetFootnote(Key, out Footnote Footnote) ?? false) &&
191 {
192 this.AppendHtml("<li id=\"fn-" + Nr.ToString() + "\">");
193
195 {
196 InlineHTML Backlink = new InlineHTML(this.Document, "<a href=\"#fnref-" + Nr.ToString() + "\" class=\"footnote-backref\">&#8617;</a>");
197
199 P.AddChild(Backlink);
200 else
201 Footnote.AddChild(Backlink);
202
203 Footnote.BacklinkAdded = true;
204 }
205
206 await Footnote.Render(this);
207
208 this.AppendHtmlLine("</li>");
209 }
210 }
211
212 this.AppendHtmlLine("</ol>");
213 this.AppendHtmlLine("</div>");
214 }
215
219 public override Task RenderDocumentFooter()
220 {
221 this.Output.AppendLine("];");
222 this.Output.AppendLine("\treturn Segments.join(\"\");");
223 this.Output.AppendLine("}");
224
225 return Task.CompletedTask;
226 }
227
228 #region Span Elements
229
234 public override async Task Render(Abbreviation Element)
235 {
236 this.AppendHtml("<abbr data-title=\"" +
237 XML.HtmlAttributeEncode(Element.Description).Replace(" ", "&nbsp;") + "\">");
238
239 await this.RenderChildren(Element);
240
241 this.AppendHtml("</abbr>");
242 }
243
248 public override Task Render(AutomaticLinkMail Element)
249 {
250 string s = Element.EMail;
251 byte[] Data = Encoding.ASCII.GetBytes(s);
252 StringBuilder sb = new StringBuilder();
253
254 foreach (byte b in Data)
255 {
256 sb.Append("&#x");
257 sb.Append(b.ToString("X2"));
258 sb.Append(';');
259 }
260
261 s = sb.ToString();
262
263 sb.Clear();
264 Data = Encoding.ASCII.GetBytes("mailto:");
265 foreach (byte b in Data)
266 {
267 sb.Append("&#x");
268 sb.Append(b.ToString("X2"));
269 sb.Append(';');
270 }
271
272 this.AppendHtml("<a href=\"" + sb.ToString() + s + "\">" + s + "</a>");
273
274 return Task.CompletedTask;
275 }
276
281 public override Task Render(AutomaticLinkUrl Element)
282 {
283 bool IsRelative = Element.URL.IndexOf(':') < 0;
284
285 this.AppendHtml("<a href=\"" +
286 XML.HtmlAttributeEncode(this.Document.CheckURL(Element.URL, null)));
287
288 if (!IsRelative)
289 this.AppendHtml("\" target=\"_blank");
290
291 this.AppendHtml("\">" + XML.HtmlValueEncode(Element.URL) + "</a>");
292
293 return Task.CompletedTask;
294 }
295
300 public override async Task Render(Delete Element)
301 {
302 this.AppendHtml("<del>");
303 await this.RenderChildren(Element);
304 this.AppendHtml("</del>");
305 }
306
311 public override Task Render(DetailsReference Element)
312 {
313 if (!(this.Document.Detail is null))
314 return this.RenderDocument(this.Document.Detail, true);
315 else
316 return this.Render((MetaReference)Element);
317 }
318
323 public override Task Render(EmojiReference Element)
324 {
325 IEmojiSource EmojiSource = this.Document.EmojiSource;
326
327 if (EmojiSource is null)
328 this.AppendHtml(Element.Delimiter + Element.Emoji.ShortName + Element.Delimiter);
329 else if (!EmojiSource.EmojiSupported(Element.Emoji))
330 this.AppendHtml(Element.Emoji.Unicode);
331 else
332 {
333 StringBuilder sb = new StringBuilder();
334 EmojiSource.GenerateHTML(sb, Element.Emoji, Element.Level, this.Document.Settings.EmbedEmojis);
335 this.AppendHtml(sb.ToString());
336 }
337
338 return Task.CompletedTask;
339 }
340
345 public override async Task Render(Emphasize Element)
346 {
347 this.AppendHtml("<em>");
348 await this.RenderChildren(Element);
349 this.AppendHtml("</em>");
350 }
351
356 public override async Task Render(FootnoteReference Element)
357 {
358 string s;
359
360 if (!(this.Document?.TryGetFootnote(Element.Key, out Footnote Footnote) ?? false))
361 Footnote = null;
362
363 if (Element.AutoExpand && !(Footnote is null))
364 await this.Render(Footnote);
365 else if (this.Document?.TryGetFootnoteNumber(Element.Key, out int Nr) ?? false)
366 {
367 s = Nr.ToString();
368
369 this.AppendHtml("<sup id=\"fnref-" + s + "\"><a href=\"#fn-" + s +
370 "\" class=\"footnote-ref\">" + s + "</a></sup>");
371
372 if (!(Footnote is null))
373 Footnote.Referenced = true;
374 }
375 }
376
381 public override Task Render(HashTag Element)
382 {
383 this.AppendHtml("<mark");
384
385 string s = this.htmlSettings?.HashtagClass;
386
387 if (!string.IsNullOrEmpty(s))
388 this.AppendHtml(" class=\"" + XML.HtmlAttributeEncode(s) + "\"");
389
390 s = this.htmlSettings?.HashtagClickScript;
391
392 if (!string.IsNullOrEmpty(s))
393 this.AppendHtml(" onclick=\"" + XML.HtmlAttributeEncode(s) + "\"");
394
395 this.AppendHtml(">" + Element.Tag + "</mark>");
396
397 return Task.CompletedTask;
398 }
399
404 public override Task Render(HtmlEntity Element)
405 {
406 if (this.htmlSettings?.XmlEntitiesOnly ?? true)
407 {
408 switch (Element.Entity)
409 {
410 case "quot":
411 case "amp":
412 case "apos":
413 case "lt":
414 case "gt":
415 case "nbsp": // Has syntactic significance when parsing HTML or Markdown
416 this.AppendHtml("&" + Element.Entity + ";");
417 break;
418
419 case "QUOT":
420 case "AMP":
421 case "LT":
422 case "GT":
423 this.AppendHtml("&" + Element.Entity.ToLower() + ";");
424 break;
425
426 default:
427 string s = Html.HtmlEntity.EntityToCharacter(Element.Entity);
428 if (!string.IsNullOrEmpty(s))
429 this.AppendHtml(s);
430 break;
431 }
432 }
433 else
434 this.AppendHtml("&" + Element.Entity + ";");
435
436 return Task.CompletedTask;
437 }
438
443 public override Task Render(HtmlEntityUnicode Element)
444 {
445 this.AppendHtml("&#" + Element.Code.ToString() + ";");
446
447 return Task.CompletedTask;
448 }
449
454 public override Task Render(InlineCode Element)
455 {
456 this.AppendHtml("<code>" + XML.HtmlValueEncode(Element.Code) + "</code>");
457
458 return Task.CompletedTask;
459 }
460
465 public override Task Render(InlineHTML Element)
466 {
467 this.AppendHtml(Element.HTML);
468
469 return Task.CompletedTask;
470 }
471
476 public override Task Render(InlineScript Element)
477 {
478 this.AppendHtml(Element.Expression.Script, true, false);
479 return Task.CompletedTask;
480 }
481
488 public async Task RenderObject(object Result, bool AloneInParagraph, Variables Variables)
489 {
490 if (Result is null)
491 return;
492
493 if (Result is XmlDocument Xml)
494 Result = await MarkdownDocument.TransformXml(Xml, Variables);
495 else if (Result is IToMatrix ToMatrix)
496 Result = ToMatrix.ToMatrix();
497
498 if (Result is Graph G)
499 {
500 PixelInformation Pixels = G.CreatePixels(out GraphSettings GraphSettings);
501 byte[] Bin = Pixels.EncodeAsPng();
502
503 if (AloneInParagraph)
504 this.AppendHtml("<figure>");
505
506 this.AppendHtml("<img border=\"2\" width=\"" + GraphSettings.Width.ToString() +
507 "\" height=\"" + GraphSettings.Height.ToString() +
508 "\" src=\"data:image/png;base64," + Convert.ToBase64String(Bin, 0, Bin.Length) +
509 "\" alt=\"");
510
511 if (G is Graph2D Graph2D && !string.IsNullOrEmpty(Graph2D.Title))
512 this.AppendHtml(XML.Encode(Graph2D.Title));
513 else
514 this.AppendHtml("Graph");
515
516 this.AppendHtml("\" />");
517
518 if (AloneInParagraph)
519 this.AppendHtml("</figure>");
520 }
521 else if (Result is PixelInformation Pixels)
522 {
523 byte[] Bin = Pixels.EncodeAsPng();
524
525 if (AloneInParagraph)
526 this.AppendHtml("<figure>");
527
528 this.AppendHtml("<img border=\"2\" width=\"" + Pixels.Width.ToString() +
529 "\" height=\"" + Pixels.Height.ToString() + "\" src=\"data:image/png;base64," +
530 Convert.ToBase64String(Bin, 0, Bin.Length) + "\" alt=\"Image\" />");
531
532 if (AloneInParagraph)
533 this.AppendHtml("</figure>");
534 }
535 else if (Result is SKImage Img)
536 {
537 using (SKData Data = Img.Encode(SKEncodedImageFormat.Png, 100))
538 {
539 byte[] Bin = Data.ToArray();
540
541 if (AloneInParagraph)
542 this.AppendHtml("<figure>");
543
544 this.AppendHtml("<img border=\"2\" width=\"" + Img.Width.ToString() +
545 "\" height=\"" + Img.Height.ToString() + "\" src=\"data:image/png;base64," +
546 Convert.ToBase64String(Bin, 0, Bin.Length) + "\" alt=\"Image\" />");
547
548 if (AloneInParagraph)
549 this.AppendHtml("</figure>");
550 }
551 }
552 else if (Result is MarkdownDocument Doc)
553 {
554 await this.RenderDocument(Doc, true); // Does not call ProcessAsyncTasks()
555 Doc.ProcessAsyncTasks();
556 }
557 else if (Result is MarkdownContent Markdown)
558 {
559 Doc = await MarkdownDocument.CreateAsync(Markdown.Markdown, Markdown.Settings ?? new MarkdownSettings());
560 await this.RenderDocument(Doc, true); // Does not call ProcessAsyncTasks()
561 Doc.ProcessAsyncTasks();
562 }
563 else if (Result is Exception ex)
564 {
565 ex = Log.UnnestException(ex);
566
567 this.AppendHtmlLine("<font class=\"error\">");
568
569 if (ex is AggregateException ex2)
570 {
571 foreach (Exception ex3 in ex2.InnerExceptions)
572 this.AppendHtmlLine("<p>" + XML.HtmlValueEncode(ex3.Message) + "</p>");
573 }
574 else
575 {
576 if (AloneInParagraph)
577 this.AppendHtml("<p>");
578
579 this.AppendHtml(XML.HtmlValueEncode(ex.Message));
580
581 if (AloneInParagraph)
582 this.AppendHtml("</p>");
583 }
584
585 this.AppendHtmlLine("</font>");
586 }
587 else if (Result is ObjectMatrix M && !(M.ColumnNames is null))
588 {
589 this.AppendHtml("<table><thead><tr>");
590
591 foreach (string s2 in M.ColumnNames)
592 this.AppendHtml("<th>" + FormatText(XML.HtmlValueEncode(s2)) + "</th>");
593
594 this.AppendHtml("</tr></thead><tbody>");
595
596 int x, y;
597
598 for (y = 0; y < M.Rows; y++)
599 {
600 this.AppendHtml("<tr>");
601
602 for (x = 0; x < M.Columns; x++)
603 {
604 this.AppendHtml("<td>");
605
606 object Item = M.GetElement(x, y).AssociatedObjectValue;
607 if (!(Item is null))
608 {
609 if (Item is string s2)
610 this.AppendHtml(FormatText(XML.HtmlValueEncode(s2)));
611 else if (Item is MarkdownElement Element)
612 await Element.Render(this);
613 else
614 this.AppendHtml(FormatText(XML.HtmlValueEncode(Expression.ToExpressionString(Item))));
615 }
616
617 this.AppendHtml("</td>");
618 }
619
620 this.AppendHtml("</tr>");
621 }
622
623 this.AppendHtml("</tbody></table>");
624 }
625 else if (Result is Array A)
626 {
627 foreach (object Item in A)
628 await this.RenderObject(Item, false, Variables);
629 }
630 else
631 {
632 if (AloneInParagraph)
633 this.AppendHtml("<p>");
634
635 this.AppendHtml(XML.HtmlValueEncode(Result?.ToString() ?? string.Empty));
636
637 if (AloneInParagraph)
638 this.AppendHtml("</p>");
639 }
640
641 if (AloneInParagraph)
642 this.AppendHtmlLine();
643 }
644
645 private static string FormatText(string s)
646 {
647 return s.Replace("\r\n", "\n").Replace("\n", "<br/>").Replace("\r", "<br/>").
648 Replace("\t", "&nbsp;&nbsp;&nbsp;").Replace(" ", "&nbsp;");
649 }
650
655 public override Task Render(InlineText Element)
656 {
657 this.AppendHtml(XML.HtmlValueEncode(Element.Value));
658
659 return Task.CompletedTask;
660 }
661
666 public override async Task Render(Insert Element)
667 {
668 this.AppendHtml("<ins>");
669 await this.RenderChildren(Element);
670 this.AppendHtml("</ins>");
671 }
672
677 public override Task Render(LineBreak Element)
678 {
679 this.AppendHtmlLine("<br/>");
680
681 return Task.CompletedTask;
682 }
683
688 public override Task Render(Link Element)
689 {
690 return this.Render(Element.Url, Element.Title, Element.Children, Element.Document);
691 }
692
700 public async Task Render(string Url, string Title, ChunkedList<MarkdownElement> ChildNodes, MarkdownDocument Document)
701 {
702 bool IsRelative = Url.IndexOf(':') < 0;
703
704 if (!IsRelative && Url.StartsWith("javascript:", StringComparison.OrdinalIgnoreCase))
705 {
706 this.AppendHtml("<a href=\"#\" onclick=\"" +
707 XML.HtmlAttributeEncode(System.Net.WebUtility.UrlDecode(Url.Substring(11))));
708
709 IsRelative = true;
710 }
711 else
712 this.AppendHtml("<a href=\"" + XML.HtmlAttributeEncode(Document.CheckURL(Url, null)));
713
714 if (!string.IsNullOrEmpty(Title))
715 this.AppendHtml("\" title=\"" + XML.HtmlAttributeEncode(Title));
716
717 if (!IsRelative)
718 this.AppendHtml("\" target=\"_blank");
719
720 this.AppendHtml("\">");
721
722 await this.Render(ChildNodes);
723
724 this.AppendHtml("</a>");
725 }
726
731 public override Task Render(LinkReference Element)
732 {
734
735 if (!(Multimedia is null))
736 return this.Render(Multimedia.Items[0].Url, Multimedia.Items[0].Title, Element.Children, Element.Document);
737 else
738 return this.RenderChildren(Element);
739 }
740
745 public override Task Render(MetaReference Element)
746 {
747 bool FirstOnRow = true;
748
749 if (Element.TryGetMetaData(out KeyValuePair<string, bool>[] Values))
750 {
751 foreach (KeyValuePair<string, bool> P in Values)
752 {
753 if (FirstOnRow)
754 FirstOnRow = false;
755 else
756 this.AppendHtml(" ");
757
758 this.AppendHtml(XML.HtmlValueEncode(P.Key));
759 if (P.Value)
760 {
761 this.AppendHtmlLine("<br/>");
762 FirstOnRow = true;
763 }
764 }
765 }
766
767 return Task.CompletedTask;
768 }
769
774 public override async Task Render(Multimedia Element)
775 {
776 IMultimediaHtmlRenderer Renderer = Element.MultimediaHandler<IMultimediaHtmlRenderer>();
777 if (Renderer is null)
778 await this.RenderChildren(Element);
779 else
780 {
781 using (HtmlRenderer Renderer2 = new HtmlRenderer(this.htmlSettings))
782 {
783 await Renderer.RenderHtml(Renderer2, Element.Items, Element.Children, Element.AloneInParagraph, Element.Document);
784 this.AppendHtml(Renderer2.ToString());
785 }
786 }
787 }
788
793 public override async Task Render(MultimediaReference Element)
794 {
796
797 if (!(Multimedia is null))
798 {
800 if (!(Renderer is null))
801 {
802 using (HtmlRenderer Renderer2 = new HtmlRenderer(this.htmlSettings))
803 {
804 await Renderer.RenderHtml(Renderer2, Multimedia.Items, Element.Children, Element.AloneInParagraph, Element.Document);
805 this.AppendHtml(Renderer2.ToString());
806 return;
807 }
808 }
809 }
810
811 await this.RenderChildren(Element);
812 }
813
818 public override async Task Render(StrikeThrough Element)
819 {
820 this.AppendHtml("<s>");
821 await this.RenderChildren(Element);
822 this.AppendHtml("</s>");
823 }
824
829 public override async Task Render(Strong Element)
830 {
831 this.AppendHtml("<strong>");
832 await this.RenderChildren(Element);
833 this.AppendHtml("</strong>");
834 }
835
840 public override async Task Render(SubScript Element)
841 {
842 this.AppendHtml("<sub>");
843 await this.RenderChildren(Element);
844 this.AppendHtml("</sub>");
845 }
846
851 public override async Task Render(SuperScript Element)
852 {
853 this.AppendHtml("<sup>");
854 await this.RenderChildren(Element);
855 this.AppendHtml("</sup>");
856 }
857
862 public override async Task Render(Underline Element)
863 {
864 this.AppendHtml("<u>");
865 await this.RenderChildren(Element);
866 this.AppendHtml("</u>");
867 }
868
869 #endregion
870
871 #region Block elements
872
877 public override async Task Render(BlockQuote Element)
878 {
879 this.AppendHtmlLine("<blockquote>");
880 await this.RenderChildren(Element);
881 this.AppendHtmlLine("</blockquote>");
882 }
883
888 public override async Task Render(BulletList Element)
889 {
890 this.AppendHtmlLine("<ul>");
891 await this.RenderChildren(Element);
892 this.AppendHtmlLine("</ul>");
893 }
894
899 public override async Task Render(CenterAligned Element)
900 {
901 this.AppendHtmlLine("<div class='horizontalAlignCenter'>");
902 await this.RenderChildren(Element);
903 this.AppendHtmlLine("</div>");
904 }
905
910 public override async Task Render(CodeBlock Element)
911 {
912 ICodeContentHtmlRenderer Renderer = Element.CodeContentHandler<ICodeContentHtmlRenderer>();
913
914 if (!(Renderer is null))
915 {
916 try
917 {
918 using (HtmlRenderer Renderer2 = new HtmlRenderer(this.htmlSettings))
919 {
920 if (await Renderer.RenderHtml(Renderer2, Element.Rows, Element.Language, Element.Indent, Element.Document))
921 {
922 this.AppendHtml(Renderer2.ToString());
923 return;
924 }
925 }
926 }
927 catch (Exception ex)
928 {
929 ex = Log.UnnestException(ex);
930
931 this.AppendHtmlLine("<font class=\"error\">");
932
933 if (ex is AggregateException ex2)
934 {
935 foreach (Exception ex3 in ex2.InnerExceptions)
936 this.AppendHtmlLine("<p>" + XML.HtmlValueEncode(ex3.Message) + "</p>");
937 }
938 else
939 this.AppendHtml("<p>" + XML.HtmlValueEncode(ex.Message) + "</p>");
940
941 this.AppendHtml("</font>");
942 }
943 }
944
945 int i;
946
947 this.AppendHtml("<pre><code class=\"");
948
949 if (string.IsNullOrEmpty(Element.Language))
950 this.AppendHtml("nohighlight");
951 else
952 this.AppendHtml(XML.Encode(Element.Language));
953
954 this.AppendHtml("\">");
955
956 for (i = Element.Start; i <= Element.End; i++)
957 this.AppendHtmlLine(Element.IndentString + XML.HtmlValueEncode(Element.Rows[i]));
958
959 this.AppendHtmlLine("</code></pre>");
960 }
961
966 public override Task Render(CommentBlock Element)
967 {
968 return Task.CompletedTask;
969 }
970
975 public override async Task Render(DefinitionDescriptions Element)
976 {
978 int i, c;
979
980 while (!(Loop is null))
981 {
982 for (i = Loop.Start, c = Loop.Pos; i < c; i++)
983 {
984 this.AppendHtml("<dd>");
985 await Loop[i].Render(this);
986 this.AppendHtmlLine("</dd>");
987 }
988
989 Loop = Loop.Next;
990 }
991 }
992
997 public override async Task Render(DefinitionList Element)
998 {
999 this.AppendHtmlLine("<dl>");
1000 await this.RenderChildren(Element);
1001 this.AppendHtmlLine("</dl>");
1002 }
1003
1008 public override async Task Render(DefinitionTerms Element)
1009 {
1011 int i, c;
1012
1013 while (!(Loop is null))
1014 {
1015 for (i = Loop.Start, c = Loop.Pos; i < c; i++)
1016 {
1017 this.AppendHtml("<dt>");
1018 await Loop[i].Render(this);
1019 this.AppendHtmlLine("</dt>");
1020 }
1021
1022 Loop = Loop.Next;
1023 }
1024 }
1025
1030 public override async Task Render(DeleteBlocks Element)
1031 {
1032 this.AppendHtmlLine("<blockquote class=\"deleted\">");
1033
1034 await this.RenderChildren(Element);
1035
1036 this.AppendHtmlLine("</blockquote>");
1037 }
1038
1043 public override Task Render(Footnote Element)
1044 {
1045 return this.RenderChildren(Element);
1046 }
1047
1052 public override async Task Render(Header Element)
1053 {
1054 this.AppendHtml("<h" + Element.Level.ToString());
1055
1056 string Id = await Element.Id;
1057
1058 if (!string.IsNullOrEmpty(Id))
1059 this.AppendHtml(" id=\"" + XML.HtmlAttributeEncode(Id) + "\"");
1060
1062 this.AppendHtml(" class=\"tocReference\"");
1063
1064 this.AppendHtml(">");
1065
1066 await this.RenderChildren(Element);
1067
1068 this.AppendHtmlLine("</h" + Element.Level.ToString() + ">");
1069 }
1070
1075 public override Task Render(HorizontalRule Element)
1076 {
1077 this.AppendHtmlLine("<hr/>");
1078
1079 return Task.CompletedTask;
1080 }
1081
1086 public override async Task Render(HtmlBlock Element)
1087 {
1088 await this.RenderChildren(Element);
1089 this.AppendHtmlLine();
1090 }
1091
1096 public override async Task Render(InsertBlocks Element)
1097 {
1098 this.AppendHtmlLine("<blockquote class=\"inserted\">");
1099 await this.RenderChildren(Element);
1100 this.AppendHtmlLine("</blockquote>");
1101 }
1102
1107 public override Task Render(InvisibleBreak Element)
1108 {
1109 return Task.CompletedTask; // TODO
1110 }
1111
1116 public override async Task Render(LeftAligned Element)
1117 {
1118 this.AppendHtmlLine("<div class='horizontalAlignLeft'>");
1119 await this.RenderChildren(Element);
1120 this.AppendHtmlLine("</div>");
1121 }
1122
1127 public override async Task Render(MarginAligned Element)
1128 {
1129 this.AppendHtmlLine("<div class='horizontalAlignMargins'>");
1130 await this.RenderChildren(Element);
1131 this.AppendHtmlLine("</div>");
1132 }
1133
1138 public override Task Render(NestedBlock Element)
1139 {
1140 return this.RenderChildren(Element);
1141 }
1142
1147 public override async Task Render(NumberedItem Element)
1148 {
1149 if (Element.NumberExplicit)
1150 this.AppendHtml("<li value=\"" + Element.Number.ToString() + "\">");
1151 else
1152 this.AppendHtml("<li>");
1153
1154 await this.RenderChild(Element);
1155
1156 this.AppendHtmlLine("</li>");
1157 }
1158
1163 public override async Task Render(NumberedList Element)
1164 {
1167 int i, c;
1168 NumberedItem Item;
1169 int Expected = 0;
1170
1171 this.AppendHtmlLine("<ol>");
1172
1173 while (!(Loop is null))
1174 {
1175 for (i = Loop.Start, c = Loop.Pos; i < c; i++)
1176 {
1177 E = Loop[i];
1178 Expected++;
1179 Item = E as NumberedItem;
1180
1181 if (Item is null)
1182 await E.Render(this);
1183 else if (Item.Number == Expected)
1184 {
1185 this.AppendHtml("<li>");
1186 await Item.Child.Render(this);
1187 this.AppendHtmlLine("</li>");
1188 }
1189 else
1190 {
1191 await Item.Render(this);
1192 Expected = Item.Number;
1193 }
1194 }
1195
1196 Loop = Loop.Next;
1197 }
1198
1199 this.AppendHtmlLine("</ol>");
1200 }
1201
1206 public override async Task Render(Paragraph Element)
1207 {
1208 if (!Element.Implicit)
1209 this.AppendHtml("<p>");
1210
1211 await this.RenderChildren(Element);
1212
1213 if (!Element.Implicit)
1214 this.AppendHtmlLine("</p>");
1215 }
1216
1221 public override async Task Render(RightAligned Element)
1222 {
1223 this.AppendHtmlLine("<div class='horizontalAlignRight'>");
1224 await this.RenderChildren(Element);
1225 this.AppendHtmlLine("</div>");
1226 }
1227
1232 public override async Task Render(Sections Element)
1233 {
1234 this.GenerateSectionHTML(Element.InitialNrColumns);
1235 await this.RenderChildren(Element);
1236 this.AppendHtmlLine("</section>");
1237 }
1238
1239 private void GenerateSectionHTML(int NrColumns)
1240 {
1241 this.AppendHtml("<section");
1242
1243 if (NrColumns > 1)
1244 {
1245 string s = NrColumns.ToString();
1246
1247 this.AppendHtml(" style=\"-webkit-column-count:" + s + ";-moz-column-count:" +
1248 s + ";column-count:" + s + "\"");
1249 }
1250
1251 this.AppendHtmlLine(">");
1252 }
1253
1258 public override Task Render(SectionSeparator Element)
1259 {
1260 this.AppendHtmlLine("</section>");
1261 this.GenerateSectionHTML(Element.NrColumns);
1262
1263 return Task.CompletedTask;
1264 }
1265
1270 public override async Task Render(Table Element)
1271 {
1273 MarkdownElement[] Row;
1274 TextAlignment?[] CellAlignments;
1275 int NrRows, RowIndex;
1276 int NrColumns = Element.Columns;
1277 int i, j, k;
1278 bool OnlyRows = false;
1279
1280 if (Element.Headers.Length == 0 && !(this.Document?.Elements is null))
1281 {
1282 OnlyRows = true;
1283
1285 int c;
1286
1287 while (!(Loop is null))
1288 {
1289 for (i = Loop.Start, c = Loop.Pos; i < c; i++)
1290 {
1291 if (Loop[i] != Element)
1292 {
1293 OnlyRows = false;
1294 Loop = null;
1295 break;
1296 }
1297 }
1298
1299 Loop = Loop?.Next;
1300 }
1301 }
1302
1303 if (!OnlyRows)
1304 {
1305 this.AppendHtmlLine("<table>");
1306
1307 if (!string.IsNullOrEmpty(Element.Id))
1308 {
1309 this.AppendHtml("<caption id=\"" + XML.HtmlAttributeEncode(Element.Id) + "\">");
1310
1311 if (string.IsNullOrEmpty(Element.Caption))
1312 this.AppendHtml(XML.HtmlValueEncode(Element.Id));
1313 else
1314 this.AppendHtml(XML.HtmlValueEncode(Element.Caption));
1315
1316 this.AppendHtmlLine("</caption>");
1317 }
1318
1319 this.AppendHtmlLine("<colgroup>");
1320
1321 foreach (TextAlignment Alignment in Element.ColumnAlignments)
1322 this.AppendHtmlLine("<col style=\"text-align:" + Alignment.ToString().ToLower() + "\"/>");
1323
1324 this.AppendHtmlLine("</colgroup>");
1325
1326 this.AppendHtmlLine("<thead>");
1327
1328 NrRows = Element.Headers.Length;
1329 for (RowIndex = 0; RowIndex < NrRows; RowIndex++)
1330 {
1331 Row = Element.Headers[RowIndex];
1332 CellAlignments = Element.HeaderCellAlignments[RowIndex];
1333
1334 this.AppendHtmlLine("<tr>");
1335
1336 for (i = 0; i < NrColumns; i++)
1337 {
1338 E = Row[i];
1339 if (E is null)
1340 continue;
1341
1342 k = 1;
1343 j = i + 1;
1344 while (j < NrColumns && Row[j++] is null)
1345 k++;
1346
1347 this.AppendHtml("<th style=\"text-align:" +
1348 (CellAlignments[i] ?? Element.ColumnAlignments[i]).ToString().ToLower());
1349
1350 if (k > 1)
1351 this.AppendHtml("\" colspan=\"" + k.ToString());
1352
1353 this.AppendHtml("\">");
1354 await E.Render(this);
1355 this.AppendHtmlLine("</th>");
1356 }
1357
1358 this.AppendHtmlLine("</tr>");
1359 }
1360 this.AppendHtmlLine("</thead>");
1361
1362 this.AppendHtmlLine("<tbody>");
1363 }
1364
1365 NrRows = Element.Rows.Length;
1366 for (RowIndex = 0; RowIndex < NrRows; RowIndex++)
1367 {
1368 Row = Element.Rows[RowIndex];
1369 CellAlignments = Element.RowCellAlignments[RowIndex];
1370
1371 this.AppendHtmlLine("<tr>");
1372
1373 for (i = 0; i < NrColumns; i++)
1374 {
1375 E = Row[i];
1376 if (E is null)
1377 continue;
1378
1379 k = 1;
1380 j = i + 1;
1381 while (j < NrColumns && Row[j++] is null)
1382 k++;
1383
1384 this.AppendHtml("<td style=\"text-align:" +
1385 (CellAlignments[i] ?? Element.ColumnAlignments[i]).ToString().ToLower());
1386
1387 if (k > 1)
1388 this.AppendHtml("\" colspan=\"" + k.ToString());
1389
1390 this.AppendHtml("\">");
1391 await E.Render(this);
1392 this.AppendHtmlLine("</td>");
1393 }
1394
1395 this.AppendHtmlLine("</tr>");
1396 }
1397
1398 if (!OnlyRows)
1399 {
1400 this.AppendHtmlLine("</tbody>");
1401 this.AppendHtmlLine("</table>");
1402 }
1403 }
1404
1409 public override async Task Render(TaskItem Element)
1410 {
1411 this.AppendHtml("<li class=\"taskListItem\"><input disabled=\"disabled");
1412
1413 if (Element.CheckPosition > 0)
1414 {
1415 this.AppendHtml("\" id=\"item" + Element.CheckPosition.ToString() +
1416 "\" data-position=\"" + Element.CheckPosition.ToString());
1417 }
1418
1419 this.AppendHtml("\" type=\"checkbox\"");
1420
1421 if (Element.IsChecked)
1422 this.AppendHtml(" checked=\"checked\"");
1423
1424 this.AppendHtml("/><span></span><label class=\"taskListItemLabel\"");
1425
1426 if (Element.CheckPosition > 0)
1427 this.AppendHtml(" for=\"item" + Element.CheckPosition.ToString() + "\"");
1428
1429 this.AppendHtml(">");
1430
1431 if (Element.Child is NestedBlock NestedBlock)
1432 {
1435 int i, c;
1436 bool EndLabel = true;
1437 bool First = true;
1438
1439 while (!(Loop is null))
1440 {
1441 for (i = Loop.Start, c = Loop.Pos; i < c; i++)
1442 {
1443 E = Loop[i];
1444
1445 if (First)
1446 {
1447 First = false;
1448
1449 if (E.InlineSpanElement)
1450 await E.Render(this);
1451 else
1452 {
1453 await NestedBlock.Render(this);
1454 Loop = null;
1455 break;
1456 }
1457 }
1458 else
1459 {
1460 if (!E.InlineSpanElement)
1461 {
1462 this.AppendHtml("</label>");
1463 EndLabel = false;
1464 }
1465
1466 await E.Render(this);
1467 }
1468 }
1469
1470 Loop = Loop?.Next;
1471 }
1472
1473 if (EndLabel)
1474 this.AppendHtml("</label>");
1475
1476 this.AppendHtmlLine("</li>");
1477 }
1478 else
1479 {
1480 await Element.Child.Render(this);
1481 this.AppendHtmlLine("</label></li>");
1482 }
1483 }
1484
1489 public override async Task Render(TaskList Element)
1490 {
1491 this.AppendHtmlLine("<ul class=\"taskList\">");
1492 await this.RenderChildren(Element);
1493 this.AppendHtmlLine("</ul>");
1494 }
1495
1500 public override async Task Render(UnnumberedItem Element)
1501 {
1502 this.AppendHtml("<li");
1503
1504 MarkdownDocument Detail = Element.Document.Detail;
1505
1506 if (!(Detail is null))
1507 {
1508 if (Element.Child is Link Link)
1509 {
1510 if (string.Compare(Detail.ResourceName, Link.Url, true) == 0)
1511 this.AppendHtml(" class=\"active\"");
1512 }
1513 else if (Element.Child is LinkReference LinkReference)
1514 {
1515 string Label = LinkReference.Label;
1516 Multimedia Multimedia = Element.Document.GetReference(Label);
1517
1518 if (!(Multimedia is null) && Multimedia.Items.Length == 1 &&
1519 string.Compare(Multimedia.Items[0].Url, Detail.ResourceName, true) == 0)
1520 {
1521 this.AppendHtml(" class=\"active\"");
1522 }
1523 }
1524 }
1525
1526 this.AppendHtml(">");
1527 await Element.Child.Render(this);
1528 this.AppendHtmlLine("</li>");
1529 }
1530
1531 #endregion
1532
1533 }
1534}
string ShortName
Emoji short name.
string Unicode
Unicode representation of emoji.
Helps with common JSON-related tasks.
Definition: JSON.cs:16
static string Encode(string s)
Encodes a string for inclusion in JSON.
Definition: JSON.cs:537
Renders JavaScript from a Markdown document.
async Task RenderObject(object Result, bool AloneInParagraph, Variables Variables)
Generates HTML from Script output.
override async Task Render(Delete Element)
Renders Element .
override async Task Render(TaskItem Element)
Renders Element .
override async Task Render(NumberedItem Element)
Renders Element .
override Task RenderDocumentHeader()
Renders the document header.
override async Task Render(BlockQuote Element)
Renders Element .
override Task Render(Link Element)
Renders Element .
override async Task Render(NumberedList Element)
Renders Element .
override async Task Render(Paragraph Element)
Renders Element .
override async Task Render(BulletList Element)
Renders Element .
override Task Render(DetailsReference Element)
Renders Element .
override async Task Render(MarginAligned Element)
Renders Element .
override Task RenderDocumentFooter()
Renders the document header.
override async Task Render(DeleteBlocks Element)
Renders Element .
override async Task Render(StrikeThrough Element)
Renders Element .
override async Task Render(HtmlBlock Element)
Renders Element .
override Task Render(InlineText Element)
Renders Element .
override async Task Render(SuperScript Element)
Renders Element .
override async Task Render(Table Element)
Renders Element .
override Task Render(HashTag Element)
Renders Element .
override async Task Render(Header Element)
Renders Element .
override async Task Render(TaskList Element)
Renders Element .
override async Task Render(DefinitionDescriptions Element)
Renders Element .
JavaScriptRenderer(HtmlSettings HtmlSettings, MarkdownDocument Document)
Renders JavaScript from a Markdown document.
override async Task Render(LeftAligned Element)
Renders Element .
override async Task Render(Abbreviation Element)
Renders Element .
override async Task RenderFootnotes()
Renders footnotes.
override async Task Render(Multimedia Element)
Renders Element .
override async Task Render(InsertBlocks Element)
Renders Element .
override async Task Render(Insert Element)
Renders Element .
override async Task Render(SubScript Element)
Renders Element .
override Task Render(InlineScript Element)
Renders Element .
override async Task Render(DefinitionTerms Element)
Renders Element .
override Task Render(CommentBlock Element)
Renders Element .
JavaScriptRenderer(StringBuilder Output, HtmlSettings HtmlSettings, MarkdownDocument Document)
Renders JavaScript from a Markdown document.
override Task Render(MetaReference Element)
Renders Element .
override async Task Render(Underline Element)
Renders Element .
override Task Render(LinkReference Element)
Renders Element .
override Task Render(SectionSeparator Element)
Renders Element .
override async Task Render(Strong Element)
Renders Element .
JavaScriptRenderer(HtmlSettings HtmlSettings)
Renders JavaScript from a Markdown document.
override async Task Render(UnnumberedItem Element)
Renders Element .
override Task Render(Footnote Element)
Renders Element .
override Task Render(InlineCode Element)
Renders Element .
override Task Render(NestedBlock Element)
Renders Element .
override async Task Render(Emphasize Element)
Renders Element .
override Task Render(HtmlEntity Element)
Renders Element .
override Task Render(LineBreak Element)
Renders Element .
JavaScriptRenderer(StringBuilder Output, HtmlSettings HtmlSettings)
Renders JavaScript from a Markdown document.
override Task Render(HtmlEntityUnicode Element)
Renders Element .
readonly HtmlSettings htmlSettings
HTML settings.
override Task Render(InvisibleBreak Element)
Renders Element .
override Task Render(HorizontalRule Element)
Renders Element .
override Task Render(EmojiReference Element)
Renders Element .
override async Task Render(CodeBlock Element)
Renders Element .
override Task Render(InlineHTML Element)
Renders Element .
async Task Render(string Url, string Title, ChunkedList< MarkdownElement > ChildNodes, MarkdownDocument Document)
Generates HTML for a link.
override async Task Render(Sections Element)
Renders Element .
override async Task Render(MultimediaReference Element)
Renders Element .
override async Task Render(CenterAligned Element)
Renders Element .
override Task Render(AutomaticLinkUrl Element)
Renders Element .
override async Task Render(RightAligned Element)
Renders Element .
override async Task Render(FootnoteReference Element)
Renders Element .
override Task Render(AutomaticLinkMail Element)
Renders Element .
override async Task Render(DefinitionList Element)
Renders Element .
Class that can be used to encapsulate Markdown to be returned from a Web Service, bypassing any encod...
Contains a markdown document. This markdown document class supports original markdown,...
static async Task< object > TransformXml(XmlDocument Xml, Variables Variables)
Transforms XML to an object that is easier to visualize.
bool IncludesTableOfContents
If the document contains a Table of Contents.
string CheckURL(string Url, string URL)
Checks the URL if it needs redirection to a proxy.
IEnumerable< string > FootnoteOrder
Order of footnotes.
IEmojiSource EmojiSource
Source for emojis in the document.
string ResourceName
Local resource name of Markdown document, if referenced through a web server. Master documents use th...
string FileName
Filename of Markdown document. Markdown inclusion will be made relative to this filename.
MarkdownDocument Detail
Detail document of a master document.
Multimedia GetReference(string Label)
Gets the multimedia information referenced by a label.
static Task< MarkdownDocument > CreateAsync(string MarkdownText, params Type[] TransparentExceptionTypes)
Contains a markdown document. This markdown document class supports original markdown,...
ChunkedList< MarkdownElement > Elements
Markdown elements making up the document.
Contains settings that the Markdown parser uses to customize its behavior.
Represents a block quote in a markdown document.
Definition: BlockQuote.cs:11
Represents a bullet list in a markdown document.
Definition: BulletList.cs:11
Represents a center-aligned set of blocks in a markdown document.
Represents a code block in a markdown document.
Definition: CodeBlock.cs:17
string IndentString
String used for indentation.
Definition: CodeBlock.cs:279
Represents a comment block in a markdown document.
Definition: CommentBlock.cs:10
Represents a definition list in a markdown document.
Represents inserted blocks in a markdown document.
Definition: DeleteBlocks.cs:11
override Task Render(IRenderer Output)
Renders the element.
bool Referenced
If the Footnote has been referenced during rendering, and therefore needs to be shown at the end of t...
Definition: Footnote.cs:51
bool BacklinkAdded
If a backlink has been added to the footnote.
Definition: Footnote.cs:69
Represents a header in a markdown document.
Definition: Header.cs:15
Represents a block of HTML in a markdown document.
Definition: HtmlBlock.cs:11
Represents inserted blocks in a markdown document.
Definition: InsertBlocks.cs:11
Represents a left-aligned set of blocks in a markdown document.
Definition: LeftAligned.cs:11
Represents a margin-aligned set of blocks in a markdown document.
Represents a nested block with no special formatting rules in a markdown document.
Definition: NestedBlock.cs:12
override Task Render(IRenderer Output)
Renders the element.
Represents a numbered item in an ordered list.
Definition: NumberedItem.cs:10
bool NumberExplicit
If number is explicitly provided (true) or inferred (false).
Definition: NumberedItem.cs:40
override Task Render(IRenderer Output)
Renders the element.
Represents a numbered list in a markdown document.
Definition: NumberedList.cs:11
Represents a paragraph in a markdown document.
Definition: Paragraph.cs:11
bool Implicit
If paragraph is implicit or not.
Definition: Paragraph.cs:41
Represents a right-aligned set of blocks in a markdown document.
Definition: RightAligned.cs:11
int NrColumns
Number of columns in following section.
Represents a sequence of sections.
Definition: Sections.cs:11
int InitialNrColumns
Number of columns for initial section.
Definition: Sections.cs:32
Represents a table in a markdown document.
Definition: Table.cs:11
TextAlignment[] ColumnAlignments
Table column alignments.
Definition: Table.cs:65
MarkdownElement[][] Headers
Headers in table.
Definition: Table.cs:55
TextAlignment?[][] RowCellAlignments
Row cell alignments in table.
Definition: Table.cs:80
TextAlignment?[][] HeaderCellAlignments
Header cell alignments in table.
Definition: Table.cs:75
MarkdownElement[][] Rows
Rows in table.
Definition: Table.cs:60
Represents a task item in a task list.
Definition: TaskItem.cs:10
int CheckPosition
Position of the checkmark in the original markdown text document.
Definition: TaskItem.cs:36
bool IsChecked
If the item is checked or not.
Definition: TaskItem.cs:31
Represents a task list in a markdown document.
Definition: TaskList.cs:11
Represents an unnumbered item in an ordered list.
MarkdownElement LastChild
Last child, or null if none.
override ChunkedList< MarkdownElement > Children
Any children of the element.
virtual void AddChild(MarkdownElement NewChild)
Adds a child to the element.
Abstract base class for all markdown elements.
abstract Task Render(IRenderer Output)
Renders the element.
abstract bool InlineSpanElement
If the element is an inline span element.
MarkdownDocument Document
Markdown document.
string Delimiter
Delimiter string used to identify emoji.
int Level
Level (number of colons used to define the emoji)
bool AutoExpand
If the footnote should automatically be expanded when rendered, if format supports auto-expansion.
Represents an HTML entity in Unicode format.
bool TryGetMetaData(out KeyValuePair< string, bool >[] Values)
Tries to get meta-data from the document.
MultimediaItem[] Items
Multimedia items.
Definition: Multimedia.cs:41
bool AloneInParagraph
If the element is alone in a paragraph.
Definition: Multimedia.cs:46
bool AloneInParagraph
If the element is alone in a paragraph.
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
Abstract base class for Markdown renderers.
Definition: Renderer.cs:15
readonly StringBuilder Output
Renderer output.
Definition: Renderer.cs:19
Task RenderChild(MarkdownElementSingleChild Element)
Renders the child of Element .
Definition: Renderer.cs:178
virtual async Task RenderDocument(MarkdownDocument Document, bool Inclusion)
Renders a document.
Definition: Renderer.cs:76
Task RenderChildren(MarkdownElementChildren Element)
Renders the children of Element .
Definition: Renderer.cs:147
override string ToString()
Returns the renderer output.
Definition: Renderer.cs:130
MarkdownDocument Document
Reference to Markdown document being processed.
Definition: Renderer.cs:24
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 Encode(string s)
Encodes a string for use in XML.
Definition: XML.cs:29
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 Exception UnnestException(Exception Exception)
Unnests an exception, to extract the relevant inner exception.
Definition: Log.cs:828
Node referencing a chunk in a ChunkedList<T>
Definition: ChunkNode.cs:11
ChunkNode< T > Next
Next chunk
Definition: ChunkNode.cs:26
int Pos
Index after the last element in chunk.
Definition: ChunkNode.cs:51
int Start
Index of first element in chunk.
Definition: ChunkNode.cs:46
A chunked list is a linked list of chunks of objects of type T .
Definition: ChunkedList.cs:54
ChunkNode< T > FirstChunk
First chunk
Definition: ChunkedList.cs:259
Class managing a script expression.
Definition: Expression.cs:41
string Script
Original script string.
Definition: Expression.cs:207
static string ToExpressionString(object Value)
Converts an object to a string, that can be parsed as part of an expression.
Definition: Expression.cs:5052
Handles two-dimensional graphs.
Definition: Graph2D.cs:27
string Title
Title for graph.
Definition: Graph2D.cs:282
Base class for graphs.
Definition: Graph.cs:88
int Width
Width of graph, in pixels. (Default=640 pixels.)
int Height
Height of graph, in pixels. (Default=480 pixels.)
Contains pixel information
virtual byte[] EncodeAsPng()
Encodes the pixels into a binary PNG image.
ToMatrix(ScriptNode Operand, bool NullCheck, int Start, int Length, Expression Expression)
To-Matrix operator.
Definition: ToMatrix.cs:22
Collection of variables.
Definition: Variables.cs:25
Interface for Emoji sources. Emoji sources provide emojis to content providers.
Definition: IEmojiSource.cs:10
Task GenerateHTML(StringBuilder Output, EmojiInfo Emoji, bool EmbedImage)
Generates HTML for a given Emoji.
bool EmojiSupported(EmojiInfo Emoji)
If the emoji is supported by the emoji source.
Interface for multimedia content HTML renderers.
Interface for objects that can be converted into matrices.
Definition: IToMatrix.cs:9
TextAlignment
Text alignment of contents.