Category talk:Wren-fmt: Difference between revisions

Content deleted Content added
PureFox (talk | contribs)
→‎Source code: Fixed Typo
PureFox (talk | contribs)
→‎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 f(w, n) { f(w, n, precision) }
static e(w, n) { e(w, n, precision) }
static g(w, n) { g(w, n, precision) }
static E(w, n) { Fmt.E(w, n, precision) }
static fz(w, n) { fz(w, n, precision) }
static f(w, n) { f(w, n, precision) }
static gz(w, n) { gz(w, n, precision) }
static g(w, n) { g(w, n, precision) }
static fc(w, n) { fc(w, n, precision) }
static h(w, n) { h(w, n, precision) }
static gc(w, n) { gc(w, n, precision) }
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, e, p) {
static callFn_(fn, w, v, p) {
return (fn == "d") ? d(w, e) :
return (fn == "d") ? d(w, v) :
(fn == "b") ? b(w, e) :
(fn == "b") ? b(w, v) :
(fn == "t") ? t(w, e) :
(fn == "t") ? t(w, v) :
(fn == "o") ? o(w, e) :
(fn == "o") ? o(w, v) :
(fn == "x") ? x(w, e) :
(fn == "x") ? x(w, v) :
(fn == "X") ? Fmt.X(w, e) :
(fn == "X") ? Fmt.X(w, v) :
(fn == "r") ? r(w, e) :
(fn == "r") ? r(w, v) :
(fn == "c") ? c(w, e) :
(fn == "c") ? c(w, v) :
(fn == "s") ? s(w, e) :
(fn == "s") ? s(w, v) :
(fn == "i") ? i(w, e) :
(fn == "i") ? i(w, v) :
(fn == "m") ? m(w, e) :
(fn == "m") ? m(w, v) :
(fn == "a") ? a(w, e) :
(fn == "a") ? a(w, v) :
(fn == "n") ? n(w, e) :
(fn == "n") ? n(w, v) :
(fn == "k") ? k(w, e) :
(fn == "k") ? k(w, v) :
(fn == "q") ? q(e) :
(fn == "q") ? q(v) :
(fn == "f") ? f(w, e, p) :
(fn == "e") ? e(w, v, p) :
(fn == "g") ? g(w, e, p) :
(fn == "E") ? Fmt.E(w, v, p) :
(fn == "dz") ? dz(w, e) :
(fn == "f") ? f(w, v, p) :
(fn == "bz") ? bz(w, e) :
(fn == "g") ? g(w, v, p) :
(fn == "tz") ? tz(w, e) :
(fn == "h") ? h(w, v, p) :
(fn == "oz") ? oz(w, e) :
(fn == "dz") ? dz(w, v) :
(fn == "xz") ? xz(w, e) :
(fn == "bz") ? bz(w, v) :
(fn == "Xz") ? Fmt.Xz(w, e) :
(fn == "tz") ? tz(w, v) :
(fn == "sz") ? sz(w, e) :
(fn == "oz") ? oz(w, v) :
(fn == "iz") ? iz(w, e) :
(fn == "xz") ? xz(w, v) :
(fn == "fz") ? fz(w, e, p) :
(fn == "Xz") ? Fmt.Xz(w, v) :
(fn == "gz") ? gz(w, e, p) :
(fn == "sz") ? sz(w, v) :
(fn == "dp") ? dp(w, e) :
(fn == "iz") ? iz(w, v) :
(fn == "dm") ? dm(w, e) :
(fn == "fz") ? fz(w, v, p) :
(fn == "dc") ? dc(w, e) :
(fn == "gz") ? gz(w, v, p) :
(fn == "rc") ? rc(w, e) :
(fn == "hz") ? hz(w, v, p) :
(fn == "sc") ? sc(w, e) :
(fn == "dp") ? dp(w, v) :
(fn == "ic") ? ic(w, e) :
(fn == "dm") ? dm(w, v) :
(fn == "fc") ? fc(w, e, p) :
(fn == "dc") ? dc(w, v) :
(fn == "gc") ? gc(w, e, p) : Fiber.abort("Method not recognized.")
(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 'gc' but is ignored otherwise.
// '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: a, b, c, d, f, g, i, k, m, n, o, q, r, s, t, v, x or X.
// 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 'gc' methods)
// , 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 zero is passed.
// 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 'g' style method. If absent, the default precision is passed.
// '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 ("abcdfgikmnoqrstxX".codePoints.contains(cp)) { // format letter
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 (!"abcdfgikmnoqrstxX".codePoints.contains(cp)) {
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" || fn == "g") && comma) {
} 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 && "dbtoxXsifg".contains(fn[0])) {
if (ns[0] == "0" && ns.count > 1 && "dbtoxXsifgh".contains(fn[0])) {
fn = fn[0] + "z"
fn = fn[0] + "z"
}
}