📘

[PowerShell]Markdownのテーブル形式で各列の開始位置を合わせ整形するFunction

2025/03/03に公開

概要

Markdownのテーブル形式で列の開始位置がバラバラになっていることがあり視認性を向上するため、
内容は変えずにフォーマットを整理するFunctionを作成。

この記事のコードはPowerShellスクリプトではなく、PowerShellウィンドウやターミナルなどの
コンソール上での実行を想定しています。

自作したコード

自作したFunction
# サブFunction
Function Test-UTF8Bom {
    param (
        [Parameter(Mandatory=$true)][System.String]$FilePath
    )
    
    # BOMのバイトシーケンス
    $UTF8_BOM = [System.Byte[]](0xEF, 0xBB, 0xBF)
    
    # 先頭行をバイトで読み込み先頭から3バイト分のデータを取得
    [System.Byte[]]$first_3bytes = (Get-Content -Path $FilePath -Encoding Byte -TotalCount 3)
    
    # 先頭バイトでBOM付きか判定
    if ($null -eq (Compare-Object $first_3bytes $UTF8_BOM -SyncWindow 0)) {
        return $true
    } else {
        return $false
    }
}
# メインFunction
Function Format-MarkdownTableColumnWidth {
    param (
        [System.String]$FilePath
    )

    # 文字コードの判定
    if (-not (Test-UTF8Bom $FilePath)) {
        Write-Warning 'Not UTF8 BOM'
        return $null
    }

    # マルチバイト文字を考慮して文字列のバイト数を計算する関数
    Function Get-DisplayWidth {
        param (
            [string]$InputString
        )
        $width = 0

        foreach ($char in $InputString.ToCharArray()) {
            if ([System.Text.Encoding]::UTF8.GetByteCount($char) -gt 1) {
                # マルチバイト文字の場合は2文字分としてカウント
                $width += 2
            } else {
                # シングルバイト文字の場合は1文字分としてカウント
                $width += 1
            }
        }

        return $width
    }


    # ファイルから入力を読み込む
    $MarkdownTable = (Get-Content -Path $FilePath -Raw)

    # 入力を行ごとに分割
    $lines = $MarkdownTable -split "`n"

    # 各列の最大幅を計算
    $maxWidths = @{}
    foreach ($line in $lines) {
        if (-not ([System.String]::IsNullOrWhiteSpace($line))) {
            $columns = $line -split '\|'
            for ($i = 1; $i -lt $columns.Length - 1; $i++) {
                $column = $columns[$i].Trim()
                $byteLength = (Get-DisplayWidth $column)
                if (-not $maxWidths.ContainsKey($i)) {
                    $maxWidths[$i] = $byteLength
                } else {
                    if ($byteLength -gt $maxWidths[$i]) {
                        $maxWidths[$i] = $byteLength
                    }
                }
            }
        }
    }

    # 列の幅を揃えて再構築
    $alignedTable = @()
    foreach ($line in $lines) {
        if (-not ([System.String]::IsNullOrWhiteSpace($line))) {
            $columns = $line -split '\|'
            $newLine = '|'
            for ($i = 1; $i -lt $columns.Length - 1; $i++) {
                $column = $columns[$i].Trim()
                $padding = " " * ($maxWidths[$i] - (Get-DisplayWidth $column))
                $newLine += " " + $column + $padding + ' |'
            }
            $alignedTable += $newLine
        }
    }

    return $alignedTable -join "`r`n"
}

対応方法

  1. PowerShellウィンドウ、もしくはターミナル経由でコンソールを起動

  2. 自作したコードをコンソール画面にコピペ

  3. 入出力ファイルの場所を定義

    入出力ファイルを定義
    # 入力ファイルのパスを指定
    $inputFilePath = "D:\Downloads\input_markdowntable.md"
    $outputFilePath = "D:\Downloads\output_markdowntable.md"
    
  4. 入力ファイルを作成し指定の場所に保存

    それぞれインデントがズレている状態を作成

    入力ファイル「input_markdowntable.md」
    | column-A | column-B | column-C |
    | --- | --- | --- |
    | value-A1 | B1 | C1 |
    | A2 | column-B2 | C2 |
    | A3 | B3 | column-C3 |
    
    
  5. 自作のコード(Function)を呼び出しリダイレクトでファイル出力

    自作Functionの呼び出し
    # 関数を呼び出して結果をファイルに出力
    Format-MarkdownTableColumnWidth $inputFilePath > $outputFilePath
    
  6. あらかじめ設定した出力先を確認しインデントが合っていることを確認

    出力ファイル「output_markdowntable.md」
    | column-A | column-B  | column-C  |
    | ---      | ---       | ---       |
    | value-A1 | B1        | C1        |
    | A2       | column-B2 | C2        |
    | A3       | B3        | column-C3 |
    
    

まとめ

手作業でやっていたことをコード化。長期運用していないので入力ファイルのケースにより、
不具合があるかもしれません。

参考文献

なし

関連記事

https://haretokidoki-blog.com/pasocon_powershell-startup/
https://zenn.dev/haretokidoki/articles/7e6924ff0cc960
https://zenn.dev/haretokidoki/articles/fb6830f9155de5

GitHubで編集を提案

Discussion