From: Joe Wreschnig Date: Tue, 13 May 2014 22:26:59 +0000 (+0200) Subject: Add documentation. X-Git-Tag: 1.0.0~21 X-Git-Url: https://git.yukkurigames.com/?p=string-lerp.git;a=commitdiff_plain;h=34182258ce91e32a350ce252a29cc73c06795089 Add documentation. --- diff --git a/Makefile b/Makefile index 5dfff02..96f45a4 100644 --- a/Makefile +++ b/Makefile @@ -4,15 +4,22 @@ JSTEST ?= node_modules/.bin/jstest JSHINT ?= node_modules/.bin/jshint UGLIFY ?= node_modules/.bin/uglifyjs SOURCES = string-lerp.js -MINIFIED = $(SOURCES:.js=.min.js) +UGLIFIED = $(SOURCES:.js=.min.js) TESTS = $(wildcard tests/*.js); LINT_TARGETS = $(addprefix build/stamp/,$(addsuffix .lint,$(SOURCES))) TEST_TARGETS = $(addprefix build/stamp/,$(addsuffix .test,$(SOURCES))) -.PHONY: all check lint test +.PHONY: all check lint test min -all: $(MINIFIED) +all: + @echo "Interesting targets:" + @echo " lint - validate source (with jshint)" + @echo " test - run tests (with jstest)" + @echo " ugly - generate minified/mangled source files" + @echo + @echo "(Running these will download packages from NPM.)" + @echo %.min.js: %.js $(UGLIFY) $(UGLIFY) -m < $< > $@ @@ -31,6 +38,8 @@ build/stamp/%.test: tests/% % build @$(JSTEST) $< > $@ || (cat $@ && rm -f $@ && exit 1) @touch $@ +ugly: $(UGLIFIED) + check: lint test lint: $(JSHINT) $(LINT_TARGETS) @@ -39,7 +48,7 @@ test: $(JSTEST) $(TEST_TARGETS) clean: rm -rf build - rm -f $(MINIFIED) + rm -f $(UGLIFIED) distclean: clean rm -rf node_modules diff --git a/README.md b/README.md new file mode 100644 index 0000000..8ec9670 --- /dev/null +++ b/README.md @@ -0,0 +1,131 @@ +# String Lerp + +This is a library to linearly interpolate between two string values, +that is, progressively turn one string into another. It implements +several ways to do this, and can automatically pick the best one based +on the strings given to it. + +For example, it knows: + +* "explore" is between "implore" and "explode". +* Or conversely, "implode" between "explode" and "implore". +* "chicken wing" and "buffalo wing" are actually the same "wing". +* Likewise, "apple core" and "core dump" can keep the "core". +* 1/3 of the way from "0%" to "100%" is "33%". +* Halfway between rgb(255, 0, 0) and rgb(0, 0, 255) is rgb(128, 0, 128). + (Well, it's good at strings, not color science.) + +To try more, open up [demo.html] in your browser. + +## Setting Up + +Include the following in your HTML: + + + +Then, you can use `window.stringLerp` (or just `stringLerp`). + +Or if you're using Node or some other non-browser whatever, + + var stringLerp = require("./string-lerp"); + +If you want a minified version, at a shell run + + $ make ugly + +If you think something's wrong, or make changes, run + + $ make check + +(Running these will also download modules from [NPM].) + +## API + +### stringLerp.lerp(a, b, p) + +Interpolate between strings a and b, given a parameter p. + +This automatically picks the best interpolator based on the strings +provided. If the strings are identical aside from numbers in them, +they are passed through `numericLerp`. + +If the strings are not numbers and short, they are passed through +`diffLerp`. + +Otherwise, they are passed through `fastLerp`. + + +### stringLerp.numericLerp(a, b, p) + +Lerp all the numbers in the string from their values in `a` to their +values in `b`. + +Numbers may have a leading `-` and a single `.` to mark the decimal +point, but something must be after the `.`. If both of the numbers in +a pair are integers, the result is clamped to an integer. + +For example, `numericLerp("0.0", "100", 0.123) === "12.3"` because the +`.` in `0.0` is interpreted as a decimal point. + +But `numericLerp("0.", "100.", 0.123) === "12."` because the strings +are interpreted as integers followed by a full stop. + +Calling this functions on strings that differ in more than numerals +gives undefined results. + + +### stringLerp.diffLerp(a, b, p) + +Lerp from `a` to `b` based on edit operations. + +This interpolation algorithm applys a partial edit of one string into +the other. This produces nice looking results, but can take a +significant amount of time and memory to compute the edits. It is not +recommended for strings longer than a few hundred characters. + + +### stringLerp.fastLerp(a, b, p) + +Lerp from `a` to `b` using a simple algorithm based on length. + +This interpolation algorithm progressively replaces the front of one +string with another. This approach is fast but does not look good when +the strings are similar. + + +### stringLerp.diff(s, t) and stringLerp.patch(edits, s) + +These are the functions used to implement `diffLerp`. `diff` +calculates a series of edit operations - substitutions, insertions, +and deletions - to turn `s` into `t`. + + +### stringLerp.levenshteinMatrix(s, t, ins, del, sub) + +Calculate the edit distance between the source and target sequences, +and return a matrix representing the possible edits and their +costs. The matrix returned is a flat typed array. + +Because stringLerp needs to be able to reconstruct the edit path, this +is not an optimal algorithm if you only need the Levenshtein distance. + + +## Unicode Concerns + +String Lerp handles Unicode reasonably well. Surrogate pairs are +recognized and not split, and combining characters stay attached to +the character they started with. All algorithms will be notably +slower, and memory-intensive, when given such strings. + +Some scripts, such as Hangul and Tamil, do not work ideally. +Multi-glyph graphemes will be split up, and potentially rejoined, +during interpolation. The intermediate string is always a valid +Unicode string containing only glyphs present in one string or the +other, but the glyphs may be arranged very differently. + +A similar problem occurs when switching between LTR and RTL in the +same string. The codepoints indicating bidi switches may move around +the string capturing glyphs in ways that are not visually appealing. + + +[NPM]: https://www.npmjs.org/