Ohm-Management - Projektarbeit B-ME
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

README.md 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. # levn [![Build Status](https://travis-ci.org/gkz/levn.png)](https://travis-ci.org/gkz/levn) <a name="levn" />
  2. __Light ECMAScript (JavaScript) Value Notation__
  3. Levn is a library which allows you to parse a string into a JavaScript value based on an expected type. It is meant for short amounts of human entered data (eg. config files, command line arguments).
  4. Levn aims to concisely describe JavaScript values in text, and allow for the extraction and validation of those values. Levn uses [type-check](https://github.com/gkz/type-check) for its type format, and to validate the results. MIT license. Version 0.3.0.
  5. __How is this different than JSON?__ levn is meant to be written by humans only, is (due to the previous point) much more concise, can be validated against supplied types, has regex and date literals, and can easily be extended with custom types. On the other hand, it is probably slower and thus less efficient at transporting large amounts of data, which is fine since this is not its purpose.
  6. npm install levn
  7. For updates on levn, [follow me on twitter](https://twitter.com/gkzahariev).
  8. ## Quick Examples
  9. ```js
  10. var parse = require('levn').parse;
  11. parse('Number', '2'); // 2
  12. parse('String', '2'); // '2'
  13. parse('String', 'levn'); // 'levn'
  14. parse('String', 'a b'); // 'a b'
  15. parse('Boolean', 'true'); // true
  16. parse('Date', '#2011-11-11#'); // (Date object)
  17. parse('Date', '2011-11-11'); // (Date object)
  18. parse('RegExp', '/[a-z]/gi'); // /[a-z]/gi
  19. parse('RegExp', 're'); // /re/
  20. parse('Int', '2'); // 2
  21. parse('Number | String', 'str'); // 'str'
  22. parse('Number | String', '2'); // 2
  23. parse('[Number]', '[1,2,3]'); // [1,2,3]
  24. parse('(String, Boolean)', '(hi, false)'); // ['hi', false]
  25. parse('{a: String, b: Number}', '{a: str, b: 2}'); // {a: 'str', b: 2}
  26. // at the top level, you can ommit surrounding delimiters
  27. parse('[Number]', '1,2,3'); // [1,2,3]
  28. parse('(String, Boolean)', 'hi, false'); // ['hi', false]
  29. parse('{a: String, b: Number}', 'a: str, b: 2'); // {a: 'str', b: 2}
  30. // wildcard - auto choose type
  31. parse('*', '[hi,(null,[42]),{k: true}]'); // ['hi', [null, [42]], {k: true}]
  32. ```
  33. ## Usage
  34. `require('levn');` returns an object that exposes three properties. `VERSION` is the current version of the library as a string. `parse` and `parsedTypeParse` are functions.
  35. ```js
  36. // parse(type, input, options);
  37. parse('[Number]', '1,2,3'); // [1, 2, 3]
  38. // parsedTypeParse(parsedType, input, options);
  39. var parsedType = require('type-check').parseType('[Number]');
  40. parsedTypeParse(parsedType, '1,2,3'); // [1, 2, 3]
  41. ```
  42. ### parse(type, input, options)
  43. `parse` casts the string `input` into a JavaScript value according to the specified `type` in the [type format](https://github.com/gkz/type-check#type-format) (and taking account the optional `options`) and returns the resulting JavaScript value.
  44. ##### arguments
  45. * type - `String` - the type written in the [type format](https://github.com/gkz/type-check#type-format) which to check against
  46. * input - `String` - the value written in the [levn format](#levn-format)
  47. * options - `Maybe Object` - an optional parameter specifying additional [options](#options)
  48. ##### returns
  49. `*` - the resulting JavaScript value
  50. ##### example
  51. ```js
  52. parse('[Number]', '1,2,3'); // [1, 2, 3]
  53. ```
  54. ### parsedTypeParse(parsedType, input, options)
  55. `parsedTypeParse` casts the string `input` into a JavaScript value according to the specified `type` which has already been parsed (and taking account the optional `options`) and returns the resulting JavaScript value. You can parse a type using the [type-check](https://github.com/gkz/type-check) library's `parseType` function.
  56. ##### arguments
  57. * type - `Object` - the type in the parsed type format which to check against
  58. * input - `String` - the value written in the [levn format](#levn-format)
  59. * options - `Maybe Object` - an optional parameter specifying additional [options](#options)
  60. ##### returns
  61. `*` - the resulting JavaScript value
  62. ##### example
  63. ```js
  64. var parsedType = require('type-check').parseType('[Number]');
  65. parsedTypeParse(parsedType, '1,2,3'); // [1, 2, 3]
  66. ```
  67. ## Levn Format
  68. Levn can use the type information you provide to choose the appropriate value to produce from the input. For the same input, it will choose a different output value depending on the type provided. For example, `parse('Number', '2')` will produce the number `2`, but `parse('String', '2')` will produce the string `"2"`.
  69. If you do not provide type information, and simply use `*`, levn will parse the input according the unambiguous "explicit" mode, which we will now detail - you can also set the `explicit` option to true manually in the [options](#options).
  70. * `"string"`, `'string'` are parsed as a String, eg. `"a msg"` is `"a msg"`
  71. * `#date#` is parsed as a Date, eg. `#2011-11-11#` is `new Date('2011-11-11')`
  72. * `/regexp/flags` is parsed as a RegExp, eg. `/re/gi` is `/re/gi`
  73. * `undefined`, `null`, `NaN`, `true`, and `false` are all their JavaScript equivalents
  74. * `[element1, element2, etc]` is an Array, and the casting procedure is recursively applied to each element. Eg. `[1,2,3]` is `[1,2,3]`.
  75. * `(element1, element2, etc)` is an tuple, and the casting procedure is recursively applied to each element. Eg. `(1, a)` is `(1, a)` (is `[1, 'a']`).
  76. * `{key1: val1, key2: val2, ...}` is an Object, and the casting procedure is recursively applied to each property. Eg. `{a: 1, b: 2}` is `{a: 1, b: 2}`.
  77. * Any test which does not fall under the above, and which does not contain special characters (`[``]``(``)``{``}``:``,`) is a string, eg. `$12- blah` is `"$12- blah"`.
  78. If you do provide type information, you can make your input more concise as the program already has some information about what it expects. Please see the [type format](https://github.com/gkz/type-check#type-format) section of [type-check](https://github.com/gkz/type-check) for more information about how to specify types. There are some rules about what levn can do with the information:
  79. * If a String is expected, and only a String, all characters of the input (including any special ones) will become part of the output. Eg. `[({})]` is `"[({})]"`, and `"hi"` is `'"hi"'`.
  80. * If a Date is expected, the surrounding `#` can be omitted from date literals. Eg. `2011-11-11` is `new Date('2011-11-11')`.
  81. * If a RegExp is expected, no flags need to be specified, and the regex is not using any of the special characters,the opening and closing `/` can be omitted - this will have the affect of setting the source of the regex to the input. Eg. `regex` is `/regex/`.
  82. * If an Array is expected, and it is the root node (at the top level), the opening `[` and closing `]` can be omitted. Eg. `1,2,3` is `[1,2,3]`.
  83. * If a tuple is expected, and it is the root node (at the top level), the opening `(` and closing `)` can be omitted. Eg. `1, a` is `(1, a)` (is `[1, 'a']`).
  84. * If an Object is expected, and it is the root node (at the top level), the opening `{` and closing `}` can be omitted. Eg `a: 1, b: 2` is `{a: 1, b: 2}`.
  85. If you list multiple types (eg. `Number | String`), it will first attempt to cast to the first type and then validate - if the validation fails it will move on to the next type and so forth, left to right. You must be careful as some types will succeed with any input, such as String. Thus put String at the end of your list. In non-explicit mode, Date and RegExp will succeed with a large variety of input - also be careful with these and list them near the end if not last in your list.
  86. Whitespace between special characters and elements is inconsequential.
  87. ## Options
  88. Options is an object. It is an optional parameter to the `parse` and `parsedTypeParse` functions.
  89. ### Explicit
  90. A `Boolean`. By default it is `false`.
  91. __Example:__
  92. ```js
  93. parse('RegExp', 're', {explicit: false}); // /re/
  94. parse('RegExp', 're', {explicit: true}); // Error: ... does not type check...
  95. parse('RegExp | String', 're', {explicit: true}); // 're'
  96. ```
  97. `explicit` sets whether to be in explicit mode or not. Using `*` automatically activates explicit mode. For more information, read the [levn format](#levn-format) section.
  98. ### customTypes
  99. An `Object`. Empty `{}` by default.
  100. __Example:__
  101. ```js
  102. var options = {
  103. customTypes: {
  104. Even: {
  105. typeOf: 'Number',
  106. validate: function (x) {
  107. return x % 2 === 0;
  108. },
  109. cast: function (x) {
  110. return {type: 'Just', value: parseInt(x)};
  111. }
  112. }
  113. }
  114. }
  115. parse('Even', '2', options); // 2
  116. parse('Even', '3', options); // Error: Value: "3" does not type check...
  117. ```
  118. __Another Example:__
  119. ```js
  120. function Person(name, age){
  121. this.name = name;
  122. this.age = age;
  123. }
  124. var options = {
  125. customTypes: {
  126. Person: {
  127. typeOf: 'Object',
  128. validate: function (x) {
  129. x instanceof Person;
  130. },
  131. cast: function (value, options, typesCast) {
  132. var name, age;
  133. if ({}.toString.call(value).slice(8, -1) !== 'Object') {
  134. return {type: 'Nothing'};
  135. }
  136. name = typesCast(value.name, [{type: 'String'}], options);
  137. age = typesCast(value.age, [{type: 'Numger'}], options);
  138. return {type: 'Just', value: new Person(name, age)};
  139. }
  140. }
  141. }
  142. parse('Person', '{name: Laura, age: 25}', options); // Person {name: 'Laura', age: 25}
  143. ```
  144. `customTypes` is an object whose keys are the name of the types, and whose values are an object with three properties, `typeOf`, `validate`, and `cast`. For more information about `typeOf` and `validate`, please see the [custom types](https://github.com/gkz/type-check#custom-types) section of type-check.
  145. `cast` is a function which receives three arguments, the value under question, options, and the typesCast function. In `cast`, attempt to cast the value into the specified type. If you are successful, return an object in the format `{type: 'Just', value: CAST-VALUE}`, if you know it won't work, return `{type: 'Nothing'}`. You can use the `typesCast` function to cast any child values. Remember to pass `options` to it. In your function you can also check for `options.explicit` and act accordingly.
  146. ## Technical About
  147. `levn` is written in [LiveScript](http://livescript.net/) - a language that compiles to JavaScript. It uses [type-check](https://github.com/gkz/type-check) to both parse types and validate values. It also uses the [prelude.ls](http://preludels.com/) library.