App-SocialCalc-Multiplayer
view release on metacpan or search on metacpan
socialcalc/formatnumber2.js view on Meta::CPAN
thisformat = scfn.format_definitions[format_string];
section = 0;
}
break; // if no comparision, matches on this section
}
if (op == scfn.commands.section) { // end of section
if (!gotcomparison) { // no comparison, so it's a match
break;
}
gotcomparison = 0;
section++; // check out next one
continue;
}
if (op == scfn.commands.comparison) { // found a comparison - do we meet it?
i=operandstr.indexOf(":");
compop=operandstr.substring(0,i);
compval=operandstr.substring(i+1)-0;
if ((compop == "<" && rawvalue < compval) ||
(compop == "<=" && rawvalue <= compval) ||
(compop == "=" && rawvalue == compval) ||
(compop == "<>" && rawvalue != compval) ||
(compop == ">=" && rawvalue >= compval) ||
(compop == ">" && rawvalue > compval)) { // a match
break;
}
gotcomparison = 1;
}
}
}
else if (section > 0) { // more than one section (separated by ";")
if (section == 1) { // two sections
if (negativevalue) {
negativevalue = 0; // sign will provided by section, not automatically
section = 1; // use second section for negative values
}
else {
section = 0; // use first for all others
}
}
else if (section == 2) { // three sections
if (negativevalue) {
negativevalue = 0; // sign will provided by section, not automatically
section = 1; // use second section for negative values
}
else if (zerovalue) {
section = 2; // use third section for zero values
}
else {
section = 0; // use first for positive
}
}
}
sectioninfo = thisformat.sectioninfo[section]; // look at values for our section
if (sectioninfo.commas > 0) { // scale by thousands
for (i=0; i<sectioninfo.commas; i++) {
value /= 1000;
}
}
if (sectioninfo.percent > 0) { // do percent scaling
for (i=0; i<sectioninfo.percent; i++) {
value *= 100;
}
}
decimalscale = 1; // cut down to required number of decimal digits
for (i=0; i<sectioninfo.fractiondigits; i++) {
decimalscale *= 10;
}
scaledvalue = Math.floor(value * decimalscale + 0.5);
scaledvalue = scaledvalue / decimalscale;
if (typeof scaledvalue != "number") return "NaN";
if (!isFinite(scaledvalue)) return "NaN";
strvalue = scaledvalue+""; // convert to string (Number.toFixed doesn't do all we need)
// strvalue = value.toFixed(sectioninfo.fractiondigits); // cut down to required number of decimal digits
// and convert to string
if (scaledvalue == 0 && (sectioninfo.fractiondigits || sectioninfo.integerdigits)) {
negativevalue = 0; // no "-0" unless using multiple sections or General
}
if (strvalue.indexOf("e")>=0) { // converted to scientific notation
return rawvalue+""; // Just return plain converted raw value
}
strparts=strvalue.match(/^\+{0,1}(\d*)(?:\.(\d*)){0,1}$/); // get integer and fraction parts
if (!strparts) return "NaN"; // if not a number
integervalue = strparts[1];
if (!integervalue || integervalue=="0") integervalue="";
fractionvalue = strparts[2];
if (!fractionvalue) fractionvalue = "";
if (sectioninfo.hasdate) { // there are date placeholders
if (rawvalue < 0) { // bad date
return "??-???-?? ??:??:??";
}
startval = (rawvalue-Math.floor(rawvalue)) * scfn.datevalues.seconds_in_a_day; // get date/time parts
estartval = rawvalue * scfn.datevalues.seconds_in_a_day; // do elapsed time version, too
hrs = Math.floor(startval / scfn.datevalues.seconds_in_an_hour);
ehrs = Math.floor(estartval / scfn.datevalues.seconds_in_an_hour);
startval = startval - hrs * scfn.datevalues.seconds_in_an_hour;
mins = Math.floor(startval / 60);
emins = Math.floor(estartval / 60);
secs = startval - mins * 60;
decimalscale = 1; // round appropriately depending if there is ss.0
for (i=0; i<sectioninfo.fractiondigits; i++) {
decimalscale *= 10;
}
secs = Math.floor(secs * decimalscale + 0.5);
secs = secs / decimalscale;
esecs = Math.floor(estartval * decimalscale + 0.5);
esecs = esecs / decimalscale;
if (secs >= 60) { // handle round up into next second, minute, etc.
secs = 0;
mins++; emins++;
if (mins >= 60) {
mins = 0;
hrs++; ehrs++;
socialcalc/formatnumber2.js view on Meta::CPAN
cval = Math.floor(secs);
result += cval+"";
}
else if (operandstrlc=="ss") {
cval = (1000 + Math.floor(secs))+"";
result += cval.substr(2);
}
else if (operandstrlc=="am/pm" || operandstrlc=="a/p") {
result += ampmstr;
}
else if (operandstrlc=="ss]") {
if (esecs < 100) {
cval = (1000 + Math.floor(esecs))+"";
result += cval.substr(2);
}
else {
cval = Math.floor(esecs);
result += cval+"";
}
}
}
else if (op == scfn.commands.section) { // end of section
break;
}
else if (op == scfn.commands.comparison) { // ignore
continue;
}
else {
result += "!! Parse error !!";
}
}
if (textcolor) {
result = '<span style="color:'+textcolor+';">'+result+'</span>';
}
if (textstyle) {
result = '<span style="'+textstyle+';">'+result+'</span>';
}
return result;
};
/* *******************
SocialCalc.FormatNumber.parse_format_string(format_defs, format_string)
Takes a format string (e.g., "#,##0.00_);(#,##0.00)") and fills in format_defs with the parsed info
format_defs
["#,##0.0"]->{} - elements in the hash are one hash for each format
.operators->[] - array of operators from parsing the format string (each a number)
.operands->[] - array of corresponding operators (each usually a string)
.sectioninfo->[] - one hash for each section of the format
.start
.integerdigits
.fractiondigits
.commas
.percent
.thousandssep
.hasdates
.hascomparison - true if any section has [<100], etc.
************************* */
SocialCalc.FormatNumber.parse_format_string = function(format_defs, format_string) {
var scfn = SocialCalc.FormatNumber;
var thisformat, section, sectionfinfo;
var integerpart = 1; // start out in integer part
var lastwasinteger; // last char was an integer placeholder
var lastwasslash; // last char was a backslash - escaping following character
var lastwasasterisk; // repeat next char
var lastwasunderscore; // last char was _ which picks up following char for width
var inquote, quotestr; // processing a quoted string
var inbracket, bracketstr, bracketdata; // processing a bracketed string
var ingeneral, gpos; // checks for characters "General"
var ampmstr, part; // checks for characters "A/P" and "AM/PM"
var indate; // keeps track of date/time placeholders
var chpos; // character position being looked at
var ch; // character being looked at
if (format_defs[format_string]) return; // already defined - nothing to do
thisformat = {operators: [], operands: [], sectioninfo: [{}]}; // create info structure for this format
format_defs[format_string] = thisformat; // add to other format definitions
section = 0; // start with section 0
sectioninfo = thisformat.sectioninfo[section]; // get reference to info for current section
sectioninfo.sectionstart = 0; // position in operands that starts this section
sectioninfo.integerdigits = 0; // number of integer-part placeholders
sectioninfo.fractiondigits = 0; // fraction placeholders
sectioninfo.commas = 0; // commas encountered, to handle scaling
sectioninfo.percent = 0; // times to scale by 100
for (chpos=0; chpos<format_string.length; chpos++) { // parse
ch = format_string.charAt(chpos); // get next char to examine
if (inquote) {
if (ch == '"') {
inquote = 0;
thisformat.operators.push(scfn.commands.copy);
thisformat.operands.push(quotestr);
continue;
}
quotestr += ch;
continue;
}
if (inbracket) {
if (ch==']') {
inbracket = 0;
bracketdata=SocialCalc.FormatNumber.parse_format_bracket(bracketstr);
if (bracketdata.operator==scfn.commands.separator) {
sectioninfo.thousandssep = 1; // explicit [,]
continue;
}
if (bracketdata.operator==scfn.commands.date) {
sectioninfo.hasdate = 1;
}
if (bracketdata.operator==scfn.commands.comparison) {
thisformat.hascomparison = 1;
}
thisformat.operators.push(bracketdata.operator);
thisformat.operands.push(bracketdata.operand);
continue;
}
bracketstr += ch;
continue;
}
if (lastwasslash) {
thisformat.operators.push(scfn.commands.copy);
thisformat.operands.push(ch);
lastwasslash=false;
continue;
}
if (lastwasasterisk) {
thisformat.operators.push(scfn.commands.copy);
thisformat.operands.push(ch+ch+ch+ch+ch); // do 5 of them since no real tabs
lastwasasterisk=false;
continue;
}
if (lastwasunderscore) {
thisformat.operators.push(scfn.commands.copy);
thisformat.operands.push(" ");
lastwasunderscore=false;
continue;
}
if (ingeneral) {
if ("general".charAt(ingeneral)==ch.toLowerCase()) {
ingeneral++;
if (ingeneral == 7) {
thisformat.operators.push(scfn.commands.general);
thisformat.operands.push(ch);
ingeneral=0;
}
socialcalc/formatnumber2.js view on Meta::CPAN
indate += ch; // accumulate it
continue;
}
thisformat.operators.push(scfn.commands.date); // something else, save date info
thisformat.operands.push(indate);
sectioninfo.hasdate=1;
indate = "";
}
if (ampmstr) {
ampmstr += ch;
part=ampmstr.toLowerCase();
if (part!="am/pm".substring(0,part.length) && part!="a/p".substring(0,part.length)) {
ampstr="";
}
else if (part=="am/pm" || part=="a/p") {
thisformat.operators.push(scfn.commands.date);
thisformat.operands.push(ampmstr);
ampmstr = "";
}
continue;
}
if (ch=="#" || ch=="0" || ch=="?") { // placeholder
if (integerpart) {
sectioninfo.integerdigits++;
if (sectioninfo.commas) { // comma inside of integer placeholders
sectioninfo.thousandssep = 1; // any number is thousands separator
sectioninfo.commas = 0; // reset count of "thousand" factors
}
lastwasinteger = 1;
thisformat.operators.push(scfn.commands.integer_placeholder);
thisformat.operands.push(ch);
}
else {
sectioninfo.fractiondigits++;
thisformat.operators.push(scfn.commands.fraction_placeholder);
thisformat.operands.push(ch);
}
}
else if (ch==".") { // decimal point
lastwasinteger = 0;
thisformat.operators.push(scfn.commands.decimal);
thisformat.operands.push(ch);
integerpart = 0;
}
else if (ch=='$') { // currency char
lastwasinteger = 0;
thisformat.operators.push(scfn.commands.currency);
thisformat.operands.push(ch);
}
else if (ch==",") {
if (lastwasinteger) {
sectioninfo.commas++;
}
else {
thisformat.operators.push(scfn.commands.copy);
thisformat.operands.push(ch);
}
}
else if (ch=="%") {
lastwasinteger = 0;
sectioninfo.percent++;
thisformat.operators.push(scfn.commands.copy);
thisformat.operands.push(ch);
}
else if (ch=='"') {
lastwasinteger = 0;
inquote = 1;
quotestr = "";
}
else if (ch=='[') {
lastwasinteger = 0;
inbracket = 1;
bracketstr = "";
}
else if (ch=='\\') {
lastwasslash = 1;
lastwasinteger = 0;
}
else if (ch=='*') {
lastwasasterisk = 1;
lastwasinteger = 0;
}
else if (ch=='_') {
lastwasunderscore = 1;
lastwasinteger = 0;
}
else if (ch==";") {
section++; // start next section
thisformat.sectioninfo[section] = {}; // create a new section
sectioninfo = thisformat.sectioninfo[section]; // get reference to info for current section
sectioninfo.sectionstart = 1 + thisformat.operators.length; // remember where it starts
sectioninfo.integerdigits = 0; // number of integer-part placeholders
sectioninfo.fractiondigits = 0; // fraction placeholders
sectioninfo.commas = 0; // commas encountered, to handle scaling
sectioninfo.percent = 0; // times to scale by 100
integerpart = 1; // reset for new section
lastwasinteger = 0;
thisformat.operators.push(scfn.commands.section);
thisformat.operands.push(ch);
}
else if (ch.toLowerCase()=="g") {
ingeneral = 1;
lastwasinteger = 0;
}
else if (ch.toLowerCase()=="a") {
ampmstr = ch;
lastwasinteger = 0;
}
else if ("dmyhHs".indexOf(ch)>=0) {
indate = ch;
}
else {
lastwasinteger = 0;
thisformat.operators.push(scfn.commands.copy);
thisformat.operands.push(ch);
}
}
if (indate) { // last char was part of unsaved date placeholder
thisformat.operators.push(scfn.commands.date);
thisformat.operands.push(indate);
sectioninfo.hasdate = 1;
}
return;
}
/* *******************
bracketdata = SocialCalc.FormatNumber.parse_format_bracket(bracketstr)
Takes a bracket contents (e.g., "RED", ">10") and returns an operator and operand
bracketdata->{}
.operator
.operand
************************* */
SocialCalc.FormatNumber.parse_format_bracket = function(bracketstr) {
var scfn = SocialCalc.FormatNumber;
var scc = SocialCalc.Constants;
var bracketdata={};
var parts;
if (bracketstr.charAt(0)=='$') { // currency
bracketdata.operator = scfn.commands.currency;
parts=bracketstr.match(/^\$(.+?)(\-.+?){0,1}$/);
if (parts) {
bracketdata.operand = parts[1] || scc.FormatNumber_defaultCurrency || '$';
}
( run in 0.871 second using v1.01-cache-2.11-cpan-84de2e75c66 )