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 "??-???-??&nbsp;??:??:??";
         }
      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("&nbsp;");
         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 )