mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-11-23 18:17:20 +00:00
Add range operator and documentation (#3346)
This commit is contained in:
parent
34e04b7ca6
commit
be58de8409
80
core/modules/filters/range.js
Normal file
80
core/modules/filters/range.js
Normal file
@ -0,0 +1,80 @@
|
||||
/*\
|
||||
title: $:/core/modules/filters/range.js
|
||||
type: application/javascript
|
||||
module-type: filteroperator
|
||||
|
||||
Filter operator for generating a numeric range.
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
Export our filter function
|
||||
*/
|
||||
exports.range = function(source,operator,options) {
|
||||
var results = [];
|
||||
|
||||
// Split the operand into numbers delimited by these symbols
|
||||
var parts = operator.operand.split(/[,:;]/g), beg, end, inc, i, fixed = 0;
|
||||
|
||||
for (i = 0; i < parts.length; ++i) {
|
||||
// Validate real number
|
||||
if (!/^\s*[+-]?((\d+(\.\d*)?)|(\.\d+))\s*$/.test(parts[i]))
|
||||
return ["range: bad number \""+parts[i]+"\""];
|
||||
|
||||
// Count digits; the most precise number determines decimal places in output.
|
||||
var frac = /\.\d+/.exec(parts[i]);
|
||||
if (frac) fixed = Math.max(fixed, frac[0].length-1);
|
||||
|
||||
parts[i] = parseFloat(parts[i]);
|
||||
}
|
||||
|
||||
switch (parts.length) {
|
||||
case 1:
|
||||
beg = 0;
|
||||
end = parts[0];
|
||||
inc = 1;
|
||||
break;
|
||||
case 2:
|
||||
beg = parts[0];
|
||||
end = parts[1];
|
||||
inc = 1;
|
||||
break;
|
||||
case 3:
|
||||
beg = parts[0];
|
||||
end = parts[1];
|
||||
inc = Math.abs(parts[2]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (inc === 0) return ["range: increment 0 causes infinite loop"];
|
||||
|
||||
// May need to count backwards
|
||||
var direction = ((end<beg) ? -1 : 1);
|
||||
inc *= direction;
|
||||
|
||||
// Estimate number of resulting elements
|
||||
if ((end-beg)/inc > 10000) return ["range: too many steps (over 10K)"];
|
||||
|
||||
// Avoid rounding error on last step
|
||||
end += direction * 0.5 * Math.pow(0.1, fixed);
|
||||
|
||||
var safety = 10010;
|
||||
|
||||
// Enumerate the range
|
||||
if (end<beg) {for (i = beg; i > end; i += inc) {results.push(i.toFixed(fixed)); if (--safety<0) break;}}
|
||||
else {for (i = beg; i < end; i += inc) {results.push(i.toFixed(fixed)); if (--safety<0) break;}}
|
||||
|
||||
if (safety<0) return ["range: unexpectedly large output"];
|
||||
|
||||
// Reverse?
|
||||
if (operator.prefix === "!") results.reverse();
|
||||
|
||||
return results;
|
||||
};
|
||||
|
||||
})();
|
59
editions/tw5.com/tiddlers/filters/range.tid
Normal file
59
editions/tw5.com/tiddlers/filters/range.tid
Normal file
@ -0,0 +1,59 @@
|
||||
created: 20171221184734665
|
||||
modified: 20171229211834620
|
||||
tags: [[Filter Operators]] [[Negatable Operators]]
|
||||
title: range Operator
|
||||
type: text/vnd.tiddlywiki
|
||||
caption: range
|
||||
op-purpose: generate a range of numbers
|
||||
op-input: ignored
|
||||
op-parameter: a range specification, like `[1,5]`
|
||||
op-parameter-name: N
|
||||
op-output: a series of evenly spaced numbers ranging from `<begin>` to `<end>`
|
||||
|
||||
\define range_example(range)
|
||||
```
|
||||
[range[$range$]]
|
||||
```
|
||||
|
||||
<$list variable=n filter="[range[$range$]]"><<n>> </$list>
|
||||
\end
|
||||
|
||||
The `range` operator allows a range of numbers to be enumerated, similar to a `for` loop in other programming languages. It's useful in combination with the [[Formula Plugin]].
|
||||
|
||||
|!Purpose|produce a range of numbers|
|
||||
|!Input|ignored.|
|
||||
|!Parameter|1-3 numbers separated by `,` or `;`.|
|
||||
|!Output|A range of numbers starting with |
|
||||
|!`!` Output|As ''Output'', but with order reversed.|
|
||||
|
||||
The parameter has three forms:
|
||||
|
||||
* `<end>`
|
||||
* `<begin>,<end>`
|
||||
* `<begin>,<end>,<step>`
|
||||
|
||||
Each part must be a number, and works as follows:
|
||||
|
||||
* `<begin>`: start counting at this number. Defaults to 0.
|
||||
* `<end>`: stop counting at this number.
|
||||
** It will be included unless it falls between two steps.
|
||||
* `<step>`: count up (or down) by this amount.
|
||||
** It may be negated so it counts in the right direction.
|
||||
** It cannot be zero.
|
||||
|
||||
The number of decimal points in the output is fixed, and based on the parameter with the //most// decimal points.
|
||||
|
||||
To prevent the browser from freezing, `range` is currently limited to 10,000 values.
|
||||
|
||||
|
||||
!!Examples
|
||||
|
||||
<<range_example "7">>
|
||||
|
||||
<<range_example "1, 10">>
|
||||
|
||||
<<range_example "17,13">>
|
||||
|
||||
<<range_example "1.001, 5, 1">>
|
||||
|
||||
<<range_example ".5,1.4,.004">>
|
Loading…
Reference in New Issue
Block a user