Índice de la sección dedicada a .NET (en el Guille) Utilidades

Utilidad para indentar el código

Código para Visual Basic.NET (VB.NET)

Código para C Sharp (C#)



Publicado el 11/Oct/2004
Actualizado el 11/Oct/2004
Autor: Guillermo 'guille' Som


Introducción

Esta utilidad te resultará "útil" si quieres indentar el código de ficheros de Visual Basic (cualquier versión), incluso del BASIC de MS-DOS.
La indentación para C# no es completa, ya que sólo indenta los bloques de código que estén encerrado entre llaves { y }, espero que en futuras revisiones amplíe la funcionalidad e indente el código completo de C#.
Si alguien se anima, que me mande un mensaje con el asunto: Quiero colaborar en gsIndentaNET (para C#). Agradecido estaré.

 

 

Cómo usar esta utilidad

La utilidad es bien sencilla de usar, tienes dos opciones:

  1. Indentar uno o varios ficheros (se puede hacer copia de seguridad)
  2. Indentar sólo un trozo de código (o un fichero completo)

En el primer caso se incluirán los ficheros a procesar en el listBox correspondiente (se pueden añadir seleccionando o bien arrastrándolos.
En el segundo, puedes pegar el código en la caja de textos o bien arrastrar el fichero a indentar.

En la siguiente imagen se muestra la utilidad en ejecución:

 


La utilidad de indentar el código

 

En el zip que se incluye más abajo, puedes bajarte el código completo.
El código de la clase Indentar es el mismo que el usado en la utilidad de colorear código.

 

Espero que te sea de utilidad, aunque a estas alturas no es muy útil, ya que los editores de código suelen tener esa opción de indentar automáticamente el código, al menos si estás usando Visual Studio .NET.

Nos vemos.
Guillermo

El zip con el código: gsIndentaNET_src.zip 17.3 KB

...


Código para Visual Basic.NET (VB.NET)El código para VB .NET

La clase para Indentar el código:

 

'------------------------------------------------------------------------------
' elGuille.UtilCode.Indentar                                        (10/Oct/04)
' Clase para indentar código BASIC
' Instrucciones soportadas de MSDOS-BASIC, VB6, VB.NET y VB2005
' En C# sólo se tendrá en cuenta el comentario de línea simple y
' los bloques encerrados entre llaves
'
' ©Guillermo 'guille' Som, 2004
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On 

Imports System
Imports vb = Microsoft.VisualBasic

Namespace elGuille.Util.Code

Public Class Indentar
    Public Shared PrimerTab As Boolean = False      ' si se debe indentar desde el principio
    '                                                 esto es útil si se procesa un trozo de código
    Private Const espaciosTab As Integer = 4        ' espacios para cada tabulación
    Private Shared nTab As Integer                  ' Número de indentaciones en procesarLinea
    ' los métodos, etc. que estén dentro de Interface no se indentan
    Private Shared noEsInterfaz As Integer = 1
    Public Shared EsCSharp As Boolean               ' si es un fichero C#
    Private Shared instruccionesIni() As String
    Private Shared instruccionesFin() As String
    Private Shared instrucciones() As String
    '
    Shared Sub New()
        ' asignar los valores predeterminados a usar en la clase
        ' No incluir las que tienen un trato especial, como:
        ' If, Select Case, Interface, End Select, End Interface
        '
        ' Las instrucciones que tienen su equivalente con END instrucción
        instrucciones = New String() { _
                "NAMESPACE ", "CLASS ", "MODULE ", "STRUCTURE ", _
                "PROPERTY ", "SUB ", "FUNCTION ", "OPERATOR ", _
                "ENUM ", "USING ", "TYPE ", _
                "WHILE ", "WITH ", "TRY"}
        ' Las instrucciones para iniciar un bloque indentado,
        ' aquí se especifican las que no tienen equivalentes con END <instrucción>
        instruccionesIni = New String() {"FOR ", "DO"}
        ' instrucciones para terminar un bloque indentado,
        ' aquí se indican las que no tienen equivalentes con END <instrucción>
        instruccionesFin = New String() {"END IF", "END GET", "END SET", "NEXT", "LOOP", "WEND"}
        '
        Dim n As Integer = instrucciones.Length - 1
        Dim m As Integer = instruccionesIni.Length
        Dim k As Integer = instruccionesFin.Length
        ReDim Preserve instruccionesIni(n + m)
        ReDim Preserve instruccionesFin(n + k)
        For i As Integer = 0 To n
            instruccionesIni(m + i) = instrucciones(i)
            instruccionesFin(k + i) = "END " & instrucciones(i).TrimEnd()
            'Console.WriteLine(instruccionesIni(m + i))
            'Console.WriteLine(instruccionesFin(k + i))
        Next
    End Sub
    '
    '''--------------------------------------------------------------------
    '''<summary>
    ''' ProcesarLineas: El método público para procesar el código a indentar
    ''' Sobrecargas que reciben distintos parámetros:
    '''     un TextReader (para usar con Streamreader
    '''     un array de strings (por si se usa desde un textBox)
    '''     una cadena en la que cada línea estará terminada con un retorno de carro
    '''</summary>
    '''<returns>
    ''' Devuelve una cadena en la que cada línea termina con un retorno de carro
    '''</returns>
    '''--------------------------------------------------------------------
    Public Shared Function ProcesarLineas(ByVal sr As System.IO.TextReader) As String
        Dim sb As New System.Text.StringBuilder
        nTab = 0
        noEsInterfaz = 1
        While sr.Peek <> -1
            sb.Append(String.Concat(procesarLinea(sr.ReadLine()), vb.vbCrLf))
        End While
        '
        Return sb.ToString()
    End Function
    Public Shared Function ProcesarLineas(ByVal lineas() As String) As String
        Dim sb As New System.Text.StringBuilder
        nTab = 0
        noEsInterfaz = 1
        For i As Integer = 0 To lineas.Length - 1
            sb.Append(String.Concat(procesarLinea(lineas(i)), vb.vbCrLf))
        Next
        '
        Return sb.ToString()
    End Function
    Public Shared Function ProcesarLineas(ByVal sr As String) As String
        Dim lineas() As String = vb.Split(sr, vb.vbCrLf)
        Return ProcesarLineas(lineas)
    End Function
    '
    '''--------------------------------------------------------------------
    '''<summary>
    ''' función interna para procesar cada línea
    ''' recibe como parámetro una cadena (una línea de código)
    '''</summary>
    '''<returns>
    ''' Devuelve una cadena ya indentada
    '''</returns>
    '''--------------------------------------------------------------------
    '
    Private Shared Function procesarLinea(ByVal entrada As String) As String
        '------------------------------------------------------------------------
        ' Procesa los datos de entrada y los pone en salida.    (23.13 25/Nov/93)
        '
        ' Devuelve el valor de la salida
        '------------------------------------------------------------------------
        Dim indentar As Integer     ' Con cuantos espacios indentar esta línea
        Dim p As Integer
        Dim salida As String
        Dim hallado As Boolean
        '
        ' indentar siempre
        '
        indentar = nTab
        '
        entrada = entrada.TrimStart(" "c, vb.Chr(9))
        If vb.Len(entrada) = 0 Then
            '    entrada = entrada.TrimStart(" "c, vb.Chr(9))
            'Else
            Return entrada
        End If
        '
        '
        ' si es un comentario o tiene comillas dobles, no comprobar nada
        If (EsCSharp = False AndAlso entrada.StartsWith("'")) OrElse _
           (EsCSharp = True AndAlso (entrada.StartsWith(""//") OrElse entrada.IndexOf(vb.Chr(34)) > -1)) Then
            If indentar > 0 Then
                entrada = New String(" "c, espaciosTab * indentar) & entrada
            End If
            Return entrada
        End If
        '
        salida = entrada
        entrada = vb.UCase(entrada)
        '
        '
        ' En las comparaciones, sólo hay que asignar indentar,
        ' después de ajustar el valor de nTab,
        ' cuando esa instrucción deba indentarse
        '
        ' Cuando se encuentra con estas instrucciones, se quitan los tabuladores
        ' y se deja para que la próxima línea se pueda indentar
        '
        '
        hallado = False
        '
        If EsCSharp Then
            hallado = True
            ' sólo comprobar { y }
            If entrada.IndexOf("{") > -1 Then
                nTab += 1
            End If
            If entrada.IndexOf("}") > -1 Then
                nTab -= 1
                indentar = nTab
            End If
        End If
        '
        If hallado = False Then
            hallado = True
            If vb.Left(entrada, 13) = "END INTERFACE" Then
                nTab -= 1
                indentar = nTab
                noEsInterfaz = 1
            ElseIf vb.InStr(" " & entrada, " INTERFACE ") > 0 Then
                nTab += 1
                noEsInterfaz = 0
                '
            ElseIf vb.Left(entrada, 3) = "GET" Then
                nTab += 1
            ElseIf vb.Left(entrada, 3) = "SET" Then
                nTab += 1
            ElseIf vb.InStr(entrada, "PUBLIC GET") > 0 Then
                nTab += 1
            ElseIf vb.InStr(entrada, "FRIEND GET") > 0 Then
                nTab += 1
            ElseIf vb.InStr(entrada, "PRIVATE GET") > 0 Then
                nTab += 1
            ElseIf vb.InStr(entrada, "PROTECTED GET") > 0 Then
                nTab += 1
            ElseIf vb.InStr(entrada, "PUBLIC SET") > 0 Then
                nTab += 1
            ElseIf vb.InStr(entrada, "FRIEND SET") > 0 Then
                nTab += 1
            ElseIf vb.InStr(entrada, "PRIVATE SET") > 0 Then
                nTab += 1
            ElseIf vb.InStr(entrada, "PROTECTED SET") > 0 Then
                nTab += 1
                '
                ' Instrucciones para BASIC de MS-DOS
            ElseIf vb.Left(entrada, 7) = "GLOBAL " Then
                indentar = 0
            ElseIf vb.InStr(entrada, "DECLARE ") > 0 Then
                ' Dejarlo como está
                indentar = 0
            ElseIf vb.Left(entrada, 5) = "BEGIN" Then
                nTab += 1
            ElseIf vb.Left(entrada, 9) = "ATTRIBUTE" Then
                indentar = 0
            ElseIf vb.Left(entrada, 6) = "COMMON" Then
                indentar = 0
            ElseIf vb.Left(entrada, 3) = "DEF" Then
                indentar = 0
                '
                ' Estas instrucciones deben aparecer en la primera columna
            ElseIf vb.Left(entrada, 7) = "OPTION " Then
                indentar = 0
                'nTab = 0
            ElseIf vb.Left(entrada, 6) = "#CONST" Then
                indentar = 0
                'nTab = 0
            ElseIf vb.Left(entrada, 7) = "#REGION" Then
                indentar = 0
                nTab = 1
            ElseIf vb.Left(entrada, 11) = "#END REGION" Then
                nTab = 1
                indentar = 0
                '
                '
                ' Si se quiere que CASE esté al nivel de SELECT: cambiar el 2 por 1
            ElseIf vb.Left(entrada, 12) = "SELECT CASE " Then
                If vb.InStr(entrada, "END SELECT") = 0 Then
                    nTab = nTab + 2
                End If
            ElseIf vb.Left(entrada, 5) = "CASE " Then
                indentar = indentar - 1
            ElseIf vb.Left(entrada, 10) = "END SELECT" Then
                nTab = nTab - 2
                indentar = nTab
                '
                '
            ElseIf vb.Left(entrada, 3) = "IF " OrElse vb.Left(entrada, 4) = "#IF " Then
                p = vb.InStr(entrada, "THEN")
                If p > 0 Then
                    If vb.Right(entrada, 4) = "THEN" Then
                        nTab += 1
                    Else
                        ' comprobar si hay un comentario
                        If vb.InStr(p + 1, entrada, "'") > 0 Then
                            nTab += 1
                        End If
                    End If
                End If
            ElseIf vb.Left(entrada, 4) = "ELSE" Then
                indentar = indentar - 1
            ElseIf vb.Left(entrada, 7) = "ELSEIF " Then
                indentar = indentar - 1
            ElseIf vb.Left(entrada, 5) = "#ELSE" Then
                indentar = indentar - 1
            ElseIf vb.Left(entrada, 8) = "#ELSEIF " Then
                indentar = indentar - 1
            ElseIf vb.Left(entrada, 7) = "#END IF" Then
                nTab -= 1
                indentar = nTab
                '
            ElseIf vb.Left(entrada, 5) = "CATCH" Then
                indentar = indentar - 1
            ElseIf vb.Left(entrada, 7) = "FINALLY" Then
                indentar = indentar - 1
                '
                '
            Else
                hallado = False
            End If
        End If
        '
        If hallado = False Then
            For i As Integer = 0 To instruccionesFin.Length - 1
                If (" " & entrada).IndexOf(" " & instruccionesFin(i)) > -1 Then
                    nTab -= 1 * noEsInterfaz
                    indentar = nTab
                    hallado = True
                    Exit For
                End If
            Next
        End If
        If hallado = False Then
            ' aquí puede darse que se encuentren los EXIT <instrucción>
            For i As Integer = 0 To instruccionesIni.Length - 1
                p = (" " & entrada).IndexOf(" " & instruccionesIni(i))
                Dim k As Integer = entrada.IndexOf("'")
                If k = -1 Then k = p + 1
                If (p > -1 AndAlso p < k) AndAlso _
                   entrada.IndexOf("EXIT " & instruccionesIni(i)) = -1 Then
                    nTab += 1 * noEsInterfaz
                    hallado = True
                    Exit For
                End If
            Next
        End If
        '
        '
        If indentar = 0 Then
            If PrimerTab Then
                indentar = 1
                nTab = 1
            End If
        End If
        If indentar > 0 Then
            ' Se puede sustituir esto por CHR$(9)en lugar de 4 espacios
            ' es que yo suelo usar 4 espacios para cada tabulacion
            ' salida = STRING$(indentar, CHR$(9)) & salida
            'salida = vb.Space(espaciosTab * indentar) & salida
            salida = New String(" "c, espaciosTab * indentar) & salida
            '
        End If
        '
        Return salida
    End Function
End Class

End Namespace

 

...

 


Código para C Sharp (C#)El código para C# (seguramente lo pondré en un futuro no muy lejano)

...

 


la Luna del Guille o... el Guille que está en la Luna... tanto monta...