Search code examples
powershellmarkdown

Using PowerShell Core ConvertFrom-Markdown to parse values in a markdown table


I'm interested in using the ConvertFrom-Markdown cmdlet to parse values in a markdown table. The cmdlet uses the markdig markdown processor, which has an Abstract Syntax Tree that should be able to be traversed for this purpose.

How can we search/enumerate the Tokens in the following powershell snippet to return the rows and columns?

(@'
# header1
## header2
| Column1 | Column2 |
| ------- | ------- |
| Row1Column1 | Row1Column2 |
| Row2Column1 | Ro2Column2 |
'@ | ConvertFrom-Markdown).Tokens

The values that I see in the Tokens look promising, I can see Markdig.Extensions.Tables.TableCell in the Parent fields, but that's about as far as I can get.


Solution

  • Here's a way to do it.

    Note I'm not sure if, example a Table can contain only TableRows, so the | where-object { ... } might not be necessary.

    # set up some sample data
    $md = @"
    # header1
    ## header2
    | Column1 | Column2 |
    | ------- | ------- |
    | Row1Column1 | Row1Column2 |
    | Row2Column1 | Ro2Column2 |
    "@ | ConvertFrom-Markdown
    
    # walk the syntax tree
    $mdDoc = $md.Tokens;
    $mdTables = @( $mdDoc | where-object { $_ -is [Markdig.Extensions.Tables.Table] } ); 
    foreach( $mdTable in $mdTables )
    {
        write-host "table";
        $mdRows = @( $mdTable | where-object { $_ -is [Markdig.Extensions.Tables.TableRow] } );
        foreach( $mdRow in $mdRows )
        {
            write-host "  row";
            write-host "    header = $($mdRow.IsHeader)";
            $mdCells = @( $mdRow | where-object { $_ -is [Markdig.Extensions.Tables.TableCell] } );
            foreach( $mdCell in $mdCells )
            {
                write-host "    cell";
                $mdInline = $mdCell.Inline;
                write-host "      inline - $($mdInline.Content)";
            }
        }
    }
    

    Which gives the following output:

    table
      row
        header = True
        cell
          inline - Column1
        cell
          inline - Column2
      row
        header = False
        cell
          inline - Row1Column1
        cell
          inline - Row1Column2
      row
        header = False
        cell
          inline - Row2Column1
        cell
          inline - Ro2Column2
    

    Hopefully that'll be enough to get you started...