Skip to content

An AutoHotkey (AHK) class that converts an input string into a markdown table, html table, or pretty-aligned plain text table.

License

Notifications You must be signed in to change notification settings

Nich-Cebolla/AutoHotkey-MakeTable

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Table of contents

  1. MakeTable
  2. AHK forum post
  3. Reddit post
  4. Usage
    1. Clone the repo
    2. What to use as the input string
    3. Parameters
    4. The MakeTable object
  5. MakeTable.Prototype.GetMarkdown
    1. Parameters
    2. Returns
  6. MakeTable.Prototype.GetHtml
    1. Parameters
    2. Example without attributes
    3. Example with attributes
  7. Changelog

MakeTable

An AutoHotkey (AHK) class that takes your csv-style text and converts it to one of the following:

  • A Markdown-formatted table.
  • An html-formatted table.
  • A pretty-aligned plain text table using character count to manage table width (for use with monospace fonts).

AHK forum post

https://www.autohotkey.com/boards/viewtopic.php?f=83&t=139518

Reddit post

https://www.reddit.com/r/AutoHotkey/comments/1ovrn3t/maketable_a_class_that_converts_an_input_string/

Usage

The examples in this document use the following input:

str := "
(
calldate,src,dst,dcontext,channel
07/14/2025 02:43:44,5555557485,17,play-system-recording,PJSIP/Cox_Trunk-0000d212
07/14/2025 05:58:22,5555557984,s,ivr-6,PJSIP/Cox_Trunk-0000d213
07/14/2025 06:36:41,5555559989,s,ivr-6,PJSIP/Cox_Trunk-0000d214
07/14/2025 06:47:11,5555552202,91017,ext-queues,PJSIP/Cox_Trunk-0000d215
)"

Basic usage:

#include <MakeTable>
str := "
(
calldate,src,dst,dcontext,channel
07/14/2025 02:43:44,5555557485,17,play-system-recording,PJSIP/Cox_Trunk-0000d212
07/14/2025 05:58:22,5555557984,s,ivr-6,PJSIP/Cox_Trunk-0000d213
07/14/2025 06:36:41,5555559989,s,ivr-6,PJSIP/Cox_Trunk-0000d214
07/14/2025 06:47:11,5555552202,91017,ext-queues,PJSIP/Cox_Trunk-0000d215
)"
options := {
    AddHeaderSeparator: true
  , InputColumnSeparator: ','
  , LinePrefix: "|  "
  , LineSuffix: "  |"
  , OutputColumnSeparator: "|"
}
tbl := MakeTable(str, options)

g := Gui()
; We need a monospaced font for the pretty-aligned text to look pretty
g.SetFont("s11 q5", "Cascadia Mono")
g.Add("Edit", "w1200 r8 -Wrap", tbl.Value)
g.Show()

; write to file
f := FileOpen(A_Temp "\MakeTable-output.md", "w")
f.Write(tbl.Value)
f.Close()

Clone the repo

  • Clone the repository.
    git clone https://github.com/Nich-Cebolla/AutoHotkey-MakeTable
  • Make a copy of the cloned repository and work with the copy. This is to avoid a situation where pulling an update breaks our scripts; by using a separate copy we can give ourselves time to review updates before updating the active copy.
    xcopy AutoHotkey-MakeTable AutoHotkey-MakeTable-Active /I /E
  • Add a file MakeTable.ahk to your lib folder. In the file is a single statement.
    #include C:\users\you\path\to\AutoHotkey-MakeTable-Active\src\MakeTable.ahk

With this setup, we can use #include <MakeTable> from any other script.

What to use as the input string

The text must be able to be divided into rows and cells using a character or regex pattern. For example, a common csv without quoted fields is viable as an input string. However, csv with quoted fields is not viable if the fields contain commas, because StrSplit will split at every comma. You can use ParseCsv to parse the csv and then recreate the csv using any character that is wholly absent from the text to separate the fields, then use that as input for MakeTable.

MakeTable accepts regex patterns to identify the boundaries between each row and each cell, so you are not limited to only csv.

Define Options.InputColumnSeparator and Options.InputRowSeparator with the patterns. The default values are listed below.

Pass the options object to MakeTable.Prototype.__New to get a MakeTable object.

The MakeTable object will have the pretty-aligned text set to property "Value". You also have two additional methods available, MakeTable.Prototype.GetMarkdown and MakeTable.Prototype.GetHtml.

If you use a very large input (e.g. 100k+ lines), MakeTable will finish the job but it might take a minute or two. Let it run and set a MsgBox to alert you when its finished.

There are various options to customize the output. Here's a few examples using various configurations.

calldate               src           dst      dcontext                 channel
--------------------------------------------------------------------------------------------------------------------
07/14/2025 02:43:44    5555557485    17       play-system-recording    PJSIP/Cox_Trunk-0000d-212-1080-@from-internal
--------------------------------------------------------------------------------------------------------------------
07/14/2025 05:58:22    5555557984    s        ivr-6                    PJSIP/Cox_Trunk-0000d-213-1080-@from-internal
--------------------------------------------------------------------------------------------------------------------
07/14/2025 06:36:41    5555559989    s        ivr-6                    PJSIP/Cox_Trunk-0000d-214-1080-@from-internal
--------------------------------------------------------------------------------------------------------------------
07/14/2025 06:47:11    5555552202    91017    ext-queues               PJSIP/Cox_Trunk-0000d-215-1080-@from-internal
|  calldate            |  src         |  dst    |  dcontext          |  channel           |
|  --------------------|--------------|---------|--------------------|------------------  |
|  07/14/2025          |  5555557485  |  17     |  play-system-reco  |  PJSIP/Cox_Trunk-  |
|  02:43:44            |              |         |  rding             |  0000d-212-1080-@  |
|                      |              |         |                    |  from-internal     |
|  07/14/2025          |  5555557984  |  s      |  ivr-6             |  PJSIP/Cox_Trunk-  |
|  05:58:22            |              |         |                    |  0000d-213-1080-@  |
|                      |              |         |                    |  from-internal     |
|  07/14/2025          |  5555559989  |  s      |  ivr-6             |  PJSIP/Cox_Trunk-  |
|  06:36:41            |              |         |                    |  0000d-214-1080-@  |
|                      |              |         |                    |  from-internal     |
|  07/14/2025          |  5555552202  |  91017  |  ext-queues        |  PJSIP/Cox_Trunk-  |
|  06:47:11            |              |         |                    |  0000d-215-1080-@  |
|                      |              |         |                    |  from-internal     |
|  calldate            |  src         |  dst    |  dcontext          |  channel           |
|  --------------------|--------------|---------|--------------------|------------------  |
|  07/14/2025          |  5555557485  |  17     |  play-system-reco  |  PJSIP/Cox_Trunk-  |
|  02:43:44            |              |         |  rding             |  0000d-212-1080-@  |
|                      |              |         |                    |  from-internal     |
|  --------------------|--------------|---------|--------------------|------------------  |
|  07/14/2025          |  5555557984  |  s      |  ivr-6             |  PJSIP/Cox_Trunk-  |
|  05:58:22            |              |         |                    |  0000d-213-1080-@  |
|                      |              |         |                    |  from-internal     |
|  --------------------|--------------|---------|--------------------|------------------  |
|  07/14/2025          |  5555559989  |  s      |  ivr-6             |  PJSIP/Cox_Trunk-  |
|  06:36:41            |              |         |                    |  0000d-214-1080-@  |
|                      |              |         |                    |  from-internal     |
|  --------------------|--------------|---------|--------------------|------------------  |
|  07/14/2025          |  5555552202  |  91017  |  ext-queues        |  PJSIP/Cox_Trunk-  |
|  06:47:11            |              |         |                    |  0000d-215-1080-@  |
|                      |              |         |                    |  from-internal     |

Parameters

  1. {String} - The input string.
  2. {Object} - The options object. The options are:
  • {Boolean} [ Options.AddHeaderSeparator = true ] - If true, adds a separator between the first row and second row.

  • {String} [ Options.ColumnPadding = "`s`s" ] - The literal string that is added to the left and right side of every column, EXCEPT the left side of the first column and the right side of the last column. Use Options.LinePrefix and Options.LineSuffix to adjust the left side of the first column and the right side of the last column.

  • {String} [ Options.InputColumnSeparator = "`t" ] - A RegEx pattern that identifies the boundary between columns.

  • {String} [ Options.InputRowSeparator = "\R" ] - A RegEx pattern that identifies the boundary between rows.

  • {String} [ Options.LinePrefix = "" ] - The literal string that is added before every line.

  • {String} [ Options.LineSuffix = "" ] - The literal string that is added after every line.

  • {Integer|Integer[]} [ Options.MaxWidths = "" ] - If in use, Options.MaxWidths is an array of integers which define the maximum allowable width per column. If the text in a cell exceeds the maximum, MakeTable breaks the text into multiple lines. If Options.MaxWidths is an integer, that value is applied as the max width of all columns.

  • {String[]} [ Options.OutputColumnPrefix = "" ] - Used to specify strings that prefix columns. The difference between Options.OutputColumnPrefix and Options.OutputColumnSeparator is that Options.OutputColumnSeparator is applied to all columns, whereas Options.OutputColumnPrefix is used to prefix every line of a specific column with a specific string. The value of this option, if used, should be an array of strings. The indices of the array are associated with the column index that is to be prefixed by the string at that index. For example, if I have a table that is three columns, and I want to prefix each line of the third column with "; ", then I would set Options.ColumnPrefix := ["", "", "; "]. I added this option with the intent of using it to comment out portions of text when using MakeTable to generate pretty-formatted code.

  • {Boolean} [ Options.OutputColumnPrefixSkipFirstRow = false ] - If true, the first line is not affected by Options.OutputColumnPrefix.

  • {String} [ Options.OutputColumnSeparator = "" ] - The literal string that is used to separate cells.

  • {Boolean} [ Options.OutputLineBetweenRows = false ] - If true, there will be an extra line separating the rows. The line will look just like the header separator seen in the above examples.

  • {String} [ Options.OutputRowSeparator = "`n" ] - The literal string that is used to separate rows.

  • {String} [ Options.TrimCharacters = "`s" ] - The value passed to the third parameter of StrSplit when breaking the input text into rows and cells. Options.TrimCharactersRow and Options.TrimCharactersCell supercede Options.TrimCharacters. For example, if you set Options.TrimCharacters := "`s" and Options.TrimCharactersRow := "$", the characters trimmed from the left and right side of each line is "$" and the characters trimmed from the left and right side of each cell is "`s" (space). https://www.autohotkey.com/docs/v2/lib/StrSplit.htm.

  • {String} [ Options.TrimCharactersRow = "" ] - The value passed to the third parameter of StrSplit when breaking the input text into lines. Options.TrimCharactersRow and Options.TrimCharactersCell supercede Options.TrimCharacters. For example, if you set Options.TrimCharacters := "`s" and Options.TrimCharactersRow := "$", the characters trimmed from the left and right side of each line is "$" and the characters trimmed from the left and right side of each cell is "`s" (space). https://www.autohotkey.com/docs/v2/lib/StrSplit.htm.

  • {String} [ Options.TrimCharactersCell = "" ] - The value passed to the third parameter of StrSplit when breaking the text lines into individual cells. Options.TrimCharactersRow and Options.TrimCharactersCell supercede Options.TrimCharacters. For example, if you set Options.TrimCharacters := "`s" and Options.TrimCharactersRow := "$", the characters trimmed from the left and right side of each line is "$" and the characters trimmed from the left and right side of each cell is "`s" (space). https://www.autohotkey.com/docs/v2/lib/StrSplit.htm.

The MakeTable object

The MakeTable object is an array of arrays of arrays of strings.

Each item of the MakeTable array is a MakeTable_Row representing a row in the table.

Each item of the MakeTable_Row arrays is a MakeTable_Cell object representing a cell in the table. MakeTable_Cell objects are arrays of strings, where each item represent a line of text for that cell. If you call the object, i.e. MakeTable_Cell.Prototype.Call, it will return the full text within the cell.

If Options.MaxWidths is not in use, then the length of the MakeTable_Cell array is always 1 (no cells are broken into multiple lines). If Options.MaxWidths is in use, then the length of the array is the number of lines that the text was broken into for that cell. The property "RowLines" is an array of integers representing the number of lines each row occupies, which is the greatest number of lines into which the text within any cell in that row was split.

Accessing a string value in the array looks like this:

; Assume `inputStr` and `options` are appropriately defined.
tbl := MakeTable(inputStr, options)
r := 1 ; row index
c := 1 ; column index
k := 1 ; line index
text := tbl[r][c][k]

Accessing the text in a cell looks like this:

; Assume `inputStr` and `options` are appropriately defined.
tbl := MakeTable(inputStr, options)
r := 1 ; row index
c := 1 ; column index
cell := tbl[r][c]
text := cell() ; call the cell object to get the entire cell's text content

You can produce a markdown table that is both pretty-aligned and valid markdown. To do that, use the following options (in addition to any other options you might want). We can't use Options.MaxWidths when producing markdown output because the line breaks will disrupt the markdown syntax. Options.MaxWidths is disabled by default. Use MakeTable.Prototype.GetMarkdown to include line breaks in your markdown table.

options := {
    AddHeaderSeparator: true
  , InputColumnSeparator: ',' ; set to whatever character / pattern identifies the boundary between each column
  , LinePrefix: "|  "
  , LineSuffix: "  |"
  , OutputColumnSeparator: "|"
}
tbl := MakeTable(inputString, options)

The above options will yield output like this:

|  calldate             |  src         |  dst    |  dcontext               |  channel                                        |
|  ---------------------|--------------|---------|-------------------------|-----------------------------------------------  |
|  07/14/2025 02:43:44  |  5555557485  |  17     |  play-system-recording  |  PJSIP/Cox_Trunk-0000d-212-1080-@from-internal  |
|  07/14/2025 05:58:22  |  5555557984  |  s      |  ivr-6                  |  PJSIP/Cox_Trunk-0000d-213-1080-@from-internal  |
|  07/14/2025 06:36:41  |  5555559989  |  s      |  ivr-6                  |  PJSIP/Cox_Trunk-0000d-214-1080-@from-internal  |
|  07/14/2025 06:47:11  |  5555552202  |  91017  |  ext-queues             |  PJSIP/Cox_Trunk-0000d-215-1080-@from-internal  |

MakeTable.Prototype.GetMarkdown

Use MakeTable.Prototype.GetMarkdown to produce a markdown table.

Parameters

  • {String} [ LineSeparator = "`n" ] - The string that separates each line in the output string.

  • {String} [ InnerLineSeparator = "" ] - The value passed to the parameter Separator which is used to separate each line of text within a cell when Options.MaxWidths is used. For example, if your cells contain very long strings that would look better broken up into multiple lines, you can set the Options.MaxWidths with an integer or array of integers. This will break up the text into multiple lines for cells that exceed the maximum. Then, when you call MakeTable.Prototype.GetMarkdown, you can set parameter InnerLineSeparator with a string to separate those lines. Use "<br>" to separate the lines with line breaks.

Returns

{String} - The markdown table.

MakeTable.Prototype.GetMarkdown has one benefit that is not available directly from the MakeTable core process - with MakeTable.Prototype.GetMarkdown we can also include <br> tags in-between long lines of text. We do that by setting the InnerLineSeparator parameter with "<br>", yielding an output like the below table, which will render correctly and will include line breaks at the <br> tags.

|calldate|src|dst|dcontext|channel|
|-|-|-|-|-|
|07/14/2025<br>02:43:44|5555557485|17|play-system-reco<br>rding|PJSIP/Cox_Trunk-<br>0000d-212-1080-@<br>from-internal|
|07/14/2025<br>05:58:22|5555557984|s|ivr-6|PJSIP/Cox_Trunk-<br>0000d-213-1080-@<br>from-internal|
|07/14/2025<br>06:36:41|5555559989|s|ivr-6|PJSIP/Cox_Trunk-<br>0000d-214-1080-@<br>from-internal|
|07/14/2025<br>06:47:11|5555552202|91017|ext-queues|PJSIP/Cox_Trunk-<br>0000d-215-1080-@<br>from-internal|

MakeTable.Prototype.GetHtml

Use MakeTable.Prototype.GetHtml to produce an html table.

Parameters

  • {String} [ Options.IndentChar = "`s" ] - The character that is used for indentation.

  • {Integer} [ Options.IndentLen = 2 ] - The number of Options.IndentChar that is used for one level of indentation.

  • {Integer} [ Options.InitialIndent = 0 ] - The initial indentation level of the output string.

  • {String} [ Options.InnerLineSeparator = "" ] - The value passed to the parameters MakeTable_Cell.Prototype.Call~Separator which is used to separate each line of text within a cell when MakeTable.Prototype.__New~Options.MaxWidths is used. For example, if your cells contain very long strings that would look better broken up into multiple lines, you can set the "MaxWidths" property of the options object that you pass to MakeTable.Prototype.__New. This will break up the text into multiple lines for cells that exceed the maximum. Then, when you call MakeTable.Prototype.GetHtml, you can set Options.InnerLineSeparator with a substring to separate those lines. A good option is "<br>". An empty string is also an appropriate option.

  • {String} [ Options.LineSeparator = "`n" ] - The literal string that separates each line in the output string.

  • {String} [ Options.TableAttribute = "" ] - Any attributes you want included with the <table> element, e.g. "class="tbl-class" border="1"". Separate each individual attribute with a space character.

  • {String} [ Options.TableStyle = "" ] - The style attribute value that will be included with the <table> elements. Only include the value that goes between the quotation marks of the style attribute, e.g. "color:red;".

  • {String|String[]|String[][]} [ Options.TdAttribute = "" ] - If a string, the attribute that will be included with all <td> elements.

    • If an array of strings, each index in the array corresponds to a row in the table (not including headers) and that string is applied as the attributes for each cell in the row. For example, index 1 is the first row after the headers.
    • If an array of arrays of strings, each index of the outer array corresponds with a row in the table (not including headers). For example, index 1 is the first row after the headers. Each index of the inner array corresponds with a cell in that row. For example, index 1 is the first cell in the row. The items of the inner array are strings that wil be applied as the attributes for the corresponding cell.
    • The arrays must have the correct number of items for the table content. If there are too few items, an IndexError will occur.
    • Separate each individual attribute with a space character.
    • For example, these are each valid, assuming the table has 3 data rows and 3 columns:
      options := { TdAttribute: "class=`"td-class`"" }
      options := { TdAttribute: [ "class=`"td-class-1`"", "class=`"td-class-2`"", "class=`"td-class-3`"" ] }
      options := { TdAttribute: [
          [ "class=`"td-class-1-1`"", "class=`"td-class-1-2`"", "class=`"td-class-1-3`"" ]
        , [ "class=`"td-class-2-1`"", "class=`"td-class-2-2`"", "class=`"td-class-2-3`"" ]
        , [ "class=`"td-class-3-1`"", "class=`"td-class-3-2`"", "class=`"td-class-3-3`"" ]
      ]}
  • {String} [ Options.TdStyle = "" ] - If a string, the style attribute value that will be included with all <td> elements. Only include the value that goes between the quotation marks of the style attribute, e.g. "color:red;".

    • If an array of strings, each index in the array corresponds to a row in the table (not including headers) and that string is applied as the attributes for each cell in the row. For example, index 1 is the first row after the headers.
    • If an array of arrays of strings, each index of the outer array corresponds with a row in the table (not including headers). For example, index 1 is the first row after the headers. Each index of the inner array corresponds with a cell in that row. For example, index 1 is the first cell in the row. The items of the inner array are strings that wil be used as the style attribute value for the corresponding cell.
    • The arrays must have the correct number of items for the table content. If there are too few items, an IndexError will occur.
    • For example, these are each valid, assuming the table has 3 data rows and 3 columns:
      options := { TdStyle: "color:red;" }
      options := { TdStyle: [ "color:red;", "color:green;", "color:blue;" ] }
      options := { TdStyle: [
          [ "color:red;", "color:green;", "color:blue;" ]
        , [ "color:blue;", "color:red;", "color:green;" ]
        , [ "color:green;", "color:blue;", "color:red;" ]
      ]}
  • {String|String[]} [ Options.ThAttribute = "" ] - If a string, the attribute that will be included with all <th> elements.

    • If an array of strings, each index in the array corresponds to an individual header.
    • The arrays must have the correct number of items for the table content. If there are too few items, an IndexError will occur.
    • Separate each individual attribute with a space character.
    • For example, these are each valid, assuming the table has a header row with 3 headers.
      options := { ThAttribute: "class=`"th-class`"" }
      options := { ThAttribute: [ "class=`"th-class-1`"", "class=`"th-class-2`"", "class=`"th-class-3`"" ] }
  • {String} [ Options.ThStyle = "" ] - If a string, the style attribute value that will be included with all <th> elements. Only include the value that goes between the quotation marks of the style attribute, e.g. "color:red;".

    • If an array of strings, each index in the array corresponds to a row in the table (not including headers).
    • The arrays must have the correct number of items for the table content. If there are too few items, an IndexError will occur.
    • For example, these are each valid, assuming the table has a header row with 3 headers.
      options := { ThStyle: "color:red;" }
      options := { ThStyle: [ "color:red;", "color:green;", "color:blue;" ] }
  • {String} [ Options.TrAttribute = "" ] - If a string, the attribute that will be included with all <tr> elements.

    • If an array of strings, each index in the array corresponds to a row in the table (not including headers).
    • The arrays must have the correct number of items for the table content. If there are too few items, an IndexError will occur.
    • Separate each individual attribute with a space character.
    • For example, these are each valid, assuming the table has 3 rows.
      options := { TrAttribute: "class=`"tr-class`"" }
      options := { TrAttribute: [ "class=`"tr-class-1`"", "class=`"tr-class-2`"", "class=`"tr-class-3`"" ] }
  • {String} [ Options.TrStyle = "" ] - If a string, the style attribute value that will be included with all <tr> elements. Only include the value that goes between the quotation marks of the style attribute, e.g. "color:red;".

    • If an array of strings, each index in the array corresponds to a row in the table (not including headers).
    • The arrays must have the correct number of items for the table content. If there are too few items, an IndexError will occur.
    • For example, these are each valid, assuming the table has 3 rows.
      options := { TrStyle: "color:red;" }
      options := { TrStyle: [ "color:red;", "color:green;", "color:blue;" ] }

Example without attributes

<table>
  <tr>
    <th>calldate</th>
    <th>src</th>
    <th>dst</th>
    <th>dcontext</th>
    <th>channel</th>
  </tr>
  <tr>
    <td>07/14/2025 02:43:44</td>
    <td>5555557485</td>
    <td>17</td>
    <td>play-system-recording</td>
    <td>PJSIP/Cox_Trunk-0000d-212-1080-@from-internal</td>
  </tr>
  <tr>
    <td>07/14/2025 05:58:22</td>
    <td>5555557984</td>
    <td>s</td>
    <td>ivr-6</td>
    <td>PJSIP/Cox_Trunk-0000d-213-1080-@from-internal</td>
  </tr>
  <tr>
    <td>07/14/2025 06:36:41</td>
    <td>5555559989</td>
    <td>s</td>
    <td>ivr-6</td>
    <td>PJSIP/Cox_Trunk-0000d-214-1080-@from-internal</td>
  </tr>
  <tr>
    <td>07/14/2025 06:47:11</td>
    <td>5555552202</td>
    <td>91017</td>
    <td>ext-queues</td>
    <td>PJSIP/Cox_Trunk-0000d-215-1080-@from-internal</td>
  </tr>
</table>

Example with attributes

<table class="table" style="color:red;">
  <tr class="tr1" style="color:red;">
    <th class="th1" style="color:red;">calldate</th>
    <th class="th2" style="color:green;">src</th>
    <th class="th3" style="color:blue;">dst</th>
    <th class="th4" style="color:pink;">dcontext</th>
    <th class="th5" style="color:purple;">channel</th>
  </tr>
  <tr class="tr2" style="color:green;">
    <td class="td2-1" style="color:purple;">07/14/2025 02:43:44</td>
    <td class="td2-2" style="color:red;">5555557485</td>
    <td class="td2-3" style="color:green;">17</td>
    <td class="td2-4" style="color:blue;">play-system-recording</td>
    <td class="td2-5" style="color:pink;">PJSIP/Cox_Trunk-0000d-212-1080-@from-internal</td>
  </tr>
  <tr class="tr3" style="color:blue;">
    <td class="td3-1" style="color:pink;">07/14/2025 05:58:22</td>
    <td class="td3-2" style="color:purple;">5555557984</td>
    <td class="td3-3" style="color:red;">s</td>
    <td class="td3-4" style="color:green;">ivr-6</td>
    <td class="td3-5" style="color:blue;">PJSIP/Cox_Trunk-0000d-213-1080-@from-internal</td>
  </tr>
  <tr class="tr4" style="color:pink;">
    <td class="td4-1" style="color:blue;">07/14/2025 06:36:41</td>
    <td class="td4-2" style="color:pink;">5555559989</td>
    <td class="td4-3" style="color:purple;">s</td>
    <td class="td4-4" style="color:red;">ivr-6</td>
    <td class="td4-5" style="color:green;">PJSIP/Cox_Trunk-0000d-214-1080-@from-internal</td>
  </tr>
  <tr class="tr5" style="color:purple;">
    <td class="td5-1" style="color:green;">07/14/2025 06:47:11</td>
    <td class="td5-2" style="color:blue;">5555552202</td>
    <td class="td5-3" style="color:pink;">91017</td>
    <td class="td5-4" style="color:purple;">ext-queues</td>
    <td class="td5-5" style="color:red;">PJSIP/Cox_Trunk-0000d-215-1080-@from-internal</td>
  </tr>
</table>

Changelog

  • 2025-11-14
    • Added property MakeTableObj.ColumnWidths, which is an array of integers representing the width, in character count, of each column.

About

An AutoHotkey (AHK) class that converts an input string into a markdown table, html table, or pretty-aligned plain text table.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published