Category talk:Wren-fmt: Difference between revisions
Content deleted Content added
→Source code: Fixed Typo |
→Source code: Further tinkerings including some formatting options which were missing before. |
||
Line 316: | Line 316: | ||
// Convenience version of the above which uses double quotes as the embedding characters. |
// Convenience version of the above which uses double quotes as the embedding characters. |
||
static q(v) { "\"%(v)\"" } |
static q(v) { "\"%(v)\"" } |
||
// Formats a number 'n' (using 'h' format) to a maximum precision of 14 decimal places. |
|||
// It then converts it to exponential format and formats the mantissa to 'p' decimal places. |
|||
// The result is then padded with spaces to a minimum width 'w'. |
|||
// Negative 'w' left justifies, non-negative 'w' right justifies. |
|||
static e(w, n, p) { |
|||
var f = Fmt.h(w, n, 14).trim() |
|||
if (f.contains("e") || n.isInfinity || n.isNan) return Fmt.s(w, n) // use 'normal' representation |
|||
var dix = f.indexOf(".") |
|||
if (dix >= 0) { |
|||
f = f.replace(".", "") |
|||
} else { |
|||
dix = f.count |
|||
} |
|||
// look for index of first non-zero digit if there is one |
|||
var nzix = -1 |
|||
var i = (f[0] == "-") ? 1 : 0 |
|||
while (i < f.count) { |
|||
if (f[i] != "0") { |
|||
nzix = i |
|||
break |
|||
} |
|||
i = i + 1 |
|||
} |
|||
if (nzix == -1) return "0e00" |
|||
var delta = dix - nzix |
|||
f = (nzix+1<f.count) ? f[nzix] + "." + f[nzix+1..-1] : f[nzix] |
|||
if (n < 0) f = "-" + f |
|||
f = Fmt.h(p+2, Num.fromString(f), p).trim() |
|||
var exp = (delta >= 0) ? Fmt.dz(2, delta-1) : Fmt.dz(3, delta-1) |
|||
return Fmt.s(w, "%(f)e%(exp)") |
|||
} |
|||
// Works like 'e' except that the exponent symbol 'e' is replaced by upper case 'E'. |
|||
static E(w, n, p) { e(w, n, p).replace("e", "E") } |
|||
// Pads a number 'n' with leading spaces to a minimum width 'w' and a precision of 'p' decimal places. |
// Pads a number 'n' with leading spaces to a minimum width 'w' and a precision of 'p' decimal places. |
||
Line 353: | Line 388: | ||
static g(w, n, p) { |
static g(w, n, p) { |
||
var f = f(w, n, p) |
var f = f(w, n, p) |
||
if (f.contains(".") && f[-1] == "0") { |
if (f.contains(".") && (f[-1] == "0" || f[-1] == " ")) { |
||
var l1 = f.count |
var l1 = f.count |
||
f = f.trimEnd("0") |
f = f.trimEnd("0 ") |
||
if (f[-1] == ".") f = f + "0" |
if (f[-1] == ".") f = f + "0" |
||
f = f + (" " * (l1 - f.count)) |
|||
} |
|||
return f |
|||
} |
|||
// Works like 'f' except replaces any trailing zeros after the decimal point with spaces. |
|||
// If the resulting string would end with a decimal point, that is also replaced with a space. |
|||
static h(w, n, p) { |
|||
var f = f(w, n, p) |
|||
if (f.contains(".") && (f[-1] == "0" || f[-1] == " ")) { |
|||
var l1 = f.count |
|||
f = f.trimEnd("0 ") |
|||
if (f[-1] == ".") f = f[0..-2] |
|||
f = f + (" " * (l1 - f.count)) |
f = f + (" " * (l1 - f.count)) |
||
} |
} |
||
Line 367: | Line 415: | ||
static fz(w, n, p) { (w >= 0) ? zfill(w, f(w, n, p).trimStart()) : f(w, n, p) } |
static fz(w, n, p) { (w >= 0) ? zfill(w, f(w, n, p).trimStart()) : f(w, n, p) } |
||
static gz(w, n, p) { (w >= 0) ? zfill(w, g(w, n, p).trimStart()) : g(w, n, p) } |
static gz(w, n, p) { (w >= 0) ? zfill(w, g(w, n, p).trimStart()) : g(w, n, p) } |
||
static hz(w, n, p) { (w >= 0) ? zfill(w, h(w, n, p).trimStart()) : h(w, n, p) } |
|||
// Formats the integer part of 'n' in commatized form, space padded, |
// Formats the integer part of 'n' in commatized form, space padded, |
||
Line 385: | Line 434: | ||
static gc(w, n, p) { |
static gc(w, n, p) { |
||
var f = fc(w, n, p) |
var f = fc(w, n, p) |
||
if (f.contains(".") && f[-1] == "0") { |
if (f.contains(".") && (f[-1] == "0" || f[-1] == " ")) { |
||
var l1 = f.count |
var l1 = f.count |
||
f = f.trimEnd("0") |
f = f.trimEnd("0 ") |
||
if (f[-1] == ".") f = f + "0" |
if (f[-1] == ".") f = f + "0" |
||
f = f + (" " * (l1 - f.count)) |
|||
} |
|||
return f |
|||
} |
|||
// Works like 'fc' except replaces any trailing zeros after the decimal point with spaces. |
|||
// If the resulting string would end with a decimal point, that is also replaced with a space. |
|||
static hc(w, n, p) { |
|||
var f = fc(w, n, p) |
|||
if (f.contains(".") && (f[-1] == "0" || f[-1] == " ")) { |
|||
var l1 = f.count |
|||
f = f.trimEnd("0 ") |
|||
if (f[-1] == ".") f = f[0..-2] |
|||
f = f + (" " * (l1 - f.count)) |
f = f + (" " * (l1 - f.count)) |
||
} |
} |
||
Line 395: | Line 457: | ||
// Convenience versions of the above methods which use the default precision. |
// Convenience versions of the above methods which use the default precision. |
||
static |
static e(w, n) { e(w, n, precision) } |
||
static |
static E(w, n) { Fmt.E(w, n, precision) } |
||
static |
static f(w, n) { f(w, n, precision) } |
||
static |
static g(w, n) { g(w, n, precision) } |
||
static |
static h(w, n) { h(w, n, precision) } |
||
static |
static fz(w, n) { fz(w, n, precision) } |
||
static gz(w, n) { gz(w, n, precision) } |
|||
static hz(w, n) { hz(w, n, precision) } |
|||
static fc(w, n) { fc(w, n, precision) } |
|||
static gc(w, n) { gc(w, n, precision) } |
|||
static hc(w, n) { hc(w, n, precision) } |
|||
// Private worker method which calls a 'short name' method and returns its result. |
// Private worker method which calls a 'short name' method and returns its result. |
||
static callFn_(fn, w, |
static callFn_(fn, w, v, p) { |
||
return (fn == "d") ? d(w, |
return (fn == "d") ? d(w, v) : |
||
(fn == "b") ? b(w, |
(fn == "b") ? b(w, v) : |
||
(fn == "t") ? t(w, |
(fn == "t") ? t(w, v) : |
||
(fn == "o") ? o(w, |
(fn == "o") ? o(w, v) : |
||
(fn == "x") ? x(w, |
(fn == "x") ? x(w, v) : |
||
(fn == "X") ? Fmt.X(w, |
(fn == "X") ? Fmt.X(w, v) : |
||
(fn == "r") ? r(w, |
(fn == "r") ? r(w, v) : |
||
(fn == "c") ? c(w, |
(fn == "c") ? c(w, v) : |
||
(fn == "s") ? s(w, |
(fn == "s") ? s(w, v) : |
||
(fn == "i") ? i(w, |
(fn == "i") ? i(w, v) : |
||
(fn == "m") ? m(w, |
(fn == "m") ? m(w, v) : |
||
(fn == "a") ? a(w, |
(fn == "a") ? a(w, v) : |
||
(fn == "n") ? n(w, |
(fn == "n") ? n(w, v) : |
||
(fn == "k") ? k(w, |
(fn == "k") ? k(w, v) : |
||
(fn == "q") ? q( |
(fn == "q") ? q(v) : |
||
(fn == " |
(fn == "e") ? e(w, v, p) : |
||
(fn == " |
(fn == "E") ? Fmt.E(w, v, p) : |
||
(fn == " |
(fn == "f") ? f(w, v, p) : |
||
(fn == " |
(fn == "g") ? g(w, v, p) : |
||
(fn == " |
(fn == "h") ? h(w, v, p) : |
||
(fn == " |
(fn == "dz") ? dz(w, v) : |
||
(fn == " |
(fn == "bz") ? bz(w, v) : |
||
(fn == " |
(fn == "tz") ? tz(w, v) : |
||
(fn == " |
(fn == "oz") ? oz(w, v) : |
||
(fn == " |
(fn == "xz") ? xz(w, v) : |
||
(fn == " |
(fn == "Xz") ? Fmt.Xz(w, v) : |
||
(fn == " |
(fn == "sz") ? sz(w, v) : |
||
(fn == " |
(fn == "iz") ? iz(w, v) : |
||
(fn == " |
(fn == "fz") ? fz(w, v, p) : |
||
(fn == " |
(fn == "gz") ? gz(w, v, p) : |
||
(fn == " |
(fn == "hz") ? hz(w, v, p) : |
||
(fn == " |
(fn == "dp") ? dp(w, v) : |
||
(fn == " |
(fn == "dm") ? dm(w, v) : |
||
(fn == " |
(fn == "dc") ? dc(w, v) : |
||
(fn == " |
(fn == "rc") ? rc(w, v) : |
||
(fn == "sc") ? sc(w, v) : |
|||
(fn == "ic") ? ic(w, v) : |
|||
(fn == "fc") ? fc(w, v, p) : |
|||
(fn == "gc") ? gc(w, v, p) : |
|||
(fn == "hc") ? hc(w, v, p) : Fiber.abort("Method not recognized.") |
|||
} |
} |
||
Line 444: | Line 516: | ||
// The method to be applied is specified (as a string) in 'fn'. |
// The method to be applied is specified (as a string) in 'fn'. |
||
// The parameters to be passed to the method are specified in 'w' and 'p' |
// The parameters to be passed to the method are specified in 'w' and 'p' |
||
// 'p' is needed for 'f', 'g', 'fz', 'gz', 'fc' or ' |
// 'p' is needed for 'e', 'E', 'f', 'g', 'h', 'fz', 'gz', 'hz', 'fc', 'gc' or 'hc' but is ignored otherwise. |
||
// The resulting strings are then joined together using the separator 'sep'. |
// The resulting strings are then joined together using the separator 'sep'. |
||
// having first applied the 'q' method, with parameter 'cc', to each of them. |
// having first applied the 'q' method, with parameter 'cc', to each of them. |
||
Line 469: | Line 541: | ||
// it is an error to provide insufficient arguments. Verbs must be given in this form: |
// it is an error to provide insufficient arguments. Verbs must be given in this form: |
||
// $[flag][width][.precision][letter] of which all bracketed items except [letter] are optional. |
// $[flag][width][.precision][letter] of which all bracketed items except [letter] are optional. |
||
// The letter must be one of the 'short' methods: |
// The letter must be one of the 'short' methods: |
||
// a, b, c, d, e, E, f, g, h, i, k, m, n, o, q, r, s, t, v, x or X. |
|||
// If present, the flag (there can only be one) must be one of the following: |
// If present, the flag (there can only be one) must be one of the following: |
||
// + 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', 'rc', 'sc', 'ic', 'fc' or ' |
// , commatizes the following number ('dc', 'rc', 'sc', 'ic', 'fc', 'gc' or 'hc' 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 |
||
// 0 when followed by an explicit width, pads with leading zeros rather than spaces: |
|||
// ('dz', 'bz', 'tz', 'oz', 'xz, 'Xz', 'sz', iz', 'fz', 'gz' and 'hz' methods) |
|||
// If present, the width is the minimum width (+/-) to be passed to the appropriate method. |
// If present, the width is the minimum width (+/-) to be passed to the appropriate method. |
||
// It doesn't include any '#' flag prefix. If [width] is absent, a width of |
// It doesn't include any '#' flag prefix. If [width] is absent, a width of one is passed. |
||
// If present, the precision is the number of decimal places to be passed to the appropriate |
// If present, the precision is the number of decimal places to be passed to the appropriate |
||
// 'f' or ' |
// 'e', 'E', 'f', 'g' or 'h' style method. If absent, the default precision is passed. |
||
// Where any optional item is inappropriate to the method being used it is simply ignored. |
// Where any optional item is inappropriate to the method being used it is simply ignored. |
||
// 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 |
||
Line 536: | Line 611: | ||
var fn = "" |
var fn = "" |
||
var ds = "" |
var ds = "" |
||
if (" |
if ("abcdeEfghikmnoqrstxX".codePoints.contains(cp)) { // format letter |
||
fn = Conv.itoc(cp) |
fn = Conv.itoc(cp) |
||
} else if (cp == 42) { // star |
} else if (cp == 42) { // star |
||
Line 571: | Line 646: | ||
if (fn == "") { |
if (fn == "") { |
||
if (!" |
if (!"abcdeEfghikmnoqrstxX".codePoints.contains(cp)) { |
||
Fiber.abort("Unrecognized character in format string.") |
Fiber.abort("Unrecognized character in format string.") |
||
} |
} |
||
Line 584: | Line 659: | ||
fn = "dc" |
fn = "dc" |
||
} |
} |
||
} else if ((fn == "r" || fn == "s" || fn == "i" || fn == "f" || |
} else if ((fn == "r" || fn == "s" || fn == "i" || fn == "f" || |
||
fn == "g" || fn == "h") && 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 && "dbtoxXsifgh".contains(fn[0])) { |
||
fn = fn[0] + "z" |
fn = fn[0] + "z" |
||
} |
} |