elv-lib/mods/format.elv

222 lines
4.0 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use math
use re
use str
use ./common
use ./list
use ./map
use ./num
fn chars {|v|
str:split '' $v
}
fn len {|v|
chars $v | count
}
fn string {|v|
var k = (kind-of $v)
if (eq $k string) {
put $v
} elif (eq $k number) {
to-string $v
} elif (eq $k bool) {
common:cond $v 'X' ''
} elif (eq $k list) {
each $string~ $v | str:join ''
} elif (eq $v $nil) {
put ''
} else {
to-string $v
}
}
fn int {|v|
var k = (kind-of $v)
if (eq $k 'string') {
try {
var n = (math:trunc $v)
var s @_ = (str:split '.' (to-string $n))
put $s
} except e {
fail (printf '%s nest pas un nombre' $v)
}
} elif (eq $k 'number') {
int (to-string $v)
} elif (eq $k 'bool') {
common:cond $v 1 0
} else {
put 0
}
}
fn repeat {|n s|
use builtin
builtin:repeat $n $s | str:join ''
}
fn blank {|n|
repeat $n ' '
}
fn left {|str size|
var l = (len $str)
if (< $l $size) {
string [ $str (blank (- $size $l)) ]
} elif (== $l $size) {
put $str
} else {
string [ (chars $str) ][..$size]
}
}
fn right {|str size|
var l = (len $str)
if (< $l $size) {
string [ (blank (- $size $l)) $str ]
} elif (== $l $size) {
put $str
} else {
string [ (chars $str) ][(- $l $size)..]
}
}
fn center {|str size|
var l = (len $str)
if (< $l $size) {
var d = (- $size $l)
var b = (math:trunc (/ $d 2))
var e = (- $d $b)
string [ (blank $b) $str (blank $e) ]
} elif (== $l $size) {
put $str
} else {
var d = (- $l $size)
var b = (math:trunc (/ $d 2))
var e = (+ $b $size)
string [ (chars $str) ][$b..$e]
}
}
var -align = [
&center=$center~
&right=$right~
&left=$left~
]
fn column {|&align=left name @label|
var c = [
&name=$name
&align=$-align[$align]
&size=0
&label=''
]
if (> (count $label) 0) {
set c[label] = $label[0]
set c[size] = (count $label[0])
}
put $c
}
fn update-props {|props data|
each {|d|
set @props = (each {|c|
var n = $c[name]
if (has-key $d $n) {
var v = (string $d[$n])
var l = (count $v)
if (< $c[size] $l) {
set c[size] = $l
}
}
put $c
} $props)
} $data
put $props
}
fn line-header {|&sep=' ' props|
var @data = (each {|c|
$c[align] $c[label] $c[size]
} $props)
str:join $sep $data
}
fn line {|&sep=' ' props line|
var @data = (each {|c|
var n v = $c[name] ''
if (has-key $line $n) {
set v = (string $line[$n])
}
$c[align] $v $c[size]
} $props)
str:join $sep $data
}
fn list {|&with-header=$true &csep=' ' &hsep='-' &recompute=$true props @data|
set data = (common:to-list $data)
if $recompute {
set props = (update-props $props $data)
}
if $with-header {
echo (line-header &sep=$csep $props)
if (bool $hsep) {
var s = (* (- (count $props) 1) (count $csep))
each {|c|
set s = (+ $s $c[size])
} $props
echo (repeat (math:trunc (/ $s (count $hsep))) $hsep)
}
}
each {|d|
echo (line &sep=$csep $props $d)
} $data
}
fn size {|size|
var u = 0
var m = [
&10=Kio
&20=Mio
&30=Gio
&40=Tio
&50=Pio
&60=Eio
&70=Zio
&80=Yio
]
while (< $u 80) {
var p = (math:pow 2 (+ $u 10))
if (< $size $p) {
break
}
set u = (to-string (+ $u 10))
}
if (== $u 0) {
put $size
} else {
var p = (math:pow 2 $u)
var e = (/ $size $p)
printf '%.1f%s' $e $m[$u]
}
}
fn tabulate {|&cols=[] &sep=' ' @lines|
var cs = (count $cols)
var @data = (eawk {|_ @parts|
var ps = (count $parts)
var diff = (- $cs $ps)
if (< $diff 0) {
use builtin
set @cols = $@cols (builtin:repeat (num:neg $diff) [&size=0])
set cs = $ps
}
map:to-map $parts
} (common:to-list $@lines))
set @cols = (list:foreach {|i c|
var a = (common:cexec (has-key $c align) { put $c[align] } left)
column &align=$a $i
} $cols)
list &csep=$sep &with-header=$false $cols $@data
}