コード例 #1
0
ファイル: HtmlToHtml.cs プロジェクト: cybercircuits/MimeKit
		/// <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);
				}
			}
		}