Jump to content

Recommended Posts

Posted (edited)

_StringToTable() – Convert Text to a Formatted Table

The _StringToTable()  function allows you to convert structured text (like tab-separated data) into a  formatted, 
aligned table using Unicode box-drawing characters.
Ideal for displaying readable output in console-based tools or logs.
 

Local $sData = _
    "Company" & @TAB & "Contact" & @TAB & "Revenue" & @CRLF & _
    "Alfreds Futterkiste" & @TAB & "Maria Anders" & @TAB & "1200" & @CRLF & _
    "Centro Moctezuma" & @TAB & "Francisco Chang" & @TAB & "950" & @CRLF & _
    "Island Trading" & @TAB & "Helen Bennett" & @TAB & "15800"

ConsoleWrite(_StringToTable($sData, 3, @TAB, "L,C,R") & @CRLF)
┌──────────────────────┬───────────────────┬──────────┐
│ Company              │      Contact      │ Revenue  │
├──────────────────────┼───────────────────┼──────────┤
│ Alfreds Futterkiste  │   Maria Anders    │     1200 │
│ Centro Moctezuma     │ Francisco Chang   │      950 │
│ Island Trading       │  Helen Bennett    │    15800 │
└──────────────────────┴───────────────────┴──────────┘

 

   Made with ❤️ for readable and elegant output.

; https://www.autoitscript.com/forum/topic/212876-_stringtotable/
;----------------------------------------------------------------------------------------
; Title...........: _StringToTable.au3
; Description.....: Converts a string to a formatted table with alignment and frame options.
; AutoIt Version..: 3.3.16.1   Author: ioa747  Script Version: 0.2
; Note............: Testet in Win10 22H2
;----------------------------------------------------------------------------------------
;~ #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7

#include <String.au3>

Example()

;---------------------------------------------------------------------------------------
Func Example()
    Local $sTxt, $sOut
    Local $sData = _
            "Company" & @TAB & "Contact" & @TAB & "Revenue" & @CRLF & _
            "Alfreds Futterkiste" & @TAB & "Maria Anders" & @TAB & "1200" & @CRLF & _
            "Centro Moctezuma" & @TAB & "Francisco Chang" & @TAB & "950" & @CRLF & _
            "Island Trading" & @TAB & "Helen Bennett" & @TAB & "15800"

    $sOut = _StringToTable($sData, 3, @TAB, "L,C,R")
    ConsoleWrite($sOut & @CRLF & @CRLF)
    $sTxt &= $sOut & @CRLF & @CRLF

    $sOut = _StringToTable($sData, 0, @TAB, "L,C,R")
    ConsoleWrite($sOut & @CRLF & @CRLF)
    $sTxt &= $sOut & @CRLF & @CRLF

    $sOut = " https://www.autoitscript.com/forum/topic/212833-json-udf-using-json-c/#findComment-1542670"
    ConsoleWrite($sOut & @CRLF)
    $sTxt &= $sOut & @CRLF

    $sData = "" ; from https://www.autoitscript.com/forum/topic/212833-json-udf-using-json-c/#findComment-1542670
    $sData &= " name                 | time[ms] | factor | Std. Dev | Std. Err. | min    | max     | range  |" & @CRLF
    $sData &= " StringRegExp only    | 1.691    | 1      | 0.351    | 0.035     | 1.304  | 3.167   | 1.863  |" & @CRLF
    $sData &= " jq UDF               | 32.933   | 19.48  | 2.929    | 0.293     | 29.308 | 43.169  | 13.861 |" & @CRLF
    $sData &= " JsonC-UDF            | 51.086   | 30.21  | 3.205    | 0.321     | 45.625 | 63.46   | 17.835 |" & @CRLF
    $sData &= " pure AutoIt JSON-UDF | 97.916   | 57.9   | 5.685    | 0.569     | 86.362 | 113.467 | 27.105 |" & @CRLF
    $sData &= " JSMN-based JSON-UDF  | 108.248  | 64.01  | 5.512    | 0.551     | 99.029 | 130.864 | 31.835 |" & @CRLF

    $sOut = _StringToTable($sData, 3, "|", "L,R,R,R,R,R,R,R")
    ConsoleWrite($sOut & @CRLF & @CRLF)
    $sTxt &= $sOut & @CRLF & @CRLF

    ClipPut($sTxt)
    Run("notepad.exe")
    WinWaitActive("[CLASS:Notepad]", "", 5)
    Sleep(100)
    Send("^v")
EndFunc   ;==>Example

; #FUNCTION# --------------------------------------------------------------------------------------------------------------------
; Name...........: _StringToTable
; Description....: Converts a string to a formatted table with alignment and frame options.
; Syntax.........: _StringToTable( $sString [, $iFrame = 3 [, $sSeparator = @TAB [, $sAlign = ""]]] )
; Parameters.....: $sString    - The input string containing data values.
;                  $iFrame     - [optional] Frame type (0=NoFrame, 1=FrameNoHeader, 2=HeaderNoFrame, 3=FrameAndHeader) (Default is 3)
;                  $sSeparator - [optional] Separator used in the input string. (Default is @TAB)
;                  $sAlign     - [optional] Alignment options for each column (e.g., "L,R,C"). (Default is "" (left-aligned))
; Return values..: The formatted table as a string.
; Author ........: ioa747
; Notes .........: This function processes an input string, splits it into rows and columns,
;                  and formats them into a visually table with optional frames and alignment.
; Link ..........: https://www.autoitscript.com/forum/topic/212876-_stringtotable/
; Dependencies...: __FormatCell()
;--------------------------------------------------------------------------------------------------------------------------------
Func _StringToTable($sString, $iFrame = 3, $sSeparator = @TAB, $sAlign = "")

    If $iFrame < 0 Or $iFrame > 3 Then $iFrame = 3
    If $sSeparator = Default Or $sSeparator = -1 Then $sSeparator = @TAB

    ;Prepare string
    $sString = StringRegExpReplace($sString, "(\r\n|\n)", @CRLF)
    $sString = StringReplace($sString, $sSeparator & @CRLF, @CRLF)
    $sString = StringReplace($sString, @CRLF & $sSeparator, @CRLF)
    $sString = StringStripCR(StringRegExpReplace($sString, "(\r\n)$", ""))
    ;ConsoleWrite($sString & @CRLF)

    Local $aRows = StringSplit($sString, @LF, 1)
    If $aRows[0] = 0 Then Return SetError(1, 0, "")

    Local $aTable[UBound($aRows)][0]
    Local $iCols = 0

    For $i = 1 To $aRows[0]
        Local $aCols = StringSplit($aRows[$i], $sSeparator, 1)
        If $i = 1 Then
            $iCols = $aCols[0]
            ReDim $aTable[$aRows[0]][$iCols]
        Else
            If $aCols[0] < $iCols Then
                ReDim $aCols[$iCols + 1]
                For $k = $aCols[0] + 1 To $iCols
                    $aCols[$k] = ""
                Next
            EndIf
        EndIf

        For $j = 0 To $iCols - 1
            $aTable[$i - 1][$j] = StringStripWS($aCols[$j + 1], 3)
        Next
    Next

    Local $aColWidths[$iCols]
    For $j = 0 To $iCols - 1
        $aColWidths[$j] = 0
        For $i = 0 To UBound($aTable) - 1
            $aColWidths[$j] = $aColWidths[$j] > StringLen($aTable[$i][$j]) ? $aColWidths[$j] : StringLen($aTable[$i][$j])
        Next
    Next

    ; Alignment
    Local $aAlign[$iCols]
    If $sAlign <> "" Then
        Local $aRawAlign = StringSplit($sAlign, ",", 2)
        For $j = 0 To $iCols - 1
            Local $iIndex = $j
            If $iIndex >= UBound($aRawAlign) Then $iIndex = UBound($aRawAlign) - 1
            $aAlign[$j] = StringStripWS(StringUpper($aRawAlign[$iIndex]), 3)

            If Not StringRegExp($aAlign[$j], "^[LRC]$") Then $aAlign[$j] = "L"
        Next
    Else
        For $j = 0 To $iCols - 1
            $aAlign[$j] = "L"
        Next
    EndIf

    ; label Meaning
    ; $TL   ┌ Top Left
    ; $TR   ┐ Top Right
    ; $BL   └ Bottom Left
    ; $BR   ┘ Bottom Right
    ; $H    ─ Horizontal
    ; $V    │ Vertical
    ; $TH   ┬ Top Head
    ; $CH   ┴ Column Head
    ; $LH   ├ Left Head
    ; $RH   ┤ Right Head
    ; $C    ┼ Center

    Local Const $TL = "┌", $TR = "┐", $BL = "└", $BR = "┘"
    Local Const $H = "─", $V = "│", $C = "┼"
    Local Const $TH = "┬", $CH = "┴", $LH = "├", $RH = "┤"

    Local $sResult = ""
    Local $bHeader = ($iFrame = 2 Or $iFrame = 3)
    Local $bBorder = ($iFrame = 1 Or $iFrame = 3)
    Local $sPre = ($iFrame = 0 ? "" : " ")

    ; Top border
    If $bBorder Then
        $sResult &= $TL
        For $j = 0 To $iCols - 1
            $sResult &= _StringRepeat($H, $aColWidths[$j] + 2)
            $sResult &= ($j < $iCols - 1) ? $TH : $TR
        Next
        $sResult &= @LF
    EndIf

    ; Header row
    If $bHeader Then
        If $bBorder Or $iFrame = 2 Then $sResult &= $V
        For $j = 0 To $iCols - 1
            $sResult &= $sPre & __FormatCell($aTable[0][$j], $aColWidths[$j], $aAlign[$j]) & " "
            If $j < $iCols - 1 Then $sResult &= ($bBorder Or $iFrame = 2) ? $V : ""
        Next
        If $bBorder Or $iFrame = 2 Then $sResult &= $V
        $sResult &= @LF

        ; Header separator
        If $bBorder Then
            $sResult &= $LH
        ElseIf $iFrame = 2 Then
            $sResult &= $V
        EndIf

        For $j = 0 To $iCols - 1
            $sResult &= _StringRepeat($H, $aColWidths[$j] + 2)
            If $j < $iCols - 1 Then
                $sResult &= ($bBorder ? $C : ($iFrame = 2 ? $C : ""))
            Else
                If $bBorder Then $sResult &= $RH
            EndIf
        Next
        If $iFrame = 2 Then $sResult &= $V
        $sResult &= @LF
    EndIf

    ; Data rows
    For $i = ($bHeader ? 1 : 0) To UBound($aTable) - 1
        If $bBorder Or $iFrame = 2 Then $sResult &= $V
        For $j = 0 To $iCols - 1
            $sResult &= $sPre & __FormatCell($aTable[$i][$j], $aColWidths[$j], $aAlign[$j]) & " "
            If $j < $iCols - 1 Then $sResult &= ($bBorder Or $iFrame = 2) ? $V : ""
        Next
        If $bBorder Or $iFrame = 2 Then $sResult &= $V
        $sResult &= @LF
    Next

    ; Bottom border
    If $bBorder Then
        $sResult &= $BL
        For $j = 0 To $iCols - 1
            $sResult &= _StringRepeat($H, $aColWidths[$j] + 2)
            $sResult &= ($j < $iCols - 1) ? $CH : $BR
        Next
    EndIf

    Return $sResult
EndFunc   ;==>_StringToTable
;---------------------------------------------------------------------------------------
Func __FormatCell($text, $width, $align) ; internal
    Switch $align
        Case "R"
            Return StringFormat("%" & $width & "s", $text)
        Case "C"
            Local $pad = $width - StringLen($text)
            Local $left = Floor($pad / 2)
            Local $right = $pad - $left
            Return _StringRepeat(" ", $left) & $text & _StringRepeat(" ", $right)
        Case Else ; "L"
            Return StringFormat("%-" & $width & "s", $text)
    EndSwitch
EndFunc   ;==>__FormatCell
;---------------------------------------------------------------------------------------

 

Please, every comment is appreciated!
leave your comments and experiences here!
Thank you very much  :)

 

Relative:
https://www.autoitscript.com/forum/topic/211237-treestructuredir/

Edited by ioa747
update to Version: 0.2

I know that I know nothing

Posted

Thanks @ioa747, I like the implementation too 👍 .

One little thing:
In frame type/mode 0 ($iFrame = 0), the table will be generated without any frame (border). But there is a leading whitespace for each table row which is unnecessary in my opionion. Do you mind to change the code to get rid of that? Of course I could do it on my own, but maybe it's also good for all others here. What do you think?

Best regards
Sven

==> AutoIt related: 🔗 GitHub, 🔗 Discord Server, 🔗 Cheat Sheet

Spoiler

🌍 Au3Forums

🎲 AutoIt (en) Cheat Sheet

📊 AutoIt limits/defaults

💎 Code Katas: [...] (comming soon)

🎭 Collection of GitHub users with AutoIt projects

🐞 False-Positives

🔮 Me on GitHub

💬 Opinion about new forum sub category

📑 UDF wiki list

✂ VSCode-AutoItSnippets

📑 WebDriver FAQs

👨‍🏫 WebDriver Tutorial (coming soon)

Posted

Is it okay when I use your function to add two more modes?
I would add a markdown table format and a gherkin feature table format.

If I would use your code in any of my open source project, I would refer to you (naming and link).

👉 Markdown table format:

Spoiler
| Item              | In Stock | Price |
| :---------------- | :------: | ----: |
| Python Hat        |   True   | 23.99 |
| SQL Hat           |   True   | 23.99 |
| Codecademy Tee    |  False   | 19.99 |
| Codecademy Hoodie |  False   | 42.99 |

👉 Gherkin feature table format:

Spoiler
Given the following users exist:
  | name   | email              | twitter         |
  | Aslak  | aslak@cucumber.io  | @aslak_hellesoy |
  | Julien | julien@cucumber.io | @jbpros         |
  | Matt   | matt@cucumber.io   | @mattwynne      |

Best regards
Sven

==> AutoIt related: 🔗 GitHub, 🔗 Discord Server, 🔗 Cheat Sheet

Spoiler

🌍 Au3Forums

🎲 AutoIt (en) Cheat Sheet

📊 AutoIt limits/defaults

💎 Code Katas: [...] (comming soon)

🎭 Collection of GitHub users with AutoIt projects

🐞 False-Positives

🔮 Me on GitHub

💬 Opinion about new forum sub category

📑 UDF wiki list

✂ VSCode-AutoItSnippets

📑 WebDriver FAQs

👨‍🏫 WebDriver Tutorial (coming soon)

Posted

@SOLVE-SMART  update to Version: 0.2

without   leading whitespace in $iFrame = 0

 

16 minutes ago, SOLVE-SMART said:

Is it okay when I use your function to add two more modes?

Of course, feel free to use it
Adding these features sounds really cool. I can't wait to see the result.  :)

I know that I know nothing

Posted
48 minutes ago, ioa747 said:

Of course, feel free to use it

Nice, thanks.

44 minutes ago, ioa747 said:

Adding these features sounds really cool. I can't wait to see the result.  :)

I will share the code, but I won't add the features to your function(s). I would use my own code style and my own use cases. Therefore not all of your frame types will be applied in my version - just to mention it 😆 . In other words, it would not be that dynamic and UDF-like, because I focus on specific use cases not on plenty of variants.

Best regards
Sven

==> AutoIt related: 🔗 GitHub, 🔗 Discord Server, 🔗 Cheat Sheet

Spoiler

🌍 Au3Forums

🎲 AutoIt (en) Cheat Sheet

📊 AutoIt limits/defaults

💎 Code Katas: [...] (comming soon)

🎭 Collection of GitHub users with AutoIt projects

🐞 False-Positives

🔮 Me on GitHub

💬 Opinion about new forum sub category

📑 UDF wiki list

✂ VSCode-AutoItSnippets

📑 WebDriver FAQs

👨‍🏫 WebDriver Tutorial (coming soon)

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...