• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

jstedfast / HtmlKit / 1.2.0.266

04 Oct 2025 02:27PM UTC coverage: 99.412% (+0.001%) from 99.411%
1.2.0.266

push

coveralls.net

jstedfast
Added leaveOpen parameters for HtmlWriter .ctors

2873 of 2890 relevant lines covered (99.41%)

0.99 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.34
/HtmlKit/HtmlWriter.cs
1
//
2
// HtmlWriter.cs
3
//
4
// Author: Jeffrey Stedfast <jestedfa@microsoft.com>
5
//
6
// Copyright (c) 2015-2025 Jeffrey Stedfast <jestedfa@microsoft.com>
7
//
8
// Permission is hereby granted, free of charge, to any person obtaining a copy
9
// of this software and associated documentation files (the "Software"), to deal
10
// in the Software without restriction, including without limitation the rights
11
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
// copies of the Software, and to permit persons to whom the Software is
13
// furnished to do so, subject to the following conditions:
14
//
15
// The above copyright notice and this permission notice shall be included in
16
// all copies or substantial portions of the Software.
17
//
18
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
// THE SOFTWARE.
25
//
26

27
using System;
28
using System.IO;
29
using System.Text;
30

31
namespace HtmlKit {
32
        /// <summary>
33
        /// An HTML writer.
34
        /// </summary>
35
        /// <remarks>
36
        /// An HTML writer.
37
        /// </remarks>
38
        public class HtmlWriter : IDisposable
39
        {
40
                readonly TextWriter html;
41
                readonly bool leaveOpen;
42
                bool disposed;
43
                bool empty;
44

45
                /// <summary>
46
                /// Initialize a new instance of the <see cref="HtmlWriter"/> class.
47
                /// </summary>
48
                /// <remarks>
49
                /// <para>Initializes a new instance of the <see cref="HtmlWriter"/> class for the specified stream
50
                /// by using the specified encoding and optionally leaves the stream open.</para>
51
                /// </remarks>
52
                /// <param name="stream">The output stream.</param>
53
                /// <param name="encoding">The encoding to use for the output.</param>
54
                /// <param name="leaveOpen"><see langword="true"/> if the <paramref name="stream"/> should be left open
55
                /// when this <see cref="HtmlWriter"/> is disposed; otherwise, <see langword="false"/>.</param>
56
                /// <exception cref="System.ArgumentNullException">
57
                /// <para><paramref name="stream"/> is <see langword="null"/>.</para>
58
                /// <para>-or-</para>
59
                /// <para><paramref name="encoding"/> is <see langword="null"/>.</para>
60
                /// </exception>
61
                public HtmlWriter (Stream stream, Encoding encoding, bool leaveOpen = false)
1✔
62
                {
1✔
63
                        if (stream is null)
1✔
64
                                throw new ArgumentNullException (nameof (stream));
1✔
65

66
                        if (encoding is null)
1✔
67
                                throw new ArgumentNullException (nameof (encoding));
1✔
68

69
                        html = new StreamWriter (stream, encoding, 4096, leaveOpen);
1✔
70
                        this.leaveOpen = false;
1✔
71
                }
1✔
72

73
                /// <summary>
74
                /// Initialize a new instance of the <see cref="HtmlWriter"/> class.
75
                /// </summary>
76
                /// <remarks>
77
                /// <para>Initializes a new instance of the <see cref="HtmlWriter"/> class using the specified
78
                /// text writer, optionally leaving the text writer open.</para>
79
                /// </remarks>
80
                /// <param name="output">The output text writer.</param>
81
                /// <param name="leaveOpen"><see langword="true"/> if the <paramref name="output"/> should be left open
82
                /// when this <see cref="HtmlWriter"/> is disposed; otherwise, <see langword="false"/>.</param>
83
                /// <exception cref="System.ArgumentNullException">
84
                /// <paramref name="output"/> is <see langword="null"/>.
85
                /// </exception>
86
                public HtmlWriter (TextWriter output, bool leaveOpen = false)
1✔
87
                {
1✔
88
                        if (output is null)
1✔
89
                                throw new ArgumentNullException (nameof (output));
1✔
90

91
                        html = output;
1✔
92
                        this.leaveOpen = leaveOpen;
1✔
93
                }
1✔
94

95
                /// <summary>
96
                /// Release unmanaged resources and perform other cleanup operations before the
97
                /// <see cref="HtmlWriter"/> is reclaimed by garbage collection.
98
                /// </summary>
99
                /// <remarks>
100
                /// Releases unmanaged resources and performs other cleanup operations before the
101
                /// <see cref="HtmlWriter"/> is reclaimed by garbage collection.
102
                /// </remarks>
103
                ~HtmlWriter ()
104
                {
×
105
                        Dispose (false);
×
106
                }
×
107

108
                void CheckDisposed ()
109
                {
1✔
110
                        if (disposed)
1✔
111
                                throw new ObjectDisposedException ("HtmlWriter");
×
112
                }
1✔
113

114
                /// <summary>
115
                /// Get the current state of the writer.
116
                /// </summary>
117
                /// <remarks>
118
                /// Gets the current state of the writer.
119
                /// </remarks>
120
                /// <value>The state of the writer.</value>
121
                public HtmlWriterState WriterState {
122
                        get; private set;
123
                }
124

125
                static void ValidateArguments (char[] buffer, int index, int count)
126
                {
1✔
127
                        if (buffer is null)
1✔
128
                                throw new ArgumentNullException (nameof (buffer));
1✔
129

130
                        if (index < 0 || index > buffer.Length)
1✔
131
                                throw new ArgumentOutOfRangeException (nameof (index));
1✔
132

133
                        if (count < 0 || count > (buffer.Length - index))
1✔
134
                                throw new ArgumentOutOfRangeException (nameof (count));
1✔
135
                }
1✔
136

137
                static void ValidateAttributeName (string name)
138
                {
1✔
139
                        if (name is null)
1✔
140
                                throw new ArgumentNullException (nameof (name));
1✔
141

142
                        if (name.Length == 0)
1✔
143
                                throw new ArgumentException ("The attribute name cannot be empty.", nameof (name));
1✔
144

145
                        if (!HtmlUtils.IsValidAttributeName (name))
1✔
146
                                throw new ArgumentException ($"Invalid attribute name: {name}", nameof (name));
1✔
147
                }
1✔
148

149
                static void ValidateTagName (string name)
150
                {
1✔
151
                        if (name is null)
1✔
152
                                throw new ArgumentNullException (nameof (name));
1✔
153

154
                        if (name.Length == 0)
1✔
155
                                throw new ArgumentException ("The tag name cannot be empty.", nameof (name));
1✔
156

157
                        if (!HtmlUtils.IsValidTagName (name))
1✔
158
                                throw new ArgumentException ($"Invalid tag name: {name}", nameof (name));
1✔
159
                }
1✔
160

161
                void EncodeAttributeName (string name)
162
                {
1✔
163
                        if (WriterState == HtmlWriterState.Default)
1✔
164
                                throw new InvalidOperationException ("Cannot write attributes in the Default state.");
1✔
165

166
                        html.Write (' ');
1✔
167
                        html.Write (name);
1✔
168
                        WriterState = HtmlWriterState.Attribute;
1✔
169
                }
1✔
170

171
                void EncodeAttributeValue (char[] value, int startIndex, int count)
172
                {
1✔
173
                        if (WriterState != HtmlWriterState.Attribute)
1✔
174
                                throw new InvalidOperationException ("Attribute values can only be written in the Attribute state.");
1✔
175

176
                        html.Write ('=');
1✔
177
                        HtmlUtils.HtmlAttributeEncode (html, value, startIndex, count);
1✔
178
                        WriterState = HtmlWriterState.Tag;
1✔
179
                }
1✔
180

181
                void EncodeAttributeValue (string value)
182
                {
1✔
183
                        if (WriterState != HtmlWriterState.Attribute)
1✔
184
                                throw new InvalidOperationException ("Attribute values can only be written in the Attribute state.");
1✔
185

186
                        html.Write ('=');
1✔
187
                        HtmlUtils.HtmlAttributeEncode (html, value);
1✔
188
                        WriterState = HtmlWriterState.Tag;
1✔
189
                }
1✔
190

191
                void EncodeAttribute (string name, char[] value, int startIndex, int count)
192
                {
1✔
193
                        EncodeAttributeName (name);
1✔
194
                        EncodeAttributeValue (value, startIndex, count);
1✔
195
                }
1✔
196

197
                void EncodeAttribute (string name, string value)
198
                {
1✔
199
                        EncodeAttributeName (name);
1✔
200
                        EncodeAttributeValue (value);
1✔
201
                }
1✔
202

203
                /// <summary>
204
                /// Write the attribute to the output stream.
205
                /// </summary>
206
                /// <remarks>
207
                /// Writes the attribute to the output stream.
208
                /// </remarks>
209
                /// <param name="id">The attribute identifier.</param>
210
                /// <param name="buffer">A buffer containing the attribute value.</param>
211
                /// <param name="index">The starting index of the attribute value.</param>
212
                /// <param name="count">The number of characters in the attribute value.</param>
213
                /// <exception cref="System.ArgumentException">
214
                /// <paramref name="id"/> is not a valid HTML attribute identifier.
215
                /// </exception>
216
                /// <exception cref="System.ArgumentNullException">
217
                /// <paramref name="buffer"/> is <see langword="null"/>.
218
                /// </exception>
219
                /// <exception cref="System.ArgumentOutOfRangeException">
220
                /// <para><paramref name="index"/> is less than zero or greater than the length of
221
                /// <paramref name="buffer"/>.</para>
222
                /// <para>-or-</para>
223
                /// <para><paramref name="index"/> and <paramref name="count"/> do not specify
224
                /// a valid range in the <paramref name="buffer"/>.</para>
225
                /// </exception>
226
                /// <exception cref="System.InvalidOperationException">
227
                /// The <see cref="HtmlWriter"/> is not in a state that allows writing attributes.
228
                /// </exception>
229
                /// <exception cref="System.ObjectDisposedException">
230
                /// The <see cref="HtmlWriter"/> has been disposed.
231
                /// </exception>
232
                public void WriteAttribute (HtmlAttributeId id, char[] buffer, int index, int count)
233
                {
1✔
234
                        if (id == HtmlAttributeId.Unknown)
1✔
235
                                throw new ArgumentException ("Invalid attribute.", nameof (id));
1✔
236

237
                        ValidateArguments (buffer, index, count);
1✔
238

239
                        CheckDisposed ();
1✔
240

241
                        EncodeAttribute (id.ToAttributeName (), buffer, index, count);
1✔
242
                }
1✔
243

244
                /// <summary>
245
                /// Write the attribute to the output stream.
246
                /// </summary>
247
                /// <remarks>
248
                /// Writes the attribute to the output stream.
249
                /// </remarks>
250
                /// <param name="name">The attribute name.</param>
251
                /// <param name="buffer">A buffer containing the attribute value.</param>
252
                /// <param name="index">The starting index of the attribute value.</param>
253
                /// <param name="count">The number of characters in the attribute value.</param>
254
                /// <exception cref="System.ArgumentNullException">
255
                /// <para><paramref name="name"/> is <see langword="null"/>.</para>
256
                /// <para>-or-</para>
257
                /// <para><paramref name="buffer"/> is <see langword="null"/>.</para>
258
                /// </exception>
259
                /// <exception cref="System.ArgumentOutOfRangeException">
260
                /// <para><paramref name="index"/> is less than zero or greater than the length of
261
                /// <paramref name="buffer"/>.</para>
262
                /// <para>-or-</para>
263
                /// <para><paramref name="index"/> and <paramref name="count"/> do not specify
264
                /// a valid range in the <paramref name="buffer"/>.</para>
265
                /// </exception>
266
                /// <exception cref="System.ArgumentException">
267
                /// <paramref name="name"/> is an invalid attribute name.
268
                /// </exception>
269
                /// <exception cref="System.InvalidOperationException">
270
                /// The <see cref="HtmlWriter"/> is not in a state that allows writing attributes.
271
                /// </exception>
272
                /// <exception cref="System.ObjectDisposedException">
273
                /// The <see cref="HtmlWriter"/> has been disposed.
274
                /// </exception>
275
                public void WriteAttribute (string name, char[] buffer, int index, int count)
276
                {
1✔
277
                        ValidateAttributeName (name);
1✔
278
                        ValidateArguments (buffer, index, count);
1✔
279
                        CheckDisposed ();
1✔
280

281
                        EncodeAttribute (name, buffer, index, count);
1✔
282
                }
1✔
283

284
                /// <summary>
285
                /// Write the attribute to the output stream.
286
                /// </summary>
287
                /// <remarks>
288
                /// Writes the attribute to the output stream.
289
                /// </remarks>
290
                /// <param name="id">The attribute identifier.</param>
291
                /// <param name="value">The attribute value.</param>
292
                /// <exception cref="System.ArgumentException">
293
                /// <paramref name="id"/> is not a valid HTML attribute identifier.
294
                /// </exception>
295
                /// <exception cref="System.ArgumentNullException">
296
                /// <paramref name="value"/> is <see langword="null"/>.
297
                /// </exception>
298
                /// <exception cref="System.InvalidOperationException">
299
                /// The <see cref="HtmlWriter"/> is not in a state that allows writing attributes.
300
                /// </exception>
301
                /// <exception cref="System.ObjectDisposedException">
302
                /// The <see cref="HtmlWriter"/> has been disposed.
303
                /// </exception>
304
                public void WriteAttribute (HtmlAttributeId id, string value)
305
                {
1✔
306
                        if (id == HtmlAttributeId.Unknown)
1✔
307
                                throw new ArgumentException ("Invalid attribute.", nameof (id));
1✔
308

309
                        if (value is null)
1✔
310
                                throw new ArgumentNullException (nameof (value));
1✔
311

312
                        CheckDisposed ();
1✔
313

314
                        EncodeAttribute (id.ToAttributeName (), value);
1✔
315
                }
1✔
316

317
                /// <summary>
318
                /// Write the attribute to the output stream.
319
                /// </summary>
320
                /// <remarks>
321
                /// Writes the attribute to the output stream.
322
                /// </remarks>
323
                /// <param name="name">The attribute name.</param>
324
                /// <param name="value">The attribute value.</param>
325
                /// <exception cref="System.ArgumentNullException">
326
                /// <para><paramref name="name"/> is <see langword="null"/>.</para>
327
                /// <para>-or-</para>
328
                /// <para><paramref name="value"/> is <see langword="null"/>.</para>
329
                /// </exception>
330
                /// <exception cref="System.ArgumentException">
331
                /// <paramref name="name"/> is an invalid attribute name.
332
                /// </exception>
333
                /// <exception cref="System.InvalidOperationException">
334
                /// The <see cref="HtmlWriter"/> is not in a state that allows writing attributes.
335
                /// </exception>
336
                /// <exception cref="System.ObjectDisposedException">
337
                /// The <see cref="HtmlWriter"/> has been disposed.
338
                /// </exception>
339
                public void WriteAttribute (string name, string value)
340
                {
1✔
341
                        ValidateAttributeName (name);
1✔
342

343
                        if (value is null)
1✔
344
                                throw new ArgumentNullException (nameof (value));
1✔
345

346
                        CheckDisposed ();
1✔
347

348
                        EncodeAttribute (name, value);
1✔
349
                }
1✔
350

351
                /// <summary>
352
                /// Write the attribute to the output stream.
353
                /// </summary>
354
                /// <remarks>
355
                /// Writes the attribute to the output stream.
356
                /// </remarks>
357
                /// <param name="attribute">The attribute.</param>
358
                /// <exception cref="System.ArgumentNullException">
359
                /// <paramref name="attribute"/> is <see langword="null"/>.
360
                /// </exception>
361
                /// <exception cref="System.InvalidOperationException">
362
                /// The <see cref="HtmlWriter"/> is not in a state that allows writing attributes.
363
                /// </exception>
364
                /// <exception cref="System.ObjectDisposedException">
365
                /// The <see cref="HtmlWriter"/> has been disposed.
366
                /// </exception>
367
                public void WriteAttribute (HtmlAttribute attribute)
368
                {
1✔
369
                        if (attribute is null)
1✔
370
                                throw new ArgumentNullException (nameof (attribute));
1✔
371

372
                        EncodeAttributeName (attribute.Name);
1✔
373

374
                        if (attribute.Value != null)
1✔
375
                                EncodeAttributeValue (attribute.Value);
1✔
376
                }
1✔
377

378
                /// <summary>
379
                /// Write the attribute name to the output stream.
380
                /// </summary>
381
                /// <remarks>
382
                /// Writes the attribute name to the output stream.
383
                /// </remarks>
384
                /// <param name="id">The attribute identifier.</param>
385
                /// <exception cref="System.ArgumentException">
386
                /// <paramref name="id"/> is not a valid HTML attribute identifier.
387
                /// </exception>
388
                /// <exception cref="System.InvalidOperationException">
389
                /// The <see cref="HtmlWriter"/> is not in a state that allows writing attributes.
390
                /// </exception>
391
                /// <exception cref="System.ObjectDisposedException">
392
                /// The <see cref="HtmlWriter"/> has been disposed.
393
                /// </exception>
394
                public void WriteAttributeName (HtmlAttributeId id)
395
                {
1✔
396
                        if (id == HtmlAttributeId.Unknown)
1✔
397
                                throw new ArgumentException ("Invalid attribute.", nameof (id));
1✔
398

399
                        if (WriterState == HtmlWriterState.Default)
1✔
400
                                throw new InvalidOperationException ("Cannot write attributes in the Default state.");
1✔
401

402
                        CheckDisposed ();
1✔
403

404
                        EncodeAttributeName (id.ToAttributeName ());
1✔
405
                }
1✔
406

407
                /// <summary>
408
                /// Write the attribute name to the output stream.
409
                /// </summary>
410
                /// <remarks>
411
                /// Writes the attribute name to the output stream.
412
                /// </remarks>
413
                /// <param name="name">The attribute name.</param>
414
                /// <exception cref="System.ArgumentNullException">
415
                /// <paramref name="name"/> is <see langword="null"/>.
416
                /// </exception>
417
                /// <exception cref="System.ArgumentException">
418
                /// <paramref name="name"/> is an invalid attribute name.
419
                /// </exception>
420
                /// <exception cref="System.InvalidOperationException">
421
                /// The <see cref="HtmlWriter"/> is not in a state that allows writing attributes.
422
                /// </exception>
423
                /// <exception cref="System.ObjectDisposedException">
424
                /// The <see cref="HtmlWriter"/> has been disposed.
425
                /// </exception>
426
                public void WriteAttributeName (string name)
427
                {
1✔
428
                        ValidateAttributeName (name);
1✔
429

430
                        if (WriterState == HtmlWriterState.Default)
1✔
431
                                throw new InvalidOperationException ("Cannot write attributes in the Default state.");
1✔
432

433
                        CheckDisposed ();
1✔
434

435
                        EncodeAttributeName (name);
1✔
436
                }
1✔
437

438
                /// <summary>
439
                /// Write the attribute value to the output stream.
440
                /// </summary>
441
                /// <remarks>
442
                /// Writes the attribute value to the output stream.
443
                /// </remarks>
444
                /// <param name="buffer">A buffer containing the attribute value.</param>
445
                /// <param name="index">The starting index of the attribute value.</param>
446
                /// <param name="count">The number of characters in the attribute value.</param>
447
                /// <exception cref="System.ArgumentNullException">
448
                /// <paramref name="buffer"/> is <see langword="null"/>.
449
                /// </exception>
450
                /// <exception cref="System.ArgumentOutOfRangeException">
451
                /// <para><paramref name="index"/> is less than zero or greater than the length of
452
                /// <paramref name="buffer"/>.</para>
453
                /// <para>-or-</para>
454
                /// <para><paramref name="index"/> and <paramref name="count"/> do not specify
455
                /// a valid range in the <paramref name="buffer"/>.</para>
456
                /// </exception>
457
                /// <exception cref="System.InvalidOperationException">
458
                /// The <see cref="HtmlWriter"/> is not in a state that allows writing attribute values.
459
                /// </exception>
460
                /// <exception cref="System.ObjectDisposedException">
461
                /// The <see cref="HtmlWriter"/> has been disposed.
462
                /// </exception>
463
                public void WriteAttributeValue (char[] buffer, int index, int count)
464
                {
1✔
465
                        ValidateArguments (buffer, index, count);
1✔
466
                        CheckDisposed ();
1✔
467

468
                        EncodeAttributeValue (buffer, index, count);
1✔
469
                }
1✔
470

471
                /// <summary>
472
                /// Write the attribute value to the output stream.
473
                /// </summary>
474
                /// <remarks>
475
                /// Writes the attribute value to the output stream.
476
                /// </remarks>
477
                /// <param name="value">The attribute value.</param>
478
                /// <exception cref="System.ArgumentNullException">
479
                /// <paramref name="value"/> is <see langword="null"/>.
480
                /// </exception>
481
                /// <exception cref="System.InvalidOperationException">
482
                /// The <see cref="HtmlWriter"/> is not in a state that allows writing attribute values.
483
                /// </exception>
484
                /// <exception cref="System.ObjectDisposedException">
485
                /// The <see cref="HtmlWriter"/> has been disposed.
486
                /// </exception>
487
                public void WriteAttributeValue (string value)
488
                {
1✔
489
                        if (value is null)
1✔
490
                                throw new ArgumentNullException (nameof (value));
1✔
491

492
                        CheckDisposed ();
1✔
493

494
                        EncodeAttributeValue (value);
1✔
495
                }
1✔
496

497
                void FlushWriterState ()
498
                {
1✔
499
                        if (WriterState != HtmlWriterState.Default) {
1✔
500
                                WriterState = HtmlWriterState.Default;
1✔
501
                                html.Write (empty ? "/>" : ">");
1✔
502
                                empty = false;
1✔
503
                        }
1✔
504
                }
1✔
505

506
                /// <summary>
507
                /// Write an empty element tag.
508
                /// </summary>
509
                /// <remarks>
510
                /// Writes an empty element tag.
511
                /// </remarks>
512
                /// <param name="id">The HTML tag identifier.</param>
513
                /// <exception cref="System.ArgumentException">
514
                /// <paramref name="id"/> is not a valid HTML tag identifier.
515
                /// </exception>
516
                /// <exception cref="System.ObjectDisposedException">
517
                /// The <see cref="HtmlWriter"/> has been disposed.
518
                /// </exception>
519
                public void WriteEmptyElementTag (HtmlTagId id)
520
                {
1✔
521
                        if (id == HtmlTagId.Unknown)
1✔
522
                                throw new ArgumentException ("Invalid tag.", nameof (id));
1✔
523

524
                        CheckDisposed ();
1✔
525

526
                        FlushWriterState ();
1✔
527

528
                        html.Write ($"<{id.ToHtmlTagName ()}");
1✔
529
                        WriterState = HtmlWriterState.Tag;
1✔
530
                        empty = true;
1✔
531
                }
1✔
532

533
                /// <summary>
534
                /// Write an empty element tag.
535
                /// </summary>
536
                /// <remarks>
537
                /// Writes an empty element tag.
538
                /// </remarks>
539
                /// <param name="name">The name of the HTML tag.</param>
540
                /// <exception cref="System.ArgumentNullException">
541
                /// <paramref name="name"/> is <see langword="null"/>.
542
                /// </exception>
543
                /// <exception cref="System.ArgumentException">
544
                /// <paramref name="name"/> is not a valid HTML tag.
545
                /// </exception>
546
                /// <exception cref="System.ObjectDisposedException">
547
                /// The <see cref="HtmlWriter"/> has been disposed.
548
                /// </exception>
549
                public void WriteEmptyElementTag (string name)
550
                {
1✔
551
                        ValidateTagName (name);
1✔
552
                        CheckDisposed ();
1✔
553

554
                        FlushWriterState ();
1✔
555

556
                        html.Write ($"<{name}");
1✔
557
                        WriterState = HtmlWriterState.Tag;
1✔
558
                        empty = true;
1✔
559
                }
1✔
560

561
                /// <summary>
562
                /// Write an end tag.
563
                /// </summary>
564
                /// <remarks>
565
                /// Writes an end tag.
566
                /// </remarks>
567
                /// <param name="id">The HTML tag identifier.</param>
568
                /// <exception cref="System.ArgumentException">
569
                /// <paramref name="id"/> is not a valid HTML tag identifier.
570
                /// </exception>
571
                /// <exception cref="System.ObjectDisposedException">
572
                /// The <see cref="HtmlWriter"/> has been disposed.
573
                /// </exception>
574
                public void WriteEndTag (HtmlTagId id)
575
                {
1✔
576
                        if (id == HtmlTagId.Unknown)
1✔
577
                                throw new ArgumentException ("Invalid tag.", nameof (id));
1✔
578

579
                        CheckDisposed ();
1✔
580

581
                        FlushWriterState ();
1✔
582

583
                        html.Write ($"</{id.ToHtmlTagName ()}>");
1✔
584
                }
1✔
585

586
                /// <summary>
587
                /// Write an end tag.
588
                /// </summary>
589
                /// <remarks>
590
                /// Writes an end tag.
591
                /// </remarks>
592
                /// <param name="name">The name of the HTML tag.</param>
593
                /// <exception cref="System.ArgumentNullException">
594
                /// <paramref name="name"/> is <see langword="null"/>.
595
                /// </exception>
596
                /// <exception cref="System.ArgumentException">
597
                /// <paramref name="name"/> is not a valid HTML tag.
598
                /// </exception>
599
                /// <exception cref="System.ObjectDisposedException">
600
                /// The <see cref="HtmlWriter"/> has been disposed.
601
                /// </exception>
602
                public void WriteEndTag (string name)
603
                {
1✔
604
                        ValidateTagName (name);
1✔
605
                        CheckDisposed ();
1✔
606

607
                        FlushWriterState ();
1✔
608

609
                        html.Write ($"</{name}>");
1✔
610
                }
1✔
611

612
                /// <summary>
613
                /// Write a buffer containing HTML markup directly to the output, without escaping special characters.
614
                /// </summary>
615
                /// <remarks>
616
                /// Writes a buffer containing HTML markup directly to the output, without escaping special characters.
617
                /// </remarks>
618
                /// <param name="buffer">The buffer containing HTML markup.</param>
619
                /// <param name="index">The index of the first character to write.</param>
620
                /// <param name="count">The number of characters to write.</param>
621
                /// <exception cref="System.ArgumentNullException">
622
                /// <paramref name="buffer"/> is <see langword="null"/>.
623
                /// </exception>
624
                /// <exception cref="System.ArgumentOutOfRangeException">
625
                /// <para><paramref name="index"/> is less than zero or greater than the length of
626
                /// <paramref name="buffer"/>.</para>
627
                /// <para>-or-</para>
628
                /// <para><paramref name="index"/> and <paramref name="count"/> do not specify
629
                /// a valid range in the <paramref name="buffer"/>.</para>
630
                /// </exception>
631
                /// <exception cref="System.ObjectDisposedException">
632
                /// The <see cref="HtmlWriter"/> has been disposed.
633
                /// </exception>
634
                public void WriteMarkupText (char[] buffer, int index, int count)
635
                {
1✔
636
                        ValidateArguments (buffer, index, count);
1✔
637
                        CheckDisposed ();
1✔
638

639
                        FlushWriterState ();
1✔
640

641
                        html.Write (buffer, index, count);
1✔
642
                }
1✔
643

644
                /// <summary>
645
                /// Write a string containing HTML markup directly to the output, without escaping special characters.
646
                /// </summary>
647
                /// <remarks>
648
                /// Writes a string containing HTML markup directly to the output, without escaping special characters.
649
                /// </remarks>
650
                /// <param name="value">The string containing HTML markup.</param>
651
                /// <exception cref="System.ArgumentNullException">
652
                /// <paramref name="value"/> is <see langword="null"/>.
653
                /// </exception>
654
                /// <exception cref="System.ObjectDisposedException">
655
                /// The <see cref="HtmlWriter"/> has been disposed.
656
                /// </exception>
657
                public void WriteMarkupText (string value)
658
                {
1✔
659
                        if (value is null)
1✔
660
                                throw new ArgumentNullException (nameof (value));
1✔
661

662
                        CheckDisposed ();
1✔
663

664
                        FlushWriterState ();
1✔
665

666
                        html.Write (value);
1✔
667
                }
1✔
668

669
                /// <summary>
670
                /// Write a start tag.
671
                /// </summary>
672
                /// <remarks>
673
                /// Writes a start tag.
674
                /// </remarks>
675
                /// <param name="id">The HTML tag identifier.</param>
676
                /// <exception cref="System.ArgumentException">
677
                /// <paramref name="id"/> is not a valid HTML tag identifier.
678
                /// </exception>
679
                /// <exception cref="System.ObjectDisposedException">
680
                /// The <see cref="HtmlWriter"/> has been disposed.
681
                /// </exception>
682
                public void WriteStartTag (HtmlTagId id)
683
                {
1✔
684
                        if (id == HtmlTagId.Unknown)
1✔
685
                                throw new ArgumentException ("Invalid tag.", nameof (id));
1✔
686

687
                        CheckDisposed ();
1✔
688

689
                        FlushWriterState ();
1✔
690

691
                        html.Write ($"<{id.ToHtmlTagName ()}");
1✔
692
                        WriterState = HtmlWriterState.Tag;
1✔
693
                }
1✔
694

695
                /// <summary>
696
                /// Write a start tag.
697
                /// </summary>
698
                /// <remarks>
699
                /// Writes a start tag.
700
                /// </remarks>
701
                /// <param name="name">The name of the HTML tag.</param>
702
                /// <exception cref="System.ArgumentNullException">
703
                /// <paramref name="name"/> is <see langword="null"/>.
704
                /// </exception>
705
                /// <exception cref="System.ArgumentException">
706
                /// <paramref name="name"/> is not a valid HTML tag.
707
                /// </exception>
708
                /// <exception cref="System.ObjectDisposedException">
709
                /// The <see cref="HtmlWriter"/> has been disposed.
710
                /// </exception>
711
                public void WriteStartTag (string name)
712
                {
1✔
713
                        ValidateTagName (name);
1✔
714
                        CheckDisposed ();
1✔
715

716
                        FlushWriterState ();
1✔
717

718
                        html.Write ($"<{name}");
1✔
719
                        WriterState = HtmlWriterState.Tag;
1✔
720
                }
1✔
721

722
                /// <summary>
723
                /// Write text to the output stream, escaping special characters.
724
                /// </summary>
725
                /// <remarks>
726
                /// Writes text to the output stream, escaping special characters.
727
                /// </remarks>
728
                /// <param name="buffer">The text buffer.</param>
729
                /// <param name="index">The index of the first character to write.</param>
730
                /// <param name="count">The number of characters to write.</param>
731
                /// <exception cref="System.ArgumentNullException">
732
                /// <paramref name="buffer"/> is <see langword="null"/>.
733
                /// </exception>
734
                /// <exception cref="System.ArgumentOutOfRangeException">
735
                /// <para><paramref name="index"/> is less than zero or greater than the length of
736
                /// <paramref name="buffer"/>.</para>
737
                /// <para>-or-</para>
738
                /// <para><paramref name="index"/> and <paramref name="count"/> do not specify
739
                /// a valid range in the <paramref name="buffer"/>.</para>
740
                /// </exception>
741
                /// <exception cref="System.ObjectDisposedException">
742
                /// The <see cref="HtmlWriter"/> has been disposed.
743
                /// </exception>
744
                public void WriteText (char[] buffer, int index, int count)
745
                {
1✔
746
                        ValidateArguments (buffer, index, count);
1✔
747
                        CheckDisposed ();
1✔
748

749
                        FlushWriterState ();
1✔
750

751
                        if (count > 0)
1✔
752
                                HtmlUtils.HtmlEncode (html, buffer, index, count);
1✔
753
                }
1✔
754

755
                /// <summary>
756
                /// Write text to the output stream, escaping special characters.
757
                /// </summary>
758
                /// <remarks>
759
                /// Writes text to the output stream, escaping special characters.
760
                /// </remarks>
761
                /// <param name="value">The text.</param>
762
                /// <exception cref="System.ArgumentNullException">
763
                /// <paramref name="value"/> is <see langword="null"/>.
764
                /// </exception>
765
                /// <exception cref="System.ObjectDisposedException">
766
                /// The <see cref="HtmlWriter"/> has been disposed.
767
                /// </exception>
768
                public void WriteText (string value)
769
                {
1✔
770
                        if (value is null)
1✔
771
                                throw new ArgumentNullException (nameof (value));
1✔
772

773
                        CheckDisposed ();
1✔
774

775
                        FlushWriterState ();
1✔
776

777
                        if (value.Length > 0)
1✔
778
                                HtmlUtils.HtmlEncode (html, value.ToCharArray (), 0, value.Length);
1✔
779
                }
1✔
780

781
                /// <summary>
782
                /// Write text to the output stream, escaping special characters.
783
                /// </summary>
784
                /// <remarks>
785
                /// Writes text to the output stream, escaping special characters.
786
                /// </remarks>
787
                /// <param name="format">A composit format string.</param>
788
                /// <param name="args">An object array that contains zero or more objects to format.</param>
789
                /// <exception cref="System.ArgumentNullException">
790
                /// <para><paramref name="format"/> is <see langword="null"/>.</para>
791
                /// <para>-or-</para>
792
                /// <para><paramref name="args"/> is <see langword="null"/>.</para>
793
                /// </exception>
794
                /// <exception cref="System.ObjectDisposedException">
795
                /// The <see cref="HtmlWriter"/> has been disposed.
796
                /// </exception>
797
                public void WriteText (string format, params object[] args)
798
                {
1✔
799
                        WriteText (string.Format (format, args));
1✔
800
                }
1✔
801

802
                /// <summary>
803
                /// Write a token to the output stream.
804
                /// </summary>
805
                /// <remarks>
806
                /// Writes a token that was emitted by the <see cref="HtmlTokenizer"/>
807
                /// to the output stream.
808
                /// </remarks>
809
                /// <param name="token">The HTML token.</param>
810
                /// <exception cref="System.ArgumentNullException">
811
                /// <paramref name="token"/> is <see langword="null"/>.
812
                /// </exception>
813
                /// <exception cref="System.ObjectDisposedException">
814
                /// The <see cref="HtmlWriter"/> has been disposed.
815
                /// </exception>
816
                public void WriteToken (HtmlToken token)
817
                {
1✔
818
                        if (token is null)
1✔
819
                                throw new ArgumentNullException (nameof (token));
1✔
820

821
                        CheckDisposed ();
1✔
822

823
                        FlushWriterState ();
1✔
824

825
                        token.WriteTo (html);
1✔
826
                }
1✔
827

828
                /// <summary>
829
                /// Flush any remaining state to the output stream.
830
                /// </summary>
831
                /// <remarks>
832
                /// Flushes any remaining state to the output stream.
833
                /// </remarks>
834
                /// <exception cref="System.ObjectDisposedException">
835
                /// The <see cref="HtmlWriter"/> has been disposed.
836
                /// </exception>
837
                public void Flush ()
838
                {
1✔
839
                        CheckDisposed ();
1✔
840

841
                        FlushWriterState ();
1✔
842

843
                        html.Flush ();
1✔
844
                }
1✔
845

846
                /// <summary>
847
                /// Release the unmanaged resources used by the <see cref="HtmlWriter"/> and
848
                /// optionally releases the managed resources.
849
                /// </summary>
850
                /// <remarks>
851
                /// Releases any unmanaged resources used by the <see cref="HtmlWriter"/> and
852
                /// optionally releases the managed resources.
853
                /// </remarks>
854
                /// <param name="disposing"><see langword="true" /> to release both managed and unmanaged resources;
855
                /// <see langword="false" /> to release only the unmanaged resources.</param>
856
                protected virtual void Dispose (bool disposing)
857
                {
1✔
858
                        if (disposing && !disposed && !leaveOpen)
1✔
859
                                html.Dispose ();
1✔
860

861
                        disposed = true;
1✔
862
                }
1✔
863

864
                /// <summary>
865
                /// Release all resource used by the <see cref="HtmlWriter"/> object.
866
                /// </summary>
867
                /// <remarks>Call <see cref="Dispose()"/> when you are finished using the <see cref="HtmlWriter"/>. The
868
                /// <see cref="Dispose()"/> method leaves the <see cref="HtmlWriter"/> in an unusable state. After calling
869
                /// <see cref="Dispose()"/>, you must release all references to the <see cref="HtmlWriter"/> so the garbage
870
                /// collector can reclaim the memory that the <see cref="HtmlWriter"/> was occupying.</remarks>
871
                public void Dispose ()
872
                {
1✔
873
                        Dispose (true);
1✔
874

875
                        GC.SuppressFinalize (this);
1✔
876
                }
1✔
877
        }
878
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc