Utilidad
para filtrar el código HTML generado por Word Para que el Guille no se mosquee con las colaboraciones... |
Publicado el 28/Feb/2005
|
Esta utilidad lo que hace es una limpieza del código "basura que el Word añade a las páginas con formato HTML que crea a partir de un documento de tipo DOC.
Se que el formato es menos "bonito" que el que muestra el navegador antes de "filtrarlo", pero también es cierto que se reduce en más de la mitad, de forma que una página que con el formato de Word ocuparía 45 KB después de filtrarlo se queda en menos de 20 KB, aunque no siempre se reduce en esa misma proporción, pero como puedes comprobar es bastante significativa.
Otra de las cosas que proporciona esta utilidad es que se puede indicar el título, la descripción y las palabras clave, cosa que muchos olvidáis de especificar... para poder hacerlo más fácil, al menos en lo que al as palabras clave se refiere, he puesto una serie de botones de opciones y checks para que se pueda indicar fácilmente que lenguaje se ha usado, si usa ADO, ASP o APIs de Windows.
Novedades del 01/Mar/05:
Estas son las nuevas cosillas que le he añadido desde ayer:
1- Permite indicar los dos lenguajes principales de .NET: VB y C#, ya que algunos tenéis la buena costumbre de mostrar el código en los dos lenguajes... cualquier día lo pondré como "norma", je, je... ¡no te asustes! que es broma, pero si usas mi utilidad de convertir el código... lo puedes hacer casi en un "pis pás".
2- Puedes indicar el zip con el código de ejemplo, así no tendrás que escribir nada, además de que calcula el tamaño y lo incluye.
3- Al arrastrar el fichero comprueba si ya tiene el título, descripción, etc., y de ser así lo incluye en las cajas de textos correspondientes. Es que esto de las expresiones regulares, cuando funciona, es una maravilla, je, je, je.
4- Puedes arrastrar ficheros con formato DOC o RTF, en estos casos solamente extrae el texto, pero, lamentablemente no distingue entre texto normal y texto de código, y por supuesto las imágenes no sabe ni que existen... Pero es un paso... aunque lo mejor en estos casos es que primero conviertas el DOC en formato HTML usando Word y después lo filtras, (que esa era la función inicial de esta aplicación).
5- No se si le he añadido más cosas... pero lo que es seguro es que ahora funciona mejor que ayer... je, je... ¡Ah! ¡Sí!, ahora tiene en cuenta si es un artículo de .NET o VB6 y utiliza tanto el link para la página de colaboraciones adecuada, como la imagen del link superior y, por supuesto el path correcto para el fichero ZIP, (si es que lo has indicado).
En la siguiente imagen tienes una captura de la utilidad en plena ejecución:
La utilidad esperando el fichero a convertir
En el ZIP te dejo tanto el ejecutable como el código para que veas cómo lo he hecho o para que la puedas mejorar o adaptar a tus necesidades.
Como nota adicional, decirte que si quieres ver ejemplos de cómo usar expresiones regulares para quitar y cambiar texto, así como para tener ejemplos de cómo usar el StringBuilder y algunas cosillas más, te veas el código... por ahora solo está en VB, pero espero que dentro de unos días incluya el de C# (cuando compruebe que no haré nuevas modificaciones).
Nota:
Si no te interesa la utilidad, porque no vas a colaborar en este sitio, y no quieres bajártela, un poco más abajo tienes parte del código para VB .NET.
Espero que la utilices y, aunque no es perfecta, al menos con pocos cambios, puedes dejar la colaboración "más o menos" como pido en la página de colaboraciones.
Muchas gracias.
Nos vemos.
Guillermo
Los ZIP:
El zip con el ejecutable y el código para VB .NET: FiltrarHTMLparaElguille.zip 38.8 KB (versión del 16/Jun/2005)
El zip con el ejecutable y el código para VB .NET: FiltrarHTMLparaElguille_1.1.zip 52.6 KB (17/Ago/2006)
MD5 checksum: 0B83F6281B01B007C832D6EDEC4C592DNota:
En la nueva "versión" de la utilidad (v1.1.*) se utilizan una serie de ficheros con parte del código interno a usar, esos ficheros deben estar en el mismo directorio del ejecutable y se incluyen tanto en formato .txt como en un zip que los contiene. Todos esos ficheros están dentro del ZIP arriba indicado.
El código para Visual Basic .NET
Recuerda que este código es de la versión anterior al 17/Ago/2006.
Pulsa aquí si quieres ver el código de la clase para manejar los datos de configuración.'------------------------------------------------------------------------------ ' Filtrar las páginas HTML creadas con Word (27/Feb/05) ' para que se adapten al estilo de mi sitio ' ' Revisado el 28/Feb y 01/Mar/2005 con nuevas opciones y características ' ' ©Guillermo 'guille' Som, 2005 '------------------------------------------------------------------------------ Option Strict On Option Explicit On Imports System Imports Microsoft.VisualBasic Imports System.Text Imports System.Text.RegularExpressions Imports System.Windows.Forms Imports System.Collections Imports System.Xml Imports System.Configuration Public Class fFiltrarHTML Inherits System.Windows.Forms.Form ' Private configXml As New XmlDocument Private ficConfig As String Private valores As IDictionary = Nothing Private seccionAnt As String = "" ' Public Sub New() MyBase.New() 'El Diseñador de Windows Forms requiere esta llamada. InitializeComponent() 'Agregar cualquier inicialización después de la llamada a InitializeComponent() ficConfig = Application.ExecutablePath & ".config" ' ' comprobar si exite el fichero de configuración If System.IO.File.Exists(ficConfig) = False Then Dim sXml As New System.Text.StringBuilder ' ' crear la cadena a asignar al objeto XmlDocument sXml.Append("<configuration>") sXml.Append(" <appSettings>") sXml.Append(" <!-- La configuración de la aplicación de usuario y de la propiedad configurada van aquí.-->") sXml.Append(" <!-- Ejemplo: <add key=""settingName"" value=""settingValue""/> -->") sXml.Append(" <add key=""txtTitulo.Text"" value="""" />") sXml.Append(" <add key=""txtKeywords.Text"" value="".NET; VB;"" />") sXml.Append(" <add key=""txtDescripcion.Text"" value="""" />") sXml.Append(" <add key=""optNET.Checked"" value=""False"" />") sXml.Append(" <add key=""optVBNET.Checked"" value=""False"" />") sXml.Append(" <add key=""optVBNET.Enabled"" value=""True"" />") sXml.Append(" <add key=""optCS.Checked"" value=""False"" />") sXml.Append(" <add key=""optCS.Enabled"" value=""True"" />") sXml.Append(" <add key=""optVB6.Checked"" value=""False"" />") sXml.Append(" <add key=""chkASP.Checked"" value=""False"" />") sXml.Append(" <add key=""chkADO.Checked"" value=""False"" />") sXml.Append(" <add key=""chkAPI32.Checked"" value=""False"" />") sXml.Append(" <add key=""txtZip.Text"" value="""" />") ' sXml.Append(" <add key=""Form1.Left"" value=""0"" />") sXml.Append(" <add key=""Form1.Top"" value=""0"" />") sXml.Append(" </appSettings>") sXml.Append("</configuration>") ' ' asignamos la cadena al objeto configXml.LoadXml(sXml.ToString) ' ' Guardamos el contenido de configXml y creamos el fichero configXml.Save(ficConfig) Else ' solo es necesario leerlo si no lo hemos creado configXml.Load(ficConfig) End If ' Me.txtTitulo.Text = cfgGetValue("configuration/appSettings", "txtTitulo.Text", "") Me.txtKeywords.Text = cfgGetValue("configuration/appSettings", "txtKeywords.Text", "") Me.txtDescripcion.Text = cfgGetValue("configuration/appSettings", "txtDescripcion.Text", "") Me.txtZip.Text = cfgGetValue("configuration/appSettings", "txtZip.Text", "") ' Me.Left = CInt(cfgGetValue("configuration/appSettings", "Form1.Left", Me.Left.ToString)) Me.Top = CInt(cfgGetValue("configuration/appSettings", "Form1.Top", Me.Top.ToString)) End Sub ' ' El punto de entrada de la aplicación <STAThread()> _ Public Shared Sub Main(ByVal args() As String) System.Windows.Forms.Application.EnableVisualStyles() System.Windows.Forms.Application.Run(New fFiltrarHTML) End Sub ' #Region " Código generado por el Diseñador de Windows Forms " ' El código del diseñador de Windows.Forms #End Region ' Private Sub btnFiltrar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnFiltrar.Click ' Filtrar página HTML Dim sbHead As New StringBuilder Dim sbBody As New StringBuilder Dim sbPie As New StringBuilder Dim sbPBox As New StringBuilder Dim sbZIP As New StringBuilder Dim sb As New StringBuilder Dim sTexto As String Dim re As Regex Dim m As Match Dim avisos As New System.Collections.ArrayList Dim i, j, k As Integer ' lblInfo.Text = "Procesando el fichero... paciencia..." lblInfo.Refresh() Me.Cursor = Cursors.WaitCursor ' ' Quitar: ' <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> ' Todo el Head y dejarlo al formato adecuado ' Copiar las secciones keywords, description, seccion y title ' <span...></span> ' <o:p></o:p> ' <style>...</style> ' Cambiar: ' <p...> por <p><font face='Verdana' size='2'> ' </p> por </font></p> ' Estos dos casos, si después de <p> no hay un <font...> ' <body...> y poner <body background="../../imagenes/cuadriculaGris30.gif" bgcolor="#FFFFFF" link="#0000FF" vlink="#0000FF" alink="#FF0000"> ' Con esto ya se queda medio aceptable ' avisos.Clear() ' ' re = New Regex("<!DOCTYPE\s*[^>]*\s*>", RegexOptions.IgnoreCase) sTexto = re.Replace(txtFic.Text, "") ' guardar los <meta keywords, description y seccion re = New Regex("<meta name\s*=\s*""description""\s*content\s*=\s*[^>]*\s*>", RegexOptions.IgnoreCase Or RegexOptions.Compiled Or RegexOptions.Singleline) m = re.Match(sTexto) If m.Success Then sb.AppendFormat("{0}{1}", m.Value, vbCrLf) Else If txtDescripcion.Text = "" Then sb.AppendFormat("<meta name=""description"" content="""">{0}", vbCrLf) avisos.Add("Debes indicar la descripción (ver <meta name =description)") Else sb.AppendFormat("<meta name=""description"" content=""{1}"">{0}", vbCrLf, txtDescripcion.Text) End If End If re = New Regex("<meta name\s*=\s*""keywords""\s*content\s*=\s*[^>]*\s*>", RegexOptions.IgnoreCase Or RegexOptions.Compiled Or RegexOptions.Singleline) m = re.Match(sTexto) If m.Success Then sb.AppendFormat("{0}{1}", m.Value, vbCrLf) Else If txtKeywords.Text = "" Then If Me.optVB6.Checked Then sb.AppendFormat("<meta name=""keywords"" content=""VB; VB6"">{0}", vbCrLf) Else If Me.optVBNET.Checked Then sb.AppendFormat("<meta name=""keywords"" content="".NET; VB.NET"">{0}", vbCrLf) End If If Me.optCS.Checked Then sb.AppendFormat("<meta name=""keywords"" content="".NET; C#"">{0}", vbCrLf) End If End If avisos.Add("Debes indicar las palabras claves que realmente indican las tecnologías usadas.") Else sb.AppendFormat("<meta name=""keywords"" content=""{1}"">{0}", vbCrLf, txtKeywords.Text) End If End If re = New Regex("(<title>.+)(</title>)", RegexOptions.IgnoreCase Or RegexOptions.Compiled) m = re.Match(sTexto) If m.Success Then If m.Value.ToLower().StartsWith("colabora") Then sb.AppendFormat("{0}{1}", m.Value, vbCrLf) ElseIf txtTitulo.Text <> "" Then sb.AppendFormat("<title>{1}</title>{0}", vbCrLf, txtTitulo.Text) End If Else If txtTitulo.Text = "" Then If Me.optNET.Checked Then sb.AppendFormat("<title>Colabora.NET: </title>{0}", vbCrLf) Else sb.AppendFormat("<title>Colabora: </title>{0}", vbCrLf) End If avisos.Add("Debes indicar el título de la colaboración, buscar <title> y escríbelo después de 'Colabora.NET: '") Else sb.AppendFormat("<title>{1}</title>{0}", vbCrLf, txtTitulo.Text) End If End If ' ' quitar todo lo que haya entre <head> y </head> re = New Regex("<head>([^\b]*)</head>", RegexOptions.IgnoreCase Or RegexOptions.Compiled Or RegexOptions.Multiline) sTexto = re.Replace(sTexto, "") ' ' buscar los <span...> que contengan color ' realmente encuentra hasta </span> ' este realmente llega hasta otros span: <span([^>]*)color:(.*)?> re = New Regex("<span([^>]*)color:(.*)?</span>", RegexOptions.IgnoreCase Or RegexOptions.Compiled Or RegexOptions.Multiline) Dim sColor As String Dim i1, j1, k1 As Integer Dim sbColor As New StringBuilder(sTexto) Dim sepColor As Char() = {"'"c, ChrW(34), ";"c, ">"c} Dim ms As MatchCollection = re.Matches(sbColor.ToString) ' k = "color:".Length k1 = "</span>".Length For Each m In ms i = m.Value.ToLower.IndexOf("color:") If i > -1 Then ' buscar hasta el próximo caracter que no sea una letra j = m.Value.IndexOfAny(sepColor, i) If j = -1 Then j = m.Value.Length End If sColor = m.Value.Substring(i + k, j - (i + k)) i1 = m.Index ' j1 = m.Value.IndexOf(">") sColor = "<font color=" & sColor & ">" & m.Value.Substring(j1 + 1) sColor = sColor.ToLower.Replace("</span>", "</font>") ' hay que rellenar la cadena resultante para ' que tenga los mismos caracteres que m.Value, ' sino, el StringBuilder no tendrá las mismas posiciones que ' el valor devuelto por cada m.Index sbColor.Replace(m.Value, rellenar(sColor, m.Value.Length), i1, m.Value.Length) End If Application.DoEvents() Next sTexto = sbColor.ToString ' quitar los <span...> re = New Regex("<span([^>]*)>", RegexOptions.IgnoreCase Or RegexOptions.Compiled Or RegexOptions.Multiline) sTexto = re.Replace(sTexto, "") ' quitar los </span> re = New Regex("</span>", RegexOptions.IgnoreCase Or RegexOptions.Compiled Or RegexOptions.Multiline) sTexto = re.Replace(sTexto, "") ' quitar los <o:p> y </o:p> re = New Regex("</?o:p>", RegexOptions.IgnoreCase Or RegexOptions.Compiled Or RegexOptions.Multiline) sTexto = re.Replace(sTexto, "") ' quitar lo que haya entre <style> y </style> (siempre que dentro no haya >... re = New Regex("<style>([^>]*)</style>", RegexOptions.IgnoreCase Or RegexOptions.Compiled Or RegexOptions.Multiline) sTexto = re.Replace(sTexto, "") ' quitar el <html... > re = New Regex("<html([^>]*)>", RegexOptions.IgnoreCase Or RegexOptions.Compiled Or RegexOptions.Multiline) sTexto = re.Replace(sTexto, "") ' quitar el <body... > re = New Regex("<body([^>]*)>", RegexOptions.IgnoreCase Or RegexOptions.Compiled Or RegexOptions.Multiline) sTexto = re.Replace(sTexto, "") ' cambiar los <b ...> por <b> re = New Regex("<b\s([^>]*)>", RegexOptions.IgnoreCase Or RegexOptions.Compiled Or RegexOptions.Multiline) sTexto = re.Replace(sTexto, "<b>") ' Cambiar los <p...> por <p> re = New Regex("<p([^>]*)>", RegexOptions.IgnoreCase Or RegexOptions.Compiled Or RegexOptions.Multiline) sTexto = re.Replace(sTexto, "<p>") ' Cambiar los <blockquote...> por <blockquote> re = New Regex("<blockquote([^>]*)>", RegexOptions.IgnoreCase Or RegexOptions.Compiled Or RegexOptions.Multiline) sTexto = re.Replace(sTexto, "<blockquote>") ' Cambiar los <Div...> por <blockquote> re = New Regex("<div([^>]*)>", RegexOptions.IgnoreCase Or RegexOptions.Compiled Or RegexOptions.Multiline) sTexto = re.Replace(sTexto, "<blockquote>") ' cambiar los </div> por </blockquote> re = New Regex("</div>", RegexOptions.IgnoreCase Or RegexOptions.Compiled Or RegexOptions.Multiline) sTexto = re.Replace(sTexto, "</blockquote>") ' '(<!--\[if gte mso 9\]>) (<!\[endif\]-->) / <!--[if gte mso 10]> k = "<![endif]-->".Length Do i = sTexto.ToLower().IndexOf("<!--[if gte mso 9]>") If i = -1 Then Exit Do j = sTexto.ToLower().IndexOf("<![endif]-->", i + 1) If j = -1 Then Exit Do sTexto = sTexto.Substring(0, i - 1) & sTexto.Substring(j + k) Loop Do i = sTexto.ToLower().IndexOf("<!--[if gte mso 10]>") If i = -1 Then Exit Do j = sTexto.ToLower().IndexOf("<![endif]-->", i + 1) If j = -1 Then Exit Do sTexto = sTexto.Substring(0, i - 1) & sTexto.Substring(j + k) Loop ' ' quitar desde </body> hasta el final i = sTexto.ToLower().IndexOf("</body>") If i > -1 Then sTexto = sTexto.Substring(0, i - 1) End If ' sbHead.AppendFormat("<html>{0}", vbCrLf) sbHead.AppendFormat("<head>{0}", vbCrLf) sbHead.AppendFormat("<meta http-equiv=""Window-target"" content=""_top"">{0}", vbCrLf) sbHead.AppendFormat("<meta http-equiv=""Content-Type"" content=""text/html; charset=windows-1252"">{0}", vbCrLf) sbHead.AppendFormat("<meta name=""MS.LOCALE"" content=""es"">{0}", vbCrLf) If Me.optNET.Checked Then sbHead.AppendFormat("<meta name=""MSHAttr"" content=""DocSet:NETFramework"" />{0}", vbCrLf) If Me.optCS.Checked Then sbHead.AppendFormat("<meta name=""MSHAttr"" content=""DevLang:CSharp"" />{0}", vbCrLf) sbHead.AppendFormat("<meta name=""MSHAttr"" content=""DocSet:C#"" />{0}", vbCrLf) Else sbHead.AppendFormat("<meta name=""MSHAttr"" content=""DevLang:VB"" />{0}", vbCrLf) sbHead.AppendFormat("<meta name=""MSHAttr"" content=""DocSet:Visual Basic"" />{0}", vbCrLf) End If Else sbHead.AppendFormat("<meta name=""MSHAttr"" content=""DevLang:VB"" />{0}", vbCrLf) sbHead.AppendFormat("<meta name=""MSHAttr"" content=""DocSet:Visual Basic"" />{0}", vbCrLf) End If ' If Me.chkASP.Checked Then sbHead.AppendFormat("<meta name=""MSHAttr"" content=""DevLang:ASP"" />{0}", vbCrLf) End If If Me.chkADO.Checked Then sbHead.AppendFormat("<meta name=""MSHAttr"" content=""DocSet:ADO"" />{0}", vbCrLf) End If If Me.chkAPI32.Checked Then sbHead.AppendFormat("<meta name=""MSHAttr"" content=""DocSet:Win32 API"" />{0}", vbCrLf) End If sbHead.AppendFormat("<meta name=""MSHAttr"" content=""DocSet:XML"" />{0}", vbCrLf) ' sbHead.Append(sb.ToString) sbHead.AppendFormat("<meta name=""seccion"" content=""Colabora.NET"">{0}", vbCrLf) sbHead.AppendFormat("</head>{0}", vbCrLf) ' sbBody.AppendFormat("<body background=""../../imagenes/cuadriculaGris30.gif"" bgcolor=""#FFFFFF"" link=""#0000FF"" vlink=""#0000FF"" alink=""#FF0000"">{0}", vbCrLf) sbBody.Append(vbCrLf) sbBody.AppendFormat("<script language=""JavaScript"">{0}", vbCrLf) sbBody.AppendFormat("var gsPath = ""../../""{0}", vbCrLf) sbBody.AppendFormat("function IrADeLista(){{{0}", vbCrLf) sbBody.AppendFormat(" var s1 = gsBanner.D1.selectedIndex;{0}", vbCrLf) sbBody.AppendFormat(" var s2 = gsBanner.D1.options[s1].value;{0}", vbCrLf) sbBody.AppendFormat(" if( s2 != ""Selecciona"" ){0}", vbCrLf) sbBody.AppendFormat(" window.location = gsPath + s2;{0}", vbCrLf) sbBody.AppendFormat("}}{0}", vbCrLf) sbBody.AppendFormat("</script>{0}", vbCrLf) sbBody.AppendFormat("<script language=""JavaScript"" src=""../../elGuille.js""></script>{0}", vbCrLf) sbBody.AppendFormat("<hr noshade size=""3"">{0}", vbCrLf) ' If Me.optNET.Checked Then sbBody.AppendFormat("<p align=""right""><font face=""Verdana""><a href=""../colaboraNET.htm"">{0}", vbCrLf) sbBody.AppendFormat("<img src=""../../imagenes/colabora_guillepuntonet.jpg"" align=""baseline"" border=""0"" width=""500"" height=""30""></a></font></p>{0}", vbCrLf) Else sbBody.AppendFormat("<p align=""right""><font face=""Verdana""><a href=""../colabora.htm"">{0}", vbCrLf) sbBody.AppendFormat("<img src=""../../imagenes/colabora_guille.jpg"" align=""baseline"" border=""0"" width=""500"" height=""30""></a></font></p>{0}", vbCrLf) End If ' sbBody.Append(vbCrLf) ' If sTexto.ToLower().IndexOf("tablePanorama") = -1 Then sbPBox.AppendFormat("<table border=""0"" cellpadding=""0"" style=""border-collapse: collapse"" width=""100%"" id=""tablePanorama"">{0}", vbCrLf) sbPBox.AppendFormat("<tr><td align=""left"" width=""80%"" valign=""top"">{0}", vbCrLf) sbPBox.AppendFormat("{0}", vbCrLf) sbPBox.AppendFormat("<p><font face=""Verdana""><strong><font size=""7"">[Título]</font><font size=""5""><br>{0}", vbCrLf) sbPBox.AppendFormat("[Subtítulo] </font>{0}", vbCrLf) sbPBox.AppendFormat("</font></strong></font></p>{0}", vbCrLf) sbPBox.AppendFormat("{0}", vbCrLf) sbPBox.AppendFormat("<p><font size=""2"" face=""Verdana""><strong>[Fecha:]<br>{0}", vbCrLf) sbPBox.AppendFormat("[Autor:]</strong></font></p>{0}", vbCrLf) sbPBox.AppendFormat("{0}", vbCrLf) sbPBox.AppendFormat("<p> </p>{0}", vbCrLf) sbPBox.AppendFormat("</td>{0}", vbCrLf) sbPBox.AppendFormat("<td align=""center"" width=""20%"" valign=""top"">{0}", vbCrLf) sbPBox.AppendFormat("<!--{0}", vbCrLf) sbPBox.AppendFormat("<iframe src=""http:"//www.panoramabox.com/Panoramabox.aspx?IdObj=NNNN""{0}", vbCrLf) sbPBox.AppendFormat("width=""180"" height=""240"" FRAMEBORDER=0 SCROLLING=NO></iframe>{0}", vbCrLf) sbPBox.AppendFormat("-->{0}", vbCrLf) sbPBox.AppendFormat("</td>{0}", vbCrLf) sbPBox.AppendFormat("</tr>{0}", vbCrLf) sbPBox.AppendFormat("</table>{0}", vbCrLf) sbPBox.AppendFormat("{0}", vbCrLf) sbPBox.AppendFormat("<hr noshade width=""90%"" size=""3"">{0}", vbCrLf) End If sbPBox.AppendFormat("<p><font face=""Verdana"" size=""2"">{0}", vbCrLf) ' sbPie.AppendFormat("</font>{0}", vbCrLf) ' sbPie.AppendFormat("<p> </p>{0}", vbCrLf) sbPie.AppendFormat("<hr noshade size=""3"">{0}", vbCrLf) sbPie.Append(vbCrLf) ' ' Añadir el fichero a bajar (01/Mar/05) If Len(txtZip.Text) > 0 Then Dim fi As System.IO.FileInfo Try fi = New System.IO.FileInfo(txtZip.Text) sbPie.AppendFormat("<blockquote>{0}", vbCrLf) sbPie.AppendFormat("<p><font size=""2"" face=""Verdana""><b>{0}", vbCrLf) If optNET.Checked Then sbPie.AppendFormat("<a href=""http:"//downloads.elguille.info/BajarZip.aspx?seccion=/colabora/NET2005/&zip={1}"" target=""_blank""> {0}", vbCrLf, fi.Name) Else sbPie.AppendFormat("<a href=""http:"//downloads.elguille.info/BajarZip.aspx?seccion=/colabora/vb2005/&zip={1}"" target=""_blank""> {0}", vbCrLf, fi.Name) End If sbPie.AppendFormat("Fichero con el código de ejemplo:</a></b> {1} - {2} KB</font></p>{0}", vbCrLf, fi.Name, (fi.Length / 1024).ToString("0.00")) sbPie.AppendFormat("</blockquote>{0}", vbCrLf) sbPie.AppendFormat("<hr noshade size=""3"">{0}", vbCrLf) sbPie.Append(vbCrLf) Catch 'ex As Exception End Try End If ' sbPie.AppendFormat("<p align=""center""><font size=""2"" face=""Verdana""><a href=""../../indice.asp"">{0}", vbCrLf) sbPie.AppendFormat("<img src=""../../imagenes/el_guille.jpg"" alt=""ir al índice"" border=""0"" width=""200"" height=""50""></a></font></p>{0}", vbCrLf) sbPie.AppendFormat("</body>{0}", vbCrLf) sbPie.AppendFormat("</html>{0}", vbCrLf) ' sbHead.Append(sbBody.ToString) sbHead.Append(sbPBox.ToString) ' añadir el texto filtrado y quitar los dobles retornos de carro sbHead.Append(sTexto.Replace(vbCrLf & vbCrLf, vbCrLf)) sbHead.Append(sbPie.ToString) ' txtFic.Text = sbHead.ToString() txtFic.Refresh() ' lblInfo.BackColor = System.Drawing.Color.FromKnownColor(Drawing.KnownColor.Control) lblInfo.ForeColor = System.Drawing.Color.FromKnownColor(Drawing.KnownColor.WindowText) lblInfo.Text = "Fichero procesado." lblInfo.Refresh() Me.Cursor = Cursors.Default ' If avisos.Count > 0 Then sb = New StringBuilder For Each s As String In avisos sb.AppendFormat("{0}{1}", s, vbCrLf) Next MessageBox.Show(sb.ToString, "Cambios que debes hacer") End If End Sub ' Private Function rellenar(ByVal s As String, ByVal n As Integer) As String Return (s & (New String(" "c, n))).Substring(0, n) End Function ' Private Sub fFiltrarHTML_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles MyBase.DragDrop If e.Data.GetDataPresent("FileDrop") Then Dim sFic As String = CType(e.Data.GetData("FileDrop"), String())(0) ' Dim zipExt As String = ".zip .rar" Dim htmExt As String = ".htm .html .asp .aspx .txt .doc .rtf .xml" Dim fi As New System.IO.FileInfo(sFic) If zipExt.IndexOf(fi.Extension) > -1 Then txtZip.Text = fi.FullName ElseIf htmExt.IndexOf(fi.Extension) > -1 Then ' si es .DOC o .RTF usar modo binario para abrirlo ' Dim sr As New System.IO.StreamReader(sFic, System.Text.Encoding.Default) ' ' si el formato es doc abrirlo en binario Select Case fi.Extension.ToLower Case ".doc" Dim st As System.IO.Stream st = sr.BaseStream Dim b() As Byte Dim offset As Integer Dim fin As Integer Dim sb As StringBuilder ReDim b(CInt(st.Length - 1)) st.Read(b, 0, b.Length) ' comprobar la posición x600, sino la xA00 offset = &H600 If b(offset) < 32 Then offset = &HA00 End If fin = Array.IndexOf(b, 0, offset) If fin = -1 Then fin = b.Length ' Convertir el array de bytes en una cadena sb = New StringBuilder(Encoding.Default.GetChars(b, offset, fin - offset)) ' el último caracter a analizar será hasta el siguiente chr(0) ' lo buscamos fin = sb.ToString.IndexOf(ChrW(0)) ' quitamos todo lo que haya desde esa posición hasta el final sb.Remove(fin, sb.Length - fin) ' sb.Replace(vbCr, "<br>" & vbCrLf) ' Quitar todos los caracteres no visibles Dim sb2 As New StringBuilder("[") For i As Integer = 1 To 9 sb2.AppendFormat("{0}", ChrW(i)) Next For i As Integer = 11 To 12 sb2.AppendFormat("{0}", ChrW(i)) Next For i As Integer = 14 To 31 sb2.AppendFormat("{0}", ChrW(i)) Next sb2.Append("]") Dim re As New Regex(sb2.ToString) Me.txtFic.Text = re.Replace(sb.ToString, "") ' Case ".rtf" ' usar un objeto RichTextBox para abrirlo Dim rtb As New RichTextBox rtb.LoadFile(fi.FullName) Dim sb As New StringBuilder(rtb.Text) sb.Replace(vbLf, "<br>" & vbCrLf) Me.txtFic.Text = sb.ToString rtb.Dispose() ' Case Else Me.txtFic.Text = sr.ReadToEnd() ' End Select ' sr.Close() ' lblInfo.BackColor = System.Drawing.Color.Aqua lblInfo.ForeColor = System.Drawing.Color.Blue lblInfo.Text = "Comprueba o rellena las opciones antes de pulsar en FILTRAR" ' ' comprobar el título, keywords, descripción y fichero zip comprobarTituloEtc() End If ' End If End Sub ' Private Sub fFiltrarHTML_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles MyBase.DragOver If e.Data.GetDataPresent("FileDrop") Then e.Effect = Windows.Forms.DragDropEffects.Copy End If End Sub ' Private Sub fFiltrarHTML_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load lblInfo.Text = "Arrastra al textBox el fichero que quieres 'filtrar'" Dim sb As New StringBuilder sb.AppendFormat("Pega aquí el texto convertido con Word{0}{0}", vbCrLf) sb.AppendFormat("Después selecciona las opciones correspondientes de la derecha.{0}{0}", vbCrLf) sb.AppendFormat("Rellena (cambia o agrega) el contenido del título, descripción y keywords.{0}{0}", vbCrLf) sb.AppendFormat("Por último pulsa en el botón FILTRAR{0}", vbCrLf) sb.AppendFormat("y así tendrás un fichero 'limpio de polvo y paja' al que solo tendrás que{0}", vbCrLf) sb.AppendFormat("aplicarle los estilos para el texto normal y el código...{0}{0}", vbCrLf) sb.AppendFormat("Espero que así lo tengas más fácil...{0}Gracias por hacerme el trabajo más fácil.{0}", vbCrLf) txtFic.Text = sb.ToString ' End Sub ' ' guardar los nuevos valores en la configuración Private Sub fFiltrarHTML_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing cfgSetValue("configuration/appSettings", "chkADO.Checked", Me.chkADO.Checked.ToString) cfgSetValue("configuration/appSettings", "chkAPI32.Checked", Me.chkAPI32.Checked.ToString) cfgSetValue("configuration/appSettings", "chkASP.Checked", Me.chkASP.Checked.ToString) cfgSetValue("configuration/appSettings", "optCS.Checked", Me.optCS.Checked.ToString) cfgSetValue("configuration/appSettings", "optNET.Checked", Me.optNET.Checked.ToString) cfgSetValue("configuration/appSettings", "optVB6.Checked", Me.optVB6.Checked.ToString) cfgSetValue("configuration/appSettings", "optVBNET.Checked", Me.optVBNET.Checked.ToString) cfgSetValue("configuration/appSettings", "txtDescripcion.Text", Me.txtDescripcion.Text) cfgSetValue("configuration/appSettings", "txtDescripcion.Text", Me.txtDescripcion.Text) cfgSetValue("configuration/appSettings", "txtTitulo.Text", Me.txtTitulo.Text) cfgSetValue("configuration/appSettings", "txtZip.Text", Me.txtZip.Text) ' If Me.WindowState = FormWindowState.Normal Then cfgSetValue("configuration/appSettings", "Form1.Left", Me.Left.ToString) cfgSetValue("configuration/appSettings", "Form1.Top", Me.Top.ToString) End If ' configXml.Save(ficConfig) End Sub ' Private Sub asignarCampos(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles optNET.CheckedChanged, optVBNET.CheckedChanged, _ chkASP.CheckedChanged, chkADO.CheckedChanged, chkAPI32.CheckedChanged, _ optVB6.CheckedChanged panelNET.Enabled = optNET.Checked optVBNET.Enabled = optNET.Checked optCS.Enabled = optNET.Checked If optNET.Checked AndAlso optCS.Checked = False AndAlso optVBNET.Checked = False Then optVBNET.Checked = True End If ' Dim s As String = "" ' If optNET.Checked Then If txtTitulo.Text = "" OrElse txtTitulo.Text.EndsWith(":") Then txtTitulo.Text = "Colabora.NET:" End If If optVBNET.Checked AndAlso Me.optCS.Checked Then s &= ".NET; VB; C#" ElseIf optVBNET.Checked Then s &= ".NET; VB" ElseIf Me.optCS.Checked Then s &= ".NET; C#" End If Else If txtTitulo.Text = "" OrElse txtTitulo.Text.EndsWith(":") Then txtTitulo.Text = "Colabora:" End If s = "VB; VB6" End If ' If chkASP.Checked Then If Me.optNET.Checked Then s &= "; ASP.NET" Else s &= "; ASP" End If End If ' If chkADO.Checked Then s &= "; Bases" If Me.optNET.Checked Then s &= "; ADO.NET" Else s &= "; ADO" End If End If ' If chkAPI32.Checked Then s &= "; API; Win32 API" If Me.optNET.Checked Then s &= "; Interop; DllImport" Else s &= "; Declare" End If End If ' txtKeywords.Text = s End Sub ' Private Function cfgGetValue(ByVal seccion As String, _ ByVal clave As String, _ ByVal predeterminado As String) As String ' Dim n As XmlNode n = configXml.SelectSingleNode(seccion & "/add[@key=""" & clave & """]") If Not n Is Nothing Then Return n.Attributes("value").InnerText Else Return predeterminado End If End Function ' Private Function cfgGetValueSection(ByVal seccion As String, _ ByVal clave As String, _ ByVal predeterminado As String) As String ' Si la sección indicada no es la última leída ' asignamos un valor nulo para que vuelva a leer la sección If seccionAnt <> seccion Then valores = Nothing seccionAnt = seccion End If ' If valores Is Nothing Then valores = CType(ConfigurationSettings.GetConfig(seccion), IDictionary) End If If valores.Contains(clave) Then Return valores(clave).ToString Else Return predeterminado End If End Function ' ' El método para guardar los valores Private Sub cfgSetValue(ByVal seccion As String, _ ByVal clave As String, _ ByVal valor As String) ' Dim n As XmlNode n = configXml.SelectSingleNode(seccion & "/add[@key=""" & clave & """]") If Not n Is Nothing Then n.Attributes("value").InnerText = valor End If End Sub ' Private Sub btnExaminaZip_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExaminaZip.Click ' seleccionar el fichero zip (28/Feb/05) Dim openFD As New OpenFileDialog ' With openFD .Title = "Seleccionar el fichero ZIP" .Filter = "Ficheros ZIP (no RAR, por favor) (*.zip)|*.zip|Ficheros RAR (*.rar)|*.rar" .FileName = txtZip.Text If .ShowDialog = DialogResult.OK Then ' End If End With End Sub ' Private Sub comprobarTituloEtc() ' comprobar los datos del fichero arrastrado (01/Mar/05) ' si es que tiene algo... Dim re As Regex Dim sTexto As String = txtFic.Text Dim m As Match ' ' guardar los <meta keywords, description y seccion ' ' Aquí utilizo Groups(1) para obtener el texto correspondiente ' para conseguirlo poner entre paréntesis lo que se quiere "capturar" ' re = New Regex("<meta name\s*=\s*""description""\s*content\s*=(\s*[^>]*)>", RegexOptions.IgnoreCase Or RegexOptions.Compiled Or RegexOptions.Singleline) m = re.Match(sTexto) If m.Success Then txtDescripcion.Text = m.Groups(1).Value.Replace(ChrW(34), "") End If re = New Regex("<meta name\s*=\s*""keywords""\s*content\s*=(\s*[^>]*)>", RegexOptions.IgnoreCase Or RegexOptions.Compiled Or RegexOptions.Singleline) m = re.Match(sTexto) If m.Success Then txtKeywords.Text = m.Groups(1).Value.Replace(ChrW(34), "") End If re = New Regex("<title>(.+)</title>", RegexOptions.IgnoreCase Or RegexOptions.Compiled) m = re.Match(sTexto) If m.Success Then txtTitulo.Text = m.Groups(1).Value.Replace(ChrW(34), "") End If ' '&zip= re = New Regex("&zip=(\w+\.zip)", RegexOptions.IgnoreCase Or RegexOptions.Compiled Or RegexOptions.Singleline) m = re.Match(sTexto) If m.Success Then txtZip.Text = m.Groups(1).Value End If End Sub End Class