/// <summary> /// Convert the contents of <paramref name="reader"/> from the <see cref="InputFormat"/> to the /// <see cref="OutputFormat"/> and uses the <paramref name="writer"/> to write the resulting text. /// </summary> /// <remarks> /// Converts the contents of <paramref name="reader"/> from the <see cref="InputFormat"/> to the /// <see cref="OutputFormat"/> and uses the <paramref name="writer"/> to write the resulting text. /// </remarks> /// <param name="reader">The text reader.</param> /// <param name="writer">The text writer.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="reader"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="writer"/> is <c>null</c>.</para> /// </exception> public override void Convert(TextReader reader, TextWriter writer) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } if (writer == null) { throw new ArgumentNullException(nameof(writer)); } if (!string.IsNullOrEmpty(Header)) { if (HeaderFormat == HeaderFooterFormat.Text) { var converter = new TextToHtml { OutputHtmlFragment = true }; using (var sr = new StringReader(Header)) converter.Convert(sr, writer); } else { writer.Write(Header); } } using (var htmlWriter = new HtmlWriter(writer)) { var callback = HtmlTagCallback ?? DefaultHtmlTagCallback; var stack = new List <HtmlToHtmlTagContext> (); var tokenizer = new HtmlTokenizer(reader); HtmlToHtmlTagContext ctx; HtmlToken token; while (tokenizer.ReadNextToken(out token)) { switch (token.Kind) { default: if (!SuppressContent(stack)) { htmlWriter.WriteToken(token); } break; case HtmlTokenKind.Comment: if (!FilterComments && !SuppressContent(stack)) { htmlWriter.WriteToken(token); } break; case HtmlTokenKind.Tag: var tag = (HtmlTagToken)token; if (!tag.IsEndTag) { //if (NormalizeHtml && AutoClosingTags.Contains (startTag.TagName) && // (ctx = Pop (stack, startTag.TagName)) != null && // ctx.InvokeCallbackForEndTag && !SuppressContent (stack)) { // var value = string.Format ("</{0}>", ctx.TagName); // var name = ctx.TagName; // // ctx = new HtmlToHtmlTagContext (new HtmlTokenTag (HtmlTokenKind.EndTag, name, value)) { // InvokeCallbackForEndTag = ctx.InvokeCallbackForEndTag, // SuppressInnerContent = ctx.SuppressInnerContent, // DeleteEndTag = ctx.DeleteEndTag, // DeleteTag = ctx.DeleteTag // }; // callback (ctx, htmlWriter); //} if (!tag.IsEmptyElement) { ctx = new HtmlToHtmlTagContext(tag); if (FilterHtml && ctx.TagId == HtmlTagId.Script) { ctx.SuppressInnerContent = true; ctx.DeleteEndTag = true; ctx.DeleteTag = true; } else if (!SuppressContent(stack)) { callback(ctx, htmlWriter); } stack.Add(ctx); } else if (!SuppressContent(stack)) { ctx = new HtmlToHtmlTagContext(tag); if (!FilterHtml || ctx.TagId != HtmlTagId.Script) { callback(ctx, htmlWriter); } } } else { if ((ctx = Pop(stack, tag.Name)) != null) { if (!SuppressContent(stack)) { if (ctx.InvokeCallbackForEndTag) { ctx = new HtmlToHtmlTagContext(tag) { InvokeCallbackForEndTag = ctx.InvokeCallbackForEndTag, SuppressInnerContent = ctx.SuppressInnerContent, DeleteEndTag = ctx.DeleteEndTag, DeleteTag = ctx.DeleteTag }; callback(ctx, htmlWriter); } else if (!ctx.DeleteEndTag) { htmlWriter.WriteEndTag(tag.Name); } } } else if (!SuppressContent(stack)) { ctx = new HtmlToHtmlTagContext(tag); callback(ctx, htmlWriter); } } break; } } htmlWriter.Flush(); } if (!string.IsNullOrEmpty(Footer)) { if (FooterFormat == HeaderFooterFormat.Text) { var converter = new TextToHtml { OutputHtmlFragment = true }; using (var sr = new StringReader(Footer)) converter.Convert(sr, writer); } else { writer.Write(Footer); } } }
/// <summary> /// Convert the contents of <paramref name="reader"/> from the <see cref="InputFormat"/> to the /// <see cref="OutputFormat"/> and uses the <paramref name="writer"/> to write the resulting text. /// </summary> /// <remarks> /// Converts the contents of <paramref name="reader"/> from the <see cref="InputFormat"/> to the /// <see cref="OutputFormat"/> and uses the <paramref name="writer"/> to write the resulting text. /// </remarks> /// <param name="reader">The text reader.</param> /// <param name="writer">The text writer.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="reader"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="writer"/> is <c>null</c>.</para> /// </exception> public override void Convert (TextReader reader, TextWriter writer) { if (reader == null) throw new ArgumentNullException (nameof (reader)); if (writer == null) throw new ArgumentNullException (nameof (writer)); if (!string.IsNullOrEmpty (Header)) { if (HeaderFormat == HeaderFooterFormat.Text) { var converter = new TextToHtml (); using (var sr = new StringReader (Header)) converter.Convert (sr, writer); } else { writer.Write (Header); } } using (var htmlWriter = new HtmlWriter (writer)) { var callback = HtmlTagCallback ?? DefaultHtmlTagCallback; var stack = new List<HtmlToHtmlTagContext> (); var tokenizer = new HtmlTokenizer (reader); HtmlToHtmlTagContext ctx; HtmlToken token; while (tokenizer.ReadNextToken (out token)) { switch (token.Kind) { default: if (!SuppressContent (stack)) htmlWriter.WriteToken (token); break; case HtmlTokenKind.Tag: var tag = (HtmlTagToken) token; if (!tag.IsEndTag) { //if (NormalizeHtml && AutoClosingTags.Contains (startTag.TagName) && // (ctx = Pop (stack, startTag.TagName)) != null && // ctx.InvokeCallbackForEndTag && !SuppressContent (stack)) { // var value = string.Format ("</{0}>", ctx.TagName); // var name = ctx.TagName; // // ctx = new HtmlToHtmlTagContext (new HtmlTokenTag (HtmlTokenKind.EndTag, name, value)) { // InvokeCallbackForEndTag = ctx.InvokeCallbackForEndTag, // SuppressInnerContent = ctx.SuppressInnerContent, // DeleteEndTag = ctx.DeleteEndTag, // DeleteTag = ctx.DeleteTag // }; // callback (ctx, htmlWriter); //} if (!tag.IsEmptyElement) { ctx = new HtmlToHtmlTagContext (tag); if (FilterHtml && ctx.TagId == HtmlTagId.Script) { ctx.SuppressInnerContent = true; ctx.DeleteEndTag = true; ctx.DeleteTag = true; } else if (!SuppressContent (stack)) { callback (ctx, htmlWriter); } stack.Add (ctx); } else if (!SuppressContent (stack)) { ctx = new HtmlToHtmlTagContext (tag); if (!FilterHtml || ctx.TagId != HtmlTagId.Script) callback (ctx, htmlWriter); } } else { if ((ctx = Pop (stack, tag.Name)) != null) { if (!SuppressContent (stack)) { if (ctx.InvokeCallbackForEndTag) { ctx = new HtmlToHtmlTagContext (tag) { InvokeCallbackForEndTag = ctx.InvokeCallbackForEndTag, SuppressInnerContent = ctx.SuppressInnerContent, DeleteEndTag = ctx.DeleteEndTag, DeleteTag = ctx.DeleteTag }; callback (ctx, htmlWriter); } else if (!ctx.DeleteEndTag) { htmlWriter.WriteEndTag (tag.Name); } } } else if (!SuppressContent (stack)) { ctx = new HtmlToHtmlTagContext (tag); callback (ctx, htmlWriter); } } break; } } htmlWriter.Flush (); } if (!string.IsNullOrEmpty (Footer)) { if (FooterFormat == HeaderFooterFormat.Text) { var converter = new TextToHtml (); using (var sr = new StringReader (Footer)) converter.Convert (sr, writer); } else { writer.Write (Footer); } } }
/// <summary> /// Convert the contents of <paramref name="reader"/> from the <see cref="InputFormat"/> to the /// <see cref="OutputFormat"/> and uses the <paramref name="writer"/> to write the resulting text. /// </summary> /// <remarks> /// Converts the contents of <paramref name="reader"/> from the <see cref="InputFormat"/> to the /// <see cref="OutputFormat"/> and uses the <paramref name="writer"/> to write the resulting text. /// </remarks> /// <param name="reader">The text reader.</param> /// <param name="writer">The text writer.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="reader"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="writer"/> is <c>null</c>.</para> /// </exception> public override void Convert(TextReader reader, TextWriter writer) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } if (writer == null) { throw new ArgumentNullException(nameof(writer)); } if (!string.IsNullOrEmpty(Header)) { if (HeaderFormat == HeaderFooterFormat.Text) { var converter = new TextToHtml(); using (var sr = new StringReader(Header)) converter.Convert(sr, writer); } else { writer.Write(Header); } } using (var htmlWriter = new HtmlWriter(writer)) { var callback = HtmlTagCallback ?? DefaultHtmlTagCallback; var stack = new List <FlowedToHtmlTagContext> (); var para = new StringBuilder(); int currentQuoteDepth = 0; int paraQuoteDepth = -1; int quoteDepth; string line; while ((line = reader.ReadLine()) != null) { // unquote the line line = Unquote(line, out quoteDepth); // remove space-stuffing if (line.Length > 0 && line[0] == ' ') { line = line.Substring(1); } if (para.Length == 0) { paraQuoteDepth = quoteDepth; } else if (quoteDepth != paraQuoteDepth) { // Note: according to rfc3676, when a folded line has a different quote // depth than the previous line, then quote-depth rules win and we need // to treat this as a new paragraph. WriteParagraph(htmlWriter, stack, ref currentQuoteDepth, para, paraQuoteDepth); paraQuoteDepth = quoteDepth; para.Length = 0; } para.Append(line); if (line.Length == 0 || line[line.Length - 1] != ' ') { // line did not end with a space, so the next line will start a new paragraph WriteParagraph(htmlWriter, stack, ref currentQuoteDepth, para, paraQuoteDepth); paraQuoteDepth = 0; para.Length = 0; } else if (DeleteSpace) { // Note: lines ending with a space mean that the next line is a continuation para.Length--; } } for (int i = stack.Count; i > 0; i--) { var ctx = stack[i - 1]; ctx.SetIsEndTag(true); if (ctx.InvokeCallbackForEndTag) { callback(ctx, htmlWriter); } else { ctx.WriteTag(htmlWriter); } } htmlWriter.Flush(); } if (!string.IsNullOrEmpty(Footer)) { if (FooterFormat == HeaderFooterFormat.Text) { var converter = new TextToHtml(); using (var sr = new StringReader(Footer)) converter.Convert(sr, writer); } else { writer.Write(Footer); } } }
/// <summary> /// Convert the contents of <paramref name="reader"/> from the <see cref="InputFormat"/> to the /// <see cref="OutputFormat"/> and uses the <paramref name="writer"/> to write the resulting text. /// </summary> /// <remarks> /// Converts the contents of <paramref name="reader"/> from the <see cref="InputFormat"/> to the /// <see cref="OutputFormat"/> and uses the <paramref name="writer"/> to write the resulting text. /// </remarks> /// <param name="reader">The text reader.</param> /// <param name="writer">The text writer.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="reader"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="writer"/> is <c>null</c>.</para> /// </exception> public override void Convert (TextReader reader, TextWriter writer) { if (reader == null) throw new ArgumentNullException (nameof (reader)); if (writer == null) throw new ArgumentNullException (nameof (writer)); if (!string.IsNullOrEmpty (Header)) { if (HeaderFormat == HeaderFooterFormat.Text) { var converter = new TextToHtml (); using (var sr = new StringReader (Header)) converter.Convert (sr, writer); } else { writer.Write (Header); } } using (var htmlWriter = new HtmlWriter (writer)) { var callback = HtmlTagCallback ?? DefaultHtmlTagCallback; var stack = new List<FlowedToHtmlTagContext> (); var para = new StringBuilder (); int currentQuoteDepth = 0; int paraQuoteDepth = -1; int quoteDepth; string line; while ((line = reader.ReadLine ()) != null) { // unquote the line line = Unquote (line, out quoteDepth); // remove space-stuffing if (line.Length > 0 && line[0] == ' ') line = line.Substring (1); if (para.Length == 0) { paraQuoteDepth = quoteDepth; } else if (quoteDepth != paraQuoteDepth) { // Note: according to rfc3676, when a folded line has a different quote // depth than the previous line, then quote-depth rules win and we need // to treat this as a new paragraph. WriteParagraph (htmlWriter, stack, ref currentQuoteDepth, para, paraQuoteDepth); paraQuoteDepth = quoteDepth; para.Length = 0; } para.Append (line); if (line.Length == 0 || line[line.Length - 1] != ' ') { // line did not end with a space, so the next line will start a new paragraph WriteParagraph (htmlWriter, stack, ref currentQuoteDepth, para, paraQuoteDepth); paraQuoteDepth = 0; para.Length = 0; } else if (DeleteSpace) { // Note: lines ending with a space mean that the next line is a continuation para.Length--; } } for (int i = stack.Count; i > 0; i--) { var ctx = stack[i - 1]; ctx.SetIsEndTag (true); if (ctx.InvokeCallbackForEndTag) callback (ctx, htmlWriter); else ctx.WriteTag (htmlWriter); } htmlWriter.Flush (); } if (!string.IsNullOrEmpty (Footer)) { if (FooterFormat == HeaderFooterFormat.Text) { var converter = new TextToHtml (); using (var sr = new StringReader (Footer)) converter.Convert (sr, writer); } else { writer.Write (Footer); } } }
/// <summary> /// Convert the contents of <paramref name="reader"/> from the <see cref="InputFormat"/> to the /// <see cref="OutputFormat"/> and uses the <paramref name="writer"/> to write the resulting text. /// </summary> /// <remarks> /// Converts the contents of <paramref name="reader"/> from the <see cref="InputFormat"/> to the /// <see cref="OutputFormat"/> and uses the <paramref name="writer"/> to write the resulting text. /// </remarks> /// <param name="reader">The text reader.</param> /// <param name="writer">The text writer.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="reader"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="writer"/> is <c>null</c>.</para> /// </exception> public override void Convert(TextReader reader, TextWriter writer) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } if (writer == null) { throw new ArgumentNullException(nameof(writer)); } if (!OutputHtmlFragment) { writer.Write("<html><body>"); } if (!string.IsNullOrEmpty(Header)) { if (HeaderFormat == HeaderFooterFormat.Text) { var converter = new TextToHtml { OutputHtmlFragment = true }; using (var sr = new StringReader(Header)) converter.Convert(sr, writer); } else { writer.Write(Header); } } using (var htmlWriter = new HtmlWriter(writer)) { var callback = HtmlTagCallback ?? DefaultHtmlTagCallback; var stack = new List <TextToHtmlTagContext> (); int currentQuoteDepth = 0, quoteDepth; TextToHtmlTagContext ctx; string line; while ((line = reader.ReadLine()) != null) { line = Unquote(line, out quoteDepth); while (currentQuoteDepth < quoteDepth) { ctx = new TextToHtmlTagContext(HtmlTagId.BlockQuote); callback(ctx, htmlWriter); currentQuoteDepth++; stack.Add(ctx); } while (quoteDepth < currentQuoteDepth) { ctx = stack[stack.Count - 1]; stack.RemoveAt(stack.Count - 1); if (!SuppressContent(stack) && !ctx.DeleteEndTag) { ctx.SetIsEndTag(true); if (ctx.InvokeCallbackForEndTag) { callback(ctx, htmlWriter); } else { ctx.WriteTag(htmlWriter); } } if (ctx.TagId == HtmlTagId.BlockQuote) { currentQuoteDepth--; } } if (!SuppressContent(stack)) { WriteText(htmlWriter, line); ctx = new TextToHtmlTagContext(HtmlTagId.Br); callback(ctx, htmlWriter); } } for (int i = stack.Count; i > 0; i--) { ctx = stack[i - 1]; ctx.SetIsEndTag(true); if (ctx.InvokeCallbackForEndTag) { callback(ctx, htmlWriter); } else { ctx.WriteTag(htmlWriter); } } htmlWriter.Flush(); } if (!string.IsNullOrEmpty(Footer)) { if (FooterFormat == HeaderFooterFormat.Text) { var converter = new TextToHtml { OutputHtmlFragment = true }; using (var sr = new StringReader(Footer)) converter.Convert(sr, writer); } else { writer.Write(Footer); } } if (!OutputHtmlFragment) { writer.Write("</body></html>"); } }
/// <summary> /// Convert the contents of <paramref name="reader"/> from the <see cref="InputFormat"/> to the /// <see cref="OutputFormat"/> and uses the <paramref name="writer"/> to write the resulting text. /// </summary> /// <remarks> /// Converts the contents of <paramref name="reader"/> from the <see cref="InputFormat"/> to the /// <see cref="OutputFormat"/> and uses the <paramref name="writer"/> to write the resulting text. /// </remarks> /// <param name="reader">The text reader.</param> /// <param name="writer">The text writer.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="reader"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="writer"/> is <c>null</c>.</para> /// </exception> public override void Convert (TextReader reader, TextWriter writer) { if (reader == null) throw new ArgumentNullException (nameof (reader)); if (writer == null) throw new ArgumentNullException (nameof (writer)); if (!string.IsNullOrEmpty (Header)) { if (HeaderFormat == HeaderFooterFormat.Text) { var converter = new TextToHtml (); using (var sr = new StringReader (Header)) converter.Convert (sr, writer); } else { writer.Write (Header); } } using (var htmlWriter = new HtmlWriter (writer)) { var callback = HtmlTagCallback ?? DefaultHtmlTagCallback; var stack = new List<TextToHtmlTagContext> (); int currentQuoteDepth = 0, quoteDepth; TextToHtmlTagContext ctx; string line; while ((line = reader.ReadLine ()) != null) { line = Unquote (line, out quoteDepth); while (currentQuoteDepth < quoteDepth) { ctx = new TextToHtmlTagContext (HtmlTagId.BlockQuote); callback (ctx, htmlWriter); currentQuoteDepth++; stack.Add (ctx); } while (quoteDepth < currentQuoteDepth) { ctx = stack[stack.Count - 1]; stack.RemoveAt (stack.Count - 1); if (!SuppressContent (stack) && !ctx.DeleteEndTag) { ctx.SetIsEndTag (true); if (ctx.InvokeCallbackForEndTag) callback (ctx, htmlWriter); else ctx.WriteTag (htmlWriter); } if (ctx.TagId == HtmlTagId.BlockQuote) currentQuoteDepth--; } if (!SuppressContent (stack)) { WriteText (htmlWriter, line); ctx = new TextToHtmlTagContext (HtmlTagId.Br); callback (ctx, htmlWriter); } } for (int i = stack.Count; i > 0; i--) { ctx = stack[i - 1]; ctx.SetIsEndTag (true); if (ctx.InvokeCallbackForEndTag) callback (ctx, htmlWriter); else ctx.WriteTag (htmlWriter); } htmlWriter.Flush (); } if (!string.IsNullOrEmpty (Footer)) { if (FooterFormat == HeaderFooterFormat.Text) { var converter = new TextToHtml (); using (var sr = new StringReader (Footer)) converter.Convert (sr, writer); } else { writer.Write (Footer); } } }
/// <summary> /// Convert the contents of <paramref name="reader"/> from the <see cref="InputFormat"/> to the /// <see cref="OutputFormat"/> and uses the <paramref name="writer"/> to write the resulting text. /// </summary> /// <remarks> /// Converts the contents of <paramref name="reader"/> from the <see cref="InputFormat"/> to the /// <see cref="OutputFormat"/> and uses the <paramref name="writer"/> to write the resulting text. /// </remarks> /// <param name="reader">The text reader.</param> /// <param name="writer">The text writer.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="reader"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="writer"/> is <c>null</c>.</para> /// </exception> public override void Convert(TextReader reader, TextWriter writer) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } if (writer == null) { throw new ArgumentNullException(nameof(writer)); } if (!string.IsNullOrEmpty(Header)) { if (HeaderFormat == HeaderFooterFormat.Text) { var converter = new TextToHtml(); using (var sr = new StringReader(Header)) converter.Convert(sr, writer); } else { writer.Write(Header); } } using (var htmlWriter = new HtmlWriter(writer)) { var callback = HtmlTagCallback ?? DefaultHtmlTagCallback; var stack = new List <HtmlToHtmlTagContext> (); var tokenizer = new HtmlTokenizer(reader); HtmlToHtmlTagContext ctx; HtmlToken token; while (tokenizer.ReadNextToken(out token)) { switch (token.Kind) { default: if (!SuppressContent(stack)) { htmlWriter.WriteToken(token); } break; case HtmlTokenKind.Tag: var tag = (HtmlTagToken)token; if (!tag.IsEndTag) { if (!tag.IsEmptyElement) { ctx = new HtmlToHtmlTagContext(tag); if (FilterHtml && ctx.TagId == HtmlTagId.Script) { ctx.SuppressInnerContent = true; ctx.DeleteEndTag = true; ctx.DeleteTag = true; } else if (!SuppressContent(stack)) { callback(ctx, htmlWriter); } stack.Add(ctx); } else if (!SuppressContent(stack)) { ctx = new HtmlToHtmlTagContext(tag); if (!FilterHtml || ctx.TagId != HtmlTagId.Script) { callback(ctx, htmlWriter); } } } else { if ((ctx = Pop(stack, tag.Name)) != null) { if (!SuppressContent(stack)) { if (ctx.InvokeCallbackForEndTag) { ctx = new HtmlToHtmlTagContext(tag) { InvokeCallbackForEndTag = ctx.InvokeCallbackForEndTag, SuppressInnerContent = ctx.SuppressInnerContent, DeleteEndTag = ctx.DeleteEndTag, DeleteTag = ctx.DeleteTag }; callback(ctx, htmlWriter); } else if (!ctx.DeleteEndTag) { htmlWriter.WriteEndTag(tag.Name); } } } else if (!SuppressContent(stack)) { ctx = new HtmlToHtmlTagContext(tag); callback(ctx, htmlWriter); } } break; case HtmlTokenKind.Comment: if (!StripComments) { htmlWriter.WriteToken(token); } break; } } htmlWriter.Flush(); } if (!string.IsNullOrEmpty(Footer)) { if (FooterFormat == HeaderFooterFormat.Text) { var converter = new TextToHtml(); using (var sr = new StringReader(Footer)) converter.Convert(sr, writer); } else { writer.Write(Footer); } } }