Version 0 of Unit converter

Updated 1999-07-22 18:39:45

Converts measures, mostly between metric and US style. "convert names" gives you the defined units. Working, but unfinished weekend fun project by Richard Suchenwirth. Examples:

 convert 10 km/h
 6.21 mph
 convert 6 ft 4 in ;# tries to group commensurable measures
 193.04 cm
 convert 6 ft 4 oz ;# ... else does them one by one
 182.88 cm 113.40 g
 convert 37.4 C
 99.32 F
 convert 193 cm ;# this, of course, is bad. Needs some work... 
 6.33 ft

 proc convert {args} {
    set res {}
    global tbl
    array set tbl {
        in {2.54 cm} ft {30.48 cm} yd {0.9144 m} mi {1.6093 km} 
        mph {1.6093 km/h}
        nmile {1.852 km} PS {0.7355 kW} sq.ft {.0929 m2} sq.mi {2.59 km2}
        EUR {1.95583 DM} C - F -
        gal {4.5436 l}  oz {28.3495 g} lb {453.59 g}  ton {1016.05 kg}
    }
    foreach i [array names tbl] {
        if {$tbl($i)=="-"}  continue
        lspread $tbl($i) -> fac unit2 ;# inverted measures
        if {![llength [array names tbl $unit2]]} {
                set tbl($unit2) [list [expr 1./$fac] $i]}
            }
    if {$args==""} {
        error "usage: convert {? value unit... }?, or: convert names.\n\
                 Units:\n[convert names]"
    }
    if {$args=="names"} {return [lsort [array names tbl]]}
    if {[llength $args]==1} {set args [lindex $args 0]}
    foreach {n unit} $args {
        if {$unit=="F"} {
            set res [list [expr ($n-32)*5/9] C]
        } elseif {$unit=="C"} {
            set res [list [expr $n*9/5+32] F]
        } elseif [llength [array names tbl $unit]] {
            lspread $tbl($unit) -> fac unit2
            lappend res [format %.2f [expr $n*$fac]]
            lappend res $unit2
        } else {
            lappend res $n; lappend res $unit
        }
    }
    foreach {x y} $res {lappend xx $x; ladd yy $y}
    if [llength $yy]==1 {set res [list [expr [join $xx +]] $yy] }
    return $res
 }