New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

functionfoundry

Package Overview
Dependencies
Maintainers
1
Versions
88
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

functionfoundry - npm Package Compare versions

Comparing version 0.7.10 to 0.7.11

src/DAYS360.js

2

package.json
{
"name": "functionfoundry",
"version": "0.7.10",
"version": "0.7.11",
"description": "Modern JavaScript inspired by spreadsheets",

@@ -5,0 +5,0 @@ "main": "lib/index.js",

@@ -41,2 +41,3 @@ export {ABS} from './ABS'

export {ISBLANK} from './ISBLANK'
export {ISDATE} from './ISDATE'
export {ISEMAIL} from './ISEMAIL'

@@ -67,2 +68,4 @@ export {ISEMPTY} from './ISEMPTY'

export {OR} from './OR'
export {PARSEBOOL} from './PARSEBOOL'
export {PARSEDATE} from './PARSEDATE'
export {PI} from './PI'

@@ -69,0 +72,0 @@ export {PMT} from './PMT'

export function ISEMAIL(email) {
// credit to http://stackoverflow.com/questions/46155/validate-email-address-in-javascript
// copied from http://stackoverflow.com/questions/46155/validate-email-address-in-javascript
var re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
};

@@ -5,8 +5,29 @@ // Author: Peter Moresi

import { d1900, JulianOffset, MinutesInHour, MinutesInDay, SecondsInMinute,
SecondsInDay, SecondsInHour, DaysInYear, MillisecondsInDay, AllowedDays, DayNames,
DayNames3, MonthNames, MonthNames3, AM, AM1, PM, PM1, DefaultCurrency,
SeparatorChar, DecimalChar, AllowedColors }
import {
d1900,
MinutesInHour,
MinutesInDay,
SecondsInMinute,
SecondsInDay,
SecondsInHour,
DaysInYear,
MillisecondsInDay,
AllowedDays,
DayNames,
DayNames3,
MonthNames,
MonthNames3,
AM,
AM1,
PM,
PM1,
DefaultCurrency,
SeparatorChar,
DecimalChar,
AllowedColors
}
from './CONSTANTS';
import {PARSEDATE} from './PARSEDATE'
let FormatNumber = {};

@@ -16,504 +37,529 @@

// Other constants
FormatNumber.commands =
{copy: 1, color: 2, integer_placeholder: 3, fraction_placeholder: 4, decimal: 5,
currency: 6, general:7, separator: 8, date: 9, comparison: 10, section: 11, style: 12};
FormatNumber.commands = {
copy: 1, color: 2, integer_placeholder: 3, fraction_placeholder: 4, decimal: 5,
currency: 6, general:7, separator: 8, date: 9, comparison: 10, section: 11, style: 12
};
/* *******************
result = FormatNumber.formatNumberWithFormat = function(rawvalue, format_string, currency_char)
result = FormatNumber.formatNumberWithFormat = function(rawvalue, format_string, currency_char)
************************* */
************************* */
FormatNumber.formatNumberWithFormat = function(rawvalue, format_string, currency_char) {
var scfn = FormatNumber;
var scfn = FormatNumber;
var op, operandstr, fromend, cval, operandstrlc;
var startval, estartval;
var hrs, mins, secs, ehrs, emins, esecs, ampmstr, ymd;
var minOK, mpos;
var result="";
var format;
var section, gotcomparison, compop, compval, cpos, oppos;
var sectioninfo;
var i, decimalscale, scaledvalue, strvalue, strparts, integervalue, fractionvalue;
var integerdigits2, integerpos, fractionpos, textcolor, textstyle, separatorchar, decimalchar;
var value; // working copy to change sign, etc.
var op, operandstr, fromend, cval, operandstrlc;
var startval, estartval;
var hrs, mins, secs, ehrs, emins, esecs, ampmstr, ymd;
var minOK, mpos, mspos;
var result='';
var format;
var section, gotcomparison, compop, compval, cpos, oppos;
var sectioninfo;
var i, decimalscale, scaledvalue, strvalue, strparts, integervalue, fractionvalue;
var integerdigits2, integerpos, fractionpos, textcolor, textstyle, separatorchar, decimalchar;
var value; // working copy to change sign, etc.
rawvalue = rawvalue-0; // make sure a number
value = rawvalue;
if (!isFinite(value)) return "NaN";
rawvalue = rawvalue-0; // make sure a number
value = rawvalue;
if (!isFinite(value)) return 'NaN';
var negativevalue = value < 0 ? 1 : 0; // determine sign, etc.
if (negativevalue) value = -value;
var zerovalue = value == 0 ? 1 : 0;
var negativevalue = value < 0 ? 1 : 0; // determine sign, etc.
if (negativevalue) value = -value;
var zerovalue = value == 0 ? 1 : 0;
currency_char = currency_char || DefaultCurrency;
currency_char = currency_char || DefaultCurrency;
scfn.parse_format_string(scfn.format_definitions, format_string); // make sure format is parsed
format = scfn.format_definitions[format_string]; // Get format structure
FormatNumber.parse_format_string(scfn.format_definitions, format_string); // make sure format is parsed
//console.log("format_string", format_string, format)
format = scfn.format_definitions[format_string]; // Get format structure
//console.log("format", format)
if (!format) throw "Format not parsed error.";
if (!format) throw 'Format not parsed error.';
section = format.sectioninfo.length - 1; // get number of sections - 1
section = format.sectioninfo.length - 1; // get number of sections - 1
if (format.hascomparison) { // has comparisons - determine which section
section = 0; // set to which section we will use
gotcomparison = 0; // this section has no comparison
for (cpos=0; ;cpos++) { // scan for comparisons
op = format.operators[cpos];
operandstr = format.operands[cpos]; // get next operator and operand
if (!op) { // at end with no match
if (gotcomparison) { // if comparison but no match
format_string = "General"; // use default of General
scfn.parse_format_string(scfn.format_definitions, format_string);
format = 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;
}
// has comparisons - determine which section
if (format.hascomparison) {
section = 0; // set to which section we will use
gotcomparison = 0; // this section has no comparison
for (cpos=0; ;cpos++) { // scan for comparisons
op = format.operators[cpos];
operandstr = format.operands[cpos]; // get next operator and operand
// at end with no match
if (!op) {
// if comparison but no match
if (gotcomparison) {
format_string = 'General'; // use default of General
scfn.parse_format_string(scfn.format_definitions, format_string);
format = scfn.format_definitions[format_string];
section = 0;
}
}
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
}
break; // if no comparision, matches on this section
}
// end of section
if (op == scfn.commands.section) {
if (!gotcomparison) { // no comparison, so it's a match
break;
}
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
}
gotcomparison = 0;
section++; // check out next one
continue;
}
// found a comparison - do we meet it?
if (op == scfn.commands.comparison) {
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)) {
break;
}
gotcomparison = 1;
}
}
}
// more than one section (separated by ";")
else if (section > 0) {
// two sections
if (section == 1) {
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
}
}
// three sections
else if (section == 2) {
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 = format.sectioninfo[section]; // look at values for our section
sectioninfo = format.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.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;
}
}
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;
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";
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 = 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
// 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 (scaledvalue == 0 && (sectioninfo.fractiondigits || sectioninfo.integerdigits)) {
negativevalue = 0; // no "-0" unless using multiple sections or General
}
//console.log(rawvalue+'')
// converted to scientific notation
if (strvalue.indexOf('e')>=0) {
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 = '';
// there are date placeholders
if (sectioninfo.hasdate) {
//console.log('hasdate')
// bad date
if (rawvalue < 0) {
return '??-???-?? ??:??:??';
}
startval = (rawvalue-Math.floor(rawvalue)) * SecondsInDay; // get date/time parts
estartval = rawvalue * SecondsInDay; // do elapsed time version, too
hrs = Math.floor(startval / SecondsInHour);
ehrs = Math.floor(estartval / SecondsInHour);
startval = startval - hrs * SecondsInHour;
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++;
if (hrs >= 24) {
hrs = 0;
rawvalue++;
}
}
}
fractionvalue = (secs-Math.floor(secs))+''; // for "hh:mm:ss.000"
fractionvalue = fractionvalue.substring(2); // skip "0."
if (strvalue.indexOf("e")>=0) { // converted to scientific notation
return rawvalue+""; // Just return plain converted raw value
ymd = PARSEDATE(rawvalue);
ymd = {
year: ymd.getFullYear(),
month: ymd.getMonth() + 1,
day: ymd.getDate()
}
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;??:??:??";
minOK = 0; // says "m" can be minutes if true
mspos = sectioninfo.sectionstart; // m scan position in ops
for ( ; ; mspos++) { // scan for "m" and "mm" to see if any minutes fields, and am/pm
op = format.operators[mspos];
operandstr = format.operands[mspos]; // get next operator and operand
if (!op) break; // don't go past end
if (op==scfn.commands.section) break;
if (op==scfn.commands.date) {
if ((operandstr.toLowerCase()=='am/pm' || operandstr.toLowerCase()=='a/p') && !ampmstr) {
if (hrs >= 12) {
hrs -= 12;
ampmstr = operandstr.toLowerCase()=='a/p' ? PM1 : PM; // "P" : "PM";
}
else {
ampmstr = operandstr.toLowerCase()=='a/p' ? AM1 : AM; // "A" : "AM";
}
if (operandstr.indexOf(ampmstr)<0)
ampmstr = ampmstr.toLowerCase(); // have case match case in format
}
startval = (rawvalue-Math.floor(rawvalue)) * SecondsInDay; // get date/time parts
estartval = rawvalue * SecondsInDay; // do elapsed time version, too
hrs = Math.floor(startval / SecondsInHour);
ehrs = Math.floor(estartval / SecondsInHour);
startval = startval - hrs * SecondsInHour;
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;
if (minOK && (operandstr=='m' || operandstr=='mm')) {
format.operands[mspos] += 'in'; // turn into "min" or "mmin"
}
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++;
if (hrs >= 24) {
hrs = 0;
rawvalue++;
}
}
if (operandstr.charAt(0)=='h') {
minOK = 1; // m following h or hh or [h] is minutes not months
}
fractionvalue = (secs-Math.floor(secs))+""; // for "hh:mm:ss.000"
fractionvalue = fractionvalue.substring(2); // skip "0."
ymd = FormatNumber.convert_date_julian_to_gregorian(Math.floor(rawvalue+JulianOffset));
minOK = 0; // says "m" can be minutes if true
mspos = sectioninfo.sectionstart; // m scan position in ops
for ( ; ; mspos++) { // scan for "m" and "mm" to see if any minutes fields, and am/pm
op = format.operators[mspos];
operandstr = format.operands[mspos]; // get next operator and operand
if (!op) break; // don't go past end
if (op==scfn.commands.section) break;
if (op==scfn.commands.date) {
if ((operandstr.toLowerCase()=="am/pm" || operandstr.toLowerCase()=="a/p") && !ampmstr) {
if (hrs >= 12) {
hrs -= 12;
ampmstr = operandstr.toLowerCase()=="a/p" ? PM1 : PM; // "P" : "PM";
}
else {
ampmstr = operandstr.toLowerCase()=="a/p" ? AM1 : AM; // "A" : "AM";
}
if (operandstr.indexOf(ampmstr)<0)
ampmstr = ampmstr.toLowerCase(); // have case match case in format
}
if (minOK && (operandstr=="m" || operandstr=="mm")) {
format.operands[mspos] += "in"; // turn into "min" or "mmin"
}
if (operandstr.charAt(0)=="h") {
minOK = 1; // m following h or hh or [h] is minutes not months
}
else {
minOK = 0;
}
}
else if (op!=scfn.commands.copy) { // copying chars can be between h and m
minOK = 0;
}
else {
minOK = 0;
}
}
else if (op!=scfn.commands.copy) { // copying chars can be between h and m
minOK = 0;
for (--mspos; ; mspos--) { // scan other way for s after m
op = format.operators[mspos];
operandstr = format.operands[mspos]; // get next operator and operand
if (!op) break; // don't go past end
if (op==scfn.commands.section) break;
if (op==scfn.commands.date) {
if (minOK && (operandstr=="m" || operandstr=="mm")) {
format.operands[mspos] += "in"; // turn into "min" or "mmin"
}
if (operandstr=="ss") {
minOK = 1; // m before ss is minutes not months
}
else {
minOK = 0;
}
}
else if (op!=scfn.commands.copy) { // copying chars can be between ss and m
minOK = 0;
}
}
}
minOK = 0;
for (--mspos; ; mspos--) { // scan other way for s after m
op = format.operators[mspos];
operandstr = format.operands[mspos]; // get next operator and operand
if (!op) break; // don't go past end
if (op==scfn.commands.section) break;
if (op==scfn.commands.date) {
if (minOK && (operandstr=='m' || operandstr=='mm')) {
format.operands[mspos] += 'in'; // turn into "min" or "mmin"
}
if (operandstr=='ss') {
minOK = 1; // m before ss is minutes not months
}
else {
minOK = 0;
}
}
else if (op!=scfn.commands.copy) { // copying chars can be between ss and m
minOK = 0;
}
}
}
integerdigits2 = 0; // init counters, etc.
integerpos = 0;
fractionpos = 0;
textcolor = "";
textstyle = "";
separatorchar = SeparatorChar;
if (separatorchar.indexOf(" ")>=0) separatorchar = separatorchar.replace(/ /g, "&nbsp;");
decimalchar = DecimalChar;
if (decimalchar.indexOf(" ")>=0) decimalchar = decimalchar.replace(/ /g, "&nbsp;");
integerdigits2 = 0; // init counters, etc.
integerpos = 0;
fractionpos = 0;
textcolor = '';
textstyle = '';
separatorchar = SeparatorChar;
if (separatorchar.indexOf(' ')>=0) separatorchar = separatorchar.replace(/ /g, ' ');
decimalchar = DecimalChar;
if (decimalchar.indexOf(' ')>=0) decimalchar = decimalchar.replace(/ /g, ' ');
oppos = sectioninfo.sectionstart;
oppos = sectioninfo.sectionstart;
while (op = format.operators[oppos]) { // execute format
operandstr = format.operands[oppos++]; // get next operator and operand
while (op = format.operators[oppos]) { // execute format
operandstr = format.operands[oppos++]; // get next operator and operand
if (op == scfn.commands.copy) { // put char in result
result += operandstr;
}
if (op == scfn.commands.copy) { // put char in result
result += operandstr;
}
else if (op == scfn.commands.color) { // set color
textcolor = operandstr;
}
else if (op == scfn.commands.color) { // set color
textcolor = operandstr;
}
else if (op == scfn.commands.style) { // set style
textstyle = operandstr;
}
else if (op == scfn.commands.style) { // set style
textstyle = operandstr;
}
else if (op == scfn.commands.integer_placeholder) { // insert number part
if (negativevalue) {
result += "-";
negativevalue = 0;
else if (op == scfn.commands.integer_placeholder) { // insert number part
if (negativevalue) {
result += '-';
negativevalue = 0;
}
integerdigits2++;
if (integerdigits2 == 1) { // first one
if (integervalue.length > sectioninfo.integerdigits) { // see if integer wider than field
for (;integerpos < (integervalue.length - sectioninfo.integerdigits); integerpos++) {
result += integervalue.charAt(integerpos);
if (sectioninfo.thousandssep) { // see if this is a separator position
fromend = integervalue.length - integerpos - 1;
if (fromend > 2 && fromend % 3 == 0) {
result += separatorchar;
}
}
integerdigits2++;
if (integerdigits2 == 1) { // first one
if (integervalue.length > sectioninfo.integerdigits) { // see if integer wider than field
for (;integerpos < (integervalue.length - sectioninfo.integerdigits); integerpos++) {
result += integervalue.charAt(integerpos);
if (sectioninfo.thousandssep) { // see if this is a separator position
fromend = integervalue.length - integerpos - 1;
if (fromend > 2 && fromend % 3 == 0) {
result += separatorchar;
}
}
}
}
}
if (integervalue.length < sectioninfo.integerdigits
&& integerdigits2 <= sectioninfo.integerdigits - integervalue.length) { // field is wider than value
if (operandstr == "0" || operandstr == "?") { // fill with appropriate characters
result += operandstr == "0" ? "0" : "&nbsp;";
if (sectioninfo.thousandssep) { // see if this is a separator position
fromend = sectioninfo.integerdigits - integerdigits2;
if (fromend > 2 && fromend % 3 == 0) {
result += separatorchar;
}
}
}
}
else { // normal integer digit - add it
result += integervalue.charAt(integerpos);
if (sectioninfo.thousandssep) { // see if this is a separator position
fromend = integervalue.length - integerpos - 1;
if (fromend > 2 && fromend % 3 == 0) {
result += separatorchar;
}
}
integerpos++;
}
}
}
else if (op == scfn.commands.fraction_placeholder) { // add fraction part of number
if (fractionpos >= fractionvalue.length) {
if (operandstr == "0" || operandstr == "?") {
result += operandstr == "0" ? "0" : "&nbsp;";
}
}
if (integervalue.length < sectioninfo.integerdigits
&& integerdigits2 <= sectioninfo.integerdigits - integervalue.length) { // field is wider than value
if (operandstr == '0' || operandstr == '?') { // fill with appropriate characters
result += operandstr == '0' ? '0' : ' ';
if (sectioninfo.thousandssep) { // see if this is a separator position
fromend = sectioninfo.integerdigits - integerdigits2;
if (fromend > 2 && fromend % 3 == 0) {
result += separatorchar;
}
else {
result += fractionvalue.charAt(fractionpos);
}
fractionpos++;
}
}
else if (op == scfn.commands.decimal) { // decimal point
if (negativevalue) {
result += "-";
negativevalue = 0;
}
result += decimalchar;
}
else { // normal integer digit - add it
result += integervalue.charAt(integerpos);
if (sectioninfo.thousandssep) { // see if this is a separator position
fromend = integervalue.length - integerpos - 1;
if (fromend > 2 && fromend % 3 == 0) {
result += separatorchar;
}
}
else if (op == scfn.commands.currency) { // currency symbol
if (negativevalue) {
result += "-";
negativevalue = 0;
}
result += operandstr;
integerpos++;
}
}
else if (op == scfn.commands.fraction_placeholder) { // add fraction part of number
if (fractionpos >= fractionvalue.length) {
if (operandstr == '0' || operandstr == '?') {
result += operandstr == '0' ? '0' : ' ';
}
}
else {
result += fractionvalue.charAt(fractionpos);
}
fractionpos++;
}
else if (op == scfn.commands.general) { // insert "General" conversion
else if (op == scfn.commands.decimal) { // decimal point
if (negativevalue) {
result += '-';
negativevalue = 0;
}
result += decimalchar;
}
// *** Cut down number of significant digits to avoid floating point artifacts:
else if (op == scfn.commands.currency) { // currency symbol
if (negativevalue) {
result += '-';
negativevalue = 0;
}
result += operandstr;
}
if (value!=0) { // only if non-zero
var factor = Math.floor(Math.LOG10E * Math.log(value)); // get integer magnitude as a power of 10
factor = Math.pow(10, 13-factor); // turn into scaling factor
value = Math.floor(factor * value + 0.5)/factor; // scale positive value, round, undo scaling
if (!isFinite(value)) return "NaN";
}
if (negativevalue) {
result += "-";
}
strvalue = value+""; // convert original value to string
if (strvalue.indexOf("e")>=0) { // converted to scientific notation
result += strvalue;
continue;
}
strparts=strvalue.match(/^\+{0,1}(\d*)(?:\.(\d*)){0,1}$/); // get integer and fraction parts
integervalue = strparts[1];
if (!integervalue || integervalue=="0") integervalue="";
fractionvalue = strparts[2];
if (!fractionvalue) fractionvalue = "";
integerpos = 0;
fractionpos = 0;
if (integervalue.length) {
for (;integerpos < integervalue.length; integerpos++) {
result += integervalue.charAt(integerpos);
if (sectioninfo.thousandssep) { // see if this is a separator position
fromend = integervalue.length - integerpos - 1;
if (fromend > 2 && fromend % 3 == 0) {
result += separatorchar;
}
}
}
}
else {
result += "0";
}
if (fractionvalue.length) {
result += decimalchar;
for (;fractionpos < fractionvalue.length; fractionpos++) {
result += fractionvalue.charAt(fractionpos);
}
}
}
else if (op==scfn.commands.date) { // date placeholder
operandstrlc = operandstr.toLowerCase();
if (operandstrlc=="y" || operandstrlc=="yy") {
result += (ymd.year+"").substring(2);
}
else if (operandstrlc=="yyyy") {
result += ymd.year+"";
}
else if (operandstrlc=="d") {
result += ymd.day+"";
}
else if (operandstrlc=="dd") {
cval = 1000 + ymd.day;
result += (cval+"").substr(2);
}
else if (operandstrlc=="ddd") {
cval = Math.floor(rawvalue+6) % 7;
result += DayNames3[cval];
}
else if (operandstrlc=="dddd") {
cval = Math.floor(rawvalue+6) % 7;
result += DayNames[cval];
}
else if (operandstrlc=="m") {
result += ymd.month+"";
}
else if (operandstrlc=="mm") {
cval = 1000 + ymd.month;
result += (cval+"").substr(2);
}
else if (operandstrlc=="mmm") {
result += MonthNames3[ymd.month-1];
}
else if (operandstrlc=="mmmm") {
result += MonthNames[ymd.month-1];
}
else if (operandstrlc=="mmmmm") {
result += MonthNames[ymd.month-1].charAt(0);
}
else if (operandstrlc=="h") {
result += hrs+"";
}
else if (operandstrlc=="h]") {
result += ehrs+"";
}
else if (operandstrlc=="mmin") {
cval = (1000 + mins)+"";
result += cval.substr(2);
}
else if (operandstrlc=="mm]") {
if (emins < 100) {
cval = (1000 + emins)+"";
result += cval.substr(2);
}
else {
result += emins+"";
}
}
else if (operandstrlc=="min") {
result += mins+"";
}
else if (operandstrlc=="m]") {
result += emins+"";
}
else if (operandstrlc=="hh") {
cval = (1000 + hrs)+"";
result += cval.substr(2);
}
else if (operandstrlc=="s") {
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.general) { // insert "General" conversion
else if (op == scfn.commands.comparison) { // ignore
continue;
}
// *** Cut down number of significant digits to avoid floating point artifacts:
else {
result += "!! Parse error.!!";
if (value!=0) { // only if non-zero
var factor = Math.floor(Math.LOG10E * Math.log(value)); // get integer magnitude as a power of 10
factor = Math.pow(10, 13-factor); // turn into scaling factor
value = Math.floor(factor * value + 0.5)/factor; // scale positive value, round, undo scaling
if (!isFinite(value)) return 'NaN';
}
if (negativevalue) {
result += '-';
}
strvalue = value+''; // convert original value to string
if (strvalue.indexOf('e')>=0) { // converted to scientific notation
result += strvalue;
continue;
}
strparts=strvalue.match(/^\+{0,1}(\d*)(?:\.(\d*)){0,1}$/); // get integer and fraction parts
integervalue = strparts[1];
if (!integervalue || integervalue=='0') integervalue='';
fractionvalue = strparts[2];
if (!fractionvalue) fractionvalue = '';
integerpos = 0;
fractionpos = 0;
if (integervalue.length) {
for (;integerpos < integervalue.length; integerpos++) {
result += integervalue.charAt(integerpos);
if (sectioninfo.thousandssep) { // see if this is a separator position
fromend = integervalue.length - integerpos - 1;
if (fromend > 2 && fromend % 3 == 0) {
result += separatorchar;
}
}
}
}
if (textcolor) {
result = '<span style="color:'+textcolor+';">'+result+'</span>';
else {
result += '0';
}
if (textstyle) {
result = '<span style="'+textstyle+';">'+result+'</span>';
if (fractionvalue.length) {
result += decimalchar;
for (;fractionpos < fractionvalue.length; fractionpos++) {
result += fractionvalue.charAt(fractionpos);
}
}
}
else if (op==scfn.commands.date) { // date placeholder
operandstrlc = operandstr.toLowerCase();
if (operandstrlc=='y' || operandstrlc=='yy') {
result += (ymd.year+'').substring(2);
}
else if (operandstrlc=='yyyy') {
result += ymd.year+'';
}
else if (operandstrlc=='d') {
result += ymd.day+'';
}
else if (operandstrlc=='dd') {
cval = 1000 + ymd.day;
result += (cval+'').substr(2);
}
else if (operandstrlc=='ddd') {
cval = Math.floor(rawvalue+6) % 7;
result += DayNames3[cval];
}
else if (operandstrlc=='dddd') {
cval = Math.floor(rawvalue+6) % 7;
result += DayNames[cval];
}
else if (operandstrlc=='m') {
result += ymd.month+'';
}
else if (operandstrlc=='mm') {
cval = 1000 + ymd.month;
result += (cval+'').substr(2);
}
else if (operandstrlc=='mmm') {
result += MonthNames3[ymd.month-1];
}
else if (operandstrlc=='mmmm') {
result += MonthNames[ymd.month-1];
}
else if (operandstrlc=='mmmmm') {
result += MonthNames[ymd.month-1].charAt(0);
}
else if (operandstrlc=='h') {
result += hrs+'';
}
else if (operandstrlc=='h]') {
result += ehrs+'';
}
else if (operandstrlc=='mmin') {
cval = (1000 + mins)+'';
result += cval.substr(2);
}
else if (operandstrlc=='mm]') {
if (emins < 100) {
cval = (1000 + emins)+'';
result += cval.substr(2);
}
else {
result += emins+'';
}
}
else if (operandstrlc=='min') {
result += mins+'';
}
else if (operandstrlc=='m]') {
result += emins+'';
}
else if (operandstrlc=='hh') {
cval = (1000 + hrs)+'';
result += cval.substr(2);
}
else if (operandstrlc=='s') {
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;
}
return result;
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>';
}
//console.log(result)
return result;
};

@@ -523,337 +569,238 @@

FormatNumber.parse_format_string(format_defs, format_string)
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
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.
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.
************************* */
************************* */
FormatNumber.parse_format_string = function(format_defs, format_string) {
var scfn = FormatNumber;
var scfn = FormatNumber;
var format, section, sectioninfo;
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
var format, section, sectioninfo;
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
if (format_defs[format_string]) return; // already defined - nothing to do
format = {operators: [], operands: [], sectioninfo: [{}]}; // create info structure for this format
format_defs[format_string] = format; // add to other format definitions
format = {operators: [], operands: [], sectioninfo: [{}]}; // create info structure for this format
format_defs[format_string] = format; // add to other format definitions
section = 0; // start with section 0
sectioninfo = format.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
section = 0; // start with section 0
sectioninfo = format.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;
format.operators.push(scfn.commands.copy);
format.operands.push(quotestr);
continue;
}
quotestr += ch;
continue;
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;
format.operators.push(scfn.commands.copy);
format.operands.push(quotestr);
continue;
}
quotestr += ch;
continue;
}
if (inbracket) {
if (ch==']') {
inbracket = 0;
bracketdata=FormatNumber.parse_format_bracket(bracketstr);
if (bracketdata.operator==scfn.commands.separator) {
sectioninfo.thousandssep = 1; // explicit [,]
continue;
}
if (inbracket) {
if (ch==']') {
inbracket = 0;
bracketdata=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) {
format.hascomparison = 1;
}
format.operators.push(bracketdata.operator);
format.operands.push(bracketdata.operand);
continue;
}
bracketstr += ch;
continue;
if (bracketdata.operator==scfn.commands.date) {
sectioninfo.hasdate = 1;
}
if (lastwasslash) {
format.operators.push(scfn.commands.copy);
format.operands.push(ch);
lastwasslash=false;
continue;
if (bracketdata.operator==scfn.commands.comparison) {
format.hascomparison = 1;
}
if (lastwasasterisk) {
format.operators.push(scfn.commands.copy);
format.operands.push(ch+ch+ch+ch+ch); // do 5 of them since no real tabs
lastwasasterisk=false;
continue;
}
if (lastwasunderscore) {
format.operators.push(scfn.commands.copy);
format.operands.push("&nbsp;");
lastwasunderscore=false;
continue;
}
if (ingeneral) {
if ("general".charAt(ingeneral)==ch.toLowerCase()) {
ingeneral++;
if (ingeneral == 7) {
format.operators.push(scfn.commands.general);
format.operands.push(ch);
ingeneral=0;
}
continue;
}
ingeneral = 0;
}
if (indate) { // last char was part of a date placeholder
if (indate.charAt(0)==ch) { // another of the same char
indate += ch; // accumulate it
continue;
}
format.operators.push(scfn.commands.date); // something else, save date info
format.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") {
format.operators.push(scfn.commands.date);
format.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;
format.operators.push(scfn.commands.integer_placeholder);
format.operands.push(ch);
}
else {
sectioninfo.fractiondigits++;
format.operators.push(scfn.commands.fraction_placeholder);
format.operands.push(ch);
}
}
else if (ch==".") { // decimal point
lastwasinteger = 0;
format.operators.push(scfn.commands.decimal);
format.operands.push(ch);
integerpart = 0;
}
else if (ch=='$') { // currency char
lastwasinteger = 0;
format.operators.push(scfn.commands.currency);
format.operands.push(ch);
}
else if (ch==",") {
if (lastwasinteger) {
sectioninfo.commas++;
}
else {
format.operators.push(scfn.commands.copy);
format.operands.push(ch);
}
}
else if (ch=="%") {
lastwasinteger = 0;
sectioninfo.percent++;
format.operators.push(scfn.commands.copy);
format.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
format.sectioninfo[section] = {}; // create a new section
sectioninfo = format.sectioninfo[section]; // get reference to info for current section
sectioninfo.sectionstart = 1 + format.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;
format.operators.push(scfn.commands.section);
format.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;
format.operators.push(scfn.commands.copy);
format.operands.push(ch);
}
format.operators.push(bracketdata.operator);
format.operands.push(bracketdata.operand);
continue;
}
bracketstr += ch;
continue;
}
if (indate) { // last char was part of unsaved date placeholder
format.operators.push(scfn.commands.date);
format.operands.push(indate);
sectioninfo.hasdate = 1;
if (lastwasslash) {
format.operators.push(scfn.commands.copy);
format.operands.push(ch);
lastwasslash=false;
continue;
}
return;
if (lastwasasterisk) {
format.operators.push(scfn.commands.copy);
format.operands.push(ch+ch+ch+ch+ch); // do 5 of them since no real tabs
lastwasasterisk=false;
continue;
}
}
if (lastwasunderscore) {
format.operators.push(scfn.commands.copy);
format.operands.push(' ');
lastwasunderscore=false;
continue;
}
/* *******************
bracketdata = FormatNumber.parse_format_bracket(bracketstr)
Takes a bracket contents (e.g., "RED", ">10") and returns an operator and operand
bracketdata->{}
.operator
.operand
************************* */
FormatNumber.parse_format_bracket = function(bracketstr) {
var scfn = FormatNumber;
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] || DefaultCurrency || '$';
if (ingeneral) {
if ('general'.charAt(ingeneral)==ch.toLowerCase()) {
ingeneral++;
if (ingeneral == 7) {
format.operators.push(scfn.commands.general);
format.operands.push(ch);
ingeneral=0;
}
else {
bracketdata.operand = bracketstr.substring(1) || DefaultCurrency || '$';
}
continue;
}
ingeneral = 0;
}
else if (bracketstr=='?$') {
bracketdata.operator = scfn.commands.currency;
bracketdata.operand = '[?$]';
// last char was part of a date placeholder
if (indate) {
//console.log('foo')
if (indate.charAt(0)==ch) { // another of the same char
indate += ch; // accumulate it
continue;
}
format.operators.push(scfn.commands.date); // something else, save date info
format.operands.push(indate);
sectioninfo.hasdate=1;
indate = '';
}
else if (AllowedColors[bracketstr.toUpperCase()]) {
bracketdata.operator = scfn.commands.color;
bracketdata.operand = AllowedColors[bracketstr.toUpperCase()];
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') {
format.operators.push(scfn.commands.date);
format.operands.push(ampmstr);
ampmstr = '';
}
continue;
}
else if (parts=bracketstr.match(/^style=([^"]*)$/)) { // [style=...]
bracketdata.operator = scfn.commands.style;
bracketdata.operand = parts[1];
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;
format.operators.push(scfn.commands.integer_placeholder);
format.operands.push(ch);
}
else if (bracketstr==",") {
bracketdata.operator = scfn.commands.separator;
bracketdata.operand = bracketstr;
else {
sectioninfo.fractiondigits++;
format.operators.push(scfn.commands.fraction_placeholder);
format.operands.push(ch);
}
else if (AllowedDates[bracketstr.toUpperCase()]) {
bracketdata.operator = scfn.commands.date;
bracketdata.operand = AllowedDates[bracketstr.toUpperCase()];
} else if (ch == '.') {
lastwasinteger = 0;
format.operators.push(scfn.commands.decimal);
format.operands.push(ch);
integerpart = 0;
} else if (ch === '$') {
lastwasinteger = 0;
format.operators.push(scfn.commands.currency);
format.operands.push(ch);
} else if (ch==',') {
if (lastwasinteger) {
sectioninfo.commas++;
} else {
format.operators.push(scfn.commands.copy);
format.operands.push(ch);
}
else if (parts=bracketstr.match(/^[<>=]/)) { // comparison operator
parts=bracketstr.match(/^([<>=]+)(.+)$/); // split operator and value
bracketdata.operator = scfn.commands.comparison;
bracketdata.operand = parts[1]+":"+parts[2];
}
else { // unknown bracket
bracketdata.operator = scfn.commands.copy;
bracketdata.operand = "["+bracketstr+"]";
}
} else if (ch=='%') {
lastwasinteger = 0;
sectioninfo.percent++;
format.operators.push(scfn.commands.copy);
format.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
format.sectioninfo[section] = {}; // create a new section
sectioninfo = format.sectioninfo[section]; // get reference to info for current section
sectioninfo.sectionstart = 1 + format.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;
format.operators.push(scfn.commands.section);
format.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) {
//console.log('foo')
indate = ch;
} else {
lastwasinteger = 0;
format.operators.push(scfn.commands.copy);
format.operands.push(ch);
}
}
return bracketdata;
// last char was part of unsaved date placeholder
if (indate) {
format.operators.push(scfn.commands.date);
format.operands.push(indate);
sectioninfo.hasdate = 1;
}
/* *******************
return;
juliandate = FormatNumber.convert_date_gregorian_to_julian(year, month, day)
From: http://aa.usno.navy.mil/faq/docs/JD_Formula.html
Uses: Fliegel, H. F. and van Flandern, T. C. (1968). Communications of the ACM, Vol. 11, No. 10 (October, 1968).
Translated from the FORTRAN
I= YEAR
J= MONTH
K= DAY
C
JD= K-32075+1461*(I+4800+(J-14)/12)/4+367*(J-2-(J-14)/12*12)
2 /12-3*((I+4900+(J-14)/12)/100)/4
************************* */
FormatNumber.convert_date_gregorian_to_julian = function(year, month, day) {
var juliandate;
juliandate = day-32075+intFunc(1461*(year+4800+intFunc((month-14)/12))/4);
juliandate += intFunc(367*(month-2-intFunc((month-14)/12)*12)/12);
juliandate = juliandate - intFunc(3*intFunc((year+4900+intFunc((month-14)/12))/100)/4);
return juliandate;
}

@@ -864,46 +811,63 @@

ymd = FormatNumber.convert_date_julian_to_gregorian(juliandate)
bracketdata = FormatNumber.parse_format_bracket(bracketstr)
ymd->{}
.year
.month
.day
Takes a bracket contents (e.g., "RED", ">10") and returns an operator and operand
From: http://aa.usno.navy.mil/faq/docs/JD_Formula.html
Uses: Fliegel, H. F. and van Flandern, T. C. (1968). Communications of the ACM, Vol. 11, No. 10 (October, 1968).
Translated from the FORTRAN
bracketdata->{}
.operator
.operand
************************* */
************************* */
FormatNumber.convert_date_julian_to_gregorian = function(juliandate) {
FormatNumber.parse_format_bracket = function(bracketstr) {
var L, N, I, J, K;
var scfn = FormatNumber;
L = juliandate+68569;
N = Math.floor(4*L/146097);
L = L-Math.floor((146097*N+3)/4);
I = Math.floor(4000*(L+1)/1461001);
L = L-Math.floor(1461*I/4)+31;
J = Math.floor(80*L/2447);
K = L-Math.floor(2447*J/80);
L = Math.floor(J/11);
J = J+2-12*L;
I = 100*(N-49)+I+L;
var bracketdata={};
var parts;
return {year:I, month:J, day:K};
// currency
if (bracketstr.charAt(0)=='$') {
bracketdata.operator = scfn.commands.currency;
parts=bracketstr.match(/^\$(.+?)(\-.+?){0,1}$/);
if (parts) {
bracketdata.operand = parts[1] || DefaultCurrency || '$';
} else {
bracketdata.operand = bracketstr.substring(1) || DefaultCurrency || '$';
}
} else if (bracketstr=='?$') {
bracketdata.operator = scfn.commands.currency;
bracketdata.operand = '[?$]';
} else if (AllowedColors[bracketstr.toUpperCase()]) {
bracketdata.operator = scfn.commands.color;
bracketdata.operand = AllowedColors[bracketstr.toUpperCase()];
} else if (parts=bracketstr.match(/^style=([^']*)$/)) {
// [style=...]
bracketdata.operator = scfn.commands.style;
bracketdata.operand = parts[1];
}
else if (bracketstr==',') {
bracketdata.operator = scfn.commands.separator;
bracketdata.operand = bracketstr;
}
else if (AllowedDates[bracketstr.toUpperCase()]) {
bracketdata.operator = scfn.commands.date;
bracketdata.operand = AllowedDates[bracketstr.toUpperCase()];
}
else if (parts=bracketstr.match(/^[<>=]/)) { // comparison operator
parts=bracketstr.match(/^([<>=]+)(.+)$/); // split operator and value
bracketdata.operator = scfn.commands.comparison;
bracketdata.operand = parts[1]+':'+parts[2];
}
else { // unknown bracket
bracketdata.operator = scfn.commands.copy;
bracketdata.operand = '['+bracketstr+']';
}
}
return bracketdata;
function intFunc (n) {
if (n < 0) {
return -Math.floor(-n);
}
else {
return Math.floor(n);
}
}
export function TEXT(value, format, currency_char) {
return FormatNumber.formatNumberWithFormat(value, format, currency_char);
}

@@ -6,3 +6,3 @@ import test from 'tape'

t.test( 76 )
t.test( 79 )
t.ok( ff.ABS, 'ABS should be there')

@@ -43,2 +43,3 @@ t.ok( ff.ACOS, 'ACOS should be there')

t.ok( ff.ISBLANK, 'ISBLANK should be there')
t.ok( ff.ISDATE, 'ISDATE should be there')
t.ok( ff.ISEMPTY, 'ISEMPTY should be there')

@@ -66,2 +67,4 @@ t.ok( ff.ISEMAIL, 'ISEMAIL should be there')

t.ok( ff.OR, 'OR should be there')
t.ok( ff.PARSEBOOL, 'PARSEBOOL should be there')
t.ok( ff.PARSEDATE, 'PARSEDATE should be there')
t.ok( ff.PI, 'PI should be there')

@@ -68,0 +71,0 @@ t.ok( ff.PMT, 'PMT should be there')

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc