1 # String Lerp
3 This is a library to linearly interpolate between two string values,
4 that is, progressively turn one string into another. It implements
5 several ways to do this, and can automatically pick the best one based
6 on the strings given to it.
8 For example, it knows:
10 * "explore" is between "implore" and "explode".
11 * Or conversely, "implode" between "explode" and "implore".
12 * "chicken wing" and "buffalo wing" are actually the same "wing".
13 * Likewise, "apple core" and "core dump" can keep the "core".
14 * 1/3 of the way from "0%" to "100%" is "33%".
15 * Halfway between rgb(255, 0, 0) and rgb(0, 0, 255) is rgb(128, 0, 128).
16 (Well, it's good at strings, not color science.)
18 To try more, open up [demo.html] in your browser.
20 ## Setting Up
22 Include the following in your HTML:
24 <script type="text/javascript" src="string-lerp.js"></script>
26 Then, you can use `window.stringLerp` (or just `stringLerp`).
28 Or if you're using Node or some other non-browser whatever,
30 var stringLerp = require("./string-lerp");
32 If you want a minified version, at a shell run
34 \$ make ugly
36 If you think something's wrong, or make changes, run
38 \$ make check
42 ## API
44 ### stringLerp.lerp(a, b, p)
46 Interpolate between strings a and b, given a parameter p.
48 This automatically picks the best interpolator based on the strings
49 provided. If the strings are identical aside from numbers in them,
50 they are passed through `numericLerp`.
52 If the strings are not numbers and short, they are passed through
53 `diffLerp`.
55 Otherwise, they are passed through `fastLerp`.
58 ### stringLerp.numericLerp(a, b, p)
60 Lerp all the numbers in the string from their values in `a` to their
61 values in `b`.
63 Numbers may have a leading "-" and a single "." to mark the decimal
64 point, but something must be after the ".". No other floating point
65 syntax (e.g. `1e6`) is supported. They are treated as fixed-point
66 values, with the point's position itself interpolating.
68 For example, `numericLerp("0.0", "100.0", 0.123) === "12.3"` because
69 the `.` in `0.0` is interpreted as a decimal point.
71 But `numericLerp("0.", "100.", 0.123) === "12."` because the strings
72 are interpreted as integers followed by a full stop.
74 Calling this functions on strings that differ in more than numerals
75 gives undefined results.
78 ### stringLerp.diffLerp(a, b, p)
80 Lerp from `a` to `b` based on edit operations.
82 This interpolation algorithm applys a partial edit of one string into
83 the other. This produces nice looking results, but can take a
84 significant amount of time and memory to compute the edits. It is not
85 recommended for strings longer than a few hundred characters.
88 ### stringLerp.fastLerp(a, b, p)
90 Lerp from `a` to `b` using a simple algorithm based on length.
92 This interpolation algorithm progressively replaces the front of one
93 string with another. This approach is fast but does not look good when
94 the strings are similar.
97 ### stringLerp.diff(s, t) and stringLerp.patch(edits, s)
99 These are the functions used to implement `diffLerp`. `diff`
100 calculates an array of edit operations - substitutions, insertions,
101 and deletions - to turn `s` into `t`.
103 The type of the edit operations is unspecified. What is guaranteed is:
105 * There's an Array of them.
106 * The array can be cut up and applied in-order but piecemeal.
107 * They are simple objects, i.e. can be (de)serialized via JSON and fed
108 into the same version of `patch` later.
110 Do not rely on edit operations to be exactly the same type (or same
111 operations) between versions / installations.
114 ### stringLerp.levenshteinMatrix(s, t, ins, del, sub)
116 Calculate the edit distance between the source and target sequences,
117 and return a matrix representing the possible edits and their
118 costs. The matrix returned is a flat typed array.
120 Because stringLerp needs to be able to reconstruct the edit path, this
121 is not an optimal algorithm if you only need the Levenshtein distance.
124 ## Unicode Concerns
126 String Lerp handles Unicode reasonably well. Surrogate pairs are
127 recognized and not split, and combining characters stay attached to
128 the character they started with. All algorithms will be notably
129 slower, and memory-intensive, when given such strings.
131 Some scripts, such as Hangul and Tamil, do not work ideally.
132 Multi-glyph graphemes will be split up, and potentially rejoined,
133 during interpolation. The intermediate string is always a valid
134 Unicode string containing only glyphs present in one string or the
135 other, but the glyphs may be arranged very differently.
137 A similar problem occurs when switching between LTR and RTL in the
138 same string. The codepoints indicating bidi switches may move around
139 the string capturing glyphs in ways that are not visually appealing.
142 [NPM]: https://www.npmjs.org/