{"id":159,"date":"2011-05-05T22:59:53","date_gmt":"2011-05-05T20:59:53","guid":{"rendered":"http:\/\/hen.co.za\/blog\/?p=159"},"modified":"2011-05-05T22:59:53","modified_gmt":"2011-05-05T20:59:53","slug":"htmlwriter-1-2","status":"publish","type":"post","link":"https:\/\/hen.co.za\/blog\/2011\/05\/htmlwriter-1-2\/","title":{"rendered":"HTMLWriter 1.2"},"content":{"rendered":"<p>And with another iteration the library has improved yet again. See the <a title=\"HTMLWriter 1.1\" href=\"https:\/\/hen.co.za\/blog\/2011\/05\/htmlwriter-1-1\/\" target=\"_blank\">previous<\/a> or <a title=\"HTMLWriter 1.0\" href=\"https:\/\/hen.co.za\/blog\/2011\/04\/htmlwriter\/\" target=\"_blank\">original<\/a> posts for details about where it came from.<\/p>\n<p>With this version I&#8217;ve made some big changes internally to the library. You can still use the basic functionality as with version 1.0 but the auto indentation has been improved greatly &#8211; and simplified in the code. Essentially it now properly formats the generated html with indentation for tags specified to do so.<\/p>\n<p>To make it much easier to manage auto formatting tags I modified the AppendTagStart and\u00a0AppendTagEnd methods to make use of some string arrays that define tags that require standard behavior &#8211; like always insert a crlf in-front of it or always append crlf etc.<\/p>\n<p>The arrays looks like this:<\/p>\n<blockquote><p>startTagsAutoOnNewLine = <span style=\"color: #0000ff;\">new string<\/span>[]<br \/>\n{<\/p>\n<p style=\"padding-left: 30px;\">&#8220;address&#8221;,<br \/>\n&#8220;blockquote&#8221;,<br \/>\n&#8220;code&#8221;,<br \/>\n&#8220;div&#8221;,<br \/>\n&#8220;h1&#8243;,&#8221;h2&#8243;,&#8221;h3&#8243;,&#8221;h4&#8243;,&#8221;h5&#8243;,&#8221;h6&#8221;,<br \/>\n&#8220;iframe&#8221;,<br \/>\n&#8220;ol&#8221;, &#8220;ul&#8221;, &#8220;dl&#8221;,<br \/>\n&#8220;table&#8221;, &#8220;thead&#8221;, &#8220;tfoot&#8221;, &#8220;tbody&#8221;, &#8220;tr&#8221;, &#8220;td&#8221;, &#8220;th&#8221;<\/p>\n<p>};<\/p>\n<p>tagsAutoIncDecIndentation = <span style=\"color: #0000ff;\">new string<\/span>[]<br \/>\n{<\/p>\n<p style=\"padding-left: 30px;\">&#8220;address&#8221;,<br \/>\n&#8220;blockquote&#8221;,<br \/>\n&#8220;ol&#8221;, &#8220;ul&#8221;, &#8220;dl&#8221;,<br \/>\n&#8220;table&#8221;, &#8220;thead&#8221;, &#8220;tfoot&#8221;, &#8220;tbody&#8221;, &#8220;tr&#8221;<\/p>\n<p>};<\/p>\n<p>endTagsAutoOnNewLine = <span style=\"color: #0000ff;\">new string<\/span>[]<br \/>\n{<\/p>\n<p style=\"padding-left: 30px;\">&#8220;address&#8221;,<br \/>\n&#8220;blockquote&#8221;,<br \/>\n&#8220;ol&#8221;, &#8220;ul&#8221;, &#8220;dl&#8221;,<br \/>\n&#8220;table&#8221;, &#8220;thead&#8221;, &#8220;tfoot&#8221;, &#8220;tbody&#8221;, &#8220;tr&#8221;,<\/p>\n<p>};<\/p>\n<p>endTagsAutoAppendCRLF = <span style=\"color: #0000ff;\">new string<\/span>[]<br \/>\n{<\/p>\n<p style=\"padding-left: 30px;\">&#8220;address&#8221;,<br \/>\n&#8220;blockquote&#8221;,<br \/>\n&#8220;code&#8221;,<br \/>\n&#8220;h1&#8243;,&#8221;h2&#8243;,&#8221;h3&#8243;,&#8221;h4&#8243;,&#8221;h5&#8243;,&#8221;h6&#8221;,<br \/>\n&#8220;iframe&#8221;,<br \/>\n&#8220;ol&#8221;, &#8220;ul&#8221;, &#8220;dl&#8221;,<br \/>\n&#8220;table&#8221;<\/p>\n<p>};<\/p><\/blockquote>\n<p>The 2 methods look like this:<\/p>\n<blockquote><p><span style=\"color: #0000ff;\">protected void<\/span> AppendTagStartInternal(<span style=\"color: #0000ff;\">string <\/span>tagName, <span style=\"color: #0000ff;\">string <\/span>className, <span style=\"color: #0000ff;\">params CustomAttribute<\/span>[] customAttributes)<br \/>\n{<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\">if<\/span> (AutoFormatting)<br \/>\n{<\/p>\n<p style=\"padding-left: 60px;\"><span style=\"color: #0000ff;\">if<\/span> (startTagsAutoOnNewLine.Contains(tagName.ToLower()))<br \/>\n{<\/p>\n<p style=\"padding-left: 90px;\">AppendNewLineInternal();<br \/>\nAppendIndentation();<\/p>\n<p style=\"padding-left: 60px;\">}<br \/>\n<span style=\"color: #0000ff;\">else if<\/span> (lastWrittenCRLF)<br \/>\n{<\/p>\n<p style=\"padding-left: 90px;\">AppendIndentation();<\/p>\n<p style=\"padding-left: 60px;\">}<\/p>\n<p style=\"padding-left: 30px;\">}<br \/>\n<span style=\"color: #0000ff;\">this<\/span>.AppendInternal(<span style=\"color: #0000ff;\">string<\/span>.Format(&#8220;&lt;{0}&#8221;, tagName));<br \/>\n<span style=\"color: #0000ff;\"> if<\/span> (className.Length &gt; 0)<\/p>\n<p style=\"padding-left: 60px;\"><span style=\"color: #0000ff;\">this<\/span>.AppendInternal(<span style=\"color: #0000ff;\">string<\/span>.Format(&#8221; class=\\&#8221;{0}\\&#8221;&#8221;, className));<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\">foreach <\/span>(<span style=\"color: #0000ff;\">CustomAttribute <\/span>customAttribute <span style=\"color: #0000ff;\">in <\/span>customAttributes)<br \/>\n{<\/p>\n<p style=\"padding-left: 60px;\"><span style=\"color: #0000ff;\">this<\/span>.AppendInternal(&#8221; &#8221; + customAttribute.ToString());<\/p>\n<p style=\"padding-left: 30px;\">}<br \/>\n<span style=\"color: #0000ff;\">this<\/span>.AppendInternal(&#8220;&gt;&#8221;);<br \/>\ntags.Push(tagName);<br \/>\n<span style=\"color: #0000ff;\">if<\/span> (AutoFormatting)<br \/>\n{<\/p>\n<p style=\"padding-left: 60px;\"><span style=\"color: #0000ff;\">if<\/span> (tagsAutoIncDecIndentation.Contains(tagName.ToLower()))<br \/>\n{<\/p>\n<p style=\"padding-left: 90px;\">IndentationInc();<br \/>\nAppendNewLineInternal();<\/p>\n<p style=\"padding-left: 60px;\">}<\/p>\n<p style=\"padding-left: 30px;\">}<\/p>\n<p>}<\/p>\n<p><span style=\"color: #0000ff;\">protected void<\/span> AppendTagEndInternal(<span style=\"color: #0000ff;\">string <\/span>tagName, <span style=\"color: #0000ff;\">bool <\/span>autoPop)<br \/>\n{<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\">if<\/span> (autoPop &amp;&amp; tags.Peek() == tagName)<\/p>\n<p style=\"padding-left: 60px;\">tags.Pop();<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\">if<\/span> (AutoFormatting)<br \/>\n{<\/p>\n<p style=\"padding-left: 60px;\"><span style=\"color: #0000ff;\">if<\/span> (tagsAutoIncDecIndentation.Contains(tagName.ToLower()))<br \/>\n{<\/p>\n<p style=\"padding-left: 90px;\">IndentationDec();<\/p>\n<p style=\"padding-left: 60px;\">}<br \/>\n<span style=\"color: #0000ff;\">if<\/span> (endTagsAutoOnNewLine.Contains(tagName.ToLower()))<br \/>\n{<\/p>\n<p style=\"padding-left: 90px;\">AppendNewLineInternal(); ;<br \/>\nAppendIndentation();<\/p>\n<p style=\"padding-left: 60px;\">}<br \/>\n<span style=\"color: #0000ff;\">else if<\/span> (lastWrittenCRLF)<br \/>\n{<\/p>\n<p style=\"padding-left: 90px;\">AppendIndentation();<\/p>\n<p style=\"padding-left: 60px;\">}<\/p>\n<p style=\"padding-left: 30px;\">}<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\">this<\/span>.AppendInternal(&#8220;&lt;\/&#8221; + tagName + &#8220;&gt;&#8221;);<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\">if<\/span> (AutoFormatting)<br \/>\n{<\/p>\n<p style=\"padding-left: 60px;\"><span style=\"color: #0000ff;\">if<\/span> (endTagsAutoAppendCRLF.Contains(tagName.ToLower()))<br \/>\n{<\/p>\n<p style=\"padding-left: 90px;\">AppendNewLineInternal();<\/p>\n<p style=\"padding-left: 60px;\">}<\/p>\n<p style=\"padding-left: 30px;\">}<\/p>\n<p>}<\/p><\/blockquote>\n<p>Additionally I split the HTMLWriter class into 2 &#8211; the plain HTMLWriter and a base class &#8211; HTMLWriterBase. The reason is simple &#8211; it makes it easier to maintain core\/internal functionality separately but also allow for another custom implementation of another type of xyzWriter.<\/p>\n<p>The DataTable specific methods were also enhanced to allow for a hyperlink (anchor tag) to be embedded based on one of the fields inside the DataTable. It allows you to specify an editing page, the parameter name passed to the page, the linked id field from the DataTable and the display field in which the link will be placed.<\/p>\n<p>Available <a title=\"HTMLWriter1.2.zip\" href=\"http:\/\/www.hen.co.za\/downloads\/HTMLWriter1.2.zip\">here<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>And with another iteration the library has improved yet again. See the previous or original posts for details about where it came from. With this version I&#8217;ve made some big changes internally to the library. You can still use the &hellip;<\/p>\n<p class=\"read-more\"><a href=\"https:\/\/hen.co.za\/blog\/2011\/05\/htmlwriter-1-2\/\">Read more &raquo;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[7,8,9,303,10],"class_list":["post-159","post","type-post","status-publish","format-standard","hentry","category-development","tag-net","tag-c","tag-code","tag-development","tag-winforms"],"_links":{"self":[{"href":"https:\/\/hen.co.za\/blog\/wp-json\/wp\/v2\/posts\/159","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hen.co.za\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hen.co.za\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hen.co.za\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/hen.co.za\/blog\/wp-json\/wp\/v2\/comments?post=159"}],"version-history":[{"count":6,"href":"https:\/\/hen.co.za\/blog\/wp-json\/wp\/v2\/posts\/159\/revisions"}],"predecessor-version":[{"id":165,"href":"https:\/\/hen.co.za\/blog\/wp-json\/wp\/v2\/posts\/159\/revisions\/165"}],"wp:attachment":[{"href":"https:\/\/hen.co.za\/blog\/wp-json\/wp\/v2\/media?parent=159"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hen.co.za\/blog\/wp-json\/wp\/v2\/categories?post=159"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hen.co.za\/blog\/wp-json\/wp\/v2\/tags?post=159"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}