Quick actions

cmd+k|ctrl+k

Navigation

Languages

out_table

Snippet info

Language

Nim

Visibility

public

Author

0hya6in

Created

2018-08-29T01:38:17Z

Updated

2018-08-30T00:57:57Z

import strutils,sequtils
import unicode,nre,options

proc display_length( text: string) : int =
    let rune_text = text.toRunes
    let text_len = rune_text.len

    for i in 0..<text_len:
        let c = $rune_text[i]
        # by http://orange-factory.com/sample/utf8/code3/ef.html#HalfwidthandFullwidthForms
        if c.match(re"(*U)[ヲ-゚]").isSome: 
            result += 1
        elif c.match(re"^[^\x01-\x7E\xA1-\xDF]").isSome :
            result += 2
        else:
            result += 1

proc out_table( rows: openArray[seq[string]]) : string =
    assert( rows.len >= 2 )
    assert( rows[0].len > 0 )

    # 各カラムの長さを計算
    var col_len_max: seq[int] = repeat(0, rows[0].len)
    for cols in rows:
        for i in 0..<cols.len:
            let col_len = cols[i].display_length
            if col_len > col_len_max[i]:
                col_len_max[i] = col_len

    # カラムの幅を+1する
    col_len_max.apply( proc (len: var int) = len += 1)

    # 水平の線を作成
    var horizon_line: seq[string] = @["+"]
    for i in 0..<rows[0].len:
        horizon_line.add(repeat("-",col_len_max[i]).join(""))
        horizon_line.add("+")
    let horizon = horizon_line.join("")

    # 結果格納用
    var newTable: seq[string] = @[ horizon ]

    # 1行ずつ出力する
    var row_num = 0
    for cols in rows:
        var newCols: seq[string] = @[""]
        for i in 0..<cols.len:
            let len_max = col_len_max[i]
            let col_len = cols[i].display_length
            newCols.add (cols[i] & repeat(" ", len_max - col_len).join(""))
        newCols.add("")

        newTable.add( newCols.join("|") )
        # 1行目出力後に、横線を追加する
        if row_num == 0:
            newTable.add( horizon )
        row_num += 1

    newTable.add( horizon )
    result = newTable.join("\n")


let text = """
abc,abcd
def,defff
ghi,ghiiiji
あいう,あいうえお
かきく,かきくけこ
さしす,ヲサシスセソ"""

let lines = text.splitLines()
var table: seq[seq[string]] = @[]

for line in lines:
    let row: seq[string] = line.split(",")
    table.add( row )

echo out_table( table )


INFO