Comparing version 2.0.0-beta.6 to 2.0.0-beta.7
@@ -40,10 +40,10 @@ ### v2.0.x | ||
- ⚡️ **New conditional formatters, and a new IF-block system to hide/show a part of the document** | ||
- ⚡️ **New conditional formatters, and a new IF-block system to hide/show a part of the document** | ||
- `ifEQ (value)` : Matches values that are equal to a specified value, it replaces `ifEqual` | ||
- `ifNE (value)` : Matches all values that are not equal to a specified value | ||
- `ifGT (value)` : Matches values, string.length, array.length or object.length that are greater than a specified value | ||
- `ifGTE (value)` : Matches values, string.length, array.length or object.length that are greater than or equal to a specified value | ||
- `ifLT (value)` : Matches values, string.length, array.length or object.length that are less than a specified value | ||
- `ifLTE (value)` : Matches values, string.length, array.length or object.length that are less than or equal to a specified value | ||
- `ifGT (value)` : Matches values that are greater than a specified value. | ||
- `ifGTE (value)` : Matches values that are greater than or equal to a specified value. | ||
- `ifLT (value)` : Matches values that are less than a specified value. | ||
- `ifLTE (value)` : Matches values that are less than or equal to a specified value. | ||
- `ifIN (value)` : Matches any of the values specified in an array or string, it replaces `ifContain` | ||
@@ -53,4 +53,4 @@ - `ifNIN (value)` : Matches none of the values specified in an array or string | ||
- `ifNEM (value)` : Matches not empty values, string, arrays or objects | ||
- `and (value)` : AND operator between two consecutive conditional formatters | ||
- `or (value)` : (default) OR operator between two consecutive conditional formatters | ||
- `and (value)` : AND operator between two consecutive conditional formatters | ||
- `or (value)` : (default) OR operator between two consecutive conditional formatters | ||
- `hideBegin` and `hideEnd` : hide text block between hideBegin and hideEnd if condition is true | ||
@@ -60,2 +60,3 @@ - `showBegin` and `showEnd` : show a text block between showBegin and showEnd if condition is true | ||
- `elseShow (message)` : print a message if condition is false | ||
- `len()` : returns the length of a string or array. | ||
@@ -84,3 +85,3 @@ No formatters can be chained after `hideBegin`, `hideEnd`, `showBegin`, `showEnd`. | ||
`{d.id:ifEQ(10):showBegin}` block of text `{d.id:showEnd}` => block of text<br> | ||
`{d.id:ifEQ(12):showBegin}` block of text `{d.id:showEnd}` => | ||
`{d.id:ifEQ(12):showBegin}` block of text `{d.id:showEnd}` => | ||
@@ -98,3 +99,3 @@ - ☀️ **Accepts to iterate on attributes of objects as is if it was an array** | ||
In the report: | ||
In the report: | ||
``` | ||
@@ -119,3 +120,3 @@ {d.myObject[i].att} {d.myObject[i].val} | ||
{d.countries[i+1].name} | ||
``` | ||
``` | ||
- Fix: avoid crashing when a sub-object is null or undefined in data | ||
@@ -130,3 +131,3 @@ - Fix: avoid crashing when the parent object of an array is null or undefined in data | ||
- all numbers are formatted with formatN() formatter | ||
- Fix: accepts white-space in array filters with simple quote and double quotes | ||
- Fix: accepts white-space in array filters with simple quote and double quotes | ||
Example: `{d.cars[i, type='Tesla car'].name}` | ||
@@ -140,2 +141,3 @@ `{d.cars[i, type="Tesla car"].name}` | ||
- Accept direct access in arrays such as `{d.myArray[2].val}` instead of `{d.myArray[i=2].val}` | ||
- Fix crash when two consecutive arrays, nested in object, were used | ||
@@ -155,3 +157,3 @@ | ||
- old `toFixed(2)} {t(currency)}` can be replaced by `formatC(2)` | ||
- `formatD()` format date according to the locale. Same as `convDate`, but consider parameters are swapped | ||
- `formatD()` format date according to the locale. Same as `convDate`, but consider parameters are swapped | ||
for consistency with formatN. Moreover, `patternIn` is ISO8601 by default. | ||
@@ -162,3 +164,3 @@ - `convDate()` is deprecated | ||
- `carbone.set` and `carbone.render` have new options | ||
- `currencySource` : default currency of source data. Ex 'EUR' | ||
- `currencySource` : default currency of source data. Ex 'EUR' | ||
- `currencyTarget` : default target currency when the formatter `convCurr` is used without target | ||
@@ -187,3 +189,3 @@ - `currencyRates` : rates, based on EUR { EUR : 1, USD : 1.14 } | ||
- `carbone.set` does not overwrite user-defined translations | ||
- Accepts iteration on non-XML. Example: `{d[i].brand} , {d[i+1].brand}` | ||
- Accepts iteration on non-XML. Example: `{d[i].brand} , {d[i+1].brand}` | ||
- Add new formatters | ||
@@ -194,3 +196,3 @@ - `unaccent()` to remove accent from string | ||
- Formatters which have the property `canInjectXML = true` can inject XML in documents | ||
- Return an error in render callback when LibreOffice is not detected | ||
- Return an error in render callback when LibreOffice is not detected | ||
- Get the last object of an array using negative values when filtering with `i` iterator | ||
@@ -231,3 +233,3 @@ - `{d.cities[i=-1].temperature}` shows the temperature (if the array is not empty) of the last city | ||
- Release February 20, 2017 | ||
- Access properties of the parent object with two points `..` or more. Use case: conditional printing of properties using filters in nested arrays: | ||
- Access properties of the parent object with two points `..` or more. Use case: conditional printing of properties using filters in nested arrays: | ||
- `{d.cities[i, temp=20]..countryName}` prints `d.countryName` only when the temperature of cities equals 20 | ||
@@ -242,6 +244,6 @@ - Built-in conditional formatters, which starts by `if`, stop propagation to next formatters if the condition is true | ||
- Change the lang dynamically in `carbone.render` and `carbone.renderXML` with `options.lang = 'fr'`. The date formatter is automatically propagated on formatters such as `convDate` | ||
- Replace module zipfile by yauzl: faster, lighter, asynchrone | ||
- Replace module zipfile by yauzl: faster, lighter, asynchrone | ||
- XLSX templates are accepted (beta) | ||
- Parse embedded XLSX and DOCX documents | ||
- Add a tool to search a text within a marker in all reports `carbone find :formatterName` | ||
- Add a tool to search a text within a marker in all reports `carbone find :formatterName` | ||
@@ -256,3 +258,3 @@ | ||
### v0.12.4 | ||
- Fix: `carbone.render` crash if `options` contains `formatName` without `formatOptionsRaw` and `formatOptions` | ||
- Fix: `carbone.render` crash if `options` contains `formatName` without `formatOptionsRaw` and `formatOptions` | ||
@@ -259,0 +261,0 @@ ### v0.12.3 |
@@ -1,99 +0,4 @@ | ||
/** | ||
* Test if data is empty (null, undefined, [], {}, ...) | ||
* Change the default operator between conditional formatters. | ||
* | ||
* @example [ null , "D'oh!" ] | ||
* @example [ [] , "D'oh!" ] | ||
* @example [ {} , "D'oh!" ] | ||
* @example [ "" , "D'oh!" ] | ||
* @example [ 0 , "D'oh!" ] | ||
* @example [ "homer" , "D'oh!" ] | ||
* @example [ [23] , "D'oh!" ] | ||
* @example [ {"id":3} , "D'oh!" ] | ||
* | ||
* @param {Mixed} d data | ||
* @param {String} message message to print if JSON data is empty | ||
* @param {Boolean} continueOnSuccess [optional], if true, next formatter will be called even if the condition is true | ||
* @return {Mixed} `message` if condition is true, `d` otherwise | ||
*/ | ||
function ifEmpty (d, message, continueOnSuccess) { | ||
if ( d === null | ||
|| typeof(d) === 'undefined' | ||
|| d === '' | ||
|| d instanceof Array && d.length === 0 | ||
|| d.constructor === Object && Object.keys(d).length === 0 | ||
|| Number.isNaN(d) === true) { | ||
if (continueOnSuccess !== true && continueOnSuccess !== 'true') { | ||
this.stopPropagation = true; | ||
} | ||
return message; | ||
} | ||
return d; | ||
} | ||
/** | ||
* Test if a value equals a variable | ||
* | ||
* @example [ 100 , 100 , "bingo" ] | ||
* @example [ 100 , 101 , "bingo" ] | ||
* @example [ "homer" , "homer" , "bingo" ] | ||
* @example [ "homer" , "bart" , "bingo" ] | ||
* @example [ "" , "" , "bingo" ] | ||
* @example [ null , 100 , "bingo" ] | ||
* @example [ null , null , "bingo" ] | ||
* @example [ 0 , 100 , "bingo" ] | ||
* | ||
* @param {String|Integer|Boolean} d data | ||
* @param {String|Integer|Boolean} value value to test | ||
* @param {String} messageIfTrue message to print if the value equals JSON data | ||
* @param {Boolean} continueOnSuccess [optional], if true, next formatter will be called even if the condition is true | ||
* @return {Mixed} `message` if condition is true, `d` otherwise | ||
*/ | ||
function ifEqual (d, value, messageIfTrue, continueOnSuccess) { | ||
// Convert everything in string (not strict Equal) | ||
if (d + '' === value + '') { | ||
if (continueOnSuccess !== true && continueOnSuccess !== 'true') { | ||
this.stopPropagation = true; | ||
} | ||
return messageIfTrue; | ||
} | ||
return d; | ||
} | ||
/** | ||
* Test if a string or an array contains a value | ||
* | ||
* @example [ "your beautiful eyes", "beauti", "bingo" ] | ||
* @example [ "your beautiful eyes", "leg" , "bingo" ] | ||
* @example [ "your beautiful eyes", "eyes" , "bingo" ] | ||
* @example [ "" , "eyes" , "bingo" ] | ||
* @example [ "your beautiful eyes", "" , "bingo" ] | ||
* @example [ [100, 120, 20] , 120 , "bingo" ] | ||
* @example [ [100, 120, 20] , 99 , "bingo" ] | ||
* @example [ ["your", "eyes"] , "eyes" , "bingo" ] | ||
* @example [ [] , "eyes" , "bingo" ] | ||
* | ||
* @param {String|Array} d data | ||
* @param {String|Integer|Boolean} value value to search | ||
* @param {String} messageIfTrue message to print if JSON data contains the value | ||
* @param {Boolean} continueOnSuccess [optional], if true, next formatter will be called even if the condition is true | ||
* @return {Mixed} `message` if condition is true, `d` otherwise | ||
*/ | ||
function ifContain (d, value, messageIfTrue, continueOnSuccess) { | ||
if ((typeof(d) === 'string' || d instanceof Array) && d.indexOf(value) !== -1) { | ||
if (continueOnSuccess !== true && continueOnSuccess !== 'true') { | ||
this.stopPropagation = true; | ||
} | ||
return messageIfTrue; | ||
} | ||
return d; | ||
} | ||
/* ***************************************************************************** */ | ||
/* CONDITION V2 */ | ||
/* ***************************************************************************** */ | ||
/** | ||
* Change default operator between conditional formatters | ||
* | ||
* For example: `{d.car:ifEQ('delorean'):and(.speed):ifGT(80):show('TravelInTime'):elseShow('StayHere')}` | ||
@@ -103,3 +8,3 @@ * means "if d.car equals 'delorean' AND d.speed is greater than 80, then it prints 'TravelInTime', otherwise | ||
* | ||
* @version 2.0 | ||
* @version 2.0.0 | ||
* @param {Mixed} d data | ||
@@ -118,3 +23,3 @@ * @param {Mixed} value [optional] new value to test | ||
/** | ||
* Change default operator between conditional formatters | ||
* Change the default operator between conditional formatters. | ||
* | ||
@@ -126,3 +31,3 @@ * For example: `{d.car:ifEQ('delorean'):or(.speed):ifGT(80):show('TravelInTime'):elseShow('StayHere')}` | ||
* | ||
* @version 2.0 | ||
* @version 2.0.0 | ||
* @param {Mixed} d data | ||
@@ -141,12 +46,12 @@ * @param {Mixed} value [optional] new value to test | ||
/** | ||
* Update condition according to operator and / or | ||
* Update the condition according to the operator and / or. | ||
* | ||
* By default, we consider "or" operator | ||
* By default, we consider "or" operator. | ||
* @private | ||
* | ||
* @version 2.0 | ||
* @param {[type]} operator [description] | ||
* @param {[type]} currentConditionState [description] | ||
* @param {[type]} newValue [description] | ||
* @return {[type]} [description] | ||
* @version 2.0.0 | ||
* @param {Boolean} operator if true, the operator is AND, otherwhise it is OR | ||
* @param {Boolean} currentConditionState the current condition state | ||
* @param {Boolean} newValue the value coming form the previous condition | ||
* @return {Boolean} the condition result | ||
*/ | ||
@@ -161,13 +66,13 @@ function _updateCondition (isAndOperator, currentConditionState, newValue) { | ||
/** | ||
* Test if data is empty (null, undefined, [], {}, ...) | ||
* Matches empty values, string, arrays or objects (null, undefined, [], {}, ...), it replaces `ifEmpty`. | ||
* | ||
* @version 2.0 | ||
* @example [ null ] | ||
* @example [ [] ] | ||
* @example [ {} ] | ||
* @example [ "" ] | ||
* @example [ 0 ] | ||
* @example [ "homer" ] | ||
* @example [ [23] ] | ||
* @example [ {"id":3} ] | ||
* @version 2.0.0 | ||
* @exampleContextFormatter [ null ] true | ||
* @exampleContextFormatter [ [] ] true | ||
* @exampleContextFormatter [ {} ] true | ||
* @exampleContextFormatter [ "" ] true | ||
* @exampleContextFormatter [ 0 ] false | ||
* @exampleContextFormatter [ "homer" ] false | ||
* @exampleContextFormatter [ [23] ] false | ||
* @exampleContextFormatter [ {"id":3} ] false | ||
* | ||
@@ -190,2 +95,17 @@ * @param {Mixed} d data | ||
/** | ||
* Matches not empty values, string, arrays or objects. | ||
* | ||
* @version 2.0.0 | ||
* @exampleContextFormatter [ 0 ] true | ||
* @exampleContextFormatter [ "homer" ] true | ||
* @exampleContextFormatter [ [23] ] true | ||
* @exampleContextFormatter [ {"id":3} ] true | ||
* @exampleContextFormatter [ null ] false | ||
* @exampleContextFormatter [ [] ] false | ||
* @exampleContextFormatter [ {} ] false | ||
* @exampleContextFormatter [ "" ] false | ||
* | ||
* @param {Mixed} d data | ||
*/ | ||
function ifNEM (d) { | ||
@@ -205,2 +125,19 @@ var _result = true; | ||
/** | ||
* Matches all values that are equal to a specified value. It can be combined with other formatters to create conditional content. It returns the initial marker. The state of the condition is not returned. | ||
* | ||
* @version 2.0.0 | ||
* @exampleContextFormatter [ 100 , 100 ] true | ||
* @exampleContextFormatter [ 100 , 101 ] false | ||
* @exampleContextFormatter [ "homer" , "homer" ] true | ||
* @exampleContextFormatter [ "homer" , "bart" ] false | ||
* @exampleContextFormatter [ "" , "" ] true | ||
* @exampleContextFormatter [ null , 100 ] false | ||
* @exampleContextFormatter [ null , null ] true | ||
* @exampleContextFormatter [ 0 , 100 ] false | ||
* | ||
* @param {String|Array|Integer} d | ||
* @param {String|Array|Integer} value value to test | ||
* @returns It returns the initial value `d`. The state of the condition is not returned. | ||
*/ | ||
function ifEQ (d, value) { | ||
@@ -216,2 +153,19 @@ var _result = false; | ||
/** | ||
* Matches all values that are not equal to a specified value. It can be combined with other formatters to create conditional content. It returns the initial marker. The state of the condition is not returned. | ||
* | ||
* @version 2.0.0 | ||
* @exampleContextFormatter [ 100 , 100 ] false | ||
* @exampleContextFormatter [ 100 , 101 ] true | ||
* @exampleContextFormatter [ "homer" , "homer" ] false | ||
* @exampleContextFormatter [ "homer" , "bart" ] true | ||
* @exampleContextFormatter [ "" , "" ] false | ||
* @exampleContextFormatter [ null , 100 ] true | ||
* @exampleContextFormatter [ null , null ] false | ||
* @exampleContextFormatter [ 0 , 100 ] true | ||
* | ||
* @param {String|Array|Integer} d | ||
* @param {String|Array|Integer} value value to test | ||
* @returns It returns the initial value `d`. The state of the condition is not returned. | ||
*/ | ||
function ifNE (d, value) { | ||
@@ -226,2 +180,20 @@ var _result = true; | ||
/** | ||
* Matches values that are greater than a specified value. | ||
* | ||
* @version 2.0.0 | ||
* @exampleContextFormatter [1234, 1] true | ||
* @exampleContextFormatter ["50", "-29"] true | ||
* @exampleContextFormatter ["32q", "4q2"] true | ||
* @exampleContextFormatter ["1234Hello", "1"] true | ||
* @exampleContextFormatter ["10", "8Hello1234"] true | ||
* @exampleContextFormatter [-23, 19] false | ||
* @exampleContextFormatter [1, 768] false | ||
* @exampleContextFormatter [0, 0] false | ||
* @exampleContextFormatter [-2891, "33Hello"] false | ||
* | ||
* @param {Integer} d | ||
* @param {Integer} value value to test | ||
* @returns It returns the initial value `d`. The state of the condition is not returned. | ||
*/ | ||
function ifGT (d, value) { | ||
@@ -231,7 +203,4 @@ var _result = false; | ||
var _d = parseFloat(d); | ||
// Convert everything in string (not strict Equal) | ||
if (typeof d === 'number' && _d > _value | ||
|| typeof d === 'string' && value && d.length > value.length | ||
|| Array.isArray(d) === true && value && d.length > value.length | ||
|| d && d.constructor === Object && value && value.constructor === Object && Object.keys(d).length > Object.keys(value).length ) { | ||
if (Number.isNaN(_d) === false && Number.isNaN(_value) === false && _d > _value) { | ||
_result = true; | ||
@@ -243,2 +212,18 @@ } | ||
/** | ||
* Matches values that are greater than or equal to a specified value. | ||
* | ||
* @version 2.0.0 | ||
* @exampleContextFormatter [50, -29] true | ||
* @exampleContextFormatter [1, 1] true | ||
* @exampleContextFormatter [1290, 768] true | ||
* @exampleContextFormatter ["1234", "1"] true | ||
* @exampleContextFormatter [-23, 19] false | ||
* @exampleContextFormatter [1, 768] false | ||
* @exampleContextFormatter ["1" , "1234"] false | ||
* | ||
* @param {Integer} d | ||
* @param {Integer} value value to test | ||
* @returns It returns the initial value `d`. The state of the condition is not returned. | ||
*/ | ||
function ifGTE (d, value) { | ||
@@ -248,7 +233,4 @@ var _result = false; | ||
var _d = parseFloat(d); | ||
// Convert everything in string (not strict Equal) | ||
if ( typeof d === 'number' && _d >= _value | ||
|| typeof d === 'string' && value && d.length >= value.length | ||
|| Array.isArray(d) === true && value && d.length >= value.length | ||
|| d && d.constructor === Object && value && value.constructor === Object && Object.keys(d).length >= Object.keys(value).length ) { | ||
if (Number.isNaN(_d) === false && Number.isNaN(_value) === false && _d >= _value) { | ||
_result = true; | ||
@@ -260,2 +242,20 @@ } | ||
/** | ||
* Matches values that are less than a specified value. | ||
* | ||
* @version 2.0.0 | ||
* @exampleContextFormatter [-23, 19] true | ||
* @exampleContextFormatter [1, 768] true | ||
* @exampleContextFormatter ["1" , "1234"] true | ||
* @exampleContextFormatter ["123dsf", "103123"] true | ||
* @exampleContextFormatter [-1299283, "-2891feihuwf"] true | ||
* @exampleContextFormatter [50, -29] false | ||
* @exampleContextFormatter [0, 0] false | ||
* @exampleContextFormatter [1290, 768] false | ||
* @exampleContextFormatter ["1234", "1"] false | ||
* | ||
* @param {Integer} d | ||
* @param {Integer} value value to test | ||
* @returns It returns the initial value `d`. The state of the condition is not returned. | ||
*/ | ||
function ifLT (d, value) { | ||
@@ -265,7 +265,4 @@ var _result = false; | ||
var _d = parseFloat(d); | ||
// Convert everything in string (not strict Equal) | ||
if ( typeof d === 'number' && _d < _value | ||
|| typeof d === 'string' && value && d.length < value.length | ||
|| Array.isArray(d) === true && value && d.length < value.length | ||
|| d && d.constructor === Object && value && value.constructor === Object && Object.keys(d).length < Object.keys(value).length ) { | ||
if (Number.isNaN(_d) === false && Number.isNaN(_value) === false && _d < _value) { | ||
_result = true; | ||
@@ -277,2 +274,17 @@ } | ||
/** | ||
* Matches values that are less than or equal to a specified value. | ||
* | ||
* @version 2.0.0 | ||
* @exampleContextFormatter [-23, 19] true | ||
* @exampleContextFormatter [1, 768] true | ||
* @exampleContextFormatter [5, 5] true | ||
* @exampleContextFormatter ["1" , "1234"] true | ||
* @exampleContextFormatter [1290, 768] false | ||
* @exampleContextFormatter ["1234", "1"] false | ||
* | ||
* @param {Integer} d | ||
* @param {Integer} value value to test | ||
* @returns It returns the initial value `d`. The state of the condition is not returned. | ||
*/ | ||
function ifLTE (d, value) { | ||
@@ -282,7 +294,4 @@ var _result = false; | ||
var _d = parseFloat(d); | ||
// Convert everything in string (not strict Equal) | ||
if ( typeof d === 'number' && _d <= _value | ||
|| typeof d === 'string' && value && d.length <= value.length | ||
|| Array.isArray(d) === true && value && d.length <= value.length | ||
|| d && d.constructor === Object && value && value.constructor === Object && Object.keys(d).length <= Object.keys(value).length ) { | ||
if (Number.isNaN(_d) === false && Number.isNaN(_value) === false && _d <= _value) { | ||
_result = true; | ||
@@ -294,2 +303,15 @@ } | ||
/** | ||
* Matches any of the values specified in an array or string, it replaces `ifContain`. | ||
* | ||
* @version 2.0.0 | ||
* @exampleContextFormatter ["car is broken", "is"] true | ||
* @exampleContextFormatter [[1, 2, "toto"], 2] true | ||
* @exampleContextFormatter ["car is broken", "are"] false | ||
* @exampleContextFormatter [[1, 2, "toto"], "titi"] false | ||
* | ||
* @param {Integer|String|Array} d | ||
* @param {Integer} value value to test | ||
* @returns It returns the initial value `d`. The state of the condition is not returned. | ||
*/ | ||
function ifIN (d, value) { | ||
@@ -304,2 +326,15 @@ var _result = false; | ||
/** | ||
* Matches none of the values specified in an array or string. | ||
* | ||
* @version 2.0.0 | ||
* @exampleContextFormatter ["car is broken", "are"] true | ||
* @exampleContextFormatter [[1, 2, "toto"], "titi"] true | ||
* @exampleContextFormatter ["car is broken", "is"] false | ||
* @exampleContextFormatter [[1, 2, "toto"], 2] false | ||
* | ||
* @param {Integer|String|Array} d | ||
* @param {Integer} value value to test | ||
* @returns It returns the initial value `d`. The state of the condition is not returned. | ||
*/ | ||
function ifNIN (d, value) { | ||
@@ -314,2 +349,11 @@ var _result = false; | ||
/** | ||
* Print a message if the condition is true. It should be used with other formatters to print conditional content. | ||
* | ||
* @version 2.0.0 | ||
* @example ["Carbone.io"] | ||
* | ||
* @param {Mixed} d marker | ||
* @param {*} message message to print | ||
*/ | ||
function show (d, message) { | ||
@@ -323,2 +367,9 @@ if (this.isConditionTrue === true || this.isConditionTrue === null && d) { | ||
/** | ||
* Print a message if the condition is false. It should be used with other formatters to print conditional content. | ||
* | ||
* @version 2.0.0 | ||
* @param {Mixed} d marker | ||
* @param {*} message message to print | ||
*/ | ||
function elseShow (d, message) { | ||
@@ -332,2 +383,8 @@ if (this.isConditionTrue === false || this.isConditionTrue === null && !d) { | ||
/** | ||
* Show a text block between showBegin and showEnd if the condition is true | ||
* @version 2.0.0 | ||
* @private | ||
* @param {*} d | ||
*/ | ||
function showBegin (d) { | ||
@@ -342,2 +399,7 @@ this.isHidden = 1; | ||
/** | ||
* show a text block between showBegin and showEnd if the condition is true | ||
* @version 2.0.0 | ||
* @private | ||
*/ | ||
function showEnd () { | ||
@@ -348,2 +410,8 @@ this.isHidden = -1; | ||
/** | ||
* hide text block between hideBegin and hideEnd if the condition is true | ||
* @version 2.0.0 | ||
* @private | ||
* @param {*} d | ||
*/ | ||
function hideBegin (d) { | ||
@@ -358,2 +426,7 @@ this.isHidden = 0; | ||
/** | ||
* hide text block between hideBegin and hideEnd if the condition is true | ||
* @version 2.0.0 | ||
* @private | ||
*/ | ||
function hideEnd () { | ||
@@ -364,2 +437,111 @@ this.isHidden = -1; | ||
/** | ||
* Returns the length of a string or array. | ||
* | ||
* @version 2.0.0 | ||
* @example ["Hello World"] | ||
* @example [""] | ||
* @example [[1, 2, 3, 4, 5]] | ||
* @example [[1, "Hello"]] | ||
* | ||
* @param {Mixed} d Array or String | ||
* @returns {Number} Length of the element | ||
*/ | ||
function len (d) { | ||
if (typeof d === 'string' || Array.isArray(d)) { | ||
return d.length; | ||
} | ||
return 0; | ||
} | ||
/** | ||
* Test if data is empty (null, undefined, [], {}, ...). The new formatter `ifEM` should be used instead of this one. | ||
* | ||
* @example [ null , "D'oh!" ] | ||
* @example [ [] , "D'oh!" ] | ||
* @example [ {} , "D'oh!" ] | ||
* @example [ "" , "D'oh!" ] | ||
* @example [ 0 , "D'oh!" ] | ||
* @example [ "homer" , "D'oh!" ] | ||
* @example [ [23] , "D'oh!" ] | ||
* @example [ {"id":3} , "D'oh!" ] | ||
* | ||
* @param {Mixed} d data | ||
* @param {String} message message to print if JSON data is empty | ||
* @param {Boolean} continueOnSuccess [optional], if true, next formatter will be called even if the condition is true | ||
* @return {Mixed} `message` if condition is true, `d` otherwise | ||
*/ | ||
function ifEmpty (d, message, continueOnSuccess) { | ||
if ( d === null | ||
|| typeof(d) === 'undefined' | ||
|| d === '' | ||
|| d instanceof Array && d.length === 0 | ||
|| d.constructor === Object && Object.keys(d).length === 0 | ||
|| Number.isNaN(d) === true) { | ||
if (continueOnSuccess !== true && continueOnSuccess !== 'true') { | ||
this.stopPropagation = true; | ||
} | ||
return message; | ||
} | ||
return d; | ||
} | ||
/** | ||
* Test if a value equals a variable. The new formatter `ifEQ` should be used instead of this one. | ||
* | ||
* @example [ 100 , 100 , "bingo" ] | ||
* @example [ 100 , 101 , "bingo" ] | ||
* @example [ "homer" , "homer" , "bingo" ] | ||
* @example [ "homer" , "bart" , "bingo" ] | ||
* @example [ "" , "" , "bingo" ] | ||
* @example [ null , 100 , "bingo" ] | ||
* @example [ null , null , "bingo" ] | ||
* @example [ 0 , 100 , "bingo" ] | ||
* | ||
* @param {String|Integer|Boolean} d data | ||
* @param {String|Integer|Boolean} value value to test | ||
* @param {String} messageIfTrue message to print if the value equals JSON data | ||
* @param {Boolean} continueOnSuccess [optional], if true, next formatter will be called even if the condition is true | ||
* @return {Mixed} `message` if condition is true, `d` otherwise | ||
*/ | ||
function ifEqual (d, value, messageIfTrue, continueOnSuccess) { | ||
// Convert everything in string (not strict Equal) | ||
if (d + '' === value + '') { | ||
if (continueOnSuccess !== true && continueOnSuccess !== 'true') { | ||
this.stopPropagation = true; | ||
} | ||
return messageIfTrue; | ||
} | ||
return d; | ||
} | ||
/** | ||
* Test if a string or an array contains a value. The new formatter `ifIN` should be used instead of this previous one. | ||
* | ||
* @example [ "your beautiful eyes", "beauti", "bingo" ] | ||
* @example [ "your beautiful eyes", "leg" , "bingo" ] | ||
* @example [ "your beautiful eyes", "eyes" , "bingo" ] | ||
* @example [ "" , "eyes" , "bingo" ] | ||
* @example [ "your beautiful eyes", "" , "bingo" ] | ||
* @example [ [100, 120, 20] , 120 , "bingo" ] | ||
* @example [ [100, 120, 20] , 99 , "bingo" ] | ||
* @example [ ["your", "eyes"] , "eyes" , "bingo" ] | ||
* @example [ [] , "eyes" , "bingo" ] | ||
* | ||
* @param {String|Array} d data | ||
* @param {String|Integer|Boolean} value value to search | ||
* @param {String} messageIfTrue message to print if JSON data contains the value | ||
* @param {Boolean} continueOnSuccess [optional], if true, next formatter will be called even if the condition is true | ||
* @return {Mixed} `message` if condition is true, `d` otherwise | ||
*/ | ||
function ifContain (d, value, messageIfTrue, continueOnSuccess) { | ||
if ((typeof(d) === 'string' || d instanceof Array) && d.indexOf(value) !== -1) { | ||
if (continueOnSuccess !== true && continueOnSuccess !== 'true') { | ||
this.stopPropagation = true; | ||
} | ||
return messageIfTrue; | ||
} | ||
return d; | ||
} | ||
module.exports = { | ||
@@ -386,3 +568,4 @@ ifContain, | ||
and, | ||
or | ||
or, | ||
len | ||
}; |
@@ -377,3 +377,9 @@ var extracter = require('./extracter'); | ||
var _lastArrayName = currentlyVisitedArrays[currentlyVisitedArrays.length-1]; | ||
var _nextArrayXmlDepth = objDependencyDescriptor[nextAttrName].depth || objDependencyDescriptor[_firstParentOfTypeArray].depth || -1; | ||
var _nextArrayXmlDepth = objDependencyDescriptor[nextAttrName].depth; | ||
if (_nextArrayXmlDepth === undefined) { | ||
_nextArrayXmlDepth = -1; | ||
if (objDependencyDescriptor[_firstParentOfTypeArray] !== undefined && objDependencyDescriptor[_firstParentOfTypeArray].depth !== undefined) { | ||
_nextArrayXmlDepth = objDependencyDescriptor[_firstParentOfTypeArray].depth; | ||
} | ||
} | ||
var _lastArrayXmlDepth = objDependencyDescriptor[_lastArrayName].depth || Number.MAX_SAFE_INTEGER; | ||
@@ -380,0 +386,0 @@ while (_firstParentOfTypeArray !== _lastArrayName && currentlyVisitedArrays.length>0 && _nextArrayXmlDepth <= _lastArrayXmlDepth) { |
@@ -290,3 +290,4 @@ var parser = require('./parser'); | ||
obj : _objParent, | ||
pos : _markerPos | ||
pos : _markerPos, | ||
posOrigin : _markerPos | ||
}; | ||
@@ -330,2 +331,11 @@ if (_conditions.length > 0) { | ||
} | ||
// after detecting arrays and conditional blocks, some markers may have moved in XML | ||
// It could create conflicts (many markers at the same XML position). | ||
// So, we sort them using their original position | ||
if (a.posOrigin > b.posOrigin) { | ||
return 1; | ||
} | ||
if (a.posOrigin < b.posOrigin) { | ||
return -1; | ||
} | ||
// other basic cases: | ||
@@ -388,5 +398,25 @@ if (a.array==='start') { | ||
// avoid having two (or more) markers at the same XML position for the final sort in builder.assembleXmlParts | ||
// fix this using float position. | ||
for (let i = 0; i < _allSortedParts.length; i++) { | ||
let _part = _allSortedParts[i]; | ||
if (Math.trunc(_part.pos) === Math.trunc(_prevPart.pos)) { | ||
// Why adding 1/64? to avoid rounding problems of floats (http://0.30000000000000004.com) | ||
// This let us the possibility to have 64 markers at the same position. It should enough for all cases. | ||
_part.pos = _prevPart.pos + 1/64; | ||
// fix also beginning and ending of arrays | ||
if (_part.array === 'start') { | ||
descriptor[_part.obj].position.start = _part.pos; | ||
} | ||
else if (_part.array === 'end') { | ||
descriptor[_part.obj].position.end = _part.pos; | ||
} | ||
} | ||
_prevPart = _part; | ||
} | ||
_prevPart = {}; | ||
for (var i = 0; i < _allSortedParts.length; i++) { | ||
var _part = _allSortedParts[i]; | ||
var _pos = Math.round(_part.pos); // can be a float | ||
var _pos = Math.trunc(_part.pos); // can be a float | ||
if (i===0) { | ||
@@ -421,3 +451,3 @@ _res.staticData.before = xml.slice(_prevPos, _pos); | ||
} | ||
else if (_part.pos > _arrayPos.end && _part.pos < _arrayPos.endOdd) { | ||
else if (Math.trunc(_part.pos) > Math.trunc(_arrayPos.end) && _part.pos < _arrayPos.endOdd) { | ||
_part.toDelete = true; // remove all parts which are in odd zone of arrays | ||
@@ -453,3 +483,3 @@ break; | ||
if (_part.array === 'end') { | ||
_prevPos = descriptor[_part.obj].position.endOdd; | ||
_prevPos = Math.trunc(descriptor[_part.obj].position.endOdd); | ||
} | ||
@@ -568,8 +598,10 @@ else if (_pos > _prevPos) { | ||
if (_safeXMLBlocks.length > 0) { | ||
_beginPart.pos = _safeXMLBlocks[0][0] - 0.1; | ||
_part.pos = _safeXMLBlocks[0][1] - 0.1; | ||
_beginPart.posOrigin = _beginPart.pos; | ||
_part.posOrigin = _part.pos; | ||
_beginPart.pos = _safeXMLBlocks[0][0]; | ||
_part.pos = _safeXMLBlocks[0][1]; | ||
for (var j = 1; j < _safeXMLBlocks.length; j++) { | ||
var _safeXMLBlock = _safeXMLBlocks[j]; | ||
_newParts.push({ attr : _beginPart.attr, obj : _beginPart.obj, formatters : _beginPart.formatters, pos : _safeXMLBlock[0] - 0.1 }); | ||
_newParts.push({ attr : _beginPart.attr, obj : _beginPart.obj, formatters : _part.formatters , pos : _safeXMLBlock[1] - 0.1 }); | ||
_newParts.push({ attr : _beginPart.attr, obj : _beginPart.obj, formatters : _beginPart.formatters, pos : _safeXMLBlock[0], posOrigin : _beginPart.posOrigin }); | ||
_newParts.push({ attr : _beginPart.attr, obj : _beginPart.obj, formatters : _part.formatters , pos : _safeXMLBlock[1], posOrigin : _part.posOrigin }); | ||
} | ||
@@ -598,4 +630,4 @@ } | ||
if (_obj.type === 'array' && _obj.iterators.length>0) { | ||
var _roughPosStart = Math.round(descriptor[_objName].position.start); | ||
var _roughPosEnd = Math.round(descriptor[_objName].position.end); | ||
var _roughPosStart = Math.trunc(descriptor[_objName].position.start); | ||
var _roughPosEnd = Math.trunc(descriptor[_objName].position.end); | ||
var _subString = xml.slice(_roughPosStart, _roughPosEnd); | ||
@@ -609,5 +641,5 @@ var _pivot = parser.findPivot(_subString); | ||
// TODO test if the repetition is found !!!!!!!!!!!! | ||
descriptor[_objName].position = {start : _realArrayPosition.startEven, end : _realArrayPosition.endEven, /* 'startOdd':_realArrayPosition.startOdd,*/ endOdd : _realArrayPosition.endOdd}; | ||
descriptor[_objName].xmlParts.push({obj : _objName, array : 'start',pos : _realArrayPosition.startEven}); | ||
descriptor[_objName].xmlParts.push({obj : _objName, array : 'end' ,pos : _realArrayPosition.endEven /* ,'next':_realArrayPosition.endOdd*/}); | ||
descriptor[_objName].position = {start : _realArrayPosition.startEven, end : _realArrayPosition.endEven, endOdd : _realArrayPosition.endOdd}; | ||
descriptor[_objName].xmlParts.push({obj : _objName, array : 'start', pos : _realArrayPosition.startEven, posOrigin : _roughPosStart}); | ||
descriptor[_objName].xmlParts.push({obj : _objName, array : 'end' , pos : _realArrayPosition.endEven , posOrigin : _roughPosEnd }); | ||
_oddZones.push([_realArrayPosition.endEven, _realArrayPosition.endOdd]); | ||
@@ -614,0 +646,0 @@ } |
{ | ||
"name": "carbone", | ||
"description": "Fast, Simple and Powerful report generator. Injects JSON and produces PDF, DOCX, XLSX, ODT, PPTX, ODS, ...!", | ||
"version": "2.0.0-beta.6", | ||
"version": "2.0.0-beta.7", | ||
"bin": "bin/carbone", | ||
@@ -6,0 +6,0 @@ "main": "./lib", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
425721
7821