LoginSignup
3
2

More than 5 years have passed since last update.

Nimでテキストの表を出力

Last updated at Posted at 2018-08-29

概要

ここ最近はNim離れしていたので、リハビリ&思い出しながら、書いてみました。
2次元配列の(文字列)データを、テキスト表形式で出力します。

ソース

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 )

結果

Screenshot from 2018-08-29 13-38-16.png

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2