| 1 | import number from "./number.js";
|
|---|
| 2 |
|
|---|
| 3 | var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,
|
|---|
| 4 | reB = new RegExp(reA.source, "g");
|
|---|
| 5 |
|
|---|
| 6 | function zero(b) {
|
|---|
| 7 | return function() {
|
|---|
| 8 | return b;
|
|---|
| 9 | };
|
|---|
| 10 | }
|
|---|
| 11 |
|
|---|
| 12 | function one(b) {
|
|---|
| 13 | return function(t) {
|
|---|
| 14 | return b(t) + "";
|
|---|
| 15 | };
|
|---|
| 16 | }
|
|---|
| 17 |
|
|---|
| 18 | export default function(a, b) {
|
|---|
| 19 | var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b
|
|---|
| 20 | am, // current match in a
|
|---|
| 21 | bm, // current match in b
|
|---|
| 22 | bs, // string preceding current number in b, if any
|
|---|
| 23 | i = -1, // index in s
|
|---|
| 24 | s = [], // string constants and placeholders
|
|---|
| 25 | q = []; // number interpolators
|
|---|
| 26 |
|
|---|
| 27 | // Coerce inputs to strings.
|
|---|
| 28 | a = a + "", b = b + "";
|
|---|
| 29 |
|
|---|
| 30 | // Interpolate pairs of numbers in a & b.
|
|---|
| 31 | while ((am = reA.exec(a))
|
|---|
| 32 | && (bm = reB.exec(b))) {
|
|---|
| 33 | if ((bs = bm.index) > bi) { // a string precedes the next number in b
|
|---|
| 34 | bs = b.slice(bi, bs);
|
|---|
| 35 | if (s[i]) s[i] += bs; // coalesce with previous string
|
|---|
| 36 | else s[++i] = bs;
|
|---|
| 37 | }
|
|---|
| 38 | if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match
|
|---|
| 39 | if (s[i]) s[i] += bm; // coalesce with previous string
|
|---|
| 40 | else s[++i] = bm;
|
|---|
| 41 | } else { // interpolate non-matching numbers
|
|---|
| 42 | s[++i] = null;
|
|---|
| 43 | q.push({i: i, x: number(am, bm)});
|
|---|
| 44 | }
|
|---|
| 45 | bi = reB.lastIndex;
|
|---|
| 46 | }
|
|---|
| 47 |
|
|---|
| 48 | // Add remains of b.
|
|---|
| 49 | if (bi < b.length) {
|
|---|
| 50 | bs = b.slice(bi);
|
|---|
| 51 | if (s[i]) s[i] += bs; // coalesce with previous string
|
|---|
| 52 | else s[++i] = bs;
|
|---|
| 53 | }
|
|---|
| 54 |
|
|---|
| 55 | // Special optimization for only a single match.
|
|---|
| 56 | // Otherwise, interpolate each of the numbers and rejoin the string.
|
|---|
| 57 | return s.length < 2 ? (q[0]
|
|---|
| 58 | ? one(q[0].x)
|
|---|
| 59 | : zero(b))
|
|---|
| 60 | : (b = q.length, function(t) {
|
|---|
| 61 | for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t);
|
|---|
| 62 | return s.join("");
|
|---|
| 63 | });
|
|---|
| 64 | }
|
|---|