private static void ExportNode(HtmlNode node, TextWriter writer, string indent)
        {
            bool emptyNode = node.ChildNodes.Count == 0;
            bool dataNode = node.Data != null;

            if (dataNode)
            {
                string value = node.Data.Value;
                value = value.Replace("&", "&");
                value = value.Replace("<", "&lt;");
                value = value.Replace(">", "&gt;");
                writer.Write("{0}", value);
            }
            else
            {
                string tagName = GetTagName(node.Tag);
                string attributes = GetAttributes(node);

                if (emptyNode && node.Tag != HtmlTag.Style)
                {
                    //writer.WriteLine("{0}<{1} {2}/>", indent, tagName, attributes);
                    writer.Write("<{0} {1}/>", tagName, attributes);
                }
                else if (node.Tag == HtmlTag.Style)
                {
                    writer.WriteLine("{0}<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">", indent);
                    writer.WriteLine("{0}<style>", indent);
                    writer.WriteLine(indent + "   body { font-family: Arial; }");
                    writer.WriteLine(indent + "   a:link { text-decoration: none; }");
                    writer.WriteLine("{0}</style>", indent);
                }
                else
                {
                    //writer.WriteLine("{0}<{1}{2}>", indent, tagName, attributes);
                    writer.Write("<{0}{1}>", tagName, attributes);
                    foreach (var childNode in node.ChildNodes)
                    {
                        ExportNode(childNode, writer, indent + "   ");
                    }
                    //writer.WriteLine("{0}</{1}>", indent, tagName);
                    writer.Write("</{0}>", tagName);
                }
            }

        }
        private static string GetAttributes(HtmlNode node)
        {
            Dictionary<string, string> attributes = new Dictionary<string, string>();
            Dictionary<string, string> styleAttributes = new Dictionary<string, string>();

            HtmlRenderState state = node.RenderState;

            if (node.Tag == HtmlTag.Html || node.Tag == HtmlTag.Head ||
                    node.Tag == HtmlTag.Title || node.Tag == HtmlTag.Style)
            {
                return "";
            }

            // Write out style attributes
            if (state.HasBackground == 1)
            {
                if (state.BackgroundImageOffset == 0)
                {
                    styleAttributes.Add("background-color", GetColor(state.BackgroundColor));
                }
                else
                {
                    styleAttributes.Add("background-image", "url(" + state.BackgroundImageTextureInfo.TextureName + ".png)");
                    styleAttributes.Add("background-repeat", GetAttributeValue(state.BackgroundRepeat));
                }
            }
            if (state.Width > -1)
            {
                if (node.NodeType == HtmlNodeType.HtmlTableNode || node.NodeType == HtmlNodeType.HtmlTableElementNode)
                {
                    attributes.Add("width", state.Width.ToString());
                }
                else
                {
                    styleAttributes.Add("width", GetSize(state.Width));
                }
            }
            if (state.Height > -1)
            {
                if (node.NodeType == HtmlNodeType.HtmlTableNode || node.NodeType == HtmlNodeType.HtmlTableElementNode)
                {
                    attributes.Add("height", state.Height.ToString());
                }
                else
                {
                    styleAttributes.Add("height", GetSize(state.Height));
                }
            }

            styleAttributes.Add("margin-left", GetSize(state.MarginLeft));
            styleAttributes.Add("margin-right", GetSize(state.MarginRight));
            styleAttributes.Add("margin-top", GetSize(state.MarginTop));
            styleAttributes.Add("margin-bottom", GetSize(state.MarginBottom));

            styleAttributes.Add("padding-left", GetSize(state.PaddingLeft));
            styleAttributes.Add("padding-right", GetSize(state.PaddingRight));
            styleAttributes.Add("padding-top", GetSize(state.PaddingTop));
            styleAttributes.Add("padding-bottom", GetSize(state.PaddingBottom));

            styleAttributes.Add("border-left", GetAttributeValue(state.BorderLeftStyle) + " " + GetSize(state.BorderLeftWidth) + " " + GetColor(state.BorderLeftColor));
            styleAttributes.Add("border-right", GetAttributeValue(state.BorderRightStyle) + " " + GetSize(state.BorderRightWidth) + " " + GetColor(state.BorderRightColor));
            styleAttributes.Add("border-top", GetAttributeValue(state.BorderTopStyle) + " " + GetSize(state.BorderTopWidth) + " " + GetColor(state.BorderTopColor));
            styleAttributes.Add("border-bottom", GetAttributeValue(state.BorderBottomStyle) + " " + GetSize(state.BorderBottomWidth) + " " + GetColor(state.BorderBottomColor));

            styleAttributes.Add("text-decoration", GetAttributeValue(state.TextDecoration));
            styleAttributes.Add("font-size", GetAttributeValue(state.FontSize));
            styleAttributes.Add("display", GetAttributeValue(state.Display));
            styleAttributes.Add("color", GetColor(state.Color));

            if (node.NodeType == HtmlNodeType.HtmlTableNode)
            {
                attributes.Add("cellpadding", state.CellPadding.ToString());
                attributes.Add("cellspacing", state.CellSpacing.ToString());
            }
            else if (node.NodeType == HtmlNodeType.HtmlTableElementNode)
            {
                if (state.ColSpan > 1)
                {
                    attributes.Add("colspan", state.ColSpan.ToString());                    
                }
                if (state.RowSpan > 1)
                {
                    attributes.Add("rowspan", state.RowSpan.ToString());
                }

                if ((int)state.VerticalAlign > -1)
                {
                    attributes.Add("valign", GetAttributeValue(state.VerticalAlign));
                }
                if ((int)state.HorizontalAlign > -1)
                {
                    attributes.Add("align", GetAttributeValue(state.HorizontalAlign));
                }
            }
            else
            {
                if ((int)state.VerticalAlign > -1)
                {
                    styleAttributes.Add("vertical-align", GetAttributeValue(state.VerticalAlign));
                }
                if ((int)state.HorizontalAlign > -1)
                {
                    styleAttributes.Add("text-align", GetAttributeValue(state.HorizontalAlign));
                }
            }
            
            if (node.Tag == HtmlTag.A)
            {
                attributes.Add("href", "#");
                attributes.Add("onclick", "alert('Link to: " + node.LinkAddress + "');");
            }
            else if (node.Tag == HtmlTag.Img)
            {
                string path = node.LinkAddress;
                path = path.Substring(0, path.Length - Path.GetExtension(path).Length);
                attributes.Add("src", path + ".png");
            }
            
            if (styleAttributes.Count > 0)
            {
                StringBuilder sbStyle = new StringBuilder();
                foreach (var pair in styleAttributes)
                {
                    sbStyle.AppendFormat("{0}: {1}; ", pair.Key, pair.Value);
                }
                attributes.Add("style", sbStyle.ToString());
            }

            StringBuilder sbAttributes = new StringBuilder();
            foreach (var pair in attributes)
            {
                sbAttributes.AppendFormat(" {0}=\"{1}\"", pair.Key, pair.Value);
            }

            return sbAttributes.ToString();
        }
 public static void Export(HtmlNode rootNode, TextWriter writer)
 {
     ExportNode(rootNode, writer, "");
 }