Repository: Mottie/javascript-number-formatter
Branch: master
Commit: c252291e0c95
Files: 19
Total size: 51.8 KB
Directory structure:
gitextract_yoaizzfr/
├── .cjsescache
├── .eslintrc
├── .gitattributes
├── .gitignore
├── .jshintrc
├── .npmrc
├── .travis.yml
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── index.d.ts
├── index.html
├── lib/
│ ├── format.es5.js
│ ├── format.esm.js
│ └── format.js
├── package.json
├── rollup.config.js
├── src/
│ └── format.js
└── test/
└── test.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .cjsescache
================================================
{
"src/format.js": null
}
================================================
FILE: .eslintrc
================================================
{
"env": {
"browser": true,
"es6": true
},
"parserOptions": {
"ecmaVersion": 2017,
"sourceType": "module"
},
"rules": {
"curly": 1,
"dot-location": [2,"property"],
"eqeqeq": 1,
"linebreak-style": [2, "unix"],
"no-else-return": 1,
"no-eval": 2,
"no-octal": 2,
"no-with": 2,
"radix": 2,
"brace-style": 1,
"camelcase": 2,
"indent": [2, "tab"],
"no-array-constructor": 2,
"quotes": [2, "double", {
"allowTemplateLiterals": true,
"avoidEscape": true
}],
"quote-props": 0,
"spaced-comment": 2,
"arrow-spacing": 2,
"no-var": 2,
"no-unused-vars": 1
}
}
================================================
FILE: .gitattributes
================================================
* text=auto
================================================
FILE: .gitignore
================================================
# lockfiles
package-lock.json
yarn.lock
# temp stuff
tmp/
*.tmp
*.bak
# logs
*.stackdump
*.log
# Build
node_modules/
# Windows crap
Thumbs.db
Desktop.ini
# Mac crap
.DS_Store
================================================
FILE: .jshintrc
================================================
{
"bitwise" : true,
"camelcase" : true,
"curly" : true,
"eqeqeq" : true,
"es3" : true,
"eqnull" : true,
"forin" : true,
"freeze" : true,
"immed" : true,
"indent" : 2,
"jquery" : true,
"latedef" : true,
"newcap" : true,
"noarg" : true,
"noempty" : true,
"nonbsp" : true,
"nonew" : true,
"quotmark" : true,
"sub" : true,
"trailing" : true,
"undef" : true,
"unused" : true
}
================================================
FILE: .npmrc
================================================
package-lock=false
================================================
FILE: .travis.yml
================================================
language: node_js
node_js:
- "12"
- "10"
- "8"
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing
Please do not submit pull requests to the main branch.
* Fork the library.
* Install [grunt](http://gruntjs.com/getting-started#installing-the-cli).
* Run `npm install` to install dependencies.
* Make your changes to the `src/format.js` file.
* Add unit tests to the `/test/test.js` file; your contribution may not be merged without unit tests.
* To test your changes, run `grunt`.
* When all your tests are passing, commit your changes to your fork.
* Submit a pull request to a branch of the repository.
================================================
FILE: LICENSE
================================================
Copyright 2016 ecava (author KPL)
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: README.md
================================================
# Javascript Number Formatter
Lightweight & Fast JavaScript Number Formatter
[![Build Status][build-image]][build-url] [![NPM Version][npm-image]][npm-url] [![devDependency Status][david-dev-image]][david-dev-url] [![MIT][license-image]][license-url]
## Introduction
This standalone number formatter<sup>†</sup> is intended to be short and fast. As they are the main factors for a high performance JavaScript app. Development release is around 150 lines including license info, blank lines and comments. And production release is less than 2,000 bytes.
```js
format( "#,##0.####", 1234567.890 ); // output: "1,234,567.89"
format( "$ #,###.00", -1234567.890 ); // output: "$ -1,234,567.89"
// Added in v2.0.0
format( "$ #,###.00", -1234567.890, {enforceMaskSign: true}); // output: "$ 1,234,567.89"
format( "$ -#,###.00", -1234567.890, {enforceMaskSign: true}); // output: "$ -1,234,567.89"
format( "$ +#,###.00", -1234567.890, {enforceMaskSign: true}); // output: "$ -1,234,567.89"
format( "$ +#,###.00", 1234567.890, {enforceMaskSign: true}); // output: "$ +1,234,567.89"
```
† Initial development release of this code was written by KPL and hosted at [Google Code](https://code.google.com/p/javascript-number-formatter/).
## Features
* Short, fast, flexible yet standalone.
* Accept standard number formatting like `#,##0.00` or with negation `-000.####`.
* Accept any country format like `# ##0,00`, `#,###.##`, `#'###.##` or any type of non-numbering symbol.
* Accept any numbers of digit grouping. `#,##,#0.000` or `#,###0.##` are all valid.
* Accept any redundant/fool-proof formatting. `##,###,##.#` or `0#,#00#.###0#` are all OK.
* Auto number rounding.
* Simple interface, just supply mask & value like this: `format( "0.0000", 3.141592)`.
* Include a prefix & suffix with the mask.
## Limitations
* No scientific/engineering formatting.
* Not for date or phone formation.
* No color control.
* <del>No prefix or suffix is allowed except leading negation symbol. So `$#,##0.00` or `#,###.##USD` will not yield expected outcome. Use `'$'+format('#,##0.00', 123.45)` or `format('#,##0.00', 456.789) + 'USD'`</del>
* The prefix or suffix *can not* include any numbers (`0-9`), dashes (`-`), or plus signs (`+`).
## Format Symbols
| Description | Symbol | Summary |
|---------------|--------|---------|
| Mask symbols | #0123456789+- | Mask symbols used for formatting the value. |
| Placeholders | #123456789 | Un-forced digit*; this optional digit will only show if it is required as a placeholder. |
| Zero | 0 | Forced digit; the digit will be shown whether or not the digit is relevant to the value. |
| Signs | +- | Indicates a positive or negative value; visible depending on the value sign and the `enforceMaskSign` setting. |
| Leftmost | | _Any_ non-mask symbol† inside the mask will be set to represent a thousands separator. |
| Rightmost | | _Any_ non-mask symbol† inside the mask‡ will be set to represent the decimal separator. |
| Prefix/Suffix | | _Any_ non-mask symbol† outside the mask. |
\* Non-zero mask digits (`1` through `9`) behave the same as the `#`.<br>
† Anything not a digit, and not a `+`, `-` or `#`.<br>
‡ In the case where there is a trailing decimal or comma, it will be included in the mask, e.g. `#.` or `0,`.
## Note
When only one symbol is supplied, the library will always treat that symbol as a decimal. For example, `format( '#,###', 1234567.890)` will output `1234567,890`.
To force a single symbol to be used as a separator, add a trailing symbol. In this example, a period is added to the end of the mask - `format( '#,###.', 1234567.890)` - resulting in it being used as a decimal and forcing the first symbol to be the separator and return this output: `1,234,567`.
## Installation
### npm package
npm install --save number-format.js
## Demos
A demo/sample page with few examples is provided ([demo](http://mottie.github.io/javascript-number-formatter/)).
And a jsFiddle was created to aid in testing: https://jsfiddle.net/Mottie/t2etyodx/
[build-url]: https://travis-ci.org/Mottie/javascript-number-formatter
[build-image]: https://travis-ci.org/Mottie/javascript-number-formatter.png?branch=master
[npm-url]: https://www.npmjs.com/package/number-format.js
[npm-image]: https://img.shields.io/npm/v/number-format.js.svg
[david-dev-url]: https://david-dm.org/Mottie/javascript-number-formatter?type=dev
[david-dev-image]: https://david-dm.org/Mottie/javascript-number-formatter/dev-status.svg
[license-url]: https://github.com/Mottie/javascript-number-formatter/blob/master/LICENSE
[license-image]: https://img.shields.io/badge/license-MIT-blue.svg
## Recent Changes
View the [complete change log here](https://github.com/Mottie/javascript-number-formatter/wiki).
### v2.0.7 (2018-11-13)
* Update typescript binding. See [issue #20](https://github.com/Mottie/javascript-number-formatter/issues/20).
* Fix improper placeholder behavior. Updated Readme with format symbols table. Closes [issue #19](https://github.com/Mottie/javascript-number-formatter/issues/19).
* Add more tests.
* Meta:
* Update dependencies.
* Improve code readability.
* Include version in min.js.
### v2.0.6 (2018-11-06)
* Trim trailing zeros in mask. Fixes [issue #18](https://github.com/Mottie/javascript-number-formatter/issues/18).
### v2.0.0 – 2.0.5 (2018-10-26)
* Add `ignoreSign` option (modified to `enforeceMaskSign`!).
* Switch to XO, AVA & rollup.
* Meta: Update dot files & remove bower support.
* Code cleanup & convert to ES2015.
* Rename `ignoreSign` to `enforceMaskSign` (default `false`).
* Reduce code complexity.
* Export as node module.
* Update TS with options.
* Switch demo to use lib file & highlight valid results.
* Switch from Grunt to rollup.
* Switch from IIFE to UMD output.
================================================
FILE: index.d.ts
================================================
declare const format : (mask: string, value: number, options?: object) => string;
export = format;
================================================
FILE: index.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Number Formatter • Test/Sample Page</title>
<style>
body, table, footer, .example { margin: 0 auto; }
h2 { text-align: center; }
h3, footer, .example { margin-left: 10%; }
table { border-collapse: collapse; }
th, td { border:1px solid lightgray; padding: 2px 5px; }
.input, .format, .output { text-align: right; }
.format, .output { white-space: pre; }
.group { background-color: wheat }
body pre.prettyprint { border: 0; }
.output:not(.valid) { background-color: rgba(160, 17, 17, 0.4); }
.output.valid { background-color: rgba(17, 160, 17, 0.4); }
</style>
</head>
<body>
<h2><a href="https://github.com/Mottie/javascript-number-formatter">JavaScript Number Formatter</a><br> Test/Sample Page</h2>
<h3>Usage</h3>
<div class="example">
<pre class="prettyprint lang-js">// format( mask, value );
// result "1,234,567.89"
format( "#,##0.####", 1234567.890 );</pre>
</div>
<h3>Examples</h3>
<table id="list" width="80%">
<tr>
<th>#</th><th>Description</th><th>Input</th><th>Format</th><th>Output</th>
</tr>
<tr>
<td colspan="6" class="group">Most common world wide</td>
</tr>
<tr class="row">
<td class="item"></td>
<td>Simple</td>
<td class="input">123456.789</td>
<td class="format">#,##0.00</td>
<td class="output" data-expected="123,456.79"></td>
</tr>
<tr class="row">
<td class="item"></td>
<td>Random</td>
<td class="input">20110628.15001234</td>
<td class="format">#,##0.###0</td>
<td class="output" data-expected="20,110,628.1500"></td>
</tr>
<tr class="row">
<td class="item"></td>
<td>Random</td>
<td class="input">0</td>
<td class="format">#,###.##0</td>
<td class="output" data-expected=".000"></td>
</tr>
<tr class="row">
<td class="item"></td>
<td>Long number</td>
<td class="input">1234567890.1234567890</td>
<td class="format">#,###.##0</td>
<td class="output" data-expected="1,234,567,890.123"></td>
</tr>
<tr class="row">
<td class="item"></td>
<td>Negative value</td>
<td class="input">-0.1</td>
<td class="format">#</td>
<td class="output" data-expected=""></td>
</tr>
<tr class="row">
<td class="item"></td>
<td>Negative value</td>
<td class="input">-0.1</td>
<td class="format">0</td>
<td class="output" data-expected="0"></td>
</tr>
<tr class="row">
<td class="item"></td>
<td>Negative value</td>
<td class="input">-0.13</td>
<td class="format">0.#</td>
<td class="output" data-expected="-0.1"></td>
</tr>
<tr class="row">
<td class="item"></td>
<td>Negative value</td>
<td class="input">-5000.123456789</td>
<td class="format">#,##0.######</td>
<td class="output" data-expected="-5,000.123457"></td>
</tr>
<tr>
<td colspan="6" class="group">Localization format</td>
</tr>
<tr class="row">
<td class="item"></td>
<td>US, UK and many more</td>
<td class="input">1234567.890</td>
<td class="format">#,##0.00</td>
<td class="output" data-expected="1,234,567.89"></td>
</tr>
<tr class="row">
<td class="item"></td>
<td>Estonia, France</td>
<td class="input">-128983833.4560022</td>
<td class="format">### ###,##</td>
<td class="output" data-expected="-128 983 833,46"></td>
</tr>
<tr class="row">
<td class="item"></td>
<td>Germany, Italy</td>
<td class="input">-1234560.10002920</td>
<td class="format">##.000,00</td>
<td class="output" data-expected="-1.234.560,10"></td>
</tr>
<tr class="row">
<td class="item"></td>
<td>Japan</td>
<td class="input">963852741.001</td>
<td class="format">###,####.00</td>
<td class="output" data-expected="9,6385,2741.00"></td>
</tr>
<tr class="row">
<td class="item"></td>
<td>Switzerland</td>
<td class="input">33445566.778899</td>
<td class="format">#'###'#00.00</td>
<td class="output" data-expected="33'445'566.78"></td>
</tr>
<tr>
<td colspan="6" class="group">Any format</td>
</tr>
<tr class="row">
<td class="item"></td>
<td></td>
<td class="input">-1234.5678</td>
<td class="format">##.000,00</td>
<td class="output" data-expected="-1.234,57"></td>
</tr>
<tr class="row">
<td class="item"></td>
<td></td>
<td class="input">4651321.841</td>
<td class="format">##^000*00</td>
<td class="output" data-expected="4^651^321*84"></td>
</tr>
<tr class="row">
<td class="item"></td>
<td></td>
<td class="input">3411.498</td>
<td class="format">-##¿000$00</td>
<td class="output" data-expected="3¿411$50"></td>
</tr>
<tr class="row">
<td class="item"></td>
<td></td>
<td class="input">465456456.87987212</td>
<td class="format">00!00@00</td>
<td class="output" data-expected="4!65!45!64!56@88"></td>
</tr>
<tr class="row">
<td class="item"></td>
<td>Force comma as separator</td>
<td class="input">1112341.4348712</td>
<td class="format">###,###.</td>
<td class="output" data-expected="1,112,341"></td>
</tr>
<tr class="row">
<td class="item"></td>
<td>Force space as separator</td>
<td class="input">2344441.4348712</td>
<td class="format">### ###.</td>
<td class="output" data-expected="2 344 441"></td>
</tr>
<tr class="row">
<td class="item"></td>
<td>Force dot as separator</td>
<td class="input">2345341.4348712</td>
<td class="format">###.### </td>
<td class="output" data-expected="2345341.435"></td>
</tr>
<tr>
<td colspan="6" class="group">Prefix & Suffix</td>
</tr>
<tr class="row">
<td class="item"></td>
<td>No spaces</td>
<td class="input">123456789.9876</td>
<td class="format">$#,##0.00USD</td>
<td class="output" data-expected="$123,456,789.99USD"></td>
</tr>
<tr class="row">
<td class="item"></td>
<td>Extra spaces (set <code>white-space: pre;</code> in cells)</td>
<td class="input">123456789.9876</td>
<td class="format">$ #,##0.00 USD</td>
<td class="output" data-expected="$ 123,456,789.99 USD"></td>
</tr>
<tr class="row">
<td class="item"></td>
<td></td>
<td class="input">123456789.9876</td>
<td class="format">##.000,00 €</td>
<td class="output" data-expected="123.456.789,99 €"></td>
</tr>
<tr class="row">
<td class="item"></td>
<td></td>
<td class="input">123456789.9876</td>
<td class="format">###,####.00 ¥</td>
<td class="output" data-expected="1,2345,6789.99 ¥"></td>
</tr>
<tr class="row">
<td class="item"></td>
<td></td>
<td class="input">123456789.9876</td>
<td class="format">### ###,### ¢ and stuff</td>
<td class="output" data-expected="123 456 789,988 ¢ and stuff"></td>
</tr>
<tr class="row">
<td class="item"></td>
<td></td>
<td class="input">123456789.9876</td>
<td class="format"> #,##0.00 a b c</td>
<td class="output" data-expected="123,456,789.99 a b c"></td>
</tr>
<tr class="row">
<td class="item"></td>
<td>Spaces & parenthesis (indicates a negative value, but the input is positive)</td>
<td class="input">123456789.9876</td>
<td class="format">$ (#,###.00) Money</td>
<td class="output" data-expected="$ (123,456,789.99) Money"></td>
</tr>
<tr class="row">
<td class="item"></td>
<td>Spaces & parenthesis (negative; not converted!)</td>
<td class="input">-123456789.9876</td>
<td class="format">$ (#,###.00) Money</td>
<td class="output" data-expected="$ (123,456,789.99) Money"></td>
</tr>
<tr class="row">
<td class="item"></td>
<td>Prefix with comma</td>
<td class="input">123456789.9876</td>
<td class="format">a, b c? #.00 yep!</td>
<td class="output" data-expected="a, b c? 123456789.99 yep!"></td>
</tr>
<tr class="row">
<td class="item"></td>
<td>Prefix with a periods</td>
<td class="input">123456789.9876</td>
<td class="format">cost... #,##0.00 yep!</td>
<td class="output" data-expected="cost... 123,456,789.99 yep!"></td>
</tr>
<tr class="row">
<td class="item"></td>
<td>Suffix with comma & period</td>
<td class="input">123456789.9876</td>
<td class="format">$# ###,00 USD, or euros.</td>
<td class="output" data-expected="$123 456 789,99 USD, or euros."></td>
</tr>
<tr class="row">
<td class="item"></td>
<td>Suffix with period</td>
<td class="input">123456789.9876</td>
<td class="format">It costs $# ###,00 euros.</td>
<td class="output" data-expected="It costs $123 456 789,99 euros."></td>
</tr>
<tr class="row">
<td class="item"></td>
<td>Hanging decimal</td>
<td class="input">123456789.9876</td>
<td class="format">test:### ###. ing</td>
<td class="output" data-expected="test:123 456 790 ing"></td>
</tr>
<tr>
<td colspan="6" class="group">Masks that don't work</td>
</tr>
<tr class="row">
<td class="item"></td>
<td>No "#" outside of mask</td>
<td class="input">123456789.9876</td>
<td class="format">item #abc $#,###.00</td>
<td class="output" data-expected="item #abc $123,456,789.99"></td>
</tr>
<tr class="row">
<td class="item"></td>
<td>No numbers outside of mask</td>
<td class="input">123456789.9876</td>
<td class="format">99 items = $#,###.00</td>
<td class="output" data-expected="99 items = $123,456,789.99"></td>
</tr>
<tr class="row">
<td class="item"></td>
<td>No dashes outside of mask</td>
<td class="input">123456789.9876</td>
<td class="format">cost -- $#,###.00 -- value</td>
<td class="output" data-expected="cost -- $123,456,789.99 -- value"></td>
</tr>
<tr class="row">
<td class="item"></td>
<td>No plus sign in prefix</td>
<td class="input">123456789.9876</td>
<td class="format">++ value! $#,###.00</td>
<td class="output" data-expected="++ value! $123,456,789.99"></td>
</tr>
<tr class="row">
<td class="item"></td>
<td>No plus sign in suffix</td>
<td class="input">123456789.9876</td>
<td class="format">$#,###.00 ++ value!</td>
<td class="output" data-expected="$123,456,789.99 ++ value!"></td>
</tr>
</table>
<br/>
<hr/>
<h3>See also...</h3>
<footer>
Original:
<ul>
<li><a href="https://code.google.com/p/javascript-number-formatter/">javascript-number-formatter</a> repository</li>
<li><del><a href="https://www.integraxor.com/developer/codes/js-formatter/format-sample.htm">Demo</a></del></li>
</ul>
</footer>
<script src="https://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="lib/format.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.css" rel="stylesheet"></link>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/run_prettify.min.js"></script>
<script>
$('.row').each( function(i) {
var inp = $(this).find('td.input'),
fmt = $(this).find('td.format'),
out = $(this).find('td.output'),
// Only this line is relevant to number formatting.
result = format(fmt.html().trim(), inp.html());
out
.toggleClass('valid', result === String(out.data('expected')))
.html(result);
$(this).find('.item').html( i + 1 );
});
</script>
</body>
</html>
================================================
FILE: lib/format.es5.js
================================================
/**
* Javascript-number-formatter
* Lightweight & Fast JavaScript Number Formatter
*
* @preserve IntegraXor Web SCADA - JavaScript Number Formatter (http://www.integraxor.com/)
* @author KPL
* @maintainer Rob Garrison
* @copyright 2019 ecava
* @license MIT
* @link http://mottie.github.com/javascript-number-formatter/
* @version 2.0.9
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = global || self, global.format = factory());
}(this, function () { 'use strict';
function _slicedToArray(arr, i) {
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest();
}
function _arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
}
function _iterableToArrayLimit(arr, i) {
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"] != null) _i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
function _nonIterableRest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
var maskRegex = /[0-9\-+#]/;
var notMaskRegex = /[^\d\-+#]/g;
function getIndex(mask) {
return mask.search(maskRegex);
}
function processMask() {
var mask = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "#.##";
var maskObj = {};
var len = mask.length;
var start = getIndex(mask);
maskObj.prefix = start > 0 ? mask.substring(0, start) : ""; // Reverse string: not an ideal method if there are surrogate pairs
var end = getIndex(mask.split("").reverse().join(""));
var offset = len - end;
var substr = mask.substring(offset, offset + 1); // Add 1 to offset if mask has a trailing decimal/comma
var indx = offset + (substr === "." || substr === "," ? 1 : 0);
maskObj.suffix = end > 0 ? mask.substring(indx, len) : "";
maskObj.mask = mask.substring(start, indx);
maskObj.maskHasNegativeSign = maskObj.mask.charAt(0) === "-";
maskObj.maskHasPositiveSign = maskObj.mask.charAt(0) === "+"; // Search for group separator & decimal; anything not digit,
// not +/- sign, and not #
var result = maskObj.mask.match(notMaskRegex); // Treat the right most symbol as decimal
maskObj.decimal = result && result[result.length - 1] || "."; // Treat the left most symbol as group separator
maskObj.separator = result && result[1] && result[0] || ","; // Split the decimal for the format string if any
result = maskObj.mask.split(maskObj.decimal);
maskObj.integer = result[0];
maskObj.fraction = result[1];
return maskObj;
}
function processValue(value, maskObj, options) {
var isNegative = false;
var valObj = {
value: value
};
if (value < 0) {
isNegative = true; // Process only abs(), and turn on flag.
valObj.value = -valObj.value;
}
valObj.sign = isNegative ? "-" : ""; // Fix the decimal first, toFixed will auto fill trailing zero.
valObj.value = Number(valObj.value).toFixed(maskObj.fraction && maskObj.fraction.length); // Convert number to string to trim off *all* trailing decimal zero(es)
valObj.value = Number(valObj.value).toString(); // Fill back any trailing zero according to format
// look for last zero in format
var posTrailZero = maskObj.fraction && maskObj.fraction.lastIndexOf("0");
var _valObj$value$split = valObj.value.split("."),
_valObj$value$split2 = _slicedToArray(_valObj$value$split, 2),
_valObj$value$split2$ = _valObj$value$split2[0],
valInteger = _valObj$value$split2$ === void 0 ? "0" : _valObj$value$split2$,
_valObj$value$split2$2 = _valObj$value$split2[1],
valFraction = _valObj$value$split2$2 === void 0 ? "" : _valObj$value$split2$2;
if (!valFraction || valFraction && valFraction.length <= posTrailZero) {
valFraction = posTrailZero < 0 ? "" : Number("0." + valFraction).toFixed(posTrailZero + 1).replace("0.", "");
}
valObj.integer = valInteger;
valObj.fraction = valFraction;
addSeparators(valObj, maskObj); // Remove negative sign if result is zero
if (valObj.result === "0" || valObj.result === "") {
// Remove negative sign if result is zero
isNegative = false;
valObj.sign = "";
}
if (!isNegative && maskObj.maskHasPositiveSign) {
valObj.sign = "+";
} else if (isNegative && maskObj.maskHasPositiveSign) {
valObj.sign = "-";
} else if (isNegative) {
valObj.sign = options && options.enforceMaskSign && !maskObj.maskHasNegativeSign ? "" : "-";
}
return valObj;
}
function addSeparators(valObj, maskObj) {
valObj.result = ""; // Look for separator
var szSep = maskObj.integer.split(maskObj.separator); // Join back without separator for counting the pos of any leading 0
var maskInteger = szSep.join("");
var posLeadZero = maskInteger && maskInteger.indexOf("0");
if (posLeadZero > -1) {
while (valObj.integer.length < maskInteger.length - posLeadZero) {
valObj.integer = "0" + valObj.integer;
}
} else if (Number(valObj.integer) === 0) {
valObj.integer = "";
} // Process the first group separator from decimal (.) only, the rest ignore.
// get the length of the last slice of split result.
var posSeparator = szSep[1] && szSep[szSep.length - 1].length;
if (posSeparator) {
var len = valObj.integer.length;
var offset = len % posSeparator;
for (var indx = 0; indx < len; indx++) {
valObj.result += valObj.integer.charAt(indx); // -posSeparator so that won't trail separator on full length
if (!((indx - offset + 1) % posSeparator) && indx < len - posSeparator) {
valObj.result += maskObj.separator;
}
}
} else {
valObj.result = valObj.integer;
}
valObj.result += maskObj.fraction && valObj.fraction ? maskObj.decimal + valObj.fraction : "";
return valObj;
}
var format = (function (mask, value) {
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
if (!mask || isNaN(Number(value))) {
// Invalid inputs
return value;
}
var maskObj = processMask(mask);
var valObj = processValue(value, maskObj, options);
return maskObj.prefix + valObj.sign + valObj.result + maskObj.suffix;
});
return format;
}));
================================================
FILE: lib/format.esm.js
================================================
/**
* Javascript-number-formatter
* Lightweight & Fast JavaScript Number Formatter
*
* @preserve IntegraXor Web SCADA - JavaScript Number Formatter (http://www.integraxor.com/)
* @author KPL
* @maintainer Rob Garrison
* @copyright 2019 ecava
* @license MIT
* @link http://mottie.github.com/javascript-number-formatter/
* @version 2.0.9
*/
const maskRegex = /[0-9\-+#]/;
const notMaskRegex = /[^\d\-+#]/g;
function getIndex(mask) {
return mask.search(maskRegex);
}
function processMask(mask = "#.##") {
const maskObj = {};
const len = mask.length;
const start = getIndex(mask);
maskObj.prefix = start > 0 ? mask.substring(0, start) : "";
// Reverse string: not an ideal method if there are surrogate pairs
const end = getIndex(mask.split("").reverse().join(""));
const offset = len - end;
const substr = mask.substring(offset, offset + 1);
// Add 1 to offset if mask has a trailing decimal/comma
const indx = offset + ((substr === "." || (substr === ",")) ? 1 : 0);
maskObj.suffix = end > 0 ? mask.substring(indx, len) : "";
maskObj.mask = mask.substring(start, indx);
maskObj.maskHasNegativeSign = maskObj.mask.charAt(0) === "-";
maskObj.maskHasPositiveSign = maskObj.mask.charAt(0) === "+";
// Search for group separator & decimal; anything not digit,
// not +/- sign, and not #
let result = maskObj.mask.match(notMaskRegex);
// Treat the right most symbol as decimal
maskObj.decimal = (result && result[result.length - 1]) || ".";
// Treat the left most symbol as group separator
maskObj.separator = (result && result[1] && result[0]) || ",";
// Split the decimal for the format string if any
result = maskObj.mask.split(maskObj.decimal);
maskObj.integer = result[0];
maskObj.fraction = result[1];
return maskObj;
}
function processValue(value, maskObj, options) {
let isNegative = false;
const valObj = {
value
};
if (value < 0) {
isNegative = true;
// Process only abs(), and turn on flag.
valObj.value = -valObj.value;
}
valObj.sign = isNegative ? "-" : "";
// Fix the decimal first, toFixed will auto fill trailing zero.
valObj.value = Number(valObj.value).toFixed(maskObj.fraction && maskObj.fraction.length);
// Convert number to string to trim off *all* trailing decimal zero(es)
valObj.value = Number(valObj.value).toString();
// Fill back any trailing zero according to format
// look for last zero in format
const posTrailZero = maskObj.fraction && maskObj.fraction.lastIndexOf("0");
let [valInteger = "0", valFraction = ""] = valObj.value.split(".");
if (!valFraction || (valFraction && valFraction.length <= posTrailZero)) {
valFraction = posTrailZero < 0
? ""
: (Number("0." + valFraction).toFixed(posTrailZero + 1)).replace("0.", "");
}
valObj.integer = valInteger;
valObj.fraction = valFraction;
addSeparators(valObj, maskObj);
// Remove negative sign if result is zero
if (valObj.result === "0" || valObj.result === "") {
// Remove negative sign if result is zero
isNegative = false;
valObj.sign = "";
}
if (!isNegative && maskObj.maskHasPositiveSign) {
valObj.sign = "+";
} else if (isNegative && maskObj.maskHasPositiveSign) {
valObj.sign = "-";
} else if (isNegative) {
valObj.sign = options && options.enforceMaskSign && !maskObj.maskHasNegativeSign
? ""
: "-";
}
return valObj;
}
function addSeparators(valObj, maskObj) {
valObj.result = "";
// Look for separator
const szSep = maskObj.integer.split(maskObj.separator);
// Join back without separator for counting the pos of any leading 0
const maskInteger = szSep.join("");
const posLeadZero = maskInteger && maskInteger.indexOf("0");
if (posLeadZero > -1) {
while (valObj.integer.length < (maskInteger.length - posLeadZero)) {
valObj.integer = "0" + valObj.integer;
}
} else if (Number(valObj.integer) === 0) {
valObj.integer = "";
}
// Process the first group separator from decimal (.) only, the rest ignore.
// get the length of the last slice of split result.
const posSeparator = (szSep[1] && szSep[szSep.length - 1].length);
if (posSeparator) {
const len = valObj.integer.length;
const offset = len % posSeparator;
for (let indx = 0; indx < len; indx++) {
valObj.result += valObj.integer.charAt(indx);
// -posSeparator so that won't trail separator on full length
if (!((indx - offset + 1) % posSeparator) && indx < len - posSeparator) {
valObj.result += maskObj.separator;
}
}
} else {
valObj.result = valObj.integer;
}
valObj.result += (maskObj.fraction && valObj.fraction)
? maskObj.decimal + valObj.fraction
: "";
return valObj;
}
var format = (mask, value, options = {}) => {
if (!mask || isNaN(Number(value))) {
// Invalid inputs
return value;
}
const maskObj = processMask(mask);
const valObj = processValue(value, maskObj, options);
return maskObj.prefix + valObj.sign + valObj.result + maskObj.suffix;
};
export default format;
================================================
FILE: lib/format.js
================================================
/**
* Javascript-number-formatter
* Lightweight & Fast JavaScript Number Formatter
*
* @preserve IntegraXor Web SCADA - JavaScript Number Formatter (http://www.integraxor.com/)
* @author KPL
* @maintainer Rob Garrison
* @copyright 2019 ecava
* @license MIT
* @link http://mottie.github.com/javascript-number-formatter/
* @version 2.0.9
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = global || self, global.format = factory());
}(this, function () { 'use strict';
const maskRegex = /[0-9\-+#]/;
const notMaskRegex = /[^\d\-+#]/g;
function getIndex(mask) {
return mask.search(maskRegex);
}
function processMask(mask = "#.##") {
const maskObj = {};
const len = mask.length;
const start = getIndex(mask);
maskObj.prefix = start > 0 ? mask.substring(0, start) : "";
// Reverse string: not an ideal method if there are surrogate pairs
const end = getIndex(mask.split("").reverse().join(""));
const offset = len - end;
const substr = mask.substring(offset, offset + 1);
// Add 1 to offset if mask has a trailing decimal/comma
const indx = offset + ((substr === "." || (substr === ",")) ? 1 : 0);
maskObj.suffix = end > 0 ? mask.substring(indx, len) : "";
maskObj.mask = mask.substring(start, indx);
maskObj.maskHasNegativeSign = maskObj.mask.charAt(0) === "-";
maskObj.maskHasPositiveSign = maskObj.mask.charAt(0) === "+";
// Search for group separator & decimal; anything not digit,
// not +/- sign, and not #
let result = maskObj.mask.match(notMaskRegex);
// Treat the right most symbol as decimal
maskObj.decimal = (result && result[result.length - 1]) || ".";
// Treat the left most symbol as group separator
maskObj.separator = (result && result[1] && result[0]) || ",";
// Split the decimal for the format string if any
result = maskObj.mask.split(maskObj.decimal);
maskObj.integer = result[0];
maskObj.fraction = result[1];
return maskObj;
}
function processValue(value, maskObj, options) {
let isNegative = false;
const valObj = {
value
};
if (value < 0) {
isNegative = true;
// Process only abs(), and turn on flag.
valObj.value = -valObj.value;
}
valObj.sign = isNegative ? "-" : "";
// Fix the decimal first, toFixed will auto fill trailing zero.
valObj.value = Number(valObj.value).toFixed(maskObj.fraction && maskObj.fraction.length);
// Convert number to string to trim off *all* trailing decimal zero(es)
valObj.value = Number(valObj.value).toString();
// Fill back any trailing zero according to format
// look for last zero in format
const posTrailZero = maskObj.fraction && maskObj.fraction.lastIndexOf("0");
let [valInteger = "0", valFraction = ""] = valObj.value.split(".");
if (!valFraction || (valFraction && valFraction.length <= posTrailZero)) {
valFraction = posTrailZero < 0
? ""
: (Number("0." + valFraction).toFixed(posTrailZero + 1)).replace("0.", "");
}
valObj.integer = valInteger;
valObj.fraction = valFraction;
addSeparators(valObj, maskObj);
// Remove negative sign if result is zero
if (valObj.result === "0" || valObj.result === "") {
// Remove negative sign if result is zero
isNegative = false;
valObj.sign = "";
}
if (!isNegative && maskObj.maskHasPositiveSign) {
valObj.sign = "+";
} else if (isNegative && maskObj.maskHasPositiveSign) {
valObj.sign = "-";
} else if (isNegative) {
valObj.sign = options && options.enforceMaskSign && !maskObj.maskHasNegativeSign
? ""
: "-";
}
return valObj;
}
function addSeparators(valObj, maskObj) {
valObj.result = "";
// Look for separator
const szSep = maskObj.integer.split(maskObj.separator);
// Join back without separator for counting the pos of any leading 0
const maskInteger = szSep.join("");
const posLeadZero = maskInteger && maskInteger.indexOf("0");
if (posLeadZero > -1) {
while (valObj.integer.length < (maskInteger.length - posLeadZero)) {
valObj.integer = "0" + valObj.integer;
}
} else if (Number(valObj.integer) === 0) {
valObj.integer = "";
}
// Process the first group separator from decimal (.) only, the rest ignore.
// get the length of the last slice of split result.
const posSeparator = (szSep[1] && szSep[szSep.length - 1].length);
if (posSeparator) {
const len = valObj.integer.length;
const offset = len % posSeparator;
for (let indx = 0; indx < len; indx++) {
valObj.result += valObj.integer.charAt(indx);
// -posSeparator so that won't trail separator on full length
if (!((indx - offset + 1) % posSeparator) && indx < len - posSeparator) {
valObj.result += maskObj.separator;
}
}
} else {
valObj.result = valObj.integer;
}
valObj.result += (maskObj.fraction && valObj.fraction)
? maskObj.decimal + valObj.fraction
: "";
return valObj;
}
var format = (mask, value, options = {}) => {
if (!mask || isNaN(Number(value))) {
// Invalid inputs
return value;
}
const maskObj = processMask(mask);
const valObj = processValue(value, maskObj, options);
return maskObj.prefix + valObj.sign + valObj.result + maskObj.suffix;
};
return format;
}));
================================================
FILE: package.json
================================================
{
"name": "number-format.js",
"nick": "javascript-number-formatter",
"description": "Lightweight & Fast JavaScript Number Formatter",
"version": "2.0.9",
"homepage": "http://mottie.github.com/javascript-number-formatter/",
"main": "lib/format.min.js",
"demo": "https://github.com/Mottie/javascript-number-formatter/index.html",
"repository": {
"type": "git",
"url": "git://github.com/Mottie/javascript-number-formatter.git"
},
"author": {
"name": "KPL",
"url": "https://code.google.com/u/100789773228459308870/"
},
"maintainers": [
{
"name": "Rob Garrison",
"url": "https://github.com/Mottie",
"email": "wowmotty@gmail.com"
}
],
"license": "MIT",
"bugs": "https://github.com/Mottie/javascript-number-formatter/issues",
"docs": "http://mottie.github.com/javascript-number-formatter/index.html",
"keywords": [
"number",
"format",
"formatter",
"currency"
],
"files": [
"lib/",
"index.d.ts"
],
"xo": {
"space": false,
"ignore": [
"rollup.config.js",
"lib"
],
"envs": [
"node"
],
"rules": {
"no-sparse-arrays": 0,
"quotes": [
"error",
"double"
],
"operator-linebreak": 0
}
},
"engines": {
"node": ">=8"
},
"scripts": {
"build": "rollup -c",
"test": "xo && ava",
"updater": "npx updates -cu && npm install"
},
"typings": "./index.d.ts",
"devDependencies": {
"@babel/core": "^7.2.2",
"@babel/plugin-transform-object-assign": "^7.2.0",
"@babel/preset-env": "^7.3.1",
"ava": "*",
"rollup": "^1.1.2",
"rollup-plugin-babel": "^4.3.2",
"rollup-plugin-cjs-es": "^0.7.0",
"rollup-plugin-node-resolve": "^4.0.0",
"rollup-plugin-terser": "^4.0.3",
"updates": "^6.2.1",
"xo": "*"
}
}
================================================
FILE: rollup.config.js
================================================
import cjs from "rollup-plugin-cjs-es";
import resolve from "rollup-plugin-node-resolve";
import babel from "rollup-plugin-babel";
import {terser} from "rollup-plugin-terser";
import pkg from "./package.json";
const banner = `/**
* Javascript-number-formatter
* Lightweight & Fast JavaScript Number Formatter
*
* @preserve IntegraXor Web SCADA - JavaScript Number Formatter (http://www.integraxor.com/)
* @author KPL
* @maintainer Rob Garrison
* @copyright ${new Date().getFullYear()} ecava
* @license MIT
* @link http://mottie.github.com/javascript-number-formatter/
* @version ${pkg.version}
*/`;
export default [{
input: "src/format.js",
output: [{
file: "lib/format.js",
name: "format",
format: "umd",
sourceMap: false,
banner,
},{
file: "lib/format.esm.js",
name: "format",
format: "esm",
sourceMap: false,
banner,
}],
plugins: [
resolve(),
cjs({
nested: true
})
]
}, {
input: "src/format.js",
output: [{
file: "lib/format.es5.js",
name: "format",
format: "umd",
sourceMap: false,
banner,
}],
plugins: [
resolve(),
cjs({
nested: true
}),
babel({
exclude: "node_modules/**",
presets: [
["@babel/preset-env", {
modules: false
}]
],
plugins: [
"@babel/plugin-transform-object-assign"
]
}),
]
},
{
input: "src/format.js",
output: {
file: "lib/format.min.js",
name: "format",
format: "umd",
sourceMap: false,
banner: `/*! Javascript-number-formatter v${pkg.version} */`,
},
plugins: [
resolve(),
cjs({
nested: true
}),
terser({
compress: {
passes: 3
},
output: {
comments: /^!/
}
})
]
}];
================================================
FILE: src/format.js
================================================
"use strict";
const maskRegex = /[0-9\-+#]/;
const notMaskRegex = /[^\d\-+#]/g;
function getIndex(mask) {
return mask.search(maskRegex);
}
function processMask(mask = "#.##") {
const maskObj = {};
const len = mask.length;
const start = getIndex(mask);
maskObj.prefix = start > 0 ? mask.substring(0, start) : "";
// Reverse string: not an ideal method if there are surrogate pairs
const end = getIndex(mask.split("").reverse().join(""));
const offset = len - end;
const substr = mask.substring(offset, offset + 1);
// Add 1 to offset if mask has a trailing decimal/comma
const indx = offset + ((substr === "." || (substr === ",")) ? 1 : 0);
maskObj.suffix = end > 0 ? mask.substring(indx, len) : "";
maskObj.mask = mask.substring(start, indx);
maskObj.maskHasNegativeSign = maskObj.mask.charAt(0) === "-";
maskObj.maskHasPositiveSign = maskObj.mask.charAt(0) === "+";
// Search for group separator & decimal; anything not digit,
// not +/- sign, and not #
let result = maskObj.mask.match(notMaskRegex);
// Treat the right most symbol as decimal
maskObj.decimal = (result && result[result.length - 1]) || ".";
// Treat the left most symbol as group separator
maskObj.separator = (result && result[1] && result[0]) || ",";
// Split the decimal for the format string if any
result = maskObj.mask.split(maskObj.decimal);
maskObj.integer = result[0];
maskObj.fraction = result[1];
return maskObj;
}
function processValue(value, maskObj, options) {
let isNegative = false;
const valObj = {
value
};
if (value < 0) {
isNegative = true;
// Process only abs(), and turn on flag.
valObj.value = -valObj.value;
}
valObj.sign = isNegative ? "-" : "";
// Fix the decimal first, toFixed will auto fill trailing zero.
valObj.value = Number(valObj.value).toFixed(maskObj.fraction && maskObj.fraction.length);
// Convert number to string to trim off *all* trailing decimal zero(es)
valObj.value = Number(valObj.value).toString();
// Fill back any trailing zero according to format
// look for last zero in format
const posTrailZero = maskObj.fraction && maskObj.fraction.lastIndexOf("0");
let [valInteger = "0", valFraction = ""] = valObj.value.split(".");
if (!valFraction || (valFraction && valFraction.length <= posTrailZero)) {
valFraction = posTrailZero < 0
? ""
: (Number("0." + valFraction).toFixed(posTrailZero + 1)).replace("0.", "");
}
valObj.integer = valInteger;
valObj.fraction = valFraction;
addSeparators(valObj, maskObj);
// Remove negative sign if result is zero
if (valObj.result === "0" || valObj.result === "") {
// Remove negative sign if result is zero
isNegative = false;
valObj.sign = "";
}
if (!isNegative && maskObj.maskHasPositiveSign) {
valObj.sign = "+";
} else if (isNegative && maskObj.maskHasPositiveSign) {
valObj.sign = "-";
} else if (isNegative) {
valObj.sign = options && options.enforceMaskSign && !maskObj.maskHasNegativeSign
? ""
: "-";
}
return valObj;
}
function addSeparators(valObj, maskObj) {
valObj.result = "";
// Look for separator
const szSep = maskObj.integer.split(maskObj.separator);
// Join back without separator for counting the pos of any leading 0
const maskInteger = szSep.join("");
const posLeadZero = maskInteger && maskInteger.indexOf("0");
if (posLeadZero > -1) {
while (valObj.integer.length < (maskInteger.length - posLeadZero)) {
valObj.integer = "0" + valObj.integer;
}
} else if (Number(valObj.integer) === 0) {
valObj.integer = "";
}
// Process the first group separator from decimal (.) only, the rest ignore.
// get the length of the last slice of split result.
const posSeparator = (szSep[1] && szSep[szSep.length - 1].length);
if (posSeparator) {
const len = valObj.integer.length;
const offset = len % posSeparator;
for (let indx = 0; indx < len; indx++) {
valObj.result += valObj.integer.charAt(indx);
// -posSeparator so that won't trail separator on full length
if (!((indx - offset + 1) % posSeparator) && indx < len - posSeparator) {
valObj.result += maskObj.separator;
}
}
} else {
valObj.result = valObj.integer;
}
valObj.result += (maskObj.fraction && valObj.fraction)
? maskObj.decimal + valObj.fraction
: "";
return valObj;
}
module.exports = (mask, value, options = {}) => {
if (!mask || isNaN(Number(value))) {
// Invalid inputs
return value;
}
const maskObj = processMask(mask);
const valObj = processValue(value, maskObj, options);
return maskObj.prefix + valObj.sign + valObj.result + maskObj.suffix;
};
================================================
FILE: test/test.js
================================================
import test from "ava";
import format from "../src/format";
/* Simple mask */
test("basic masks", t => {
t.is(format("#,##0.00", 123456789.123), "123,456,789.12", "Mask: \"#,##0.00\"");
t.is(format("#,##0.00", "123456.789"), "123,456.79");
t.is(format("#,##0.00", 123456.789), "123,456.79");
t.is(format("#,##0.00", 123456.7), "123,456.70");
t.is(format("#,##0.00", 123456), "123,456.00");
t.is(format("#,##0.00", 0), "0.00");
t.is(format("#", -0.1), "");
t.is(format("0", -0.1), "0");
t.is(format("0.#", -0.13), "-0.1");
t.is(format("#,##0.00", -123), "-123.00");
t.is(format("#,##0.00", -123456.789), "-123,456.79");
t.is(format("#,##0.0", 123456789.123), "123,456,789.1", "Mask: \"#,##0.0\"");
t.is(format("#,##0.0", 123456.789), "123,456.8");
t.is(format("#,##0.0", 123456.7), "123,456.7");
t.is(format("#,##0.0", 123456), "123,456.0");
t.is(format("#,##0.0", 0), "0.0");
t.is(format("#,##0.0", -123), "-123.0");
t.is(format("#,##0.0", -123456.789), "-123,456.8");
t.is(format("#,##0.", 123456789.123), "123,456,789", "Mask: \"#,##0.\"");
t.is(format("#,##0.", 123456.789), "123,457");
t.is(format("#,##0.", 123456.7), "123,457");
t.is(format("#,##0.", 123456), "123,456");
t.is(format("#,##0.", 0), "0");
t.is(format("#,##0.", -123), "-123");
t.is(format("#,##0.", -123456.789), "-123,457");
t.is(format("#.##0,", 123456789.123), "123.456.789", "Mask: \"#.##0,\"");
t.is(format("#.##0,", 123456.789), "123.457");
t.is(format("#.##0,", 123456.7), "123.457");
t.is(format("#.##0,", 123456), "123.456");
t.is(format("#.##0,", 0), "0");
t.is(format("#.##0,", -123), "-123");
t.is(format("#.##0,", -123456.789), "-123.457");
t.is(format("#,##0.###0", 12345678.98765432), "12,345,678.9877", "Mask: \"#,##0.###0\"");
});
/* Localizations */
test("Localizations", t => {
t.is(format("### ###,##", 123456789.987654321), "123 456 789,99", "Estonia, France: ### ###,##");
t.is(format("##.000,00", 123456789.987654321), "123.456.789,99", "Germany, Italy: ##.000,00");
t.is(format("###,####.00", 123456789.987654321), "1,2345,6789.99", "Japan: ###,####.00");
t.is(format("#'###'#00.00", 123456789.987654321), "123'456'789.99", "Switzerland: #'###'#00.00");
});
/* Made-up-izations */
test("Any format", t => {
t.is(format("#,##0 00", 123456789.987654321), "123,456,789 99");
t.is(format("#x##0 00", 123456789.987654321), "123x456x789 99");
t.is(format("##^000*00", 123456789.987654321), "123^456^789*99");
t.is(format("##¿000$00", 123456789.987654321), "123¿456¿789$99");
t.is(format("00!00@00", 123456789.987654321), "1!23!45!67!89@99");
});
/* Any non-zero digit in mask behaves like # */
test("Non-zero digits", t => {
t.is(format("999.999", 123.0), "123");
t.is(format("123,456789", 123.0), "123");
});
/* Precision */
test("Precision", t => {
t.is(format("### ###,", 123456789.987654321), "123 456 790");
t.is(format("###.###,", 123456789.987654321), "123.456.790");
t.is(format("##,000.", 123456789.987654321), "123,456,790");
t.is(format("###,####.", 123456789.187654321), "1,2345,6789");
t.is(format("#'###'#00,", 123456789.087654321), "123'456'789");
t.is(format("#,##0.####", 1234567.890), "1,234,567.89");
t.is(format("#,##0.###0", 1234567.890), "1,234,567.8900");
t.is(format("#,##0.##0#", 1234567.890), "1,234,567.890");
t.is(format("#,##0.#0##", 1234567.890), "1,234,567.89");
t.is(format("#,##0.#", 1234567.890), "1,234,567.9");
t.is(format("#,###.", 1234567.890), "1,234,568");
t.is(format("#,###.", 1234567), "1,234,567");
t.is(format("#,###.#", 1234567), "1,234,567");
t.is(format("#,###.##", 1234567), "1,234,567");
t.is(format("#,###.0", 1234567), "1,234,567.0");
t.is(format("#,###.00", 1234567), "1,234,567.00");
t.is(format("#.00", 0.78), ".78");
t.is(format("#.000", 0.78), ".780");
t.is(format("#.0000", 0.78), ".7800");
t.is(format("0.00", 0.78), "0.78");
t.is(format("0.000", 0.78), "0.780");
t.is(format("0.0000", 0.78), "0.7800");
t.is(format("00.00", 0.78), "00.78");
t.is(format("#.##", 0), "");
t.is(format("0.00", 0), "0.00");
t.is(format("0", 0), "0");
});
/* Mask with prefix and/or suffix */
test("Prefix & Suffix", t => {
// Usage
t.is(format("$#,##0.00USD", 123456789.123), "$123,456,789.12USD", "$#,##0.00USD");
t.is(format("$ #,##0.00 USD", 123456789.123), "$ 123,456,789.12 USD", "$ #,##0.00 USD");
t.is(format("##.000,00 €", 123456789.123), "123.456.789,12 €", "##.000,00 €");
t.is(format("###,####.00 ¥", 123456789.123), "1,2345,6789.12 ¥", "###,####.00 ¥");
t.is(format("### ###,### ¢ and stuff", 123456789.123), "123 456 789,123 ¢ and stuff", "### ###,### ¢ and stuff");
t.is(format(" #,##0.00 a b c ", 123456789.123), " 123,456,789.12 a b c ", "leading & trailing spaces");
t.is(format("$ (#,###.00) Money", 123456789.123), "$ (123,456,789.12) Money", "spaces & mask wrapped in parenthesis");
t.is(format("prefix with a comma, includes everything? #.00 yep!", 123456789.123), "prefix with a comma, includes everything? 123456789.12 yep!", "prefix with a comma");
t.is(format("$# ###,00 USD, or euros.", 123456789.123), "$123 456 789,12 USD, or euros.", "suffix with comma & period");
t.is(format("prefix with a periods?... #.00 yep!", 123456789.123), "prefix with a periods?... 123456789.12 yep!", "prefix with a periods");
t.is(format("It costs $# ###,00 euros.", 123456789.123), "It costs $123 456 789,12 euros.", "suffix with period");
t.is(format("test:### ###. ing", 123456789.123), "test:123 456 789 ing", "Hanging decimals");
});
test("Masks that don't work", t => {
// Not allowed
t.is(format("No # outside of the mask $#,###.00", 123456789.123) !== "No # outside of the mask $123,456,789.12", true, "BROKEN: # outside of the mask");
t.is(format("99 items = $#,###.00", 123456789.123) !== "99 items = $123,456,789.12", true, "BROKEN: numbers outside of mask");
t.is(format("cost -- $#,###.00 -- value", 123456789.123) !== "cost -- $123,456,789.12 -- value", true, "BROKEN: dashes outside of mask");
t.is(format("++ value! $#,###.00 ++ value!", 123456789.123) !== "++ value! $123,456,789.12 ++ value!", true, "BROKEN: plus signs outside of mask");
});
test("Numbers with negative sign", t => {
t.is(format("-#,##0.######", -5000.123456789), "-5,000.123457");
t.is(format("-#,##0.######", 5000.123456789), "5,000.123457");
t.is(format("#,##0.######", -5000.123456789), "-5,000.123457");
t.is(format("$ #,###.00", -1234567.890), "$ -1,234,567.89");
t.is(format("$ -#,###.00", -1234567.890), "$ -1,234,567.89");
t.is(format("-#,##0.######", -5000.123456789, {enforceMaskSign: true}), "-5,000.123457");
t.is(format("-#,##0.######", 5000.123456789, {enforceMaskSign: true}), "5,000.123457");
t.is(format("#,##0.######", -5000.123456789, {enforceMaskSign: true}), "5,000.123457");
t.is(format("$ #,###.00", -1234567.890, {enforceMaskSign: true}), "$ 1,234,567.89");
t.is(format("$ -#,###.00", -1234567.890, {enforceMaskSign: true}), "$ -1,234,567.89");
});
test("Numbers with positive sign", t => {
t.is(format("+#,##0.######", +5000.123456789), "+5,000.123457");
t.is(format("+#,##0.######", 5000.123456789), "+5,000.123457");
t.is(format("#,##0.######", +5000.123456789), "5,000.123457");
t.is(format("+#,##0.######", -5000.123456789), "-5,000.123457");
t.is(format("+#,##0.######", +5000.123456789, {enforceMaskSign: true}), "+5,000.123457");
t.is(format("+#,##0.######", 5000.123456789, {enforceMaskSign: true}), "+5,000.123457");
t.is(format("#,##0.######", +5000.123456789, {enforceMaskSign: true}), "5,000.123457");
t.is(format("+#,##0.######", -5000.123456789, {enforceMaskSign: true}), "-5,000.123457");
t.is(format("$ +#,###.00", -1234567.890, {enforceMaskSign: true}), "$ -1,234,567.89");
t.is(format("$ +#,###.00", 1234567.890, {enforceMaskSign: true}), "$ +1,234,567.89");
});
gitextract_yoaizzfr/
├── .cjsescache
├── .eslintrc
├── .gitattributes
├── .gitignore
├── .jshintrc
├── .npmrc
├── .travis.yml
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── index.d.ts
├── index.html
├── lib/
│ ├── format.es5.js
│ ├── format.esm.js
│ └── format.js
├── package.json
├── rollup.config.js
├── src/
│ └── format.js
└── test/
└── test.js
SYMBOL INDEX (20 symbols across 4 files)
FILE: lib/format.es5.js
function _slicedToArray (line 19) | function _slicedToArray(arr, i) {
function _arrayWithHoles (line 23) | function _arrayWithHoles(arr) {
function _iterableToArrayLimit (line 27) | function _iterableToArrayLimit(arr, i) {
function _nonIterableRest (line 53) | function _nonIterableRest() {
function getIndex (line 60) | function getIndex(mask) {
function processMask (line 64) | function processMask() {
function processValue (line 94) | function processValue(value, maskObj, options) {
function addSeparators (line 147) | function addSeparators(valObj, maskObj) {
FILE: lib/format.esm.js
function getIndex (line 16) | function getIndex(mask) {
function processMask (line 20) | function processMask(mask = "#.##") {
function processValue (line 53) | function processValue(value, maskObj, options) {
function addSeparators (line 105) | function addSeparators(valObj, maskObj) {
FILE: lib/format.js
function getIndex (line 22) | function getIndex(mask) {
function processMask (line 26) | function processMask(mask = "#.##") {
function processValue (line 59) | function processValue(value, maskObj, options) {
function addSeparators (line 111) | function addSeparators(valObj, maskObj) {
FILE: src/format.js
function getIndex (line 6) | function getIndex(mask) {
function processMask (line 10) | function processMask(mask = "#.##") {
function processValue (line 43) | function processValue(value, maskObj, options) {
function addSeparators (line 95) | function addSeparators(valObj, maskObj) {
Condensed preview — 19 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (59K chars).
[
{
"path": ".cjsescache",
"chars": 27,
"preview": "{\n \"src/format.js\": null\n}"
},
{
"path": ".eslintrc",
"chars": 665,
"preview": "{\n \"env\": {\n \"browser\": true,\n \"es6\": true\n },\n \"parserOptions\": {\n \"ecmaVersion\": 2017,\n \"sourceType\": \""
},
{
"path": ".gitattributes",
"chars": 12,
"preview": "* text=auto\n"
},
{
"path": ".gitignore",
"chars": 180,
"preview": "# lockfiles\npackage-lock.json\nyarn.lock\n\n# temp stuff\ntmp/\n*.tmp\n*.bak\n\n# logs\n*.stackdump\n*.log\n\n# Build\nnode_modules/\n"
},
{
"path": ".jshintrc",
"chars": 483,
"preview": "{\n \"bitwise\" : true,\n \"camelcase\" : true,\n \"curly\" : true,\n \"eqeqeq\" : true,\n \"es3\" : true,\n \"eqnul"
},
{
"path": ".npmrc",
"chars": 19,
"preview": "package-lock=false\n"
},
{
"path": ".travis.yml",
"chars": 53,
"preview": "language: node_js\nnode_js:\n - \"12\"\n - \"10\"\n - \"8\"\n"
},
{
"path": "CONTRIBUTING.md",
"chars": 523,
"preview": "# Contributing\n\nPlease do not submit pull requests to the main branch.\n\n* Fork the library.\n* Install [grunt](http://gru"
},
{
"path": "LICENSE",
"chars": 1057,
"preview": "Copyright 2016 ecava (author KPL)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis "
},
{
"path": "README.md",
"chars": 5948,
"preview": "# Javascript Number Formatter\n\nLightweight & Fast JavaScript Number Formatter\n\n[![Build Status][build-image]][build-url]"
},
{
"path": "index.d.ts",
"chars": 99,
"preview": "declare const format : (mask: string, value: number, options?: object) => string;\nexport = format;\n"
},
{
"path": "index.html",
"chars": 11135,
"preview": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<title>JS Number Formatter • Test/Sample Page</title>\n\t<styl"
},
{
"path": "lib/format.es5.js",
"chars": 6792,
"preview": "/**\n * Javascript-number-formatter\n * Lightweight & Fast JavaScript Number Formatter\n *\n * @preserve IntegraXor Web SCAD"
},
{
"path": "lib/format.esm.js",
"chars": 4903,
"preview": "/**\n * Javascript-number-formatter\n * Lightweight & Fast JavaScript Number Formatter\n *\n * @preserve IntegraXor Web SCAD"
},
{
"path": "lib/format.js",
"chars": 5302,
"preview": "/**\n * Javascript-number-formatter\n * Lightweight & Fast JavaScript Number Formatter\n *\n * @preserve IntegraXor Web SCAD"
},
{
"path": "package.json",
"chars": 1837,
"preview": "{\n \"name\": \"number-format.js\",\n \"nick\": \"javascript-number-formatter\",\n \"description\": \"Lightweight & Fast JavaScript"
},
{
"path": "rollup.config.js",
"chars": 1647,
"preview": "import cjs from \"rollup-plugin-cjs-es\";\nimport resolve from \"rollup-plugin-node-resolve\";\nimport babel from \"rollup-plug"
},
{
"path": "src/format.js",
"chars": 4548,
"preview": "\"use strict\";\n\nconst maskRegex = /[0-9\\-+#]/;\nconst notMaskRegex = /[^\\d\\-+#]/g;\n\nfunction getIndex(mask) {\n\treturn mask"
},
{
"path": "test/test.js",
"chars": 7763,
"preview": "import test from \"ava\";\nimport format from \"../src/format\";\n\n/* Simple mask */\ntest(\"basic masks\", t => {\n\tt.is(format(\""
}
]
About this extraction
This page contains the full source code of the Mottie/javascript-number-formatter GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 19 files (51.8 KB), approximately 17.0k tokens, and a symbol index with 20 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.