git @ Cat's Eye Technologies Lexeduct / de1e97a
Use real function composition to compose filters. Chris Pressey 10 years ago
3 changed file(s) with 46 addition(s) and 20 deletion(s). Raw diff Collapse all Expand all
99 Basic Usage
1010 -----------
1111
12 The main tool is `lexeduct.js`. You can run it from the `src` directory.
12 The main tool is `lexeduct.js`. You can `cd` into the `src` directory and run
13 it as `./lexeduct.js`, or you can put the `src` directory on your executable
14 search path (e.g. `export PATH=$PATH:/path/to/lexeduct/src`) and run it as
15 `lexeduct.js` from anywhere on your system. (YMMV on Windows.)
16
1317 The basic usage is
1418
15 ./lexeduct.js {filter}
19 lexeduct.js {filter}
1620
17 So, for example, go into the `src` directory and run
21 So, for example,
1822
19 ./lexeduct.js upper <../README.md
23 lexeduct.js upper <input.txt
2024
21 and an uppercased version of this document will be dumped to standard output.
25 and an uppercased version of the contents of `input.txt` will be dumped to
26 the standard output.
2227
2328 You can of course use shell pipelines to compose filters:
2429
25 ./lexeduct.js upper <../README.md | ./lexeduct.js double-space
30 cat input.txt | lexeduct.js upper | lexeduct.js double-space
2631
27 Or you can name multiple filters on `lexeduct.js`'s command line to compose
32 *Or* you can name multiple filters on `lexeduct.js`'s command line to compose
2833 them:
2934
30 ./lexeduct.js upper double-space <../README.md
35 lexeduct.js upper double-space <input.txt
3136
3237 Filters
3338 -------
3439
3540 The idea is that this repository will eventually contain a giant catalogue
36 of possible text filters that can be composed. Or at least, more than three.
41 of possible text filters that can be composed. Or at least, more than four.
3742
3843 Each filter is in a seperate Javascript file in the `src/filter` directory
3944 which exports, node-style, a single function called `filter` which takes
4954 `state` is an object whose members may be read or written to store ancillary
5055 state. (Doing so will make it an 'impure' pipeline.)
5156
57 **NOTE**: this interface is likely to change real soon now, to support passing
58 parameters to filters.
59
5260 TODO
5361 ----
5462
55 * Add a shell script wrapper which allows `lexeduct.js` to be run from
56 any directory, via your executable search path.
5763 * Allow filters to take parameters, possibly.
5864 * Allow filters to do something at the very end, maybe.
5965 * Many, many other things.
0 module.exports = {
1 filter: function(line, state) {
2 var s = "";
3 var vowels = "aeiou";
4 for (var i = 0; i < line.length; i++) {
5 s += line.charAt(i) + vowels.charAt(Math.floor(Math.random() * vowels.length));
6 }
7 return s;
8 }
9 };
11
22 var pipe = require('./lib/pipe');
33 var args = process.argv.slice(2);
4 var filters = [];
54
6 // TODO: actually use function composition here
5 var filter = undefined;
6
7 /*
8 * Like mathematical https://en.wikipedia.org/wiki/Function_composition,
9 * except with 'data' parameter also.
10 */
11 var compose = function(g, f) {
12 return function(line, data) {
13 line = f(line, data);
14 return g(line, data);
15 };
16 };
17
718 for (var i = 0; i < args.length; i++) {
819 var module = require('./filter/' + args[i]);
9 filters.push(module.filter);
20 if (filter === undefined) {
21 filter = module.filter;
22 } else {
23 filter = compose(module.filter, filter);
24 }
1025 }
1126
1227 var output = function(line) {
1328 process.stdout.write(line + "\n");
1429 };
1530
16 pipe.line(process.stdin, output, function(line) {
17 for (var i = 0; i < filters.length; i++) {
18 line = filters[i](line);
19 }
20 return line;
21 });
31 pipe.line(process.stdin, output, filter);