@@ -3,86 +3,52 @@ import "number";
33d3 . interpolateString = d3_interpolateString ;
44
55function d3_interpolateString ( a , b ) {
6- var m , // current match
7- i , // current index
8- j , // current index (for coalescing)
9- s0 = 0 , // start index of current string prefix
10- s1 = 0 , // end index of current string prefix
6+ var bi = d3_interpolate_numberA . lastIndex = d3_interpolate_numberB . lastIndex = 0 , // scan index for next number in b
7+ am , // current match in a
8+ bm , // current match in b
9+ bs , // string preceding current number in b, if any
10+ i = - 1 , // index in s
1111 s = [ ] , // string constants and placeholders
12- q = [ ] , // number interpolators
13- n , // q.length
14- o ;
12+ q = [ ] ; // number interpolators
1513
1614 // Coerce inputs to strings.
1715 a = a + "" , b = b + "" ;
1816
19- // Reset our regular expression!
20- d3_interpolate_number . lastIndex = 0 ;
21-
22- // Find all numbers in b.
23- for ( i = 0 ; m = d3_interpolate_number . exec ( b ) ; ++ i ) {
24- if ( m . index ) s . push ( b . substring ( s0 , s1 = m . index ) ) ;
25- q . push ( { i : s . length , x : m [ 0 ] } ) ;
26- s . push ( null ) ;
27- s0 = d3_interpolate_number . lastIndex ;
28- }
29- if ( s0 < b . length ) s . push ( b . substring ( s0 ) ) ;
30-
31- // Find all numbers in a.
32- for ( i = 0 , n = q . length ; ( m = d3_interpolate_number . exec ( a ) ) && i < n ; ++ i ) {
33- o = q [ i ] ;
34- if ( o . x == m [ 0 ] ) { // The numbers match, so coalesce.
35- if ( o . i ) {
36- if ( s [ o . i + 1 ] == null ) { // This match is followed by another number.
37- s [ o . i - 1 ] += o . x ;
38- s . splice ( o . i , 1 ) ;
39- for ( j = i + 1 ; j < n ; ++ j ) q [ j ] . i -- ;
40- } else { // This match is followed by a string, so coalesce twice.
41- s [ o . i - 1 ] += o . x + s [ o . i + 1 ] ;
42- s . splice ( o . i , 2 ) ;
43- for ( j = i + 1 ; j < n ; ++ j ) q [ j ] . i -= 2 ;
44- }
45- } else {
46- if ( s [ o . i + 1 ] == null ) { // This match is followed by another number.
47- s [ o . i ] = o . x ;
48- } else { // This match is followed by a string, so coalesce twice.
49- s [ o . i ] = o . x + s [ o . i + 1 ] ;
50- s . splice ( o . i + 1 , 1 ) ;
51- for ( j = i + 1 ; j < n ; ++ j ) q [ j ] . i -- ;
52- }
53- }
54- q . splice ( i , 1 ) ;
55- n -- ;
56- i -- ;
57- } else {
58- o . x = d3_interpolateNumber ( parseFloat ( m [ 0 ] ) , parseFloat ( o . x ) ) ;
17+ // Interpolate pairs of numbers in a & b.
18+ while ( ( am = d3_interpolate_numberA . exec ( a ) )
19+ && ( bm = d3_interpolate_numberB . exec ( b ) ) ) {
20+ if ( ( bs = bm . index ) > bi ) { // a string precedes the next number in b
21+ bs = b . substring ( bi , bs ) ;
22+ if ( s [ i ] ) s [ i ] += bs ; // coalesce with previous string
23+ else s [ ++ i ] = bs ;
5924 }
60- }
61-
62- // Remove any numbers in b not found in a.
63- while ( i < n ) {
64- o = q . pop ( ) ;
65- if ( s [ o . i + 1 ] == null ) { // This match is followed by another number.
66- s [ o . i ] = o . x ;
67- } else { // This match is followed by a string, so coalesce twice.
68- s [ o . i ] = o . x + s [ o . i + 1 ] ;
69- s . splice ( o . i + 1 , 1 ) ;
25+ if ( ( am = + am [ 0 ] ) === ( bm = + ( bs = bm [ 0 ] ) ) ) { // coalesce matching numbers
26+ if ( s [ i ] ) s [ i ] += bs ; // coalesce with previous string
27+ else s [ ++ i ] = bs ;
28+ } else { // interpolate non-matching numbers
29+ s [ ++ i ] = null ;
30+ q . push ( { i : i , x : d3_interpolateNumber ( am , bm ) } ) ;
7031 }
71- n -- ;
32+ bi = d3_interpolate_numberB . lastIndex ;
7233 }
7334
74- // Special optimization for only a single match .
75- if ( s . length === 1 ) {
76- return s [ 0 ] == null
77- ? ( o = q [ 0 ] . x , function ( t ) { return o ( t ) + "" ; } )
78- : function ( ) { return b ; } ;
35+ // Add remains of b .
36+ if ( bi < b . length ) {
37+ bs = b . substring ( bi ) ;
38+ if ( s [ i ] ) s [ i ] += bs ; // coalesce with previous string
39+ else s [ ++ i ] = bs ;
7940 }
8041
42+ // Special optimization for only a single match.
8143 // Otherwise, interpolate each of the numbers and rejoin the string.
82- return function ( t ) {
83- for ( i = 0 ; i < n ; ++ i ) s [ ( o = q [ i ] ) . i ] = o . x ( t ) ;
84- return s . join ( "" ) ;
85- } ;
44+ return s . length < 2
45+ ? ( q [ 0 ] ? ( b = q [ 0 ] . x , function ( t ) { return b ( t ) + "" ; } )
46+ : function ( ) { return b ; } )
47+ : ( b = q . length , function ( t ) {
48+ for ( var i = 0 , o ; i < b ; ++ i ) s [ ( o = q [ i ] ) . i ] = o . x ( t ) ;
49+ return s . join ( "" ) ;
50+ } ) ;
8651}
8752
88- var d3_interpolate_number = / [ - + ] ? (?: \d + \. ? \d * | \. ? \d + ) (?: [ e E ] [ - + ] ? \d + ) ? / g;
53+ var d3_interpolate_numberA = / [ - + ] ? (?: \d + \. ? \d * | \. ? \d + ) (?: [ e E ] [ - + ] ? \d + ) ? / g,
54+ d3_interpolate_numberB = new RegExp ( d3_interpolate_numberA . source , "g" ) ;
0 commit comments