diff --git a/0.21.0/docs/index.html b/0.21.0/docs/index.html index 4b8fbf37..3f3b0371 100644 --- a/0.21.0/docs/index.html +++ b/0.21.0/docs/index.html @@ -21,6 +21,11 @@
  • Home
  • Documentation
  • Try Ramda
  • +
  • Cookbook
  • + + + diff --git a/0.21.0/examples/code/apply.function.n.times.json b/0.21.0/examples/code/apply.function.n.times.json new file mode 100644 index 00000000..edc8f868 --- /dev/null +++ b/0.21.0/examples/code/apply.function.n.times.json @@ -0,0 +1 @@ +{"title":"Apply a given function N times","name":"Apply function N times","description":null,"source":"let R = require('ramda');\n\n// applyN :: (a -> a) -> Number -> (a -> a)\nconst applyN = R.compose(R.reduceRight(R.compose, R.identity), R.repeat);\n\napplyN(x => x * x, 4)(2); //=> 65536 (2 -> 4 -> 16 -> 256 -> 65536)\n\nconst isOdd = n => n % 2 == 1;\nconst collatz = n => isOdd(n) ? (3 * n + 1) : (n / 2);\n\napplyN(collatz, 5)(27);\n"} diff --git a/0.21.0/examples/code/convert.list.to.object.json b/0.21.0/examples/code/convert.list.to.object.json new file mode 100644 index 00000000..ae36b6cb --- /dev/null +++ b/0.21.0/examples/code/convert.list.to.object.json @@ -0,0 +1 @@ +{"title":"Convert a list of property-lists (with header) into a list of objects","name":"Convert List to Object","description":null,"source":"let R = require('ramda');\n\nconst tsv = [\n ['name', 'age', 'drink'], \n ['john', 23, 'wine'], \n ['maggie', 45, 'water']\n];\nR.compose(R.apply(R.lift(R.zipObj)), R.splitAt(1))(tsv);\n"} diff --git a/0.21.0/examples/code/convert.object.to.array.json b/0.21.0/examples/code/convert.object.to.array.json new file mode 100644 index 00000000..aa643dec --- /dev/null +++ b/0.21.0/examples/code/convert.object.to.array.json @@ -0,0 +1 @@ +{"title":"Convert object to array","name":"Convert object to array","description":null,"source":"let R = require('ramda');\n\n// convert :: {a} -> [{ word :: String, count :: a }]\nconst convert = R.compose(R.map(R.zipObj(['word', 'count'])), R.toPairs);\n\nconvert({I: 2, it: 4, that: 1});\n"} diff --git a/0.21.0/examples/code/create.list.json b/0.21.0/examples/code/create.list.json new file mode 100644 index 00000000..54bcb949 --- /dev/null +++ b/0.21.0/examples/code/create.list.json @@ -0,0 +1 @@ +{"title":"Create a list","name":"Create a list","description":"This snippet will create a new list with the specified values. Check out https://clojuredocs.org/clojure.core/list.","source":"let R = require('ramda');\n\n// list :: a... -> [a...]\nvar list = R.unapply(R.identity);\nlist(1, 2, 3);\n"} diff --git a/0.21.0/examples/code/diff.objects.json b/0.21.0/examples/code/diff.objects.json new file mode 100644 index 00000000..89e823b4 --- /dev/null +++ b/0.21.0/examples/code/diff.objects.json @@ -0,0 +1 @@ +{"title":"diffing objects","name":"Diff Objects","description":"similar to Guava's Maps Difference","source":"let R = require('ramda');\n\nvar groupObjBy = R.curry(R.pipe(\n // Call groupBy with the object as pairs, passing only the value to the key function\n R.useWith(R.groupBy, [R.useWith(__, [R.last]), R.toPairs]),\n R.map(R.fromPairs)\n))\n\nvar diffObjs = R.pipe(\n R.useWith(R.mergeWith(R.merge), [R.map(R.objOf(\"leftValue\")), R.map(R.objOf(\"rightValue\"))]),\n R.groupObjBy(R.cond([\n [\n R.both(R.has(\"leftValue\"), R.has(\"rightValue\")),\n R.pipe(R.values, R.ifElse(R.apply(equals), R.always(\"common\"), R.always(\"difference\")))\n ],\n [R.has(\"leftValue\"), R.always(\"onlyOnLeft\")],\n [R.has(\"rightValue\"), R.always(\"onlyOnRight\")],\n ])),\n R.evolve({\n common: R.map(R.prop(\"leftValue\")),\n onlyOnLeft: R.map(R.prop(\"leftValue\")),\n onlyOnRight: R.map(R.prop(\"rightValue\"))\n })\n);\n\ndiffObjs({a: 1, c: 5, d: 4 }, {a: 1, b: 2, d: 7});\n"} diff --git a/0.21.0/examples/code/do.any.strings.appear.json b/0.21.0/examples/code/do.any.strings.appear.json new file mode 100644 index 00000000..49fa9571 --- /dev/null +++ b/0.21.0/examples/code/do.any.strings.appear.json @@ -0,0 +1 @@ +{"title":"Do any of these strings appear in another list?","name":"Any Duplicate Strings","description":null,"source":"let R = require('ramda');\n// overlaps :: [a] -> [a] -> Boolean\nconst overlaps = R.pipe(R.intersection, R.complement(R.isEmpty));\nprocess.argv // ['node', 'script.js', '-v']\noverlaps(['-v', '--verbose'], process.argv)\n"} diff --git a/0.21.0/examples/code/filter.using.keys.and.values.json b/0.21.0/examples/code/filter.using.keys.and.values.json new file mode 100644 index 00000000..6657d85c --- /dev/null +++ b/0.21.0/examples/code/filter.using.keys.and.values.json @@ -0,0 +1 @@ +{"title":"Filter an object using keys as well as values","name":"Filter w/ Keys & Vals","description":null,"source":"let R = require('ramda');\n\nconst filterWithKeys = (pred, obj) => R.pipe(\n R.toPairs, \n R.filter(R.apply(pred)), \n R.fromPairs\n)(obj);\n\nfilterWithKeys(\n (key, val) => key.length === val, \n {red: 3, blue: 5, green: 5, yellow: 2}\n);\n"} diff --git a/0.21.0/examples/code/get.object.by.id.json b/0.21.0/examples/code/get.object.by.id.json new file mode 100644 index 00000000..b6a326b3 --- /dev/null +++ b/0.21.0/examples/code/get.object.by.id.json @@ -0,0 +1 @@ +{"title":"Get object by id","name":"Get object by id","description":null,"source":"let R = require('ramda');\n\n// findById :: String -> Array -> Object\nconst findById = R.converge(\n R.find,\n [R.pipe(R.nthArg(0), R.propEq(\"id\")), R.nthArg(1)]\n);\n"} diff --git a/0.21.0/examples/code/get.objects.methods.json b/0.21.0/examples/code/get.objects.methods.json new file mode 100644 index 00000000..cc88e298 --- /dev/null +++ b/0.21.0/examples/code/get.objects.methods.json @@ -0,0 +1 @@ +{"title":"Get an object's method names","name":"Get method names","description":null,"source":"let R = require('ramda');\n\n// methodNames :: Object -> [String]\nvar methodNames = R.compose(R.keys, R.pickBy(R.is(Function)));\n\nvar obj = {\n foo: true,\n bar: function() {},\n baz: function() {},\n};\n\nmethodNames(obj);\n"} diff --git a/0.21.0/examples/code/increment.with.step.json b/0.21.0/examples/code/increment.with.step.json new file mode 100644 index 00000000..de519692 --- /dev/null +++ b/0.21.0/examples/code/increment.with.step.json @@ -0,0 +1 @@ +{"title":"Create an incrementing or decrementing range of numbers with a step","name":"Increment with step","description":null,"source":"let R = require('ramda');\n\nconst rangeStep = (start, step, stop) => R.map(\n n => start + step * n,\n R.range(0, (1 + (stop - start) / step) >>> 0)\n);\n\nconsole.log(rangeStep(1, 1, 4)); // [1, 2, 3, 4]\nconsole.log(rangeStep(2, 2, 8)); // [2, 4, 6, 8]\nconsole.log(rangeStep(0, 3, 10)); // [0, 3, 6, 9]\nconsole.log(rangeStep(3, -2, -3)); // [3, 1, -1, -3]\n"} diff --git a/0.21.0/examples/code/make.objects.out.of.keys.json b/0.21.0/examples/code/make.objects.out.of.keys.json new file mode 100644 index 00000000..331475a2 --- /dev/null +++ b/0.21.0/examples/code/make.objects.out.of.keys.json @@ -0,0 +1 @@ +{"title":"Make an object out of keys, with values derived from them","name":"Make object from keys","description":null,"source":"let R = require('ramda');\nlet fs = require('fs');\n\n// objFromKeys :: (String -> a) -> [String] -> {String: a}\nconst objFromKeys = R.curry((fn, keys) =>\n R.zipObj(keys, R.map(fn, keys)));\nconst files = ['diary.txt', 'shopping.txt'];\nobjFromKeys(fs.readFileSync, files);\n"} diff --git a/0.21.0/examples/code/map.keys.of.object.json b/0.21.0/examples/code/map.keys.of.object.json new file mode 100644 index 00000000..528cb1a6 --- /dev/null +++ b/0.21.0/examples/code/map.keys.of.object.json @@ -0,0 +1 @@ +{"title":"Map keys of an object","description":null,"source":"let R = require('ramda');\n\n// mapKeys :: (String -> String) -> Object -> Object\nconst mapKeys = R.curry((fn, obj) =>\n R.fromPairs(R.map(R.adjust(fn, 0), R.toPairs(obj))));\nmapKeys(R.toUpper, { a: 1, b: 2, c: 3 });\n"} diff --git a/0.21.0/examples/code/map.keys.to.objects.json b/0.21.0/examples/code/map.keys.to.objects.json new file mode 100644 index 00000000..cb55a10b --- /dev/null +++ b/0.21.0/examples/code/map.keys.to.objects.json @@ -0,0 +1 @@ +{"title":"Map Keys To Objects","name":"Map keys to objects","description":null,"source":"let R = require('ramda');\n\nconst mapKeys = R.curry((fn, obj) =>\n R.fromPairs(R.map(R.adjust(fn, 0), R.toPairs(obj))));\n mapKeys(R.toUpper, { a: 1, b: 2, c: 3 });\n"} diff --git a/0.21.0/examples/code/map.value.at.end.of.path.json b/0.21.0/examples/code/map.value.at.end.of.path.json new file mode 100644 index 00000000..d84b42b1 --- /dev/null +++ b/0.21.0/examples/code/map.value.at.end.of.path.json @@ -0,0 +1 @@ +{"title":"Map over the value at the end of a path","name":"Map val at end of path","description":null,"source":"let R = require('ramda');\n\n// :: [String] -> (a -> b) -> {k: a} -> {k: b}\nconst mapPath = R.curry((path, f, obj) =>\n R.assocPath(path, f(R.path(path, obj)), obj)\n);\n\nmapPath(['a', 'b', 'c'], R.inc, {a: {b: {c: 3}}});\n"} diff --git a/0.21.0/examples/code/mess.with.dom.json b/0.21.0/examples/code/mess.with.dom.json new file mode 100644 index 00000000..0b6e7c9c --- /dev/null +++ b/0.21.0/examples/code/mess.with.dom.json @@ -0,0 +1 @@ +{"title":"Mess with the DOM","name":"Mess with DOM","description":"This example shows how to set styles so that all paragraphs are red.","source":"let R = require('ramda');\n\n// Get all descendants that match selector\n// Note: NodeList is array-like so you can run ramda list functions on it.\n// cssQuery :: String -> Node -> NodeList\nvar cssQuery = R.invoker(1, 'querySelectorAll');\n\n// Mutate style properties on an element\n// setStyle :: String -> String -> Element -> Element\nvar setStyle = R.assoc('style');\n\n// Make all paragraphs and anchors red\nR.pipe(\n cssQuery('a, p'),\n R.map(setStyle('color', 'red'))\n)(document)\n"} diff --git a/0.21.0/examples/code/n.function.calls.json b/0.21.0/examples/code/n.function.calls.json new file mode 100644 index 00000000..300e769a --- /dev/null +++ b/0.21.0/examples/code/n.function.calls.json @@ -0,0 +1 @@ +{"title":"Get n function calls as a list","name":"Get n function calls","description":null,"source":"let R = require('ramda');\n\nR.map(R.call, R.repeat(Math.random, 5));\n"} diff --git a/0.21.0/examples/code/object.size.json b/0.21.0/examples/code/object.size.json new file mode 100644 index 00000000..8f659aa1 --- /dev/null +++ b/0.21.0/examples/code/object.size.json @@ -0,0 +1 @@ +{"title":"Get Object Size","name":"Object Size","description":null,"source":"let R = require('ramda');\n\n// objSize :: Object -> Number\nconst objSize = R.nAry(1, R.pipe(\n R.when(R.is(Object), R.keys),\n R.when(R.is(Boolean), R.cond([[R.equals(false), R.always(null)], [R.T, R.always(1)]])),\n R.when(R.is(Number), R.toString),\n R.ifElse(R.isNil, R.always(0), R.length)\n));\nconsole.log(objSize()); // 0\nconsole.log(objSize(undefined)); // 0\nconsole.log(objSize(null)); // 0\nconsole.log(objSize(false)); // 0\nconsole.log(objSize(true)); // 1\nconsole.log(objSize('')); // 0\nconsole.log(objSize('foo')); // 3\nconsole.log(objSize(0)); // 1\nconsole.log(objSize(13)); // 2\nconsole.log(objSize(101)); // 3\nconsole.log(objSize(0.01)); // 4\nconsole.log(objSize({})); // 0\nconsole.log(objSize({foo:undefined, bar:undefined})); // 2\nconsole.log(objSize([])); // 0\nconsole.log(objSize([undefined, undefined])); // 2\n"} diff --git a/0.21.0/examples/code/pick-list.json b/0.21.0/examples/code/pick-list.json new file mode 100644 index 00000000..217f93b4 --- /dev/null +++ b/0.21.0/examples/code/pick-list.json @@ -0,0 +1 @@ +{"title":"Pick List Values by Index","name":"Pick List by Index","description":"This example shows you how to specify multiple indexes of an array to retrieve multiple values from the array.","source":"let R = require('ramda');\n\n// :: [Number] -> [a] -> [a]\nvar pickIndexes = R.compose(R.values, R.pickAll);\npickIndexes([0, 2], ['a', 'b', 'c']);\n"} diff --git a/0.21.0/examples/code/r.props.deep.fields.json b/0.21.0/examples/code/r.props.deep.fields.json new file mode 100644 index 00000000..d605c27a --- /dev/null +++ b/0.21.0/examples/code/r.props.deep.fields.json @@ -0,0 +1 @@ +{"title":"Derivative of R.props for deep fields","name":"R.props for deep fields","description":null,"source":"let R = require('ramda');\n\nvar dotPath = R.useWith(R.path, R.split('.'));\nvar propsDotPath = R.useWith(R.ap, R.map(dotPath), R.of);\nvar obj = {\n a: { b: { c: 1 } },\n x: 2\n};\n\npropsDotPath(['a.b.c', 'x'], obj);\n"} diff --git a/0.21.0/examples/code/ramda.fantasy.ajax.json b/0.21.0/examples/code/ramda.fantasy.ajax.json new file mode 100644 index 00000000..37068fc1 --- /dev/null +++ b/0.21.0/examples/code/ramda.fantasy.ajax.json @@ -0,0 +1 @@ +{"title":"Use ramda-fantasy Future to wrap AJAX","name":"ramda-fantasy wrap AJAX","description":null,"source":"var Future = require('ramda-fantasy').Future;\n// Wrap ajax in a future\n// fetch :: String -> Future String\nvar fetch = function(url) {\n return new Future(function(rej, res) {\n var oReq = new XMLHttpRequest();\n oReq.addEventListener('load', res, false);\n oReq.addEventListener('error', rej, false);\n oReq.addEventListener('abort', rej, false);\n oReq.open('get', url, true);\n oReq.send();\n });\n};\n\n// Could use Either instead of Future but they work about the same.\n// parseJSON :: String -> Future Object\nvar parseJSON = function(str) {\n return new Future(function(rej, res) {\n try {\n res(JSON.parse(str));\n } catch (err) {\n rej({ error: 'json parse error' });\n }\n });\n};\n\n// We have\n// String -> Future String\n// And\n// String -> Future Object\n// So we can .chain() them together\nvar fetchJSON = fetch.chain(parseJSON);\n\n// Get the items out of it?\n// fetchItems :: Future Object -> Future []\nvar fetchItems = fetchJSON.map(R.prop('items'));\n\n// BTW at this point in the code the request still hasn't been sent\n\n// Filter the response?\n// Have to map first to get at the contents of the future then filter\n// fetchNewItems :: Future [Object] -> Future [Object]\nvar fetchNewItems = fetchItems.map(R.filter(R.prop('new')));\n\n// Just get the titles of the items\n// getNewTitles :: Future [Object] -> Future [String]\nvar getNewTitles = fetchNewItems.map(R.map('title'));\n\n// Finally do something\ngetNewTitles('/products.json').fork(console.error, console.log);\n// Now the AJAX req is sent and will log success or failure to console.\n\n// Bonus: Make one ajax request dependent on another\nfetchDependent = fetchJSON.map(R.prop('url')).chain(fetch);\nfetchDependent('urls.json').fork(console.error, console.log);\n"} diff --git a/0.21.0/examples/code/rename.keys.of.object.json b/0.21.0/examples/code/rename.keys.of.object.json new file mode 100644 index 00000000..7a986132 --- /dev/null +++ b/0.21.0/examples/code/rename.keys.of.object.json @@ -0,0 +1 @@ +{"title":"Rename keys of an object","name":"Rename keys","description":null,"source":"let R = require('ramda');\n\n/**\n* Creates a new object with the own properties of the provided object, but the\n* keys renamed according to the keysMap object as `{oldKey: newKey}`.\n* When some key is not found in the keysMap, then it's passed as-is.\n*\n* Keep in mind that in the case of keys conflict is behaviour undefined and\n* the result may vary between various JS engines!\n*\n* @sig {a: b} -> {a: *} -> {b: *}\n*/\nconst renameKeys = R.curry((keysMap, obj) => {\n return R.reduce((acc, key) => {\n acc[keysMap[key] || key] = obj[key];\n return acc;\n }, {}, R.keys(obj));\n});\n\nconst input = { firstName: 'Elisia', age: 22, type: 'human' }\n\nrenameKeys({ firstName: 'name', type: 'kind', foo: 'bar' })(input)\n"} diff --git a/0.21.0/examples/code/set.properties.if.dont.exist.json b/0.21.0/examples/code/set.properties.if.dont.exist.json new file mode 100644 index 00000000..217d0d2f --- /dev/null +++ b/0.21.0/examples/code/set.properties.if.dont.exist.json @@ -0,0 +1 @@ +{"title":"Set properties only if they don't exist","name":"Set non-existent properties","description":"Useful for passing defaults, similar to lodash's _.defaults.","source":"let R = require('ramda');\n\n// defaults :: Object -> Object -> Object\nvar defaults = R.flip(R.merge);\n\n// process.env.SECRET overwrites deadbeef if it exists\ndefaults(process.env, {\n SECRET: 'deadbeef'\n});\n"} diff --git a/0.21.0/examples/code/specific.order.json b/0.21.0/examples/code/specific.order.json new file mode 100644 index 00000000..c38fb0cd --- /dev/null +++ b/0.21.0/examples/code/specific.order.json @@ -0,0 +1 @@ +{"title":"Apply a list of functions in a specific order into a list of values","name":"Functions in order","description":null,"source":"let R = require('ramda');\n\nconst {red, green, blue} = require('chalk');\nconst disco = R.pipe(R.zipWith(R.call, [ red, green, blue ]), R.join(' '));\nconsole.log(disco([ 'foo', 'bar', 'xyz' ]));\n"} diff --git a/0.21.0/examples/index.html b/0.21.0/examples/index.html new file mode 100644 index 00000000..970f16f1 --- /dev/null +++ b/0.21.0/examples/index.html @@ -0,0 +1,97 @@ + + + + + + Ramda Cookbook + + + + + + + + +
    +

    Cookbook

    +
    +
    +
    + + + + + \ No newline at end of file diff --git a/0.21.0/index.html b/0.21.0/index.html index a63744dc..ae7ef6ed 100644 --- a/0.21.0/index.html +++ b/0.21.0/index.html @@ -21,6 +21,11 @@
  • Home
  • Documentation
  • Try Ramda
  • +
  • Cookbook
  • + + + diff --git a/0.21.0/style.css b/0.21.0/style.css index 0fb6eabc..e95a343f 100644 --- a/0.21.0/style.css +++ b/0.21.0/style.css @@ -6741,6 +6741,9 @@ header { display: none; } } +.padded { + padding: 5px; +} /** * Home */ @@ -6876,6 +6879,9 @@ html.docs-page #open-nav:checked ~ main { border-right: 1px solid #ccc; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; } +.sidebar.no-filter { + padding-top: 20px; +} .sidebar .filter { width: 100%; margin: 15px 0; @@ -6895,6 +6901,10 @@ html.docs-page #open-nav:checked ~ main { .sidebar .toc li { margin: 0; } +.sidebar .toc li.active { + background-color: #849; + color: white; +} .sidebar .toc a { padding: 5px 15px; border-radius: 0; diff --git a/Makefile b/Makefile index ca363f95..3323d938 100644 --- a/Makefile +++ b/Makefile @@ -1,16 +1,19 @@ GITBOOK = node_modules/.bin/gitbook JSDOC = node_modules/.bin/jsdoc LESS = node_modules/.bin/lessc +YAML = node_modules/.bin/yaml2json JSDOC_FILES := $(shell find jsdoc -type f | sort) LESS_FILES := $(shell find less -name '*.less' | sort) - +EXAMPLE_FILES := $(shell find examples -name '*.json' | sort) +YAML_FILES := $(shell find examples -name '*.yaml' | sort) .PHONY: all all: \ check-version \ $(VERSION)/tmp/README.md \ $(VERSION)/tmp/package.json \ + yaml \ $(VERSION)/docs/dist/ramda.js \ $(VERSION)/docs/index.html \ $(VERSION)/docs/main.js \ @@ -21,12 +24,20 @@ all: \ $(VERSION)/fonts/glyphicons-halflings-regular.woff \ $(VERSION)/fonts/glyphicons-halflings-regular.woff2 \ $(VERSION)/style.css \ + $(VERSION)/examples/index.html \ gitbook \ docs/dist/ramda.js \ docs/index.html \ docs/main.js \ index.html \ style.css \ + examples/index.html \ + +.PHONY: clean +clean: $(VERSION)/clean + +$(VERSION)/clean: + rm -r $(VERSION)/* $(VERSION)/tmp/%: mkdir -p '$(@D)' @@ -36,7 +47,7 @@ $(VERSION)/docs/dist/ramda.js: mkdir -p '$(@D)' curl --silent 'https://raw.githubusercontent.com/ramda/ramda/v$(VERSION)/dist/ramda.js' >'$@' -$(VERSION)/docs/index.html $(VERSION)/index.html: $(JSDOC_FILES) +$(VERSION)/docs/index.html $(VERSION)/index.html $(VERSION)/examples/index.html: $(JSDOC_FILES) VERSION='$(VERSION)' $(JSDOC) \ --destination '$(VERSION)' \ --template '$( $(VERSION)/$${file%yaml}json; \ + done + .PHONY: index.html index.html: check-version echo '' >'$@' diff --git a/README.md b/README.md index 2a14ffbf..4676d31f 100644 --- a/README.md +++ b/README.md @@ -13,3 +13,30 @@ $ VERSION=X.Y.Z make npm run server Then visit [localhost:8080](http://localhost:8080/) to view the docs. + + +## Cookbook + +To add an example to the cookbook, simply add a `yaml` file in the `examples/code` folder, run `make` and issue a PR. + +Here's an example yaml file: + +```yaml +title: Pick List Values by Index +name: Pick List by Index +description: "This example shows you how to specify multiple indexes of an array to retrieve multiple values from the array." +source: | + let R = require('ramda'); + + // :: [Number] -> [a] -> [a] + var pickIndexes = R.compose(R.values, R.pickAll); + pickIndexes([0, 2], ['a', 'b', 'c']); +``` + +**title** will be displayed on the page when the example is selected. + +**name** will be the text displayed in the left-hand menu. + +**description** is optional and will be displayed below the title if it is supplied. + +**source** is the code for the cookbook. In order for it to run in `Tonic`, please require all libraries used, including Ramda. \ No newline at end of file diff --git a/docs/index.html b/docs/index.html index 4b8fbf37..3f3b0371 100644 --- a/docs/index.html +++ b/docs/index.html @@ -21,6 +21,11 @@
  • Home
  • Documentation
  • Try Ramda
  • +
  • Cookbook
  • + + + diff --git a/docs/index.html.handlebars b/docs/index.html.handlebars index 949a0f62..ea219265 100644 --- a/docs/index.html.handlebars +++ b/docs/index.html.handlebars @@ -21,6 +21,11 @@
  • Home
  • Documentation
  • Try Ramda
  • +
  • Cookbook
  • + + + diff --git a/examples/Index.html b/examples/Index.html new file mode 100644 index 00000000..970f16f1 --- /dev/null +++ b/examples/Index.html @@ -0,0 +1,97 @@ + + + + + + Ramda Cookbook + + + + + + + + +
    +

    Cookbook

    +
    +
    +
    + + + + + \ No newline at end of file diff --git a/examples/Index.html.handlebars b/examples/Index.html.handlebars new file mode 100644 index 00000000..9933db2a --- /dev/null +++ b/examples/Index.html.handlebars @@ -0,0 +1,77 @@ + + + + + + Ramda Cookbook + + + + + + + + +
    +

    Cookbook

    +
    +
    +
    + + + + + \ No newline at end of file diff --git a/examples/code/apply.function.n.times.yaml b/examples/code/apply.function.n.times.yaml new file mode 100644 index 00000000..88754420 --- /dev/null +++ b/examples/code/apply.function.n.times.yaml @@ -0,0 +1,15 @@ +title: Apply a given function N times +name: Apply function N times +description: +source: | + let R = require('ramda'); + + // applyN :: (a -> a) -> Number -> (a -> a) + const applyN = R.compose(R.reduceRight(R.compose, R.identity), R.repeat); + + applyN(x => x * x, 4)(2); //=> 65536 (2 -> 4 -> 16 -> 256 -> 65536) + + const isOdd = n => n % 2 == 1; + const collatz = n => isOdd(n) ? (3 * n + 1) : (n / 2); + + applyN(collatz, 5)(27); \ No newline at end of file diff --git a/examples/code/convert.list.to.object.yaml b/examples/code/convert.list.to.object.yaml new file mode 100644 index 00000000..9a162034 --- /dev/null +++ b/examples/code/convert.list.to.object.yaml @@ -0,0 +1,12 @@ +title: Convert a list of property-lists (with header) into a list of objects +name: Convert List to Object +description: +source: | + let R = require('ramda'); + + const tsv = [ + ['name', 'age', 'drink'], + ['john', 23, 'wine'], + ['maggie', 45, 'water'] + ]; + R.compose(R.apply(R.lift(R.zipObj)), R.splitAt(1))(tsv); \ No newline at end of file diff --git a/examples/code/convert.object.to.array.yaml b/examples/code/convert.object.to.array.yaml new file mode 100644 index 00000000..eb560af6 --- /dev/null +++ b/examples/code/convert.object.to.array.yaml @@ -0,0 +1,11 @@ +title: Convert object to array +name: Convert object to array +description: +source: | + let R = require('ramda'); + + // convert :: {a} -> [{ word :: String, count :: a }] + const convert = R.compose(R.map(R.zipObj(['word', 'count'])), R.toPairs); + + convert({I: 2, it: 4, that: 1}); + \ No newline at end of file diff --git a/examples/code/create.list.yaml b/examples/code/create.list.yaml new file mode 100644 index 00000000..2e9fd25f --- /dev/null +++ b/examples/code/create.list.yaml @@ -0,0 +1,9 @@ +title: Create a list +name: Create a list +description: This snippet will create a new list with the specified values. Check out https://clojuredocs.org/clojure.core/list. +source: | + let R = require('ramda'); + + // list :: a... -> [a...] + var list = R.unapply(R.identity); + list(1, 2, 3); diff --git a/examples/code/diff.objects.yaml b/examples/code/diff.objects.yaml new file mode 100644 index 00000000..88f98293 --- /dev/null +++ b/examples/code/diff.objects.yaml @@ -0,0 +1,30 @@ +title: diffing objects +name: Diff Objects +description: similar to Guava's Maps Difference +source: | + let R = require('ramda'); + + var groupObjBy = R.curry(R.pipe( + // Call groupBy with the object as pairs, passing only the value to the key function + R.useWith(R.groupBy, [R.useWith(__, [R.last]), R.toPairs]), + R.map(R.fromPairs) + )) + + var diffObjs = R.pipe( + R.useWith(R.mergeWith(R.merge), [R.map(R.objOf("leftValue")), R.map(R.objOf("rightValue"))]), + R.groupObjBy(R.cond([ + [ + R.both(R.has("leftValue"), R.has("rightValue")), + R.pipe(R.values, R.ifElse(R.apply(equals), R.always("common"), R.always("difference"))) + ], + [R.has("leftValue"), R.always("onlyOnLeft")], + [R.has("rightValue"), R.always("onlyOnRight")], + ])), + R.evolve({ + common: R.map(R.prop("leftValue")), + onlyOnLeft: R.map(R.prop("leftValue")), + onlyOnRight: R.map(R.prop("rightValue")) + }) + ); + + diffObjs({a: 1, c: 5, d: 4 }, {a: 1, b: 2, d: 7}); diff --git a/examples/code/do.any.strings.appear.yaml b/examples/code/do.any.strings.appear.yaml new file mode 100644 index 00000000..89fa0a03 --- /dev/null +++ b/examples/code/do.any.strings.appear.yaml @@ -0,0 +1,10 @@ +title: Do any of these strings appear in another list? +name: Any Duplicate Strings +description: +source: | + let R = require('ramda'); + // overlaps :: [a] -> [a] -> Boolean + const overlaps = R.pipe(R.intersection, R.complement(R.isEmpty)); + process.argv // ['node', 'script.js', '-v'] + overlaps(['-v', '--verbose'], process.argv) + \ No newline at end of file diff --git a/examples/code/filter.using.keys.and.values.yaml b/examples/code/filter.using.keys.and.values.yaml new file mode 100644 index 00000000..194f61b3 --- /dev/null +++ b/examples/code/filter.using.keys.and.values.yaml @@ -0,0 +1,16 @@ +title: Filter an object using keys as well as values +name: "Filter w/ Keys & Vals" +description: +source: | + let R = require('ramda'); + + const filterWithKeys = (pred, obj) => R.pipe( + R.toPairs, + R.filter(R.apply(pred)), + R.fromPairs + )(obj); + + filterWithKeys( + (key, val) => key.length === val, + {red: 3, blue: 5, green: 5, yellow: 2} + ); \ No newline at end of file diff --git a/examples/code/get.object.by.id.yaml b/examples/code/get.object.by.id.yaml new file mode 100644 index 00000000..c9a8e272 --- /dev/null +++ b/examples/code/get.object.by.id.yaml @@ -0,0 +1,12 @@ +title: Get object by id +name: Get object by id +description: +source: | + let R = require('ramda'); + + // findById :: String -> Array -> Object + const findById = R.converge( + R.find, + [R.pipe(R.nthArg(0), R.propEq("id")), R.nthArg(1)] + ); + \ No newline at end of file diff --git a/examples/code/get.objects.methods.yaml b/examples/code/get.objects.methods.yaml new file mode 100644 index 00000000..ae1b9d33 --- /dev/null +++ b/examples/code/get.objects.methods.yaml @@ -0,0 +1,16 @@ +title: Get an object's method names +name: Get method names +description: +source: | + let R = require('ramda'); + + // methodNames :: Object -> [String] + var methodNames = R.compose(R.keys, R.pickBy(R.is(Function))); + + var obj = { + foo: true, + bar: function() {}, + baz: function() {}, + }; + + methodNames(obj); \ No newline at end of file diff --git a/examples/code/increment.with.step.yaml b/examples/code/increment.with.step.yaml new file mode 100644 index 00000000..aace7699 --- /dev/null +++ b/examples/code/increment.with.step.yaml @@ -0,0 +1,16 @@ +title: Create an incrementing or decrementing range of numbers with a step +name: Increment with step +description: +source: | + let R = require('ramda'); + + const rangeStep = (start, step, stop) => R.map( + n => start + step * n, + R.range(0, (1 + (stop - start) / step) >>> 0) + ); + + console.log(rangeStep(1, 1, 4)); // [1, 2, 3, 4] + console.log(rangeStep(2, 2, 8)); // [2, 4, 6, 8] + console.log(rangeStep(0, 3, 10)); // [0, 3, 6, 9] + console.log(rangeStep(3, -2, -3)); // [3, 1, -1, -3] + \ No newline at end of file diff --git a/examples/code/make.objects.out.of.keys.yaml b/examples/code/make.objects.out.of.keys.yaml new file mode 100644 index 00000000..e9a50ba0 --- /dev/null +++ b/examples/code/make.objects.out.of.keys.yaml @@ -0,0 +1,13 @@ +title: "Make an object out of keys, with values derived from them" +name: Make object from keys +description: +source: | + let R = require('ramda'); + let fs = require('fs'); + + // objFromKeys :: (String -> a) -> [String] -> {String: a} + const objFromKeys = R.curry((fn, keys) => + R.zipObj(keys, R.map(fn, keys))); + const files = ['diary.txt', 'shopping.txt']; + objFromKeys(fs.readFileSync, files); + \ No newline at end of file diff --git a/examples/code/map.keys.of.object.yaml b/examples/code/map.keys.of.object.yaml new file mode 100644 index 00000000..07457707 --- /dev/null +++ b/examples/code/map.keys.of.object.yaml @@ -0,0 +1,10 @@ +title: "Map keys of an object" +description: +source: | + let R = require('ramda'); + + // mapKeys :: (String -> String) -> Object -> Object + const mapKeys = R.curry((fn, obj) => + R.fromPairs(R.map(R.adjust(fn, 0), R.toPairs(obj)))); + mapKeys(R.toUpper, { a: 1, b: 2, c: 3 }); + \ No newline at end of file diff --git a/examples/code/map.keys.to.objects.yaml b/examples/code/map.keys.to.objects.yaml new file mode 100644 index 00000000..7759116f --- /dev/null +++ b/examples/code/map.keys.to.objects.yaml @@ -0,0 +1,9 @@ +title: Map Keys To Objects +name: Map keys to objects +description: +source: | + let R = require('ramda'); + + const mapKeys = R.curry((fn, obj) => + R.fromPairs(R.map(R.adjust(fn, 0), R.toPairs(obj)))); + mapKeys(R.toUpper, { a: 1, b: 2, c: 3 }); \ No newline at end of file diff --git a/examples/code/map.value.at.end.of.path.yaml b/examples/code/map.value.at.end.of.path.yaml new file mode 100644 index 00000000..270527f5 --- /dev/null +++ b/examples/code/map.value.at.end.of.path.yaml @@ -0,0 +1,13 @@ +title: Map over the value at the end of a path +name: Map val at end of path +description: +source: | + let R = require('ramda'); + + // :: [String] -> (a -> b) -> {k: a} -> {k: b} + const mapPath = R.curry((path, f, obj) => + R.assocPath(path, f(R.path(path, obj)), obj) + ); + + mapPath(['a', 'b', 'c'], R.inc, {a: {b: {c: 3}}}); + \ No newline at end of file diff --git a/examples/code/mess.with.dom.yaml b/examples/code/mess.with.dom.yaml new file mode 100644 index 00000000..d1ba56f9 --- /dev/null +++ b/examples/code/mess.with.dom.yaml @@ -0,0 +1,20 @@ +title: Mess with the DOM +name: Mess with DOM +description: This example shows how to set styles so that all paragraphs are red. +source: | + let R = require('ramda'); + + // Get all descendants that match selector + // Note: NodeList is array-like so you can run ramda list functions on it. + // cssQuery :: String -> Node -> NodeList + var cssQuery = R.invoker(1, 'querySelectorAll'); + + // Mutate style properties on an element + // setStyle :: String -> String -> Element -> Element + var setStyle = R.assoc('style'); + + // Make all paragraphs and anchors red + R.pipe( + cssQuery('a, p'), + R.map(setStyle('color', 'red')) + )(document) diff --git a/examples/code/n.function.calls.yaml b/examples/code/n.function.calls.yaml new file mode 100644 index 00000000..33184c3f --- /dev/null +++ b/examples/code/n.function.calls.yaml @@ -0,0 +1,7 @@ +title: Get n function calls as a list +name: Get n function calls +description: +source: | + let R = require('ramda'); + + R.map(R.call, R.repeat(Math.random, 5)); \ No newline at end of file diff --git a/examples/code/object.size.yaml b/examples/code/object.size.yaml new file mode 100644 index 00000000..e575172f --- /dev/null +++ b/examples/code/object.size.yaml @@ -0,0 +1,29 @@ +title: Get Object Size +name: Object Size +description: +source: | + let R = require('ramda'); + + // objSize :: Object -> Number + const objSize = R.nAry(1, R.pipe( + R.when(R.is(Object), R.keys), + R.when(R.is(Boolean), R.cond([[R.equals(false), R.always(null)], [R.T, R.always(1)]])), + R.when(R.is(Number), R.toString), + R.ifElse(R.isNil, R.always(0), R.length) + )); + console.log(objSize()); // 0 + console.log(objSize(undefined)); // 0 + console.log(objSize(null)); // 0 + console.log(objSize(false)); // 0 + console.log(objSize(true)); // 1 + console.log(objSize('')); // 0 + console.log(objSize('foo')); // 3 + console.log(objSize(0)); // 1 + console.log(objSize(13)); // 2 + console.log(objSize(101)); // 3 + console.log(objSize(0.01)); // 4 + console.log(objSize({})); // 0 + console.log(objSize({foo:undefined, bar:undefined})); // 2 + console.log(objSize([])); // 0 + console.log(objSize([undefined, undefined])); // 2 + \ No newline at end of file diff --git a/examples/code/pick-list.yaml b/examples/code/pick-list.yaml new file mode 100644 index 00000000..683280e0 --- /dev/null +++ b/examples/code/pick-list.yaml @@ -0,0 +1,9 @@ +title: Pick List Values by Index +name: Pick List by Index +description: "This example shows you how to specify multiple indexes of an array to retrieve multiple values from the array." +source: | + let R = require('ramda'); + + // :: [Number] -> [a] -> [a] + var pickIndexes = R.compose(R.values, R.pickAll); + pickIndexes([0, 2], ['a', 'b', 'c']); \ No newline at end of file diff --git a/examples/code/r.props.deep.fields.yaml b/examples/code/r.props.deep.fields.yaml new file mode 100644 index 00000000..fcbaf75c --- /dev/null +++ b/examples/code/r.props.deep.fields.yaml @@ -0,0 +1,14 @@ +title: Derivative of R.props for deep fields +name: R.props for deep fields +description: +source: | + let R = require('ramda'); + + var dotPath = R.useWith(R.path, R.split('.')); + var propsDotPath = R.useWith(R.ap, R.map(dotPath), R.of); + var obj = { + a: { b: { c: 1 } }, + x: 2 + }; + + propsDotPath(['a.b.c', 'x'], obj); \ No newline at end of file diff --git a/examples/code/ramda.fantasy.ajax.yaml b/examples/code/ramda.fantasy.ajax.yaml new file mode 100644 index 00000000..5dae3d5d --- /dev/null +++ b/examples/code/ramda.fantasy.ajax.yaml @@ -0,0 +1,59 @@ +title: Use ramda-fantasy Future to wrap AJAX +name: ramda-fantasy wrap AJAX +description: +source: | + var Future = require('ramda-fantasy').Future; + // Wrap ajax in a future + // fetch :: String -> Future String + var fetch = function(url) { + return new Future(function(rej, res) { + var oReq = new XMLHttpRequest(); + oReq.addEventListener('load', res, false); + oReq.addEventListener('error', rej, false); + oReq.addEventListener('abort', rej, false); + oReq.open('get', url, true); + oReq.send(); + }); + }; + + // Could use Either instead of Future but they work about the same. + // parseJSON :: String -> Future Object + var parseJSON = function(str) { + return new Future(function(rej, res) { + try { + res(JSON.parse(str)); + } catch (err) { + rej({ error: 'json parse error' }); + } + }); + }; + + // We have + // String -> Future String + // And + // String -> Future Object + // So we can .chain() them together + var fetchJSON = fetch.chain(parseJSON); + + // Get the items out of it? + // fetchItems :: Future Object -> Future [] + var fetchItems = fetchJSON.map(R.prop('items')); + + // BTW at this point in the code the request still hasn't been sent + + // Filter the response? + // Have to map first to get at the contents of the future then filter + // fetchNewItems :: Future [Object] -> Future [Object] + var fetchNewItems = fetchItems.map(R.filter(R.prop('new'))); + + // Just get the titles of the items + // getNewTitles :: Future [Object] -> Future [String] + var getNewTitles = fetchNewItems.map(R.map('title')); + + // Finally do something + getNewTitles('/products.json').fork(console.error, console.log); + // Now the AJAX req is sent and will log success or failure to console. + + // Bonus: Make one ajax request dependent on another + fetchDependent = fetchJSON.map(R.prop('url')).chain(fetch); + fetchDependent('urls.json').fork(console.error, console.log); \ No newline at end of file diff --git a/examples/code/rename.keys.of.object.yaml b/examples/code/rename.keys.of.object.yaml new file mode 100644 index 00000000..f68f72dc --- /dev/null +++ b/examples/code/rename.keys.of.object.yaml @@ -0,0 +1,26 @@ +title: Rename keys of an object +name: Rename keys +description: +source: | + let R = require('ramda'); + + /** + * Creates a new object with the own properties of the provided object, but the + * keys renamed according to the keysMap object as `{oldKey: newKey}`. + * When some key is not found in the keysMap, then it's passed as-is. + * + * Keep in mind that in the case of keys conflict is behaviour undefined and + * the result may vary between various JS engines! + * + * @sig {a: b} -> {a: *} -> {b: *} + */ + const renameKeys = R.curry((keysMap, obj) => { + return R.reduce((acc, key) => { + acc[keysMap[key] || key] = obj[key]; + return acc; + }, {}, R.keys(obj)); + }); + + const input = { firstName: 'Elisia', age: 22, type: 'human' } + + renameKeys({ firstName: 'name', type: 'kind', foo: 'bar' })(input) \ No newline at end of file diff --git a/examples/code/set.properties.if.dont.exist.yaml b/examples/code/set.properties.if.dont.exist.yaml new file mode 100644 index 00000000..db9e8bc9 --- /dev/null +++ b/examples/code/set.properties.if.dont.exist.yaml @@ -0,0 +1,13 @@ +title: Set properties only if they don't exist +name: Set non-existent properties +description: "Useful for passing defaults, similar to lodash's _.defaults." +source: | + let R = require('ramda'); + + // defaults :: Object -> Object -> Object + var defaults = R.flip(R.merge); + + // process.env.SECRET overwrites deadbeef if it exists + defaults(process.env, { + SECRET: 'deadbeef' + }); \ No newline at end of file diff --git a/examples/code/specific.order.yaml b/examples/code/specific.order.yaml new file mode 100644 index 00000000..9b6e18b9 --- /dev/null +++ b/examples/code/specific.order.yaml @@ -0,0 +1,9 @@ +title: Apply a list of functions in a specific order into a list of values +name: Functions in order +description: +source: | + let R = require('ramda'); + + const {red, green, blue} = require('chalk'); + const disco = R.pipe(R.zipWith(R.call, [ red, green, blue ]), R.join(' ')); + console.log(disco([ 'foo', 'bar', 'xyz' ])); \ No newline at end of file diff --git a/jsdoc/publish.js b/jsdoc/publish.js index f649d391..a65967de 100644 --- a/jsdoc/publish.js +++ b/jsdoc/publish.js @@ -6,6 +6,7 @@ var hljs = require('highlight.js'); var helper = require('jsdoc/util/templateHelper'); var marked = require('marked'); +var requireDir = require('require-dir-all'); if (!Object.prototype.hasOwnProperty.call(process.env, 'VERSION')) { throw new Error('No environment variable named "VERSION"'); @@ -13,11 +14,11 @@ if (!Object.prototype.hasOwnProperty.call(process.env, 'VERSION')) { var VERSION = process.env.VERSION; -var headOr = function(x, xs) { +var headOr = function (x, xs) { return xs.length === 0 ? x : xs[0]; }; -var chain = function(f, xs) { +var chain = function (f, xs) { var result = []; for (var idx = 0; idx < xs.length; idx += 1) { result = result.concat(f(xs[idx])); @@ -25,7 +26,7 @@ var chain = function(f, xs) { return result; }; -var valuesForTitle = function(title, xs) { +var valuesForTitle = function (title, xs) { var result = []; for (var idx = 0; idx < xs.length; idx += 1) { if (xs[idx].title === title) { @@ -35,36 +36,36 @@ var valuesForTitle = function(title, xs) { return result; }; -var prettifySig = function(s) { +var prettifySig = function (s) { return s.replace(/[.][.][.]/g, '\u2026').replace(/->/g, '\u2192'); }; -var prettifyCode = function(s) { +var prettifyCode = function (s) { return hljs.highlight('javascript', s.join('\n').replace(/^[ ]{5}/gm, '')).value; }; // simplifySee :: [String] -> [String] // // Handles any combination of comma-separated and multi-line @see annotations. -var simplifySee = function(xs) { +var simplifySee = function (xs) { var result = []; - xs.forEach(function(x) { - x.split(/\s*,\s*/).forEach(function(s) { + xs.forEach(function (x) { + x.split(/\s*,\s*/).forEach(function (s) { result.push(s.replace(/^R[.]/, '')); }); }); return result; }; -var simplifyData = function(d) { +var simplifyData = function (d) { return { - aka: chain(function(s) { return s.split(/,\s*/); }, valuesForTitle('aka', d.tags)), + aka: chain(function (s) { return s.split(/,\s*/); }, valuesForTitle('aka', d.tags)), category: headOr('', valuesForTitle('category', d.tags)), deprecated: d.deprecated == null ? '' : d.deprecated, description: d.description == null ? '' : marked(d.description), example: d.examples == null ? [] : prettifyCode(d.examples), name: d.name == null ? '' : d.name, - params: d.params == null ? [] : d.params.map(function(p) { + params: d.params == null ? [] : d.params.map(function (p) { return { type: p.type.names[0] || '', description: marked(p.description || ''), @@ -73,19 +74,19 @@ var simplifyData = function(d) { }), returns: { type: - d.returns != null && + d.returns != null && d.returns[0] != null && d.returns[0].type != null && d.returns[0].type.names != null && d.returns[0].type.names[0] != null ? - d.returns[0].type.names[0] : - '', + d.returns[0].type.names[0] : + '', description: - d.returns != null && + d.returns != null && d.returns[0] != null && d.returns[0].description != null ? - marked(d.returns[0].description) : - '', + marked(d.returns[0].description) : + '', }, see: d.see == null ? [] : simplifySee(d.see), sigs: valuesForTitle('sig', d.tags).map(prettifySig), @@ -94,37 +95,43 @@ var simplifyData = function(d) { }; }; -var readFile = function(filename) { - return fs.readFileSync(filename, {encoding: 'utf8'}); +var readFile = function (filename) { + return fs.readFileSync(filename, { encoding: 'utf8' }); }; -var render = function(templateFile, outputFile, context) { +var render = function (templateFile, outputFile, context) { fs.writeFileSync(outputFile, - handlebars.compile(readFile(templateFile))(context), - {encoding: 'utf8'}); + handlebars.compile(readFile(templateFile))(context), + { encoding: 'utf8' }); }; -exports.publish = function(data, opts) { +exports.publish = function (data, opts) { var context = { docs: helper.prune(data)() - .order('name, version, since') - .filter({kind: ['function', 'constant']}) - .get() - .filter(function(x) { return x.access !== 'private'; }) - .map(simplifyData), + .order('name, version, since') + .filter({ kind: ['function', 'constant'] }) + .get() + .filter(function (x) { return x.access !== 'private'; }) + .map(simplifyData), readme: new handlebars.SafeString(marked(readFile(VERSION + '/tmp/README.md'))), version: require('../' + VERSION + '/tmp/package.json').version, + files: requireDir('../' + VERSION + '/examples/code', {includeFiles: /^.*\.json$/}) }; render('jsdoc/templates/index.html.handlebars', - path.resolve(opts.destination, 'index.html'), - context); + path.resolve(opts.destination, 'index.html'), + context); render('docs/index.html.handlebars', - path.resolve(opts.destination, 'docs/index.html'), - context); + path.resolve(opts.destination, 'docs/index.html'), + context); render('repl/index.html.handlebars', - path.resolve('./repl/index.html'), - context); + path.resolve('./repl/index.html'), + context); + + render('examples/index.html.handlebars', + path.resolve('./examples/index.html'), + context); + }; diff --git a/jsdoc/templates/index.html.handlebars b/jsdoc/templates/index.html.handlebars index cf1484e7..845af7d0 100644 --- a/jsdoc/templates/index.html.handlebars +++ b/jsdoc/templates/index.html.handlebars @@ -21,6 +21,11 @@
  • Home
  • Documentation
  • Try Ramda
  • +
  • Cookbook
  • + + + diff --git a/less/layout.less b/less/layout.less index 35813c5e..dcee6817 100644 --- a/less/layout.less +++ b/less/layout.less @@ -29,6 +29,10 @@ header { } } +.padded { + padding: 5px; +} + /** * Home */ diff --git a/less/sidebar.less b/less/sidebar.less index ae97cbc9..5cf7b270 100644 --- a/less/sidebar.less +++ b/less/sidebar.less @@ -5,6 +5,10 @@ border-right: @border; font-family: @font-family-monospace; + &.no-filter { + padding-top: 20px; + } + .filter { width: 100%; margin: 15px 0; @@ -29,6 +33,11 @@ li { margin: 0; + + &.active { + background-color: #849; + color: white; + } } a { diff --git a/package.json b/package.json index c880c537..7fa42ddf 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "handlebars": "2.x.x", "highlight.js": "8.x.x", "http-server": "0.8.x", + "js-yaml": "^3.6.0", "jsdoc": "3.3.x", "less": "2.5.x", "marked": "0.3.x" @@ -21,5 +22,8 @@ "scripts": { "jsdoc": "jsdoc --destination ./docs --template . ./docs/dist/ramda.js", "server": "http-server" + }, + "dependencies": { + "require-dir-all": "^0.4.9" } } diff --git a/repl/index.html b/repl/index.html index 76270615..0e58e7e7 100644 --- a/repl/index.html +++ b/repl/index.html @@ -53,10 +53,16 @@ + + diff --git a/repl/index.html.handlebars b/repl/index.html.handlebars index 9b1eac85..f7d6ddd2 100644 --- a/repl/index.html.handlebars +++ b/repl/index.html.handlebars @@ -53,10 +53,16 @@ + + diff --git a/style.css b/style.css index 0fb6eabc..e95a343f 100644 --- a/style.css +++ b/style.css @@ -6741,6 +6741,9 @@ header { display: none; } } +.padded { + padding: 5px; +} /** * Home */ @@ -6876,6 +6879,9 @@ html.docs-page #open-nav:checked ~ main { border-right: 1px solid #ccc; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; } +.sidebar.no-filter { + padding-top: 20px; +} .sidebar .filter { width: 100%; margin: 15px 0; @@ -6895,6 +6901,10 @@ html.docs-page #open-nav:checked ~ main { .sidebar .toc li { margin: 0; } +.sidebar .toc li.active { + background-color: #849; + color: white; +} .sidebar .toc a { padding: 5px 15px; border-radius: 0;