Category talk:Wren-fmt: Difference between revisions
Content added Content deleted
m (→Source code: Typo.) |
(→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 == "m") ? m(w, e) : |
(fn == "m") ? m(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 == "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 |
// 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 (!minusAllowed) Fiber.abort("Invalid format string") |
|||
⚫ | |||
⚫ | |||
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 != "" && "*+, |
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 space = false |
var space = false |
||
var hash = false |
var hash = false |
||
var fn = "" |
var fn = "" |
||
var ds = "" |
var ds = "" |
||
if (" |
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 == 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 (!" |
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 && " |
if (ns[0] == "0" && ns.count > 1 && "dbtoxXsifg".contains(fn[0])) { |
||
fn = fn[0] + "z" |
fn = fn[0] + "z" |
||
} |
} |
||
var |
var w = Num.fromString(ns) |
||
⚫ | |||
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)) { |
||
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) |