gnome-shell/js/misc/format.js

72 lines
2.9 KiB
JavaScript
Raw Normal View History

// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const ShellJS = imports.gi.ShellJS;
/*
* This function is intended to extend the String object and provide
* an String.format API for string formatting.
* It has to be set up using String.prototype.format = Format.format;
* Usage:
* "somestring %s %d".format('hello', 5);
* It supports %s, %d, %x and %f, for %f it also support precisions like
* "%.2f".format(1.526). All specifiers can be prefixed with a minimum
* field width, e.g. "%5s".format("foo"). Unless the width is prefixed
* with '0', the formatted string will be padded with spaces.
*/
function format() {
let str = this;
let i = 0;
let args = arguments;
return str.replace(/%(I+)?([0-9]+)?(?:\.([0-9]+))?(.)/g, function (str, flagsGroup, widthGroup, precisionGroup, genericGroup) {
if (precisionGroup != '' && genericGroup != 'f')
throw new Error("Precision can only be specified for 'f'");
let hasAlternativeIntFlag = (flagsGroup.indexOf('I') != -1);
if (hasAlternativeIntFlag && genericGroup != 'd')
throw new Error("Alternative output digits can only be specfied for 'd'");
let fillChar = (widthGroup[0] == '0') ? '0' : ' ';
let width = parseInt(widthGroup, 10) || 0;
function fillWidth(s, c, w) {
let fill = '';
for (let i = 0; i < w; i++)
fill += c;
return fill.substr(s.length) + s;
}
let s = '';
switch (genericGroup) {
case '%':
return '%';
break;
case 's':
s = args[i++].toString();
break;
case 'd':
let intV = parseInt(args[i++]);
if (hasAlternativeIntFlag)
s = ShellJS.format_int_alternative_output(intV);
else
s = intV.toString();
break;
case 'x':
s = parseInt(args[i++]).toString(16);
break;
case 'f':
if (precisionGroup == '')
s = parseFloat(args[i++]).toString();
else
s = parseFloat(args[i++]).toFixed(parseInt(precisionGroup));
break;
default:
throw new Error('Unsupported conversion character %' + genericGroup);
}
return fillWidth(s, fillChar, width);
});
}