Category talk:Wren-fmt: Difference between revisions

Content added Content deleted
(→‎Source code: Several minor enhancements.)
Line 263: Line 263:
// Negative 'w' left justifies, non-negative 'w' right justifies.
// Negative 'w' left justifies, non-negative 'w' right justifies.
static s(w, v) { (w >= 0) ? rjust(w, v) : ljust(-w, v) }
static s(w, v) { (w >= 0) ? rjust(w, v) : ljust(-w, v) }

// As 's' above but pads with leading zeros instead of spaces.
// Any minus sign will be placed before the padding.
// When used with negative 'w' behaves the same as the above method.
static sz(w, v) { (w >= 0) ? zfill(w, v) : ljust(-w, v) }


// Formats a string or value 'v' in commatized form, space padded, using ',' as the separator.
// Formats a string or value 'v' in commatized form, space padded, using ',' as the separator.
Line 269: Line 274:
return (w >= 0) ? rjust(w, commatize(v)): ljust(-w, commatize(v))
return (w >= 0) ? rjust(w, commatize(v)): ljust(-w, commatize(v))
}
}

// These methods use the appropriate 'd' format if 'v' is a safe integer or the 's' format otherwise.
static i(w, v) { (v is Num && v.isInteger && v.abs <= Conv.maxSafeInt) ? d (w, v) : s (w, v) }
static iz(w, v) { (v is Num && v.isInteger && v.abs <= Conv.maxSafeInt) ? dz(w, v) : sz(w, v) }
static ic(w, v) { (v is Num && v.isInteger && v.abs <= Conv.maxSafeInt) ? dc(w, v) : sc(w, v) }


// Middles a string or value 'v' within a field of minimum width 'w'. Pads with spaces.
// Middles a string or value 'v' within a field of minimum width 'w'. Pads with spaces.
static m(w, v) { cjust(w, v) }
static m(w, v) { cjust(w, v) }

// Applies the 's' format to the kind (i.e. type) of 'v'.
static k(w, v) { s(w, v.type) }


// Embeds a string or value 'v' in 'cc', a string with no more than two characters.
// Embeds a string or value 'v' in 'cc', a string with no more than two characters.
Line 385: Line 398:
(fn == "c") ? c(w, e) :
(fn == "c") ? c(w, e) :
(fn == "s") ? s(w, e) :
(fn == "s") ? s(w, e) :
(fn == "i") ? i(w, e) :
(fn == "m") ? m(w, e) :
(fn == "m") ? m(w, e) :
(fn == "k") ? k(w, e) :
(fn == "q") ? q(e) :
(fn == "q") ? q(e) :
(fn == "f") ? f(w, e, p) :
(fn == "f") ? f(w, e, p) :
Line 395: Line 410:
(fn == "xz") ? xz(w, e) :
(fn == "xz") ? xz(w, e) :
(fn == "Xz") ? Fmt.Xz(w, e) :
(fn == "Xz") ? Fmt.Xz(w, e) :
(fn == "sz") ? sz(w, e) :
(fn == "iz") ? iz(w, e) :
(fn == "fz") ? fz(w, e, p) :
(fn == "fz") ? fz(w, e, p) :
(fn == "gz") ? gz(w, e, p) :
(fn == "gz") ? gz(w, e, p) :
Line 401: Line 418:
(fn == "dc") ? dc(w, e) :
(fn == "dc") ? dc(w, e) :
(fn == "sc") ? sc(w, e) :
(fn == "sc") ? sc(w, e) :
(fn == "ic") ? ic(w, e) :
(fn == "fc") ? fc(w, e, p) :
(fn == "fc") ? fc(w, e, p) :
(fn == "gc") ? gc(w, e, p) : Fiber.abort("Method not recognized.")
(fn == "gc") ? gc(w, e, p) : Fiber.abort("Method not recognized.")
Line 437: Line 455:
// + always prints a + or - sign ('dp' method)
// + always prints a + or - sign ('dp' method)
// (space) leaves a space for the sign but only prints minus ('dm' method)
// (space) leaves a space for the sign but only prints minus ('dm' method)
// , commatizes the following number ('dc', 'fc' or 'gc' methods)
// , commatizes the following number ('dc', 'sc', 'ic', 'fc' or 'gc' methods)
// # adds the appropriate prefix for the number formats: b, t, o, d, x and X.
// # adds the appropriate prefix for the number formats: b, t, o, d, x and X.
// * reads the width from the argument before the one to be formatted
// * reads the width from the argument before the one to be formatted
Line 447: Line 465:
// Where one of the arguments is a sequence (other than a string) this method senses it
// Where one of the arguments is a sequence (other than a string) this method senses it
// and applies the 'v' method to it. However, the 'sep' parameter is always a single space
// and applies the 'v' method to it. However, the 'sep' parameter is always a single space
// and the 'bb' and 'cc' parameters are always empty strings. The '#' flag has no effect.
// and the 'bb' and 'cc' parameters are always empty strings.
static slwrite(fmt, a) {
static slwrite(fmt, a) {
if (!(fmt is String)) Fiber.abort("First argument must be a string.")
if (!(fmt is String)) Fiber.abort("First argument must be a string.")
Line 460: Line 478:


// Gets the next numeric string from the format.
// Gets the next numeric string from the format.
var getNumber = Fn.new {
var getNumber = Fn.new { |minusAllowed|
i = i + 1
i = i + 1
if (i == le) Fiber.abort("Invalid format string.")
if (i == le) Fiber.abort("Invalid format string.")
cp = cps[i]
cp = cps[i]
var ns = ""
var ns = ""
if (cp == 45) {
if (!minusAllowed) Fiber.abort("Invalid format string")
ns = "-"
i = i + 1
if (i == le) Fiber.abort("Invalid format string.")
cp = cps[i]
}
while (cp >= 48 && cp <= 57) {
while (cp >= 48 && cp <= 57) {
ns = ns + Conv.itoc(cp)
ns = ns + Conv.itoc(cp)
Line 470: Line 495:
if (i == le) Fiber.abort("Invalid format string.")
if (i == le) Fiber.abort("Invalid format string.")
cp = cps[i]
cp = cps[i]
}
}
if (ns == "-") Fiber.abort("Invalid format string.")
return ns
return ns
}
}
Line 482: Line 508:
i = i + 1
i = i + 1
} else {
} else {
var ns = getNumber.call()
var ns = getNumber.call(true)
if (ns != "" && "*+,- #".codePoints.contains(cp)) {
if (ns != "" && "*+,#".codePoints.contains(cp)) {
Fiber.abort("Invalid format string.")
Fiber.abort("Invalid format string.")
}
}
var plus = false
var plus = false
var comma = false
var comma = false
var minus = false
var space = false
var space = false
var hash = false
var hash = false
var fn = ""
var fn = ""
var ds = ""
var ds = ""
if ("bcdfgmoqrstxX".codePoints.contains(cp)) { // format letter
if ("bcdfgikmoqrstxX".codePoints.contains(cp)) { // format letter
fn = Conv.itoc(cp)
fn = Conv.itoc(cp)
} else if (cp == 42) { // star
} else if (cp == 42) { // star
Line 504: Line 529:
i = i + 1
i = i + 1
cp = cps[i]
cp = cps[i]
if (cp == 46) ds = getNumber.call()
if (cp == 46) ds = getNumber.call(false)
} else if (cp == 43) { // plus sign
} else if (cp == 43) { // plus sign
plus = true
plus = true
ns = getNumber.call()
ns = getNumber.call(true)
if (cp == 46) ds = getNumber.call()
if (cp == 46) ds = getNumber.call(false)
} else if (cp == 44) { // comma
} else if (cp == 44) { // comma
comma = true
comma = true
ns = getNumber.call()
ns = getNumber.call(true)
if (cp == 46) ds = getNumber.call()
if (cp == 46) ds = getNumber.call(false)
} else if (cp == 45) { // minus sign
minus = true
ns = getNumber.call()
if (cp == 46) ds = getNumber.call()
} else if (cp == 46) { // dot
} else if (cp == 46) { // dot
ds = getNumber.call()
ds = getNumber.call(false)
} else if (cp == 32) { // space
} else if (cp == 32) { // space
space = true
space = true
ns = getNumber.call()
ns = getNumber.call(true)
if (cp == 46) ds = getNumber.call()
if (cp == 46) ds = getNumber.call(false)
} else if (cp == 35) { // hash
} else if (cp == 35) { // hash
hash = true
hash = true
ns = getNumber.call()
ns = getNumber.call(true)
if (cp == 46) ds = getNumber.call()
if (cp == 46) ds = getNumber.call(false)
} else {
} else {
Fiber.abort("Unrecognized character in format string.")
Fiber.abort("Unrecognized character in format string.")
Line 532: Line 553:


if (fn == "") {
if (fn == "") {
if (!"bcdfgmoqrstxX".codePoints.contains(cp)) {
if (!"bcdfgikmoqrstxX".codePoints.contains(cp)) {
Fiber.abort("Unrecognized character in format string.")
Fiber.abort("Unrecognized character in format string.")
}
}
Line 545: Line 566:
fn = "dc"
fn = "dc"
}
}
} else if ((fn == "s" || fn == "f" || fn == "g") && comma) {
} else if ((fn == "s" || fn == "i" || fn == "f" || fn == "g") && comma) {
fn = fn + "c"
fn = fn + "c"
}
}
if (ns == "") ns = "1"
if (ns == "") ns = "1"
if (ns[0] == "0" && ns.count > 1 && "dbtoxXfg".contains(fn[0])) {
if (ns[0] == "0" && ns.count > 1 && "dbtoxXsifg".contains(fn[0])) {
fn = fn[0] + "z"
fn = fn[0] + "z"
}
}
var n = Num.fromString(ns)
var w = Num.fromString(ns)
var w = minus ? -n : n
var p = (ds != "") ? Num.fromString(ds) : precision
var p = (ds != "") ? Num.fromString(ds) : precision
if (next < a.count) {
if (next < a.count) {
var e = a[next]
var e = a[next]
if ((e is Sequence) && !(e is String)) {
if ((e is Sequence) && !(e is String)) {
s = s + Fmt.v(fn, w, e, p, " ", "", "")
if (hash && "btodxX".contains(fn[0])) {
var rr = []
for (ee in e) {
var r = callFn_(fn, w, ee, p)
if (r[0] == "-") {
r = "-" + Conv.prefixes[fn[0]] + r[1..-1]
} else {
r = Conv.prefixes[fn[0]] + r
}
rr.add(r)
}
s = s + rr.join(" ")
} else {
s = s + Fmt.v(fn, w, e, p, " ", "", "")
}
} else {
} else {
var r = callFn_(fn, w, e, p)
var r = callFn_(fn, w, e, p)