├── .gitignore ├── .npmignore ├── .travis.yml ├── LICENSE ├── README.md ├── TODO.md ├── compose_.md ├── index.js ├── lprc.js ├── no-augments.md ├── package-lock.json ├── package.json ├── project.md ├── setup.md ├── src ├── commands.md ├── commonmark.md ├── debugging.md ├── directives.md ├── events.md ├── logs.md ├── matrix.md ├── requires.md ├── stitching.md ├── subcommands.md └── tests.md ├── test.js └── tests ├── anon.md ├── arrayify.md ├── assert.md ├── async.md ├── asynceval.md ├── backslash.md ├── blockoff.md ├── capitalizations.md ├── caps.md ├── cd.md ├── codeblocks.md ├── commands.md ├── comments-pipes.md ├── comments.md ├── compile-minidoc.md ├── compile.md ├── compileminor.md ├── compose.md ├── config.md ├── constructor.md ├── cycle.md ├── dash.md ├── defaults.md ├── define.md ├── directivesubbing.md ├── direval.md ├── dirpush.md ├── done.md ├── echo.md ├── emitcache.md ├── empty-main.md ├── empty-minor.md ├── empty.md ├── erroreval.md ├── eval.md ├── failure.mdn ├── first.md ├── fsubcommand.md ├── funify.md ├── h5.md ├── h5push.md ├── h5pushodd.md ├── headless.md ├── html-helpers.md ├── if.md ├── ife.md ├── ifelse.md ├── ignore.md ├── indents.md ├── join-filter.md ├── js-string.md ├── lineterm.md ├── linkquotes.md ├── load.md ├── log.md ├── logs-doc.md ├── logs-reports.md ├── mainblock.md ├── mapc-gymnastics.md ├── mapc.md ├── matrix-row-col.md ├── matrixify.md ├── merge.md ├── moresubcommands.md ├── nameafterpipe.md ├── objectify.md ├── partial.md ├── psetgetstore.md ├── pushpop.md ├── raw.md ├── repeatheaders.md ├── reports.md ├── savepipe.md ├── scope.md ├── scopeexists.md ├── snippets.md ├── store-pipe.md ├── store.md ├── sub-input-match.md ├── sub-reg.md ├── sub.md ├── subcommands.md ├── subindent.md ├── switch.md ├── switchcmd.md ├── templateexample.md ├── templating.md ├── trailingunderscore.md ├── transform.md ├── version.md └── wrap.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | temp 3 | /.checksum 4 | /build 5 | old 6 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | tests 2 | test.js 3 | .travis.yml 4 | ghpages 5 | node_modules 6 | *.md 7 | lprc.js 8 | build/ 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "node" 4 | sudo: false 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2020 James Taylor 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | Review docs, tests, better error and debugging reporting. 2 | 3 | source maps? 4 | 5 | an escape function for Folder? it seems I keep writing that. 6 | 7 | options parser for arguments in commands, 8 | i.e., -o, object to say an object is coming in 9 | instead of object detection? could shift arguments appropriately to clean them 10 | up; options would vanish from the inherited order, perhaps. 11 | 12 | snippets: `|s js-t obj, object` would be a boolean expression generated 13 | (type) 14 | `| s js-d obj, default` could generate (typeof obj !== "undefined") ? obj : 15 | default 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /compose_.md: -------------------------------------------------------------------------------- 1 | Compose -- testing simple composition 2 | --- 3 | 4 | Need to test composing. 5 | 6 | _"stuff | split \n-!-\n " 7 | 8 | _"stuff | longsplit \n-!-\n, arr(;, some, more) " 9 | 10 | _"tb | compsplit _'template' " 11 | 12 | _"t | nlsplit temp2 " 13 | 14 | _"| arrtest" 15 | 16 | 17 | [longsplit](# "compose: split $0 | join @1, kool, @1") 18 | 19 | [split](# "compose: .split $0 | *trim | .join 5 ") 20 | 21 | [nlsplit](# "compose: .split \n---\n | minors title, body | ->$1 | 22 | | *store $0, *KEY* | get template | compile $0 23 | | ->$2 | $1->*clear$2-> $0, *KEY* ") 24 | 25 | [compsplit](# "compose: .split \n---\n | minors title, body 26 | | templating $0 ") 27 | 28 | [arrtest](# "compose: echo this | ->@0 | echo that\nhar\n | ->@0 29 | | $0->| | *trim | .join ! ") 30 | 31 | 32 | ## template 33 | 34 | \_":title" 35 | \_":body" 36 | 37 | ## tb 38 | 39 | ttl 40 | --- 41 | body 42 | body 43 | 44 | ## t 45 | 46 | ttl 47 | 48 | ## stuff 49 | 50 | this is 51 | -!- 52 | great 53 | -!- 54 | Does it 55 | work 56 | -!- 57 | Yes 58 | --- 59 | this is5great5Does it 60 | work5Yes 61 | 62 | this is5great5Does it 63 | work5Yes;kool;some;more 64 | 65 | ttl 66 | body 67 | body 68 | 69 | ttl 70 | 71 | 72 | this!that 73 | har 74 | -------------------------------------------------------------------------------- /lprc.js: -------------------------------------------------------------------------------- 1 | /*global module, require*/ 2 | module.exports = function(Folder, args) { 3 | 4 | //require('litpro-jshint')(Folder, args); 5 | Folder.plugins.jshint.clean = true; 6 | 7 | 8 | }; 9 | -------------------------------------------------------------------------------- /no-augments.md: -------------------------------------------------------------------------------- 1 | This is a brief note about the change of dropping the augment story. The 2 | augments were there as a way to keep the footprint of commands small and 3 | because arrays are not easily subclassed. 4 | 5 | By adding in a few commands, I intend to eliminate the augments. They were 6 | cumbersome and rather a distraction, particularly as the augmentation had to 7 | be kept track of and the properties would pollute the scope. 8 | 9 | Here is how all the features were replaced. 10 | 11 | The key function is `mapc command`. This maps a command over an array or object 12 | values. The shorthand notation is `*command`. 13 | 14 | Minidoc replacements: 15 | 16 | * `minidoc` with `minors` 17 | * `.compile` with `templating` though with the actual compile block, not the 18 | name, as first arg. For compositions, to use the name, one can do something 19 | like `->$1 | get template-name | ->$2 | $1-> | templating $2`. May want to 20 | look into allowing templating to choose or a smoother mechanism for storage, 21 | something like `get template-name -> $2`with the prevailing input just going 22 | along. 23 | * `.store blockname` replaced with `*store blockname:*KEY*` or `*store 24 | blockname, *KEY*` 25 | * `.clear` same as store 26 | * `.apply key, cmd, args` replaced with `apply` 27 | * `.clone` with `clone` 28 | * `.get` with `pget` 29 | * `.set with `pset` 30 | * `.keys` with ``forin fun(` (val, key) => return key`)`` 31 | * `.toString sep, valsep, fkey, fval` with ``forin fun(`(val, key, ret) => return 32 | fkey(key) + sep + fval(val) + valsep`), ''`` 33 | * `.toJSON` with `toJSON` Also added in `fromJSON` 34 | * `.forin` with `forin` 35 | 36 | 37 | Array replacements: 38 | 39 | * `.trim` with `*trim` 40 | * `.splitsep` with `*.split \n---\n` 41 | * `.mapc` with `mapc` 42 | * `.pluck` `*pget` 43 | * `.put` with `forin fun(`(val, key, init, input) => input[key] = init[key]; 44 | return key;`), object/array whose keys match with values wanted` 45 | * `.get` with `pget` 46 | * `.set` with `pset` 47 | * 48 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "literate-programming-lib", 3 | "version": "2.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "balanced-match": { 8 | "version": "1.0.0", 9 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 10 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 11 | "dev": true 12 | }, 13 | "brace-expansion": { 14 | "version": "1.1.11", 15 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 16 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 17 | "dev": true, 18 | "requires": { 19 | "balanced-match": "^1.0.0", 20 | "concat-map": "0.0.1" 21 | } 22 | }, 23 | "cli": { 24 | "version": "1.0.1", 25 | "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz", 26 | "integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=", 27 | "dev": true, 28 | "requires": { 29 | "exit": "0.1.2", 30 | "glob": "^7.1.1" 31 | } 32 | }, 33 | "commonmark": { 34 | "version": "0.29.1", 35 | "resolved": "https://registry.npmjs.org/commonmark/-/commonmark-0.29.1.tgz", 36 | "integrity": "sha512-DafPdNYFXoEhsSiR4O+dJ45UJBfDL4cBTks4B+agKiaWt7qjG0bIhg5xuCE0RqU71ikJcBIf4/sRHh9vYQVF8Q==", 37 | "requires": { 38 | "entities": "~1.1.1", 39 | "mdurl": "~1.0.1", 40 | "minimist": "~1.2.0", 41 | "string.prototype.repeat": "^0.2.0" 42 | } 43 | }, 44 | "concat-map": { 45 | "version": "0.0.1", 46 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 47 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 48 | "dev": true 49 | }, 50 | "console-browserify": { 51 | "version": "1.1.0", 52 | "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", 53 | "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", 54 | "dev": true, 55 | "requires": { 56 | "date-now": "^0.1.4" 57 | } 58 | }, 59 | "core-util-is": { 60 | "version": "1.0.2", 61 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 62 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", 63 | "dev": true 64 | }, 65 | "date-now": { 66 | "version": "0.1.4", 67 | "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", 68 | "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", 69 | "dev": true 70 | }, 71 | "deep-equal": { 72 | "version": "1.1.1", 73 | "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", 74 | "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", 75 | "dev": true, 76 | "requires": { 77 | "is-arguments": "^1.0.4", 78 | "is-date-object": "^1.0.1", 79 | "is-regex": "^1.0.4", 80 | "object-is": "^1.0.1", 81 | "object-keys": "^1.1.1", 82 | "regexp.prototype.flags": "^1.2.0" 83 | } 84 | }, 85 | "define-properties": { 86 | "version": "1.1.3", 87 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", 88 | "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", 89 | "dev": true, 90 | "requires": { 91 | "object-keys": "^1.0.12" 92 | } 93 | }, 94 | "defined": { 95 | "version": "1.0.0", 96 | "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", 97 | "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", 98 | "dev": true 99 | }, 100 | "dom-serializer": { 101 | "version": "0.2.2", 102 | "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", 103 | "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", 104 | "dev": true, 105 | "requires": { 106 | "domelementtype": "^2.0.1", 107 | "entities": "^2.0.0" 108 | }, 109 | "dependencies": { 110 | "domelementtype": { 111 | "version": "2.0.1", 112 | "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", 113 | "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==", 114 | "dev": true 115 | }, 116 | "entities": { 117 | "version": "2.0.0", 118 | "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", 119 | "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==", 120 | "dev": true 121 | } 122 | } 123 | }, 124 | "domelementtype": { 125 | "version": "1.3.1", 126 | "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", 127 | "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", 128 | "dev": true 129 | }, 130 | "domhandler": { 131 | "version": "2.3.0", 132 | "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", 133 | "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", 134 | "dev": true, 135 | "requires": { 136 | "domelementtype": "1" 137 | } 138 | }, 139 | "domutils": { 140 | "version": "1.5.1", 141 | "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", 142 | "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", 143 | "dev": true, 144 | "requires": { 145 | "dom-serializer": "0", 146 | "domelementtype": "1" 147 | } 148 | }, 149 | "dotignore": { 150 | "version": "0.1.2", 151 | "resolved": "https://registry.npmjs.org/dotignore/-/dotignore-0.1.2.tgz", 152 | "integrity": "sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw==", 153 | "dev": true, 154 | "requires": { 155 | "minimatch": "^3.0.4" 156 | } 157 | }, 158 | "entities": { 159 | "version": "1.1.2", 160 | "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", 161 | "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" 162 | }, 163 | "es-abstract": { 164 | "version": "1.17.0", 165 | "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.0.tgz", 166 | "integrity": "sha512-yYkE07YF+6SIBmg1MsJ9dlub5L48Ek7X0qz+c/CPCHS9EBXfESorzng4cJQjJW5/pB6vDF41u7F8vUhLVDqIug==", 167 | "dev": true, 168 | "requires": { 169 | "es-to-primitive": "^1.2.1", 170 | "function-bind": "^1.1.1", 171 | "has": "^1.0.3", 172 | "has-symbols": "^1.0.1", 173 | "is-callable": "^1.1.5", 174 | "is-regex": "^1.0.5", 175 | "object-inspect": "^1.7.0", 176 | "object-keys": "^1.1.1", 177 | "object.assign": "^4.1.0", 178 | "string.prototype.trimleft": "^2.1.1", 179 | "string.prototype.trimright": "^2.1.1" 180 | } 181 | }, 182 | "es-to-primitive": { 183 | "version": "1.2.1", 184 | "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", 185 | "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", 186 | "dev": true, 187 | "requires": { 188 | "is-callable": "^1.1.4", 189 | "is-date-object": "^1.0.1", 190 | "is-symbol": "^1.0.2" 191 | } 192 | }, 193 | "event-when": { 194 | "version": "1.7.0", 195 | "resolved": "https://registry.npmjs.org/event-when/-/event-when-1.7.0.tgz", 196 | "integrity": "sha1-NTIP6NMKRaFPEZY4ejInl9tuIkg=" 197 | }, 198 | "exit": { 199 | "version": "0.1.2", 200 | "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", 201 | "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", 202 | "dev": true 203 | }, 204 | "for-each": { 205 | "version": "0.3.3", 206 | "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", 207 | "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", 208 | "dev": true, 209 | "requires": { 210 | "is-callable": "^1.1.3" 211 | } 212 | }, 213 | "fs.realpath": { 214 | "version": "1.0.0", 215 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 216 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 217 | "dev": true 218 | }, 219 | "function-bind": { 220 | "version": "1.1.1", 221 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 222 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 223 | "dev": true 224 | }, 225 | "glob": { 226 | "version": "7.1.6", 227 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 228 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 229 | "dev": true, 230 | "requires": { 231 | "fs.realpath": "^1.0.0", 232 | "inflight": "^1.0.4", 233 | "inherits": "2", 234 | "minimatch": "^3.0.4", 235 | "once": "^1.3.0", 236 | "path-is-absolute": "^1.0.0" 237 | } 238 | }, 239 | "has": { 240 | "version": "1.0.3", 241 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 242 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 243 | "dev": true, 244 | "requires": { 245 | "function-bind": "^1.1.1" 246 | } 247 | }, 248 | "has-symbols": { 249 | "version": "1.0.1", 250 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", 251 | "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", 252 | "dev": true 253 | }, 254 | "htmlparser2": { 255 | "version": "3.8.3", 256 | "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", 257 | "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", 258 | "dev": true, 259 | "requires": { 260 | "domelementtype": "1", 261 | "domhandler": "2.3", 262 | "domutils": "1.5", 263 | "entities": "1.0", 264 | "readable-stream": "1.1" 265 | }, 266 | "dependencies": { 267 | "entities": { 268 | "version": "1.0.0", 269 | "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", 270 | "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=", 271 | "dev": true 272 | } 273 | } 274 | }, 275 | "inflight": { 276 | "version": "1.0.6", 277 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 278 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 279 | "dev": true, 280 | "requires": { 281 | "once": "^1.3.0", 282 | "wrappy": "1" 283 | } 284 | }, 285 | "inherits": { 286 | "version": "2.0.4", 287 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 288 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 289 | "dev": true 290 | }, 291 | "is-arguments": { 292 | "version": "1.0.4", 293 | "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", 294 | "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", 295 | "dev": true 296 | }, 297 | "is-callable": { 298 | "version": "1.1.5", 299 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", 300 | "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", 301 | "dev": true 302 | }, 303 | "is-date-object": { 304 | "version": "1.0.2", 305 | "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", 306 | "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", 307 | "dev": true 308 | }, 309 | "is-regex": { 310 | "version": "1.0.5", 311 | "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", 312 | "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", 313 | "dev": true, 314 | "requires": { 315 | "has": "^1.0.3" 316 | } 317 | }, 318 | "is-symbol": { 319 | "version": "1.0.3", 320 | "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", 321 | "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", 322 | "dev": true, 323 | "requires": { 324 | "has-symbols": "^1.0.1" 325 | } 326 | }, 327 | "isarray": { 328 | "version": "0.0.1", 329 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", 330 | "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", 331 | "dev": true 332 | }, 333 | "jshint": { 334 | "version": "2.11.0", 335 | "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.11.0.tgz", 336 | "integrity": "sha512-ooaD/hrBPhu35xXW4gn+o3SOuzht73gdBuffgJzrZBJZPGgGiiTvJEgTyxFvBO2nz0+X1G6etF8SzUODTlLY6Q==", 337 | "dev": true, 338 | "requires": { 339 | "cli": "~1.0.0", 340 | "console-browserify": "1.1.x", 341 | "exit": "0.1.x", 342 | "htmlparser2": "3.8.x", 343 | "lodash": "~4.17.11", 344 | "minimatch": "~3.0.2", 345 | "shelljs": "0.3.x", 346 | "strip-json-comments": "1.0.x" 347 | } 348 | }, 349 | "litpro-jshint": { 350 | "version": "0.4.0", 351 | "resolved": "https://registry.npmjs.org/litpro-jshint/-/litpro-jshint-0.4.0.tgz", 352 | "integrity": "sha512-ZRTVrQnHXgTIVaF0LH+DToaeMhOXOwWAfVNWGVelLW7CAUGDWZ0mTFSIYBzVfDOM8tHppoNBmhG/RUIhe4aefg==", 353 | "dev": true, 354 | "requires": { 355 | "jshint": "^2.11.0", 356 | "merge": "^1.2.1" 357 | } 358 | }, 359 | "lodash": { 360 | "version": "4.17.15", 361 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", 362 | "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", 363 | "dev": true 364 | }, 365 | "mdurl": { 366 | "version": "1.0.1", 367 | "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", 368 | "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" 369 | }, 370 | "merge": { 371 | "version": "1.2.1", 372 | "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.1.tgz", 373 | "integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==", 374 | "dev": true 375 | }, 376 | "minimatch": { 377 | "version": "3.0.4", 378 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 379 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 380 | "dev": true, 381 | "requires": { 382 | "brace-expansion": "^1.1.7" 383 | } 384 | }, 385 | "minimist": { 386 | "version": "1.2.0", 387 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", 388 | "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" 389 | }, 390 | "object-inspect": { 391 | "version": "1.7.0", 392 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", 393 | "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", 394 | "dev": true 395 | }, 396 | "object-is": { 397 | "version": "1.0.2", 398 | "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.0.2.tgz", 399 | "integrity": "sha512-Epah+btZd5wrrfjkJZq1AOB9O6OxUQto45hzFd7lXGrpHPGE0W1k+426yrZV+k6NJOzLNNW/nVsmZdIWsAqoOQ==", 400 | "dev": true 401 | }, 402 | "object-keys": { 403 | "version": "1.1.1", 404 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", 405 | "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", 406 | "dev": true 407 | }, 408 | "object.assign": { 409 | "version": "4.1.0", 410 | "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", 411 | "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", 412 | "dev": true, 413 | "requires": { 414 | "define-properties": "^1.1.2", 415 | "function-bind": "^1.1.1", 416 | "has-symbols": "^1.0.0", 417 | "object-keys": "^1.0.11" 418 | } 419 | }, 420 | "once": { 421 | "version": "1.4.0", 422 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 423 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 424 | "dev": true, 425 | "requires": { 426 | "wrappy": "1" 427 | } 428 | }, 429 | "path-is-absolute": { 430 | "version": "1.0.1", 431 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 432 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 433 | "dev": true 434 | }, 435 | "path-parse": { 436 | "version": "1.0.6", 437 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", 438 | "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", 439 | "dev": true 440 | }, 441 | "readable-stream": { 442 | "version": "1.1.14", 443 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", 444 | "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", 445 | "dev": true, 446 | "requires": { 447 | "core-util-is": "~1.0.0", 448 | "inherits": "~2.0.1", 449 | "isarray": "0.0.1", 450 | "string_decoder": "~0.10.x" 451 | } 452 | }, 453 | "regexp.prototype.flags": { 454 | "version": "1.3.0", 455 | "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", 456 | "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", 457 | "dev": true, 458 | "requires": { 459 | "define-properties": "^1.1.3", 460 | "es-abstract": "^1.17.0-next.1" 461 | } 462 | }, 463 | "resolve": { 464 | "version": "1.14.2", 465 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.14.2.tgz", 466 | "integrity": "sha512-EjlOBLBO1kxsUxsKjLt7TAECyKW6fOh1VRkykQkKGzcBbjjPIxBqGh0jf7GJ3k/f5mxMqW3htMD3WdTUVtW8HQ==", 467 | "dev": true, 468 | "requires": { 469 | "path-parse": "^1.0.6" 470 | } 471 | }, 472 | "resumer": { 473 | "version": "0.0.0", 474 | "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", 475 | "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", 476 | "dev": true, 477 | "requires": { 478 | "through": "~2.3.4" 479 | } 480 | }, 481 | "shelljs": { 482 | "version": "0.3.0", 483 | "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", 484 | "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=", 485 | "dev": true 486 | }, 487 | "string.fromcodepoint": { 488 | "version": "0.2.1", 489 | "resolved": "https://registry.npmjs.org/string.fromcodepoint/-/string.fromcodepoint-0.2.1.tgz", 490 | "integrity": "sha1-jZeDM8C8klOPUPOD5IiPPlYZ1lM=" 491 | }, 492 | "string.prototype.repeat": { 493 | "version": "0.2.0", 494 | "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-0.2.0.tgz", 495 | "integrity": "sha1-q6Nt4I3O5qWjN9SbLqHaGyj8Ds8=" 496 | }, 497 | "string.prototype.trim": { 498 | "version": "1.2.1", 499 | "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.1.tgz", 500 | "integrity": "sha512-MjGFEeqixw47dAMFMtgUro/I0+wNqZB5GKXGt1fFr24u3TzDXCPu7J9Buppzoe3r/LqkSDLDDJzE15RGWDGAVw==", 501 | "dev": true, 502 | "requires": { 503 | "define-properties": "^1.1.3", 504 | "es-abstract": "^1.17.0-next.1", 505 | "function-bind": "^1.1.1" 506 | } 507 | }, 508 | "string.prototype.trimleft": { 509 | "version": "2.1.1", 510 | "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", 511 | "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", 512 | "dev": true, 513 | "requires": { 514 | "define-properties": "^1.1.3", 515 | "function-bind": "^1.1.1" 516 | } 517 | }, 518 | "string.prototype.trimright": { 519 | "version": "2.1.1", 520 | "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", 521 | "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", 522 | "dev": true, 523 | "requires": { 524 | "define-properties": "^1.1.3", 525 | "function-bind": "^1.1.1" 526 | } 527 | }, 528 | "string_decoder": { 529 | "version": "0.10.31", 530 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", 531 | "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", 532 | "dev": true 533 | }, 534 | "strip-json-comments": { 535 | "version": "1.0.4", 536 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", 537 | "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=", 538 | "dev": true 539 | }, 540 | "tape": { 541 | "version": "4.13.0", 542 | "resolved": "https://registry.npmjs.org/tape/-/tape-4.13.0.tgz", 543 | "integrity": "sha512-J/hvA+GJnuWJ0Sj8Z0dmu3JgMNU+MmusvkCT7+SN4/2TklW18FNCp/UuHIEhPZwHfy4sXfKYgC7kypKg4umbOw==", 544 | "dev": true, 545 | "requires": { 546 | "deep-equal": "~1.1.1", 547 | "defined": "~1.0.0", 548 | "dotignore": "~0.1.2", 549 | "for-each": "~0.3.3", 550 | "function-bind": "~1.1.1", 551 | "glob": "~7.1.6", 552 | "has": "~1.0.3", 553 | "inherits": "~2.0.4", 554 | "is-regex": "~1.0.5", 555 | "minimist": "~1.2.0", 556 | "object-inspect": "~1.7.0", 557 | "resolve": "~1.14.2", 558 | "resumer": "~0.0.0", 559 | "string.prototype.trim": "~1.2.1", 560 | "through": "~2.3.8" 561 | } 562 | }, 563 | "through": { 564 | "version": "2.3.8", 565 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 566 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", 567 | "dev": true 568 | }, 569 | "wrappy": { 570 | "version": "1.0.2", 571 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 572 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 573 | "dev": true 574 | } 575 | } 576 | } 577 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "literate-programming-lib", 3 | "description": "A literate programming compiler. Write your program in markdown. This is the core library and does not know about files.", 4 | "version": "2.1.0", 5 | "homepage": "https://github.com/jostylr/literate-programming-lib", 6 | "author": { 7 | "name": "James Taylor", 8 | "email": "jostylr@gmail.com" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git://github.com/jostylr/literate-programming-lib.git" 13 | }, 14 | "bugs": { 15 | "url": "https://github.com/jostylr/literate-programming-lib/issues" 16 | }, 17 | "license": "MIT", 18 | "main": "index.js", 19 | "engines": { 20 | "node": ">=0.10" 21 | }, 22 | "dependencies":{ 23 | "event-when" : "^1.7.0", 24 | "commonmark" : "^0.29.1", 25 | "string.fromcodepoint" : "^0.2.1" 26 | }, 27 | "devDependencies" : { 28 | "tape" : "^4.13.0", 29 | "litpro-jshint" : "^0.4.0" 30 | }, 31 | "scripts" : { 32 | "test" : "node ./test.js" 33 | }, 34 | "keywords": ["literate programming"] 35 | } 36 | -------------------------------------------------------------------------------- /setup.md: -------------------------------------------------------------------------------- 1 | # [literate-programming-lib](# "version:2.1.0; A literate programming compiler. Write your program in markdown. This is the core library and does not know about files.") 2 | 3 | This creates the core of the literate-programming system. It is a stand-alone 4 | module that can be used on its own or with plugins. It can run in node or the 5 | browser via browserify. 6 | 7 | The basic idea is that the text is fed to it already and then it parses it. It 8 | is event based and so to have it do something, one has to connect up the 9 | events. 10 | 11 | A literate program is a series of chunks of explanatory text and code blocks 12 | that get woven together. The compilation of a literate program can grunt, 13 | after a fashion, as it weaves. 14 | 15 | ## Save 16 | 17 | * [../](# "cd: save") 18 | * [lprc.js](#lprc "save:|jshint") The litpro config file. 19 | * [package.json](#npm-package "save: | jshint") The requisite package file for a npm project. 20 | * [LICENSE](#license-mit "save:") The MIT license as I think that is the standard in the node community. 21 | * [.npmignore](#npmignore "save: ") 22 | * [.gitignore](#gitignore "save: ") 23 | * [.travis.yml](#travis "save: ") 24 | * [](# "cd: save") 25 | 26 | ## lprc 27 | 28 | This is compiled by litpro and uses the following lprc.js file 29 | 30 | /*global module, require*/ 31 | module.exports = function(Folder, args) { 32 | 33 | //require('litpro-jshint')(Folder, args); 34 | Folder.plugins.jshint.clean = true; 35 | 36 | 37 | }; 38 | 39 | 40 | ## NPM package 41 | 42 | The requisite npm package file. 43 | 44 | 45 | 46 | { 47 | "name": "_`g::docname`", 48 | "description": "_`g::tagline`", 49 | "version": "_`g::docversion`", 50 | "homepage": "https://github.com/_`g::gituser`/_`g::docname`", 51 | "author": { 52 | "name": "_`g::authorname`", 53 | "email": "_`g::authoremail`" 54 | }, 55 | "repository": { 56 | "type": "git", 57 | "url": "git://github.com/_`g::gituser`/_`g::docname`.git" 58 | }, 59 | "bugs": { 60 | "url": "https://github.com/_`g::gituser`/_`g::docname`/issues" 61 | }, 62 | "license": "MIT", 63 | "main": "index.js", 64 | "engines": { 65 | "node": ">=0.10" 66 | }, 67 | "dependencies":{ 68 | _"g::npm dependencies" 69 | }, 70 | "devDependencies" : { 71 | _"g::npm dev dependencies" 72 | }, 73 | "scripts" : { 74 | "test" : "node ./test.js" 75 | }, 76 | "keywords": ["literate programming"] 77 | } 78 | 79 | 80 | ## gitignore 81 | 82 | node_modules 83 | temp 84 | /.checksum 85 | /build 86 | old 87 | 88 | ## npmignore 89 | 90 | 91 | tests 92 | test.js 93 | .travis.yml 94 | ghpages 95 | node_modules 96 | *.md 97 | lprc.js 98 | build/ 99 | 100 | 101 | ## Travis 102 | 103 | A travis.yml file for continuous test integration! 104 | 105 | language: node_js 106 | node_js: 107 | - "node" 108 | sudo: false 109 | 110 | 111 | ## LICENSE MIT 112 | 113 | 114 | The MIT License (MIT) 115 | Copyright (c) _"g::year" _"g::authorname" 116 | 117 | Permission is hereby granted, free of charge, to any person obtaining a copy 118 | of this software and associated documentation files (the "Software"), to deal 119 | in the Software without restriction, including without limitation the rights 120 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 121 | copies of the Software, and to permit persons to whom the Software is 122 | furnished to do so, subject to the following conditions: 123 | 124 | The above copyright notice and this permission notice shall be included in all 125 | copies or substantial portions of the Software. 126 | 127 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 128 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 129 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 130 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 131 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 132 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 133 | SOFTWARE. 134 | 135 | 136 | 137 | 138 | 139 | by [James Taylor](https://github.com/jostylr "npminfo: jostylr@gmail.com ; 140 | deps: event-when 1.7.0, commonmark 0.29.1, string.fromcodepoint 0.2.1; 141 | dev: tape 4.13.0, litpro-jshint 0.4.0") 142 | 143 | -------------------------------------------------------------------------------- /src/commonmark.md: -------------------------------------------------------------------------------- 1 | Here we implement the markdown parser. We use commonmark and it generates an 2 | AST which we can then do whatever we like with it. Our purposes are purely 3 | informational and we extract headers, links, and code blocks. 4 | 5 | function (doc) { 6 | var gcd = doc.gcd; 7 | var file = doc.file; 8 | 9 | gcd.when("marked done:"+file, "parsing done:"+file); 10 | 11 | gcd.on("parsing done:"+file, function () { 12 | doc.parsed = true; 13 | }); 14 | 15 | var text = doc.text; 16 | _"process comments" 17 | 18 | var reader = new commonmark.Parser(); 19 | var parsed = reader.parse(text); 20 | 21 | var walker = parsed.walker(); 22 | var event, node, entering, htext = false, ltext = false, lang, code; 23 | var ind, pipes, middle, title, href, directive; //for links 24 | 25 | while ((event = walker.next())) { 26 | node = event.node; 27 | entering = event.entering; 28 | 29 | _"walk the tree" 30 | 31 | // console.log(node.type, node.literal || '', node.destination|| '', node.title|| '', node.info|| '', node.level|| '', node.sourcepos, event.entering); 32 | } 33 | 34 | gcd.emit("marked done:" + file); 35 | } 36 | 37 | 38 | ## process comments 39 | 40 | 41 | This strips the comment part of comments of the form ``. This 42 | allows one to hide a great deal from viewing while maintaining functionality. 43 | The comment needs to start at a new line. 44 | 45 | var bits = text.split("\n"); 49 | if (ind !== -1) { 50 | return el.slice(0, ind).trim() + el.slice(ind+3); 51 | } else { 52 | return el; 53 | } 54 | }).join("\n"); 55 | } 56 | 57 | 58 | 59 | # walk the tree 60 | 61 | So we examine the nodes and decide when to do something of interest. The nodes 62 | of interest are of type Heading, Link, Text, and CodeBlock. CodeBlock is easy 63 | as the literal is all we need. Both Heading and Link require us to descend and 64 | string together the text. 65 | 66 | 67 | switch (node.type) { 68 | case "text" : 69 | _":text" 70 | break; 71 | case "link" : 72 | _"link" 73 | break; 74 | case "code_block" : 75 | _":code" 76 | break; 77 | case "heading" : 78 | _":heading" 79 | break; 80 | } 81 | 82 | 83 | [text]() 84 | 85 | This simply adds the text to an array if the array is there. We have header 86 | text and link text. Since links may be in headers, we have two separate text 87 | trackers. 88 | 89 | if (htext) { 90 | htext.push(node.literal); 91 | } 92 | if (ltext) { 93 | ltext.push(node.literal); 94 | } 95 | 96 | [heading]() 97 | 98 | Headings create blocks. We emit an event to say we found one. We collect the 99 | text as we go with the text and then join them when ready. 100 | 101 | if (entering) { 102 | htext = []; 103 | } else { 104 | gcd.emit("heading found:"+node.level+":"+file, htext.join("")); 105 | htext = false; 106 | } 107 | 108 | [code]() 109 | 110 | We emit found code blocks with optional language. These should be stored and 111 | concatenated as need be. 112 | 113 | lang = node.info; 114 | code = node.literal || ''; 115 | if (code[code.length -1] === "\n") { 116 | code = code.slice(0,-1); 117 | } 118 | if (lang) { 119 | gcd.emit("code block found:"+lang+":"+file, code); 120 | } else { 121 | gcd.emit("code block found:"+ file, code); 122 | } 123 | 124 | ### Link 125 | 126 | Links may be directives if one of the following things occur: 127 | 128 | 1. Title contains a colon. If so, then it is emitted as a directive with the 129 | stuff preceeding the colon being a directive. The data sent is an array 130 | with the link text, the stuff after the colon, and the href being sent. No 131 | pipe parsing is done at this point. 132 | 2. Title starts with a colon in which case it is a switch directive. The stuff 133 | after the colon is sent as second in the data array, with the link text as 134 | first. The href in this instance is completely ignored. There is some pipe 135 | processing that happens. 136 | 3. Title and href are empty. 137 | 138 | Return the text in case it is included in a header; only the link text will be 139 | in the heading then. 140 | 141 | if (entering) { 142 | ltext = []; 143 | } else { 144 | href = node.destination; 145 | 146 | Commonmark translates `^` into `%5E`. This undoes that. May want to think 147 | about a general transformation back or to block it, but this is sufficient for 148 | now. 149 | 150 | if (href === "#%5E") { 151 | href = "#^"; 152 | } 153 | title = node.title; 154 | ltext = ltext.join('').trim(); 155 | 156 | if (title) { 157 | title = title.replace(/'/g, "'").replace(/"/g, '"'); 158 | } 159 | if ((!href) && (!title)) { 160 | gcd.emit("switch found:"+file, [ltext, ""]); 161 | } else if (title[0] === ":") { 162 | if ((ltext.indexOf("|") !== -1) || ( ltext.length === 0) ) { 163 | _":transform" 164 | } else { 165 | _":switch with pipes" 166 | } 167 | } else if ( (ind = title.indexOf(":")) !== -1) { 168 | _":directive" 169 | } 170 | ltext = false; 171 | } 172 | 173 | [transform]() 174 | 175 | This becomes a directive, but looks a lot like a switch. It kind of fills in 176 | the gap of main blocks not having pipes that can act on them. The idea is that 177 | this can transform the text and do something with it, maybe just log or eval'd 178 | or stored in a different variable. 179 | 180 | It is triggered by having a pipe in the link text; one can 181 | then write a descriptive for the rest of the link text before the pipe and/or 182 | a variable name to store the result in after the pipe. One can also have 183 | empty link text though that becomes entirely hidden to the reader and is best not done. 184 | 185 | gcd.emit("directive found:transform:" + file, 186 | { link : ltext, 187 | input : title.slice(1), 188 | href: href, 189 | cur: doc.curname, 190 | directive : "transform" 191 | } 192 | ); 193 | 194 | 195 | 196 | [directive]() 197 | 198 | A nice customary directive found. The load and save prefixes allow for 199 | changing the path. Those directives need that data sent to them. 200 | 201 | directive = doc.convertHeading(title.slice(0,ind)); 202 | var toSend = { link : ltext, 203 | input : title.slice(ind+1), 204 | href: href, 205 | cur: doc.curname, 206 | directive : directive 207 | }; 208 | if (doc.loadprefix) { 209 | toSend.loadprefix = doc.loadprefix; 210 | } 211 | if (doc.saveprefix) { 212 | toSend.saveprefix = doc.saveprefix; 213 | } 214 | gcd.emit("directive found:" + 215 | directive + ":" + file, 216 | toSend 217 | ); 218 | 219 | 220 | [switch with pipes]() 221 | 222 | Switch probably with pipes. This adds an extension in the middle of colon and 223 | pipe. Really not 224 | sure why. Probably should remove that. 225 | 226 | ind = 0; 227 | _":before pipe" 228 | if (middle) { 229 | ltext += "." + middle.toLowerCase(); 230 | } 231 | gcd.emit("switch found:" + file, [ltext,pipes]); 232 | 233 | 234 | 235 | [before pipe]() 236 | 237 | This takes the possible part in the middle between the switch directive's colon and 238 | the first pipe. 239 | 240 | This will produce `middle === 'js'` for `: js` or `: js| jshint` with the 241 | latter producing `pipes === 'jshint'`. If there is no extension such as `:` 242 | or `: | jshint`, then `middle === ''` and should be falsey. 243 | 244 | We add a quote to pipes to terminate it as that is a signal to end in other 245 | pipe parsings, one that got stripped by the title matching of links. 246 | 247 | 248 | pipes = title.indexOf("|"); 249 | if (pipes === -1) { 250 | middle = title.slice(ind+1).trim(); 251 | pipes = ''; 252 | } else { 253 | middle = title.slice(ind+1, pipes).trim(); 254 | pipes = title.slice(pipes+1).trim(); 255 | } 256 | 257 | 258 | 259 | 260 | -------------------------------------------------------------------------------- /src/debugging.md: -------------------------------------------------------------------------------- 1 | This is where we have some reporters. This is a section to be greatly 2 | improved. 3 | 4 | 5 | Folder.reporters = { 6 | save : _"directives::save:reporter", 7 | out : _"directives::out:reporter", 8 | "command defined" : _"directives::define directive:reporter", 9 | "scope exists" : _"stitching::create global scope:reporter", 10 | "text" : _"text reporter", 11 | "minor" : _"text reporter", 12 | "retrieval" : _"retrieval reporter", 13 | "cmd" : _"command reporter" 14 | 15 | }; 16 | 17 | Folder.prototype.reportwaits = _"reporting on waiting"; 18 | 19 | Folder.prototype.simpleReport = _"Simple Report"; 20 | 21 | 22 | ## Simple Report 23 | 24 | This generates a report of the stitch fragments that have not yet been 25 | resolved. 26 | 27 | function () { 28 | var folder = this; 29 | var recording = folder.recording; 30 | var gcd = this.gcd; 31 | var key, lname, ret = [], el, pieces; 32 | var v = this.colon.v; 33 | for (key in gcd.whens) { 34 | if (key.slice(0,15) === "stitch fragment") { 35 | lname = key.slice(16); 36 | ret.push("PROBLEM WITH: " + recording[lname] + 37 | " IN: " + lname.slice(lname.indexOf(":")+1, 38 | lname.indexOf(v) ) + 39 | " FILE: " + lname.slice(0, lname.indexOf(":"))); 40 | } 41 | } 42 | for (key in gcd._onces) { 43 | el = gcd._onces[key]; 44 | if ( el[0].slice(0, 15) === "command defined") { 45 | pieces = key.split(":"); 46 | if (pieces.length < 3) { 47 | gcd.error("error:simple report:"+ el[1]); 48 | return ret; 49 | } 50 | ret.push("COMMAND REQUESTED: " + 51 | pieces[1] + 52 | " BUT NOT DEFINED. REQUIRED IN: " + 53 | pieces[3].slice(0, pieces[3].indexOf(v)) + 54 | " FILE: " + pieces[2] ); 55 | } 56 | } 57 | return ret; 58 | } 59 | 60 | ### Reporting on waiting 61 | 62 | This is a folder level function that goes through and reports on everything, 63 | returning an array of waiting arguments. 64 | 65 | function () { 66 | var report = this.reports; 67 | var reporters = this.reporters; 68 | var arr, msg, data, temp; 69 | 70 | arr = []; 71 | 72 | for (msg in report) { 73 | data = report[msg]; 74 | if (reporters.hasOwnProperty(data[0]) ) { 75 | temp = reporters[data[0]].call(this, data.slice(1) ); 76 | if (temp) { 77 | arr.push(temp); 78 | } else { 79 | // console.log(msg, data); 80 | } 81 | } 82 | } 83 | 84 | return arr; 85 | } 86 | 87 | 88 | ### Text Reporter 89 | 90 | This function deals with text that we are waiting for. 91 | 92 | function (data) { 93 | var hint = this.recording[data[0]]; 94 | var parts = data[0].split(":").reverse(); 95 | var block = parts[0].split(this.colon.v)[0]; 96 | if (hint) { 97 | return "PROBLEM WITH: " + hint + " IN: " + block + 98 | " FIlE: " + parts[1]; 99 | } 100 | 101 | } 102 | 103 | ### Retrieval Reporter 104 | 105 | This function deal with waiting for a variable to be stored. 106 | 107 | function (data) { 108 | return "NEED VAR: " + data[1] + " FROM: " + data[0]; 109 | } 110 | 111 | ### Command Reporter 112 | 113 | This reports on somebody waiting for a command. 114 | 115 | function (data) { 116 | var ind = data[1].lastIndexOf(this.colon.v); 117 | if (ind === -1) { 118 | ind = data[1].length + 1; 119 | } 120 | var name = data[1].slice(0, ind); 121 | var hint = this.recording[name]; 122 | return "NEED COMMAND: " + data[0] + " FOR: " + hint; 123 | } 124 | 125 | ## var tracking 126 | 127 | This is an attempt to report sections that have been asked for, but have not 128 | been reported. 129 | 130 | This was an idea, I tried, couldn't get it quite right, so nullifying it, but 131 | leaving it here for now for inspiration. 132 | 133 | [initialize](# ": | echo ") 134 | 135 | this.varTrack = {}; 136 | 137 | [need var](# ": | echo ") 138 | 139 | doc.parent.varTrack[file + "::" + varname] = true; 140 | 141 | [has var](# ": | echo ") 142 | 143 | doc.parent.varTrack[ file + "::" + varname ] = false; 144 | 145 | [report](# ": | echo ") 146 | 147 | process.on('exit', function () { 148 | console.log(Object.keys(parent.varTrack). 149 | sort(). 150 | reduce(function (prev, cur) { 151 | if (parent.varTrack[cur]) { 152 | return prev + "\nNEED: " + cur; 153 | } else { 154 | return prev; 155 | } 156 | }, '') 157 | ); 158 | }); 159 | 160 | -------------------------------------------------------------------------------- /src/events.md: -------------------------------------------------------------------------------- 1 | These are the handler actions common to much. Note that some handlers are 2 | defined in the code and are difficult to overwrite. This was done for 3 | closure's sake and ease. Perhaps it will get revised. 4 | 5 | 6 | _"Action compiling block | oa" 7 | 8 | _"heading | oa" 9 | 10 | _"heading 5| oa" 11 | 12 | _"heading 6| oa" 13 | 14 | _"switch| oa" 15 | 16 | _"code | oa" 17 | 18 | _"code ignore | oa" 19 | 20 | _"directive | oa" 21 | 22 | _"Ready to start compiling blocks |oa" 23 | 24 | _"what is waiting| oa" 25 | 26 | _"directives::push:action | oa" 27 | 28 | 29 | ## done when 30 | 31 | This creates the done object which is needed for done and when commands. 32 | 33 | this.done = { 34 | gcd : new EvW(), 35 | cache : {} 36 | }; 37 | this.done.gcd.action("done", _"commands::done:action", this); 38 | 39 | ## apply 40 | 41 | We will load events, actions, and handlers, etc., here. They should be passed 42 | in to the constructor in the form of `method name: [ [args 1], [args2], ...]` 43 | and this method will iterate over it all to load the events and so forth to 44 | the emitter. 45 | 46 | function (instance, obj) { 47 | var meth, i, n; 48 | 49 | for (meth in obj) { 50 | n = obj[meth].length; 51 | for (i = 0; i < n; i += 1) { 52 | instance[meth].apply(instance, obj[meth][i]); 53 | } 54 | 55 | } 56 | } 57 | 58 | 59 | ## parsing events 60 | 61 | These are common events that need to be loaded to the emitter. These are the 62 | ones that assemble the literate programs. 63 | 64 | 65 | ### heading vars 66 | 67 | This is just an intro that seems commonly needed. 68 | 69 | var file = evObj.pieces[0]; 70 | var doc = gcd.parent.docs[file]; 71 | 72 | ### init block 73 | 74 | I am separating out this one line since I may want to revise it. We have the 75 | option of concatenating what is already there or overwriting. While I think it 76 | is best form not to have the same block name twice and concatenating it up, 77 | there may be use cases for it and this might also help track down accidental 78 | double blocking (you get the code of both blocks to search for!). 79 | 80 | if ( ! doc.blocks.hasOwnProperty(curname) ) { 81 | doc.blocks[curname] = ''; 82 | } 83 | 84 | ### heading 85 | 86 | Headings create blocks. For heading levels 1-4, they create new blocks on an 87 | equal footing. For heading leavels 5,6, they create relative blocks using 88 | slashes from the currently selected block (a directive could be used to switch 89 | current block?) Level 6 is relative to level 5 and the level above so 90 | something like `great code/test/particular` from a 3, 5, 6 combo. 91 | 92 | The headings are there to start code blocks. The code blocks concatenate into 93 | whatever is there. 94 | 95 | We use doc.levels to navigate 96 | 97 | heading found --> add block 98 | _"heading vars" 99 | var text = doc.convertHeading(data); 100 | var curname = doc.heading = doc.curname = text; 101 | doc.levels[0] = text; 102 | doc.levels[1] = ''; 103 | doc.levels[2] = ''; 104 | _"init block" 105 | 106 | ### heading 5 107 | 108 | The 5 level is one level below current heading. We stop the event propagation. 109 | 110 | 111 | heading found:5 --> add slashed block 112 | _"heading vars" 113 | var text = doc.convertHeading(data); 114 | doc.levels[1] = text; 115 | doc.levels[2] = ''; 116 | var curname = doc.heading = doc.curname = doc.levels[0]+'/'+text; 117 | _"init block" 118 | evObj.stop = true; 119 | 120 | 121 | ### heading 6 122 | 123 | The 6 level is one level below current heading. We stop the event propagation. 124 | 125 | 126 | heading found:6 --> add double slashed block 127 | _"heading vars" 128 | var text = doc.convertHeading(data); 129 | doc.levels[2] = text; 130 | var curname = doc.heading = doc.curname = doc.levels[0]+'/'+doc.levels[1]+'/'+text; 131 | _"init block" 132 | evObj.stop = true; 133 | 134 | ### switch 135 | 136 | Whenever a minor block directive is found, this is used. 137 | 138 | It uses the doc.heading as the base, appending a colonated heading stored in 139 | the current name. Note the colon is a triple colon. All variable recalls will 140 | have colons transformed into triple colons. This is stored in colon.v for 141 | global overriding if need be. 142 | 143 | Switches can execute stuff on the compiled block. To signify when done, we 144 | emit gcd.emit("text ready:"+ curname). But within the block compiling, we will 145 | emit a text ready:minor:... which we should listen for here. 146 | 147 | Note that for piping of minors, there could be a problem if those listening 148 | for the text then call something else wanting it; there could be a gap from 149 | when the text ready event is fired and the storage happens. It won't happen 150 | unless piping is going on. And the risk seems low. Let me know if it is a 151 | problem. 152 | 153 | switch found --> create minor block 154 | _"heading vars" 155 | var colon = doc.colon; 156 | var text = doc.convertHeading(data[0]); 157 | 158 | var subEmit, textEmit, doneEmit; 159 | 160 | var curname = doc.curname = doc.heading+colon.v+text; 161 | _"init block" 162 | 163 | 164 | var title = data[1]; 165 | var fname = evObj.pieces[0] + ":" + curname; 166 | doneEmit = "text ready:" + fname; 167 | var pipename; 168 | if (title) { // need piping 169 | title = title.trim()+'"'; 170 | pipename = fname + colon.v + "sp"; 171 | textEmit = "text ready:" + pipename; 172 | subEmit = "switch chain done:" + pipename; 173 | 174 | gcd.when(textEmit, subEmit); 175 | 176 | gcd.once(subEmit, function (data) { 177 | var text = data[data.length-1][1] || ''; 178 | doc.store(curname, text); 179 | gcd.emit(doneEmit, text); 180 | }); 181 | 182 | gcd.flatWhen("minor ready:" + fname, textEmit); 183 | 184 | doc.pipeParsing(title, 0, '"' , pipename, doc.heading, 185 | subEmit, textEmit ); 186 | } else { //just go 187 | gcd.once("minor ready:" + fname, function (text) { 188 | doc.store(curname, text); 189 | }); 190 | gcd.flatWhen("minor ready:" + fname, "text ready:" + fname); 191 | 192 | } 193 | 194 | 195 | ### code 196 | 197 | Code blocks are concatenated into the current one. The language is ignored for 198 | this. 199 | 200 | If no language is provided, we just call it none. Hopefully there is no 201 | language called none?! 202 | 203 | We join them by adding doc.join character; this is default a newline. 204 | 205 | Note: doc.blockOff allows us to stop compiling the blocks. This is a hack. I 206 | tried to manipulate the action, but somehow that did not work. Anyway, this 207 | will be scoped to the doc so that's good. 208 | 209 | code block found --> add code block 210 | _"heading vars" 211 | if (doc.blockOff > 0) { return;} 212 | if (doc.blocks[doc.curname]) { 213 | doc.blocks[doc.curname] += doc.join + data; 214 | } else { 215 | doc.blocks[doc.curname] = data; 216 | } 217 | 218 | 219 | ### code ignore 220 | 221 | If you want to have code that gets ignored, you can use code fences with a 222 | language of `ignore`. We do nothing other than stop the event propagation. 223 | 224 | The downside is that we loose the highlight. One can provide other events in 225 | plugins the could ignore other languages. For example, if you are coding in 226 | JavaScript, you could have JavaScript being ignored while js not being 227 | ignored. Or you could just put the code in its own block. 228 | 229 | code block found:ignore --> ignore code block 230 | evObj.stop = true; 231 | gcd=gcd; //js hint quieting 232 | 233 | 234 | ### directive 235 | 236 | Here we deal with directives. A directive can do a variety of things and it is 237 | not at all clear what can be done in general to help the process. Note that 238 | directives, unlike switches, are not parsed for pipes or anything after the 239 | colon is touched. 240 | 241 | You can also stop this generic handling by listening for a specific directive 242 | and stopping the propagation with evObj.stop = true. 243 | 244 | This really just converts from event handling to function calling. Probably a 245 | bit easier for others to handle. 246 | 247 | 248 | directive found --> process directives 249 | _"heading vars" 250 | var fun; 251 | var directive = evObj.pieces[1]; 252 | if (directive && (fun = doc.directives[directive] ) ) { 253 | fun.call(doc, data); 254 | } 255 | 256 | 257 | ## Action compiling block 258 | 259 | This is where we deal with parsing a given code block and handling the 260 | substituting. 261 | 262 | This is a function that responds to the event `block needs compiling:file:block name`. 263 | 264 | 265 | block needs compiling --> compiling block 266 | var file = evObj.pieces[1]; 267 | var blockname = evObj.pieces[0]; 268 | var doc = gcd.parent.docs[file]; 269 | var block = doc.blocks[blockname]; 270 | doc.blockCompiling(block, file, blockname); 271 | 272 | 273 | 274 | ## Ready to start compiling blocks 275 | 276 | We will compile each block once the parsing is done. 277 | 278 | To exclude a block from the compiling phase, use the directives block off and 279 | later block on to turn the block back on. 280 | 281 | parsing done --> list blocks to compile 282 | var file = evObj.pieces[0]; 283 | var doc = gcd.parent.docs[file]; 284 | var blocks = doc.blocks; 285 | var name; 286 | for (name in blocks) { 287 | gcd.emit("block needs compiling:" + file + ":" + name); 288 | } 289 | 290 | ## What is waiting 291 | 292 | This is where we define the waiting function. It takes in a message to report 293 | for whatever is interested in checking (maybe the end of a process or in a web 294 | page, a user clicking on a report -- difficult since the compilation phase 295 | never officially ends). It also takes in an array that should be of the form 296 | `[event for removal, type of reporter, args for reporters...]` 297 | 298 | `waiting for:type:file:name, [evt, reportname, args to report` 299 | 300 | 301 | waiting for --> wait reporting 302 | 303 | var reports = gcd.parent.reports; 304 | 305 | var evt = data[0]; 306 | var msg = evObj.pieces.slice(0,-1).reverse().join(":"); 307 | 308 | 309 | reports[msg] = data.slice(1); 310 | gcd.once(evt, function () { 311 | delete reports[msg]; 312 | }); 313 | 314 | ## Convert Heading 315 | 316 | This converts the heading to a normal form with lower caps, one space, no 317 | spaces at ends. 318 | 319 | function (str) { 320 | var reg = /\s+/g; 321 | str = str.trim().toLowerCase(); 322 | str = str.replace(reg, " "); 323 | return str; 324 | } 325 | 326 | 327 | ## On action 328 | 329 | To smoothly integrate event-action workflows, we want to take a block, using 330 | the first line for an on and action pairing. 331 | 332 | Then the rest of it will be in the function block of the action. 333 | 334 | The syntax is `event --> action : context` on the first line and the rest 335 | are to be used as the function body of the handler associated with the 336 | action. The handler has signature data, evObj. 337 | 338 | 339 | function (code) { 340 | var lines = code.split("\n"); 341 | 342 | var top = lines.shift().split("-->"); 343 | var event = top[0].trim(); 344 | var actcon = top[1].split(":"); 345 | var action = actcon[0].trim(); 346 | var context = (actcon[1] || "").trim(); 347 | 348 | var ret = 'gcd.on("' + event + '", "' + action + 349 | '"' + (context ? (', ' + context) : '') + ");\n\n"; 350 | 351 | ret += 'gcd.action("' + action + '", '; 352 | ret += 'function (data, evObj) {\n var gcd = evObj.emitter;\n'; 353 | ret += ' ' + lines.join('\n '); 354 | ret += '\n }\n);'; 355 | 356 | return ret; 357 | } 358 | 359 | [oa](# "define:") 360 | 361 | 362 | ## Event playbook 363 | 364 | !Be skeptical of the following. 365 | 366 | So this is a quick sketch of the kinds of events and actions that get taken in 367 | the course of compiling. A tilde means it is not literal but rather a 368 | variable name. 369 | 370 | * Document compiling starts with a `need parsing:~filename, text` 371 | 372 | 373 | * `text ready` is for when a text is ready for being used. Each level of use 374 | had a name and when the text is ready it gets emitted. The emitted data 375 | should either by text itself or a .when wrapped up [[ev, data]] setup. 376 | 377 | * filename:blockname;loc;comnum;argnum(;comnum;argnum...) 378 | 379 | 380 | -------------------------------------------------------------------------------- /src/logs.md: -------------------------------------------------------------------------------- 1 | This deals with the log data 2 | 3 | _":fp | sub SEP, '\n* * *\n', FEN, '\n`````\n', ARG, '\n~~~\n' " 4 | 5 | [fp]() 6 | 7 | Folder.prototype.log = _"log"; 8 | Folder.prototype.error= _"error"; 9 | Folder.prototype.warn= _"warn"; 10 | Folder.prototype.dirlog = _"directive log"; 11 | Folder.prototype.cmdlog = _"command log"; 12 | Folder.prototype.eventlog = _"events"; 13 | Folder.prototype.formatters = { 14 | _"|formatters error, warn, out, log, command log, 15 | one arg, directive log, events | compile " 16 | }; 17 | Folder.prototype.reportOut = _"out reporter"; 18 | Folder.prototype.logLevel = 0; 19 | 20 | [formatters]() 21 | 22 | function (input, args) { 23 | return args. 24 | map( el => '"' + el + '": \_`' + el + ':formatter`'). 25 | join(",\n"); 26 | } 27 | 28 | [formatters](# "define:") 29 | 30 | [junk]() 31 | 32 | ```ignore 33 | error: _"error:formatter", 34 | warn : _"warn:formatter", 35 | out : _"diagnostics:formatter", 36 | log : _"log:formatter", 37 | "command log" : _"diagnostics:cmd log formatter", 38 | "one arg" : _"diagnostics:one arg", 39 | "directive log" : "directive log:formatter" 40 | ``` 41 | 42 | ## Doc 43 | 44 | This is for the doc constructor. 45 | 46 | this.logs = _"diagnostics"; 47 | this.log = this.parent.log; 48 | this.error = this.parent.error; 49 | this.warn = this.parent.warn; 50 | this.dirlog = this.parent.dirlog; 51 | this.cmdlog = this.parent.cmdlog; 52 | this.eventlog = this.parent.eventlog; 53 | 54 | ## Diagnostics 55 | 56 | We have error, warnings, and logs of various levels. They get collected into a 57 | single object whose keys are errors, warnings, and numbered log entries. Each 58 | keyed entry points to an array. This is created for each doc. 59 | 60 | { 61 | error : [], 62 | warn : [], 63 | events : [], 64 | "command log" : [], 65 | "directive log" : {}, 66 | out : {}, 67 | 0 : [] 68 | } 69 | 70 | ### Out 71 | 72 | [formatter]() 73 | 74 | function (obj) { 75 | return Object.keys(obj). 76 | map(function (key) { 77 | return "### " + key + "\n`````\n" + obj[key] + "\n`````"; 78 | }). 79 | join(SEP); 80 | } 81 | 82 | 83 | 84 | [cmd log formatter]() 85 | junk 86 | 87 | This is for the command log. 88 | 89 | function (list) { 90 | _"|globals typeit" 91 | 92 | var ret = list.map(function (arr) { 93 | var ret = ''; 94 | var t = typeit(input); 95 | var input = arr.shift(); 96 | var args = arr.shift(); 97 | var msg = args.shift(); 98 | if (msg) { 99 | ret += "ID: " + msg; 100 | } 101 | if (t === 'undefined' || t === 'null') { 102 | ret += "TYPE: " + t; 103 | } else if (t !== 'string') { 104 | ret += "TYPE: " + t + "\n" + input.toString(); 105 | } else { 106 | ret += input; 107 | } 108 | ret += args.join(ARG); 109 | return ret; 110 | }). 111 | join(SEP); 112 | 113 | return ret; 114 | } 115 | 116 | 117 | ### One Arg 118 | 119 | [formatter]() 120 | 121 | This is a function suitable for logging types that just have one (short) 122 | argument that does not need a separator. 123 | 124 | function (list) { 125 | var ret = ''; 126 | ret += list.map( 127 | function (args) { 128 | return args.shift(); 129 | }). 130 | join("\n"); 131 | return ret; 132 | } 133 | 134 | 135 | 136 | 137 | ### Out Reporter 138 | 139 | This creates a reporter. The filter is a function that filters out the keys of 140 | the diagnostic tools. The idea is, for example, to just get a specific kind of 141 | log message for debugging purposes. 142 | 143 | It is designed to eliminate any parts that are empty of content. 144 | 145 | function (filter) { 146 | var folder = this; 147 | var formatters = folder.formatters; 148 | var docs = Object.keys(folder.docs); 149 | var ret = ''; 150 | docs.forEach(function (key) { 151 | var dig = folder.docs[key].logs; 152 | _":text generation | sub DOCSTRING, 153 | ec('"# DOC: " + key + "\n" ') " 154 | }); 155 | var dig = this.logs; 156 | _":text generation | sub DOCSTRING, 157 | ec('"# FOLDER LOGS\n"') " 158 | 159 | The fences may add too many newlines, so we remove one. 160 | 161 | ret = ret.replace(FEN + "\n", FEN); 162 | return ret; 163 | } 164 | 165 | [text generation]() 166 | 167 | This is the common part of the text. 168 | 169 | var temp = ''; 170 | var keys = Object.keys(dig); 171 | if (typeit(filter, 'function') ) { 172 | keys = keys.filter(filter); 173 | } 174 | temp += keys.map (function (typ) { 175 | var str = ''; 176 | if (typeit(formatters[typ], 'function') ) { 177 | str += formatters[typ](dig[typ]); 178 | } else { 179 | str += formatters.log(dig[typ], typ); 180 | } 181 | if (str) { 182 | str = "## " + typ.toUpperCase() + "\n" + str; 183 | } 184 | return str; 185 | }). 186 | filter(function (el) {return !!el;}). 187 | join("\n"); 188 | if (temp) { 189 | ret += (ret ? "\n" : "") + DOCSTRING + temp; 190 | } 191 | 192 | [details]() 193 | 194 | if (args.length) { 195 | ret += "\n * " + 196 | args.join("\n * "); 197 | } 198 | 199 | 200 | ### Log 201 | 202 | This is the logging function 203 | 204 | function (msg, level) { 205 | var out = this.logs; 206 | var args = Array.prototype.slice.call(arguments, 2); 207 | args.unshift(msg); 208 | if (typeit(level, "undefined")) { 209 | out[0].push(args); 210 | } else { 211 | if (typeit(out[level], "array") ) { 212 | out[level].push(args); 213 | } else { 214 | out[level] = [args]; 215 | } 216 | } 217 | 218 | } 219 | 220 | [formatter]() 221 | 222 | function (list) { 223 | return list.map( 224 | function (args) { 225 | var msg = args.shift(); 226 | var ret = "* " + msg; 227 | _"out reporter:details" 228 | return ret; 229 | }). 230 | join(SEP); 231 | } 232 | 233 | 234 | 235 | ### Error 236 | 237 | This creates an error function that can be called. It can be overwritten on 238 | the `Folder.prototype.error` or individually on a doc. 239 | 240 | function () { 241 | var doc = this; 242 | var gcd = doc.gcd; 243 | var args = Array.prototype.slice.call(arguments); 244 | 245 | doc.logs.error.push(args); 246 | //shuts off all further processing 247 | gcd.stop(); 248 | } 249 | 250 | [formatter]() 251 | 252 | This can be used to do a foreach on the error argument. 253 | 254 | function (list) { 255 | return list.map( 256 | function (args) { 257 | var kind = args.shift(); 258 | var description = args.shift(); 259 | var ret = "### " + kind + "\n" + description + "\n"; 260 | if (args.length) { 261 | ret += args.join("\n* "); 262 | } 263 | return ret; 264 | }). 265 | join("\n"); 266 | } 267 | 268 | 269 | ### Warn 270 | 271 | Same as error, except no stopping of execution. 272 | 273 | function () { 274 | var doc = this; 275 | var args = Array.prototype.slice.call(arguments); 276 | 277 | doc.logs.warn.push(args); 278 | } 279 | 280 | 281 | [formatter]() 282 | 283 | _"error:formatter" 284 | 285 | ### Events 286 | 287 | This has the form event, label, data. The label allows us to group them. 288 | 289 | function (event, lbl, data) { 290 | var out = this.logs; 291 | out.events.push([lbl, event, data]); 292 | } 293 | 294 | [pre-formatter]() 295 | 296 | Sort by lbl, then use lbl as a `###` heading and have `event` on its own line 297 | followed by code fences and data. 298 | 299 | function (list) { 300 | var types = {}; 301 | list.forEach(function (el) { 302 | var lbl = el[0]; 303 | if (!(types[lbl]) ) { 304 | types[lbl] = []; 305 | } 306 | types[lbl].push(el.slice(1)); 307 | }); 308 | return Object.keys(types).map(function (el) { 309 | var str = "### " + el + "\n"; 310 | str += types[el].map(function (evd) { 311 | var event = evd[0]; 312 | var data = evd[1]; 313 | return event + 314 | DATA; 315 | }). 316 | join(SEP); 317 | return str; 318 | }). 319 | join(SEP); 320 | } 321 | 322 | [formatter]() 323 | 324 | _":pre-formatter | sub DATA, _':data'" 325 | 326 | [data]() 327 | 328 | This is for the data. 329 | 330 | (data ? (FEN + data + FEN) : '') 331 | 332 | ### command log 333 | 334 | Has the form input, type (first arg as grouping), other args. Basically the 335 | same function as event log with a bit of change in names. 336 | 337 | _"events | sub out.events, out['command log'], event, input" 338 | 339 | [formatter]() 340 | 341 | Similar idea to event log, but the data are the args of the log (except for 342 | first one) and thus we want to join the data 343 | 344 | _"events:pre-formatter | sub DATA, _':args'" 345 | 346 | [args]() 347 | 348 | (data.length ? (ARG + data.join(ARG) ) : '' ) 349 | 350 | ### directive log 351 | 352 | Has the form `name, data`. We expect the name and store it in an object. 353 | 354 | function (name, data) { 355 | _"|globals doc" 356 | var out = doc.logs; 357 | if (!name) { 358 | name = 'dirlog'+this.uniq(); 359 | doc.warn('dir:log', 'need unique name for directive log', name); 360 | } 361 | out["directive log"][name] = data; 362 | } 363 | 364 | [formatter]() 365 | 366 | We want to sort by name and then do `name \n fence data` 367 | 368 | function (obj) { 369 | var keys = Object.keys(obj); 370 | return keys.map(function (name) { 371 | var data = obj[name]; 372 | return name + FEN + data + FEN; 373 | }). 374 | join(SEP); 375 | } 376 | 377 | 378 | -------------------------------------------------------------------------------- /src/matrix.md: -------------------------------------------------------------------------------- 1 | This creates a two dimension array from the text. 2 | 3 | 4 | var Matrix = _"constructor"; 5 | 6 | Matrix.prototype = _"prototype"; 7 | 8 | Folder.Matrix = Matrix; 9 | 10 | Folder.sync("matrixify", _":fun"); 11 | 12 | [fun]() 13 | 14 | function (input, args) { 15 | return new Matrix(input, args); 16 | } 17 | 18 | ## Constructor 19 | 20 | Note that pushing the row array into the result is correct; we want an array 21 | of arrays. 22 | 23 | We escape it by slicing out the escape character if the next is an escaped 24 | character. 25 | 26 | function (code, args) { 27 | var rowsep, colsep, esc, doTrim, i, start, row, seps, char; 28 | if (typeit(code, 'string')) { 29 | _":string" 30 | } else if (typeit(code, 'array')) { 31 | this.mat = code; 32 | } 33 | 34 | return this; 35 | } 36 | 37 | [string]() 38 | 39 | If it is a string passed in, then we parse it and create. 40 | 41 | rowsep = this.rowsep = args[0] || this.rowsep; 42 | colsep = this.colsep = args[1] || this.colsep; 43 | esc = this.escp = args[2] || this.esc; 44 | doTrim = ( typeof args[3] !== "undefined") ? args[3] : this.doTrim; 45 | 46 | i = 0; 47 | start = 0; 48 | row = []; 49 | this.mat = [row]; 50 | seps = [rowsep, esc, colsep]; 51 | while (i < code.length) { 52 | char = code[i]; 53 | if (char === rowsep) { 54 | row.push(code.slice(start, i)); 55 | start = i + 1; 56 | row = []; 57 | this.mat.push(row); 58 | } else if (char === colsep) { 59 | row.push(code.slice(start, i)); 60 | start = i + 1; 61 | } else if (char === esc) { 62 | char = code[i+1]; 63 | if (seps.indexOf(char) !== -1) { 64 | code = code.slice(0,i) + char + 65 | code.slice(i+1); 66 | } 67 | } 68 | i += 1; 69 | } 70 | row.push(code.slice(start)); 71 | if (doTrim) { 72 | this.trim(); 73 | } 74 | 75 | ## Doc 76 | 77 | * **matrixify** This takes in some text and splits into a two dimensional 78 | array using the passed in separators. The first separator divides the 79 | columns, the second divides the rows. The result is an array each of 80 | whose entries are the rows. There is also an escape character. The 81 | defaults are commas, newlines, and backslashes, respectively. The escpae 82 | character escapes the separators and itself, nothing else. There is also 83 | a boolean for whether to trim entries; that is true by default. Pass in 84 | `f()` in the fourth argument if not desired. All the characters should 85 | be just that, of length 1. 86 | 87 | This returns a matrix (prototyped) that has the properties: 88 | * `rows` Iterates a function over the rows. If an array is returned, it 89 | replaces the row. 90 | * `cols` Iterates a function over the cols and will also replace the 91 | columns if an array is returned. 92 | * `transpose` This returns a new matrix with flipped rows and columns. 93 | * `trim` This trims the entries in the matrix, returning the original. 94 | * `num` This converts every entry into a number, when possible. 95 | * `clone` This creates a copy. 96 | * `traverse` This runs through the matrix, applying a function to each 97 | entry, the arguments being `element, inner index, outer index, the 98 | row object, the matrix`. 99 | * `equals` This takes in a second matrix and checks if they are strictly 100 | equal. 101 | * `print` This prints the matrix using the passed in row and col 102 | separator or using the property 103 | 104 | ## Prototype 105 | 106 | This is where we create various matrix prototype properties. 107 | 108 | { 109 | rowsep : "\n", 110 | colsep : ",", 111 | esc : "\\", 112 | doTrim : true, 113 | transpose : _"mat transpose", 114 | traverse : _"mat traverse", 115 | trim : _"mat trim", 116 | clone : "_mat clone", 117 | num : _"mat num", 118 | scale : _"mat scale", 119 | rows : _"rows", 120 | cols : _"cols", 121 | equals : _"equals", 122 | print : _"print" 123 | } 124 | 125 | ## Mat transpose 126 | 127 | This flips the matrix, a two-d array. It returns a new object since we have a 128 | mess unless it is square. 129 | 130 | function () { 131 | var old = this.mat; 132 | var ret = new Matrix('', []); 133 | var result = ret.mat; 134 | var oldcols = old.reduce(function (n, el) { 135 | return Math.max(n, el.length); 136 | }, 0); 137 | var i; 138 | for (i=0; i < oldcols; i += 1) { 139 | result[i] = []; 140 | } 141 | var oldrows = old.length, j; 142 | for (i = 0; i < oldcols; i+= 1) { 143 | for (j=0; j< oldrows ; j += 1) { 144 | result[i][j] = old[j][i]; 145 | } 146 | } 147 | return ret; 148 | } 149 | 150 | ## Mat traverse 151 | 152 | This takes in a function that should act on each entry. If it returns a value, 153 | then it replaces that value. 154 | 155 | function (fun) { 156 | var mat = this; 157 | if ( (typeof fun) !== "function" ) { 158 | //this is an error, not sure who to tell 159 | return; 160 | } 161 | mat.mat.forEach(function (row, rind) { 162 | row = row.forEach(function (el, ind) { 163 | var val = fun(el, ind, rind, row, mat.mat); 164 | if (typeof val !== "undefined") { 165 | row[ind] = val; 166 | } 167 | }); 168 | }); 169 | return this; 170 | } 171 | 172 | ## Mat trim 173 | 174 | This guards against things that might not have trim, hopefully in a way that 175 | is not bad for large matrices. 176 | 177 | function () { 178 | var trim = function (el) { 179 | if (typeof el.trim === "function") { 180 | return el.trim(); 181 | } else { 182 | return; 183 | } 184 | }; 185 | this.traverse(trim); 186 | return this; 187 | } 188 | 189 | ### Mat clone 190 | 191 | function () { 192 | var ret = new Matrix('', []); 193 | var clone = ret.mat; 194 | var currow = 0; 195 | cloning = function (el, ind, rind) { 196 | if (rind === currow) { 197 | clone[rind][ind] = el; 198 | } else if (rind === (currow +1) { 199 | clone.push([]); 200 | currow = rind; 201 | clone[rind][ind] = el; 202 | } else { 203 | //error! 204 | } 205 | }; 206 | this.traverse(cloning); 207 | return ret; 208 | } 209 | 210 | ### Mat num 211 | 212 | This converts everything into a number or NaN. 213 | 214 | function () { 215 | var fun = function (el) { 216 | return parseFloat(el); 217 | }; 218 | this.traverse(fun); 219 | return this; 220 | } 221 | 222 | ### Mat scale 223 | 224 | This converts everything into a number or NaN. 225 | 226 | function (scalar) { 227 | var fun = function (el) { 228 | return el*scalar; 229 | }; 230 | this.traverse(fun); 231 | return this; 232 | } 233 | 234 | 235 | ## rows 236 | 237 | This creates a copy of the rows and applies the incoming function to it. 238 | 239 | The matrix is inherently row-based so we can just do a forEach over them. 240 | 241 | function (f, val) { 242 | var red = (typeit(val, "!undefined") ); 243 | var self = this; 244 | var mat = self.mat; 245 | mat.forEach(function (row, ind) { 246 | var ret = f(row.slice(), ind, self, val); 247 | if (typeit(ret, 'array') ) { 248 | mat[ind] = ret; 249 | } else { 250 | val = ret; 251 | } 252 | }); 253 | if ( red ) { 254 | return val; 255 | } else { 256 | return self; 257 | } 258 | } 259 | 260 | ## cols 261 | 262 | This creates a copy of the columns and applies the incoming function to it. 263 | 264 | The matrix is inherently row-based so we use the transpose function (transpose 265 | --> rows --> transpose). If the 266 | columns get modified, then replace the original matrix object's matrix with 267 | the new ones. This is not cool. 268 | 269 | function (f, val) { 270 | var red = typeit(val, "!undefined"); 271 | var self = this; 272 | var trans = self.transpose(); 273 | val = trans.rows(f, val); 274 | var dbl = trans.transpose(); 275 | if (! (dbl.equals(self) ) ) { 276 | self.mat = dbl.mat; 277 | } 278 | if ( red ) { 279 | return val; 280 | } else { 281 | return self; 282 | } 283 | } 284 | 285 | ## equals 286 | 287 | Are the values of the two matrices the same? Any differences and we return 288 | false. 289 | 290 | function (other) { 291 | var self = this; 292 | var i, n, srow, orow, j, m; 293 | var smat = self.mat; 294 | var omat = other.mat; 295 | if (smat.length !== omat.length) { 296 | return false; 297 | } 298 | n = smat.length; 299 | for (i = 0; i < n; i +=1) { 300 | srow = smat[i]; 301 | orow = omat[i]; 302 | if (srow.length !== orow.length) { 303 | return false; 304 | } 305 | m = srow.length; 306 | for (j= 0; j < m; j += 1) { 307 | if (srow[j] !== orow[j] ) { 308 | return false; 309 | } 310 | } 311 | } 312 | return true; 313 | } 314 | 315 | ## Print 316 | 317 | This prints the matrix. 318 | 319 | Should deal with escaping stuff as well. But leaving that off for now. This is 320 | mainly for quick printing out. 321 | 322 | function (rowsep, colsep) { 323 | var self = this; 324 | rowsep = (typeit(rowsep, 'undefined') ) ? this.rowsep : rowsep; 325 | colsep = (typeit(colsep, 'undefined') ) ? this.colsep : colsep; 326 | var ret = []; 327 | self.rows(function (row) { 328 | ret.push(row.join(rowsep)); 329 | }); 330 | return ret.join(colsep); 331 | } 332 | -------------------------------------------------------------------------------- /src/requires.md: -------------------------------------------------------------------------------- 1 | # Requires 2 | 3 | Here are some utility functions that may be of some general use and reside in 4 | the Folder.requires object. 5 | 6 | ### Unique counter 7 | 8 | This is a little helper counter that one can use to generate a unique count 9 | for event names. Best to avoid if possible, but this will deal with 10 | non-uniqueness effectively. 11 | 12 | `doc.uniq` 13 | 14 | function () { 15 | var counter = 0; 16 | return function () { 17 | return counter += 1; 18 | }; 19 | } 20 | 21 | 22 | ## Merge 23 | 24 | This is modified from yeikos https://github.com/yeikos/js.merge 25 | with `Copyright 2014 yeikos - MIT license` 26 | 27 | This is for relatively simple objects. 28 | 29 | The first two arguments are to determine whether the object should be cloned 30 | and, if so, whether it should be done recursively, that is, whether subitems 31 | should be cloned. 32 | 33 | function (bclone, recursive) { 34 | var merge_recursive = _":merge recurse"; 35 | var merge = _":top merge"; 36 | if ( typeit(bclone) !== 'boolean' ) { 37 | return merge(false, false, arguments); 38 | } else if (typeit(recursive) !== 'boolean') { 39 | return merge(bclone, false, arguments); 40 | } else { 41 | return merge(bclone, recursive, arguments); 42 | } 43 | } 44 | 45 | 46 | 47 | [merge recurse]() 48 | 49 | function merge_recursive(base, extend) { 50 | 51 | if ( typeit(base) !== 'object') { 52 | return extend; 53 | } 54 | 55 | var i, key; 56 | var keys = Object.keys(extend); 57 | var n = keys.length; 58 | for (i = 0; i < n; i += 1) { 59 | key = keys[i]; 60 | if ( (typeit(base[key]) === 'object') && 61 | (typeit(extend[key]) === 'object') ) { 62 | base[key] = merge_recursive(base[key], extend[key]); 63 | } else { 64 | base[key] = extend[key]; 65 | } 66 | } 67 | return base; 68 | } 69 | 70 | 71 | [top merge]() 72 | 73 | This merges two or more objects, recursively. 74 | 75 | function merge(bclone, recursive, argv) { 76 | 77 | var result = argv[0]; 78 | var n = argv.length; 79 | 80 | if (bclone || typeit(result) !== 'object') { 81 | result = {}; 82 | } 83 | 84 | var item, sitem, key, i, type, j, m, keys; 85 | for ( i=0; i=" : _":comparator | sub OP, >=", 549 | ">" : _":comparator | sub OP, >", 550 | "<=" : _":comparator | sub OP, <=", 551 | "<" : _":comparator | sub OP, <", 552 | "!=" : _":compare all | sub OP, ==", 553 | "!==" : _":compare all | sub OP, ===", 554 | "flag" : function (flag) { 555 | return this.parent.flags.hasOwnProperty(flag); 556 | }, 557 | "match" : _":match", 558 | "type" : _":type" 559 | } 560 | 561 | [comparator]() 562 | 563 | function (args) { 564 | var prev = args.shift(); 565 | var ret = args.every(function (el) { 566 | var one = prev; 567 | prev = el; 568 | return (one OP el); 569 | }); 570 | return ret; 571 | } 572 | [compare all]() 573 | 574 | For something like not equals, we need to compare all the pairs. 575 | 576 | function (args) { 577 | var i, j, n = args.length, cur; 578 | for (i = 0; i < n; i += 1) { 579 | cur = args[i]; 580 | for (j = i + 1; j < n; j += 1) { 581 | if ( (cur OP args[j] ) ) { 582 | return false; 583 | } 584 | } 585 | } 586 | return true; 587 | } 588 | 589 | [match]() 590 | 591 | This checks if the first argument has or matches the string/reg that followes 592 | it. 593 | 594 | function (args) { 595 | _"|globals doc, typeit" 596 | 597 | var str = args[0]; 598 | var condition = args[1]; 599 | 600 | if (typeit(str) !== 'string') { 601 | _":match-warn | sub DESC, 602 | first argument needs to be a string" 603 | } 604 | 605 | var typ = typeit(condition); 606 | 607 | if (typ === 'string') { 608 | return (str.indexOf(condition) !== -1); 609 | } else if (typ === 'regexp') { 610 | return (condition.test(str)); 611 | } else { 612 | _":match-warn | sub DESC, 613 | second argument needs to be string or regex" 614 | } 615 | 616 | } 617 | 618 | [match-warn]() 619 | 620 | doc.warn("subcmd:boolean match", 621 | "DESC", 622 | "inputs: ", str, condition); 623 | return false; 624 | 625 | 626 | 627 | [type]() 628 | 629 | This uses typeit to check the type of the object and checks to see if it 630 | matches any of the types. If the second argument is an exclamation point, it 631 | checks to see if it is not any of the types that follow. 632 | 633 | function (obj) { 634 | _"|globals typeit" 635 | 636 | var args = Array.prototype.slice.call(arguments, 1); 637 | 638 | var t = typeit(obj); 639 | 640 | if (args.length === 1) { 641 | return t === args[0]; 642 | } else if (args[0] === '!') { 643 | args.shift(); 644 | return args.every(function (el) { 645 | return t !== el; 646 | }); 647 | } else { 648 | return args.some(function (el) { 649 | return t === el; 650 | }); 651 | } 652 | 653 | } 654 | 655 | -------------------------------------------------------------------------------- /src/tests.md: -------------------------------------------------------------------------------- 1 | Let's create a testing environment. The idea is that we'll have a series of 2 | documents in the tests folder that will have the convention `name - 3 | description` at the top, then three dashed separator line to create a new 4 | document to parse followed by its result. In more advanced tests, we will 5 | introduce a syntax of input/output and related names. 6 | 7 | The log array should be cleared between tests. 8 | 9 | Underscores in filenames trigger different behavior; one underscore will limit 10 | test runs to just those and produce some simple info. Two underscores will 11 | list all events fired. 12 | 13 | Only files wit `.md` extension are considered, but all of them are. To have 14 | one not be run, change extension to, say, `.mdn` 15 | 16 | /*global require, setTimeout, console*/ 17 | /*jslint evil:true*/ 18 | 19 | var fs = require('fs'); 20 | var test = require('tape'); 21 | var Litpro = require('./index.js'); 22 | 23 | 24 | var testrunner = _"testrunner"; 25 | 26 | var equalizer = _"equalizer"; 27 | 28 | var spaces = _"spaces"; 29 | 30 | _"testfiles" 31 | 32 | 33 | Litpro.commands.readfile = Litpro.prototype.wrapAsync(_"test async", "readfile"); 34 | 35 | 36 | var i, n = testfiles.length; 37 | 38 | for (i =0; i < n; i += 1) { 39 | testrunner(testfiles[i]); 40 | } 41 | 42 | ### testrunner 43 | 44 | This is a function that sets up and then runs the test. We need a function to 45 | avoid the implicit closures if it was looped over code. Yay async! 46 | 47 | The plan is: read in the file, split it on `---`, figure out what is to be 48 | input vs output and link the tests to the outputs being saved, and then 49 | process the inputs. 50 | 51 | function (file) { 52 | 53 | 54 | 55 | var pieces, name, i, n, td, newline, piece, 56 | start, text, j, m, filename; 57 | 58 | var testdata = {}; 59 | 60 | text = fs.readFileSync('./tests/'+file, 'utf-8'); 61 | pieces = text.split("\n---"); 62 | 63 | name = file + ": " + spaces(file) + pieces.shift().trim(); 64 | 65 | td = testdata[name] = { 66 | start : [], 67 | in : {}, 68 | out : {}, 69 | log : [] 70 | }; 71 | 72 | 73 | _"set up test data" 74 | 75 | 76 | var folder = new Litpro({ 77 | "on" : [ 78 | ["need document", "fetch document"], 79 | ["document fetched", "compile document"] 80 | ], 81 | "action" : [ 82 | ["fetch document", _"test fetch document"], 83 | ["compile document", _"test compile document"] 84 | ] 85 | }); 86 | var gcd = folder.gcd; 87 | 88 | 89 | var log = td.log; 90 | 91 | if (monitor) { 92 | //gcd.makeLog(); 93 | //data too messy so just event name 94 | gcd.monitor('', function (evt) { console.log(evt); }); 95 | } 96 | 97 | test(name, function (t) { 98 | var outs, m, j, out; 99 | 100 | _"dealing with logs" 101 | 102 | outs = Object.keys(td.out); 103 | m = outs.length; 104 | 105 | t.plan(m+log.length+ (td.reports ? 1 : 0)); 106 | 107 | for (j = 0; j < m; j += 1) { 108 | out = outs[j]; 109 | gcd.on("file ready:" + out, equalizer(t, td.out[out]) ); 110 | } 111 | 112 | 113 | start = td.start; 114 | n = start.length; 115 | for (i = 0; i < n; i += 1) { 116 | filename = start[i]; 117 | if (!folder.docs.hasOwnProperty(filename) ) { 118 | folder.newdoc(filename, td.in[filename]); 119 | } 120 | } 121 | 122 | var notEmit = _"not emitting"; 123 | 124 | if (showLogs) { 125 | notEmit(); 126 | setTimeout( function () { 127 | console.log( 128 | "Scopes: ", folder.scopes, 129 | "\nRecording: " , folder.recording 130 | );}, 100); 131 | setTimeout( function () { 132 | console.log(folder.reportwaits().join("\n")); 133 | }); 134 | } 135 | }); 136 | } 137 | 138 | 139 | ## Testfiles 140 | 141 | To gather the files, we read the tests directory, filter on`.md` files, and we 142 | see if there are any that contain an underscore. If so, we flag that as on 143 | the list to run and ignore the others. With one underscore, we run it and give 144 | out some basic information. With two underscores, we monitor it. This is 145 | global (assuming just one file at a time, anyway). 146 | 147 | var reduced = []; 148 | var showLogs = false; 149 | var monitor = false; 150 | var testfiles = fs.readdirSync('./tests').filter(function(el) { 151 | if ( (/\.md$/).test(el) ) { 152 | if ( (/\_/).test(el) ) { 153 | reduced.push(el); 154 | showLogs = true; 155 | if ( (/\__/).test(el) ) { 156 | monitor = true; 157 | } 158 | } 159 | return true; 160 | } else { 161 | return false; 162 | } 163 | }); 164 | testfiles = (reduced.length !== 0) ? reduced : testfiles; 165 | 166 | 167 | 168 | 169 | ## Set up test data 170 | 171 | Here we put the tests into testdata either as an input or output. If there are 172 | just two, we assume the first is input and the second is output. The default 173 | names are in and out, respectively. So we should save the output to out. 174 | 175 | The start listing are the ones that get specifically processed. The in, which 176 | includes the starts, are those that can be loaded from within the documents. 177 | 178 | We split the log portion (if present) on `\n!`. We will expect a test for 179 | each log entry and we will verify by the called log function text being in the 180 | array. That should cover most cases. 181 | 182 | 183 | if (pieces.length === 2) { 184 | // \n---\n will be assumed and the rest is to be used 185 | // the first is input, the second is output 186 | td.start.push("in"); 187 | td.in.in = pieces[0].slice(1); 188 | td.out.out = pieces[1].slice(1).trim(); 189 | } else { 190 | m = pieces.length; 191 | for (j = 0; j < m; j += 1) { 192 | piece = pieces[j]; 193 | newline = piece.indexOf("\n"); 194 | if (piece.slice(0,3) === "in:") { 195 | td.in[piece.slice(3, newline)] = piece.slice(newline + 1); 196 | } else if (piece.slice(0,4) === "out:") { 197 | td.out[piece.slice(4, newline)] = 198 | piece.slice(newline + 1).trim(); 199 | } else if (piece.slice(0,6) === "start:") { 200 | td.start.push(piece.slice(6, newline)); 201 | td.in[piece.slice(6, newline)] = piece.slice(newline + 1); 202 | } else if (piece.slice(0,4) === "log:" ) { 203 | td.log = piece.slice(newline + 1).split("\n!"); 204 | td.log.pop(); // test log should end in an \n! 205 | if( td.log[0]) { 206 | td.log[0] = td.log[0].slice(1); 207 | } 208 | } else if (piece.slice(0, 8) === "reports:") { 209 | td.reports = piece.slice(newline+1); 210 | } 211 | } 212 | } 213 | _":check start for save" 214 | 215 | [check start for save]() 216 | 217 | So we want a convenience measure in which if there is no save our out, then we 218 | use the beginning block of the first start. 219 | 220 | We have two natural options: 221 | * scan all the starts and ins for "out:" and "save:" directives. Failing to 222 | find any, we add one `[out](#^ "save:")` to the end of the start. 223 | * look for a first header in the first start. Failure leads to appending the 224 | save. 225 | 226 | We'll do the second for convenience. 227 | 228 | var firstName = td.start[0]; 229 | var firstText = td.in[firstName]; 230 | if ( !(/^#/).test(firstText) ) { 231 | if (firstText) { 232 | td.in[firstName] = firstText + '\n[out](#^ "save:")'; 233 | //console.log(td.in[firstName]); 234 | } 235 | } 236 | 237 | 238 | 239 | 240 | ### Dealing with logs 241 | 242 | This is a bit of a pain with logs. Trying to make it somewhat work. This cuts 243 | out the doc.log normal behavior. We can try that out in a different place 244 | (logs-doc.md). 245 | 246 | So here we want to convert the incoming command log and directive log into 247 | their original form which worked for these tests. The second argument is the 248 | type. 249 | 250 | if (td.log.length > 0) { 251 | _":log replace" 252 | } else if (td.reports) { 253 | _":reports" 254 | } else { 255 | _":convert warn" 256 | _":convert warn | sub warn, error, WARNING, ERROR" 257 | folder.cmdlog = folder.log = function () { 258 | var args = Array.prototype.slice.call(arguments, 0); 259 | console.log.apply(console, args); 260 | }; 261 | } 262 | 263 | [log replace]() 264 | 265 | This replaces the log functions for inspection. 266 | 267 | folder.eventlog = _":event log"; 268 | folder.cmdlog = _":cmd log"; 269 | folder.dirlog = _":dir log"; 270 | folder.log = function (text) { 271 | if (log.indexOf(text) !== -1) { 272 | t.pass(); 273 | } else { 274 | console.log(text); 275 | t.fail(text); 276 | } 277 | }; 278 | 279 | 280 | [event log]() 281 | 282 | Here we want something of the form `EVENT: ... DATA: ...` 283 | 284 | function (event, type, data) { 285 | folder.log("EVENT: " + event + " DATA: " + data); 286 | } 287 | 288 | 289 | [dir log]() 290 | 291 | 292 | function (name, data) { 293 | folder.log("DIR LOG:" + name + "\n" + data); 294 | } 295 | 296 | [cmd log]() 297 | 298 | Here we join the input with the args using tildas to separate. 299 | 300 | function (input, lbl, args) { 301 | if (lbl) { 302 | args.unshift(lbl); 303 | } 304 | args.unshift(input); 305 | folder.log(args.join("\n~~~\n")); 306 | } 307 | 308 | [reports]() 309 | 310 | This checks the report format. This is a bit tricky in that we need to do this 311 | at the end of the process, but it is not always clear when that happens. We 312 | will assume this is for nonasync with just one in file. The queueEmpty should 313 | be fine to use after the parsing is done event has been dealt with. 314 | 315 | gcd.on("parsing done", function () { 316 | gcd.queueEmpty = function () { 317 | var rep = folder.reportOut(); 318 | if (rep.trim() === td.reports.trim()) { 319 | t.pass("report testing"); 320 | } else { 321 | t.fail("bad report"); 322 | console.log( 323 | "ACTUAL:\n" + rep + 324 | "\n~~~\n" + 325 | "EXPECTED:\n" + td.reports 326 | ); 327 | } 328 | }; 329 | }); 330 | 331 | [convert warn]() 332 | 333 | folder.warn = function (kind, description ) { 334 | console.error("\nWARNING:\nKind: " + kind + 335 | "\nDescription: " + description + 336 | "\nArgs:\n" + 337 | Array.prototype.slice.call(arguments, 2).join("\n~~~\n")); 338 | }; 339 | 340 | 341 | ### Not emitting 342 | 343 | This hopefully is useful diagnostic information for saying why something did 344 | not fire. 345 | 346 | function () { 347 | var key, el, nofire; 348 | var comreg = /command defined/; 349 | var textreg = /text stored/; 350 | var savereg = /for save/; 351 | for (key in gcd._onces) { 352 | el = gcd._onces[key]; 353 | nofire = el[0]; 354 | if (comreg.test(nofire)) { 355 | console.log("COMMAND NOT DEFINED: " + 356 | nofire.slice( ("command defined:").length ) ); 357 | } else if (textreg.test(nofire) ) { 358 | console.log("NOT STORED: " + 359 | nofire.slice(("text stored:").length) ); 360 | } else if (savereg.test(nofire) ) { 361 | //nothing; report waits will get it 362 | } else { 363 | console.log("DID NOT FIRE: " + nofire); 364 | } 365 | } 366 | } 367 | 368 | [junk]() 369 | 370 | function () { 371 | setTimeout( function () { 372 | var key, el; 373 | for (key in gcd.whens) { 374 | console.log("NOT EMITTING: " + key + " BECAUSE OF " + 375 | Object.keys(gcd.whens[key].events).join(" ; ")); 376 | } 377 | 378 | for (key in gcd._onces) { 379 | el = gcd._onces[key]; 380 | console.log("NOT EXECUTED "+ el[1] + " TIMES: " + 381 | key + " BECAUSE EVENT " + el[0] + 382 | " DID NOT FIRE. " + el[2] + " TIMES LEFT" 383 | ); 384 | } 385 | 386 | }); 387 | } 388 | 389 | ### Equalizer 390 | 391 | This is just a little function constructor to close around the handler for the 392 | output file name. 393 | 394 | function (t, out) { 395 | return function (text) { 396 | if (text !== out) { 397 | if ( (text[text.length-1] === "\n") && 398 | (out[out.length-1] !== "\n" ) ) { 399 | out += "\n"; 400 | } else { 401 | console.log(text + "---\n" + out); 402 | } 403 | } 404 | t.equals(text, out); 405 | }; 406 | } 407 | 408 | ### Test fetch document 409 | 410 | This will fetch the document from the ins of the testdata. 411 | 412 | The emit will be of the form "need document:file location", 413 | with data being the actual file location. 414 | 415 | function (rawname, evObj) { 416 | var gcd = evObj.emitter; 417 | var filename = evObj.pieces[0]; 418 | 419 | if (td.in.hasOwnProperty(filename) ) { 420 | gcd.emit("document fetched:" + filename, td.in[rawname]); 421 | } else { 422 | console.log("ERROR~File not found: " + filename); 423 | gcd.parent.createScope(filename); 424 | gcd.emit("error:file not found:"+ filename); 425 | 426 | } 427 | 428 | } 429 | 430 | ### Test compile document 431 | 432 | This takes in the text of a file and compiles it. 433 | 434 | function (text, evObj) { 435 | var gcd = evObj.emitter; 436 | var filename = evObj.pieces[0]; 437 | var folder = gcd.parent; 438 | 439 | setTimeout(function () { 440 | folder.newdoc(filename, text); 441 | }, 1); 442 | 443 | } 444 | 445 | ### Test async 446 | 447 | This is the example async function. It takes in filename and gives out the 448 | text after a timeout. This is to simulate a readfile, but without actually 449 | using the file structures. 450 | 451 | function (input, args, cb) { 452 | var f = function () { 453 | if (args[0] === "stuff") { 454 | cb(null, "Hello world. I am cool."); 455 | } else if ( args[0] === "hello") { 456 | cb(null, "'Hello world.' + ' I am js.'"); 457 | } else { 458 | cb(new Error("no such file")) ; 459 | } 460 | }; 461 | setTimeout(f, 5); 462 | } 463 | 464 | ## Spaces 465 | 466 | This adds spaces if needed in between filename and description to get past 467 | the equals messages. 468 | 469 | function (file) { 470 | var n = ("ok ... should be equal").length - file.length; 471 | var i; 472 | var ret = ''; 473 | for (i = 0; i < n; i += 1 ) { 474 | ret += ' '; 475 | } 476 | return ret; 477 | } 478 | 479 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | /*global require, setTimeout, console*/ 2 | /*jslint evil:true*/ 3 | 4 | var fs = require('fs'); 5 | var test = require('tape'); 6 | var Litpro = require('./index.js'); 7 | 8 | 9 | var testrunner = function (file) { 10 | 11 | 12 | 13 | var pieces, name, i, n, td, newline, piece, 14 | start, text, j, m, filename; 15 | 16 | var testdata = {}; 17 | 18 | text = fs.readFileSync('./tests/'+file, 'utf-8'); 19 | pieces = text.split("\n---"); 20 | 21 | name = file + ": " + spaces(file) + pieces.shift().trim(); 22 | 23 | td = testdata[name] = { 24 | start : [], 25 | in : {}, 26 | out : {}, 27 | log : [] 28 | }; 29 | 30 | 31 | if (pieces.length === 2) { 32 | // \n---\n will be assumed and the rest is to be used 33 | // the first is input, the second is output 34 | td.start.push("in"); 35 | td.in.in = pieces[0].slice(1); 36 | td.out.out = pieces[1].slice(1).trim(); 37 | } else { 38 | m = pieces.length; 39 | for (j = 0; j < m; j += 1) { 40 | piece = pieces[j]; 41 | newline = piece.indexOf("\n"); 42 | if (piece.slice(0,3) === "in:") { 43 | td.in[piece.slice(3, newline)] = piece.slice(newline + 1); 44 | } else if (piece.slice(0,4) === "out:") { 45 | td.out[piece.slice(4, newline)] = 46 | piece.slice(newline + 1).trim(); 47 | } else if (piece.slice(0,6) === "start:") { 48 | td.start.push(piece.slice(6, newline)); 49 | td.in[piece.slice(6, newline)] = piece.slice(newline + 1); 50 | } else if (piece.slice(0,4) === "log:" ) { 51 | td.log = piece.slice(newline + 1).split("\n!"); 52 | td.log.pop(); // test log should end in an \n! 53 | if( td.log[0]) { 54 | td.log[0] = td.log[0].slice(1); 55 | } 56 | } else if (piece.slice(0, 8) === "reports:") { 57 | td.reports = piece.slice(newline+1); 58 | } 59 | } 60 | } 61 | var firstName = td.start[0]; 62 | var firstText = td.in[firstName]; 63 | if ( !(/^#/).test(firstText) ) { 64 | if (firstText) { 65 | td.in[firstName] = firstText + '\n[out](#^ "save:")'; 66 | //console.log(td.in[firstName]); 67 | } 68 | } 69 | 70 | 71 | var folder = new Litpro({ 72 | "on" : [ 73 | ["need document", "fetch document"], 74 | ["document fetched", "compile document"] 75 | ], 76 | "action" : [ 77 | ["fetch document", function (rawname, evObj) { 78 | var gcd = evObj.emitter; 79 | var filename = evObj.pieces[0]; 80 | 81 | if (td.in.hasOwnProperty(filename) ) { 82 | gcd.emit("document fetched:" + filename, td.in[rawname]); 83 | } else { 84 | console.log("ERROR~File not found: " + filename); 85 | gcd.parent.createScope(filename); 86 | gcd.emit("error:file not found:"+ filename); 87 | 88 | } 89 | 90 | }], 91 | ["compile document", function (text, evObj) { 92 | var gcd = evObj.emitter; 93 | var filename = evObj.pieces[0]; 94 | var folder = gcd.parent; 95 | 96 | setTimeout(function () { 97 | folder.newdoc(filename, text); 98 | }, 1); 99 | 100 | }] 101 | ] 102 | }); 103 | var gcd = folder.gcd; 104 | 105 | 106 | var log = td.log; 107 | 108 | if (monitor) { 109 | //gcd.makeLog(); 110 | //data too messy so just event name 111 | gcd.monitor('', function (evt) { console.log(evt); }); 112 | } 113 | 114 | test(name, function (t) { 115 | var outs, m, j, out; 116 | 117 | if (td.log.length > 0) { 118 | folder.eventlog = function (event, type, data) { 119 | folder.log("EVENT: " + event + " DATA: " + data); 120 | }; 121 | folder.cmdlog = function (input, lbl, args) { 122 | if (lbl) { 123 | args.unshift(lbl); 124 | } 125 | args.unshift(input); 126 | folder.log(args.join("\n~~~\n")); 127 | }; 128 | folder.dirlog = function (name, data) { 129 | folder.log("DIR LOG:" + name + "\n" + data); 130 | }; 131 | folder.log = function (text) { 132 | if (log.indexOf(text) !== -1) { 133 | t.pass(); 134 | } else { 135 | console.log(text); 136 | t.fail(text); 137 | } 138 | }; 139 | } else if (td.reports) { 140 | gcd.on("parsing done", function () { 141 | gcd.queueEmpty = function () { 142 | var rep = folder.reportOut(); 143 | if (rep.trim() === td.reports.trim()) { 144 | t.pass("report testing"); 145 | } else { 146 | t.fail("bad report"); 147 | console.log( 148 | "ACTUAL:\n" + rep + 149 | "\n~~~\n" + 150 | "EXPECTED:\n" + td.reports 151 | ); 152 | } 153 | }; 154 | }); 155 | } else { 156 | folder.warn = function (kind, description ) { 157 | console.error("\nWARNING:\nKind: " + kind + 158 | "\nDescription: " + description + 159 | "\nArgs:\n" + 160 | Array.prototype.slice.call(arguments, 2).join("\n~~~\n")); 161 | }; 162 | folder.error = function (kind, description ) { 163 | console.error("\nERROR:\nKind: " + kind + 164 | "\nDescription: " + description + 165 | "\nArgs:\n" + 166 | Array.prototype.slice.call(arguments, 2).join("\n~~~\n")); 167 | }; 168 | folder.cmdlog = folder.log = function () { 169 | var args = Array.prototype.slice.call(arguments, 0); 170 | console.log.apply(console, args); 171 | }; 172 | } 173 | 174 | outs = Object.keys(td.out); 175 | m = outs.length; 176 | 177 | t.plan(m+log.length+ (td.reports ? 1 : 0)); 178 | 179 | for (j = 0; j < m; j += 1) { 180 | out = outs[j]; 181 | gcd.on("file ready:" + out, equalizer(t, td.out[out]) ); 182 | } 183 | 184 | 185 | start = td.start; 186 | n = start.length; 187 | for (i = 0; i < n; i += 1) { 188 | filename = start[i]; 189 | if (!folder.docs.hasOwnProperty(filename) ) { 190 | folder.newdoc(filename, td.in[filename]); 191 | } 192 | } 193 | 194 | var notEmit = function () { 195 | var key, el, nofire; 196 | var comreg = /command defined/; 197 | var textreg = /text stored/; 198 | var savereg = /for save/; 199 | for (key in gcd._onces) { 200 | el = gcd._onces[key]; 201 | nofire = el[0]; 202 | if (comreg.test(nofire)) { 203 | console.log("COMMAND NOT DEFINED: " + 204 | nofire.slice( ("command defined:").length ) ); 205 | } else if (textreg.test(nofire) ) { 206 | console.log("NOT STORED: " + 207 | nofire.slice(("text stored:").length) ); 208 | } else if (savereg.test(nofire) ) { 209 | //nothing; report waits will get it 210 | } else { 211 | console.log("DID NOT FIRE: " + nofire); 212 | } 213 | } 214 | }; 215 | 216 | if (showLogs) { 217 | notEmit(); 218 | setTimeout( function () { 219 | console.log( 220 | "Scopes: ", folder.scopes, 221 | "\nRecording: " , folder.recording 222 | );}, 100); 223 | setTimeout( function () { 224 | console.log(folder.reportwaits().join("\n")); 225 | }); 226 | } 227 | }); 228 | }; 229 | 230 | var equalizer = function (t, out) { 231 | return function (text) { 232 | if (text !== out) { 233 | if ( (text[text.length-1] === "\n") && 234 | (out[out.length-1] !== "\n" ) ) { 235 | out += "\n"; 236 | } else { 237 | console.log(text + "---\n" + out); 238 | } 239 | } 240 | t.equals(text, out); 241 | }; 242 | }; 243 | 244 | var spaces = function (file) { 245 | var n = ("ok ... should be equal").length - file.length; 246 | var i; 247 | var ret = ''; 248 | for (i = 0; i < n; i += 1 ) { 249 | ret += ' '; 250 | } 251 | return ret; 252 | }; 253 | 254 | var reduced = []; 255 | var showLogs = false; 256 | var monitor = false; 257 | var testfiles = fs.readdirSync('./tests').filter(function(el) { 258 | if ( (/\.md$/).test(el) ) { 259 | if ( (/\_/).test(el) ) { 260 | reduced.push(el); 261 | showLogs = true; 262 | if ( (/\__/).test(el) ) { 263 | monitor = true; 264 | } 265 | } 266 | return true; 267 | } else { 268 | return false; 269 | } 270 | }); 271 | testfiles = (reduced.length !== 0) ? reduced : testfiles; 272 | 273 | 274 | Litpro.commands.readfile = Litpro.prototype.wrapAsync(function (input, args, cb) { 275 | var f = function () { 276 | if (args[0] === "stuff") { 277 | cb(null, "Hello world. I am cool."); 278 | } else if ( args[0] === "hello") { 279 | cb(null, "'Hello world.' + ' I am js.'"); 280 | } else { 281 | cb(new Error("no such file")) ; 282 | } 283 | }; 284 | setTimeout(f, 5); 285 | }, "readfile"); 286 | 287 | 288 | var i, n = testfiles.length; 289 | 290 | for (i =0; i < n; i += 1) { 291 | testrunner(testfiles[i]); 292 | } 293 | -------------------------------------------------------------------------------- /tests/anon.md: -------------------------------------------------------------------------------- 1 | anon -- testing the annonymous commands 2 | --- 3 | This tests the anonymous commands. 4 | 5 | _"|echo Awesome | anon return input + '!' " 6 | _"|echo Awesome | anon (input, args) => input + args.join('!'), 5, 6" 7 | _"|echo Awesome | anon fun(`function (input, args) { 8 | return input + args.join('!');}`), 9, 10 " 9 | _"|echo Awesome | anonasync 10 | ec(`return callback(null, input + '!' + args[0])`), 2 " 11 | 12 | --- 13 | Awesome! 14 | Awesome5!6 15 | Awesome9!10 16 | Awesome!2 17 | -------------------------------------------------------------------------------- /tests/arrayify.md: -------------------------------------------------------------------------------- 1 | Arrayify - testing the array making function 2 | --- 3 | # First 4 | 5 | _":main | arrayify | .map _"f|evil" | .toString" 6 | _":other | arrayify ec(' ') | .join -" 7 | _":more | arrayify | mapc compile, , what, 75 " 8 | 9 | [out](# "save:") 10 | 11 | [main]() 12 | 13 | 5 14 | 3 15 | 2 16 | 1 17 | 18 | [other]() 19 | 20 | ab ji lo\ we 21 | 22 | [more]() 23 | 24 | \_":main" 25 | _":other" 26 | \_":what" 27 | 28 | # f 29 | 30 | A map function to act on the array. 31 | 32 | ret = function (el) { 33 | return el*2; 34 | } 35 | 36 | --- 37 | 10,6,4,2 38 | ab-ji-lo we 39 | 5 40 | 3 41 | 2 42 | 1,ab ji lo\ we,75 43 | -------------------------------------------------------------------------------- /tests/assert.md: -------------------------------------------------------------------------------- 1 | Assert - testing assert 2 | ---start:in 3 | # Something 4 | 5 | this is Grate 6 | 7 | [out](# "save: | sub Grate, Great | assert this is Great, not | 8 | assert this is Grate, intended ") 9 | 10 | ---out:out 11 | this is Great 12 | ---log: 13 | !FAIL: intended 14 | ACTUAL: this is Great 15 | EXPECTED: this is Grate 16 | ! 17 | -------------------------------------------------------------------------------- /tests/async.md: -------------------------------------------------------------------------------- 1 | async - async testing 2 | --- 3 | # Async 4 | 5 | Let's get async going. So we'll start simple with a straight read file command 6 | done asynchronously. 7 | 8 | This is the command "readfile(text)" It does not use the input into it at all 9 | so it would most likely be used as an argument in another command with an 10 | empty pipe in front or just an empty pipe sub. 11 | 12 | So something like `sub *, _"|readfile stuff.txt"` 13 | 14 | Let's see if we can that working. 15 | 16 | [out](#subbing "save:") 17 | 18 | ## Text 19 | 20 | Some text. 21 | 22 | This is great. I can just insert a snippet here: 23 | 24 | _"|readfile stuff" 25 | 26 | or perhaps eval some code and use its output 27 | 28 | _"async|readfile hello|eval text = eval(text)" 29 | 30 | or using the sub 31 | 32 | * 33 | 34 | ## Subbing 35 | 36 | A subbing is done. 37 | 38 | _"text|sub *, _"|readfile stuff"" 39 | 40 | --- 41 | This is great. I can just insert a snippet here: 42 | 43 | Hello world. I am cool. 44 | 45 | or perhaps eval some code and use its output 46 | 47 | Hello world. I am js. 48 | 49 | or using the sub 50 | 51 | Hello world. I am cool. 52 | -------------------------------------------------------------------------------- /tests/asynceval.md: -------------------------------------------------------------------------------- 1 | aync eval - an eval that uses async 2 | --- 3 | # Async Eval 4 | 5 | We'll do a setTimeout and then report some text. This should establish whether 6 | eval async is working. 7 | 8 | [out](#start "save:") 9 | 10 | ## Eval Stuff 11 | 12 | This is the eval block 13 | 14 | setTimeout(function () { 15 | callback(null, "cool !eans"); 16 | }, 1); 17 | 18 | ## Start 19 | 20 | We simply run the eval and pipe into a sub. 21 | 22 | great. _"|async _"eval stuff" | sub !, b" 23 | 24 | --- 25 | great. cool beans 26 | -------------------------------------------------------------------------------- /tests/backslash.md: -------------------------------------------------------------------------------- 1 | backslash -- backslash testing 2 | --- 3 | # Backslashing 4 | 5 | This tests the backslashing numbering scheme. 6 | 7 | [sub test]() 8 | 9 | _"oops" 10 | _"oops | compile" 11 | _"oops | compile | compile" 12 | 13 | _"woops | compile jack | compile jean" 14 | 15 | [out](# "save:") 16 | 17 | 18 | ## Woops 19 | 20 | \_":this" 21 | 22 | \2_":this" 23 | 24 | ## jack 25 | 26 | [this]() 27 | 28 | hi 29 | 30 | ## jean 31 | 32 | [this]() 33 | 34 | bye 35 | 36 | 37 | ## Oops 38 | 39 | \2_"awesome | sub oo, _"self" | sub \", \' " 40 | 41 | ## awesome 42 | 43 | shoo 44 | 45 | ## self 46 | 47 | irt 48 | 49 | --- 50 | \1_"awesome | sub oo, _"self" | sub \", \' " 51 | \0_"awesome | sub oo, _"self" | sub \", \' " 52 | shirt 53 | 54 | hi 55 | 56 | bye 57 | -------------------------------------------------------------------------------- /tests/blockoff.md: -------------------------------------------------------------------------------- 1 | block off - turning code blocks on and off 2 | --- 3 | # Block on and off 4 | 5 | So we want to test turning off code blocks and their nesting. 6 | 7 | Some code 8 | 9 | [off](# "block:") 10 | 11 | more code 12 | 13 | [off](# "block:") 14 | 15 | [out](# "save:") 16 | 17 | [on](# "block:") 18 | 19 | more ignored code 20 | 21 | [on](# "block:") 22 | 23 | great 24 | --- 25 | Some code 26 | great 27 | -------------------------------------------------------------------------------- /tests/capitalizations.md: -------------------------------------------------------------------------------- 1 | Capitalizations - Checking for capitals not making a difference 2 | --- 3 | # Great 4 | 5 | Some stuff 6 | _":awesome work" 7 | 8 | [Awesome work]() 9 | 10 | Dude 11 | 12 | ## Let's go 13 | 14 | _"gReat" 15 | _"Great : awesome work" 16 | 17 | ### Still to go 18 | 19 | _"let's go" 20 | 21 | _":template | co_Mpil-e Great" 22 | 23 | [out](# "save:") 24 | 25 | [template]() 26 | 27 | \_":awesome work" 28 | 29 | --- 30 | Some stuff 31 | Dude 32 | Dude 33 | 34 | Dude 35 | -------------------------------------------------------------------------------- /tests/caps.md: -------------------------------------------------------------------------------- 1 | caps - testing the caps command 2 | --- 3 | # adding to caps 4 | 5 | doc.plugins.caps.J = "AWEsome"; 6 | 7 | [caps](# "eval:") 8 | 9 | ## caps 10 | 11 | M W<400px 12 | 13 | J 14 | 15 | [out](# "save: | caps") 16 | --- 17 | @media (max-width: 400px) 18 | 19 | AWEsome 20 | -------------------------------------------------------------------------------- /tests/cd.md: -------------------------------------------------------------------------------- 1 | Cd - changing the paths 2 | ---start:in 3 | # CD 4 | 5 | This will be a lot of saving and loading. 6 | 7 | [one/](# "cd: load") 8 | [dude](dude.md "load:") 9 | [dude2](dude2.md "load:") 10 | [](# "cd: load") 11 | 12 | [first/](# "cd: save") 13 | [one](#dude::here "save:") 14 | [two](#dude2::here "save:") 15 | [](# "cd: save") 16 | 17 | ## Reports 18 | 19 | This actually puts the output that we want to see 20 | 21 | _"|async _"timeout"" 22 | 23 | [reports](# "save:") 24 | 25 | ## Timeout 26 | 27 | This is where we do a bit of black magic to pop it out of the flow. This 28 | delays it to allow the rest of the stuff to compile and be waiting. 29 | 30 | setTimeout(function () { 31 | var a = doc.parent.simpleReport().join("\n"); 32 | var b = doc.parent.reportwaits().join("\n"); 33 | callback(null, b + "\n" + a); 34 | }, 1); 35 | 36 | 37 | ---in:one/dude.md 38 | # Here 39 | 40 | Something 41 | 42 | ---in:one/dude2.md 43 | # Here 44 | 45 | Bye 46 | ---out:first/one 47 | Something 48 | ---out:first/two 49 | Bye 50 | ---out:reports 51 | NOT SAVED: reports AS REQUESTED BY: in NEED: reports 52 | PROBLEM WITH: _"|async _"timeout"" IN: reports FILE: in 53 | -------------------------------------------------------------------------------- /tests/codeblocks.md: -------------------------------------------------------------------------------- 1 | code blocks - checking the different types of code blocks 2 | --- 3 | # Code blocks 4 | 5 | This is a series of code blocks of different types to see if it all works out 6 | fine. They should just all concatenate together 7 | 8 | jack and jill 9 | 10 | And then 11 | 12 | ``` 13 | went up a hill 14 | ``` 15 | 16 | oops 17 | 18 |
19 | ignored text
20 | 
21 | 22 | oh 23 | 24 | ```ignore 25 | also ignored 26 | ``` 27 | 28 | and 29 | 30 | ```js 31 | to fetch a pail of water 32 | ``` 33 | 34 | and then we finish (a blank line in the code fences at the end gets stripped 35 | apparently, but not a leading blank line). 36 | 37 | ``` 38 | 39 | jack fell down 40 | and broke his crown 41 | and jill came tumbling down after 42 | ``` 43 | 44 | 45 | [out](# "save:") 46 | --- 47 | jack and jill 48 | went up a hill 49 | to fetch a pail of water 50 | 51 | jack fell down 52 | and broke his crown 53 | and jill came tumbling down after 54 | -------------------------------------------------------------------------------- /tests/commands.md: -------------------------------------------------------------------------------- 1 | Commands -- testing commands 2 | --- 3 | This is a test for multiple commands. 4 | 5 | _"|echo Awesome | cmds sub, arr(Awe, Dud), sub, arr(some, thing)" 6 | 7 | _"|echo Awesome | cmds async, ec(`callback(null, text+ '!!')`) " 8 | 9 | --- 10 | Dudthing 11 | 12 | Awesome!! 13 | -------------------------------------------------------------------------------- /tests/comments-pipes.md: -------------------------------------------------------------------------------- 1 | Comments Pipes -- comments in pipes 2 | --- 3 | # Comments 4 | 5 | We would like comments in pipes. 6 | 7 | _"| echo Awesome 8 | | # what is up 9 | | sub Awe, Dud 10 | | #dude replacing awe with dud" 11 | 12 | [out](# "save: | # just making a mess 13 | | sub some, ley 14 | | # dudley yea, did dudley 15 | | # ec('what | is this , _`whatever` , ') 16 | | eval ec(`var what = Object.keys(doc.comments). 17 | sort(). 18 | map( (key) => key + ' : ' + doc.comments[key] ). 19 | join('\n'); 20 | text = text + '\n' + what;`) 21 | ") 22 | 23 | --- 24 | Dudley 25 | dude : Dudsome 26 | dudley yea : Dudley 27 | -------------------------------------------------------------------------------- /tests/comments.md: -------------------------------------------------------------------------------- 1 | comments -- testing the comments 2 | --- 3 | This implements comments in headings 4 | 5 | _":name" 6 | 7 | 8 | 9 | 10 | jack 11 | 12 | --- 13 | jack 14 | -------------------------------------------------------------------------------- /tests/compile-minidoc.md: -------------------------------------------------------------------------------- 1 | Compile-minidoc -- testing compile minidoc 2 | --- 3 | # Compile 4 | 5 | This should compile a minidoc. 6 | 7 | [out](# "save: | echo arr(1, 2, 3 ) 8 | | minors a, b, c 9 | | templating _'ralph' ") 10 | 11 | ## Ralph 12 | 13 | \_":a" = \_":b" = \_":c" 14 | 15 | 16 | [d]() 17 | 18 | hey 19 | 20 | --- 21 | 1 = 2 = 3 22 | -------------------------------------------------------------------------------- /tests/compile.md: -------------------------------------------------------------------------------- 1 | compile - compiling in a command and backslashing 2 | ---start:in 3 | # Compiling 4 | 5 | This tests compiling a block of text. The idea is to use the backslashing of 6 | the subs and then see if it can make it through. 7 | 8 | [first](first.md "load:") 9 | 10 | [out](#start "save:") 11 | 12 | ## Start 13 | 14 | Cool. _"beans | store stub | compile || " 15 | 16 | Raw. _"stub" 17 | 18 | _"stuff | compile dude" 19 | 20 | _"stuff | compile " 21 | 22 | _"stuff | compile first::filler" 23 | 24 | _"first::template | compile" 25 | 26 | [cool]() 27 | 28 | ice 29 | 30 | [hot]() 31 | 32 | steam 33 | 34 | 35 | ## Beans 36 | 37 | We will have beans and more 38 | 39 | beans and \_"more" 40 | 41 | ## More 42 | 43 | kale 44 | 45 | 46 | ## Stuff 47 | 48 | This is a template \_":cool" 49 | 50 | A second block \_":hot" 51 | 52 | ## dude 53 | 54 | [cool]() 55 | 56 | is cool. 57 | 58 | [hot]() 59 | 60 | whatever. 61 | 62 | ---in:first.md 63 | 64 | # filler 65 | 66 | This is a template section. 67 | 68 | [hot]() 69 | 70 | Rocking 71 | 72 | [cool]() 73 | 74 | Sleeping 75 | 76 | ## Template 77 | 78 | This is a simple template to see if it works as well. 79 | 80 | \_":cool" 81 | 82 | \_":hot" 83 | 84 | ---out:out 85 | 86 | Cool. beans and kale 87 | 88 | Raw. beans and _"more" 89 | 90 | This is a template is cool. 91 | 92 | A second block whatever. 93 | 94 | This is a template ice 95 | 96 | A second block steam 97 | 98 | This is a template Sleeping 99 | 100 | A second block Rocking 101 | 102 | ice 103 | 104 | steam 105 | -------------------------------------------------------------------------------- /tests/compileminor.md: -------------------------------------------------------------------------------- 1 | Compile Minors Supplied - checks for multiple argument compile 2 | --- 3 | # Template 4 | 5 | \_":dude" 6 | 7 | \_":cat" 8 | 9 | ## In space 10 | 11 | _"template|compile , cat, great" 12 | 13 | [dude]() 14 | 15 | howdy 16 | 17 | ## Out home 18 | 19 | _"in space" 20 | 21 | _"template| compile whatever, dude, this, cat, that" 22 | 23 | [out](# "save:") 24 | 25 | --- 26 | howdy 27 | 28 | great 29 | 30 | this 31 | 32 | that 33 | -------------------------------------------------------------------------------- /tests/compose.md: -------------------------------------------------------------------------------- 1 | Compose -- testing simple composition 2 | --- 3 | 4 | Need to test composing. 5 | 6 | _"stuff | split \n-!-\n " 7 | 8 | _"stuff | longsplit \n-!-\n, arr(;, some, more) " 9 | 10 | _"tb | compsplit " 11 | 12 | _"t | nlsplit temp2 " 13 | 14 | _"| arrtest" 15 | 16 | _"tb|botharrows rrl" 17 | 18 | 19 | [longsplit](# "compose: split $0 | join @1, kool, @1") 20 | 21 | [split](# "compose: .split $0 | *trim | .join 5 ") 22 | 23 | [nlsplit](# "compose: .split \n---\n | minors title, body | ->$1 | 24 | | *store $0, *KEY* | get template | compile $0 25 | | ->$2 | $1->*clear $0, *KEY* | $2-> ") 26 | 27 | [compsplit](# "compose: .split \n---\n | minors title, body 28 | | get->$0 template | templating $0 ") 29 | 30 | [arrtest](# "compose: echo this | ->@0 | echo that\nhar\n | ->@0 31 | | $0->| | *trim | .join ! ") 32 | 33 | [botharrows](# "compose: .split->$1 \n 34 | | $0->sub->$2 r, t 35 | | *sub $2, heck, ---, $0") 36 | 37 | ## template 38 | 39 | \_":title" 40 | \_":body" 41 | 42 | ## tb 43 | 44 | ttl 45 | --- 46 | body 47 | body 48 | 49 | ## t 50 | 51 | ttl 52 | 53 | ## stuff 54 | 55 | this is 56 | -!- 57 | great 58 | -!- 59 | Does it 60 | work 61 | -!- 62 | Yes 63 | --- 64 | this is5great5Does it 65 | work5Yes 66 | 67 | this is5great5Does it 68 | work5Yes;kool;some;more 69 | 70 | ttl 71 | body 72 | body 73 | 74 | ttl 75 | 76 | 77 | this!that 78 | har 79 | 80 | heck 81 | rrl 82 | body 83 | body 84 | -------------------------------------------------------------------------------- /tests/config.md: -------------------------------------------------------------------------------- 1 | config -- testing a configuration style pass-in 2 | --- 3 | 4 | The point of this is to demonstrate how configuration information can be 5 | passed into a function -- think of it as named parameters, if you like. 6 | 7 | _"|paired set(kv(1, +, 2, *, join, -- )), 8 | num(1, 2, 3, 4, 5), clog(!!!hey)" 9 | _"|paired set(kv(1, *, 2, + )), 10 | num(1, 2, 3, 4, 5), clog(!!!reversed) | store arr | 11 | slice num(1, 2) | cat !" 12 | _"|paired args(act( _"arr", concat, _"arr"))" 13 | 14 | 15 | ## op 16 | 17 | Define your own two step action. First it does the operation of 1, pairwise in 18 | sequence, generating a n-1 list, then it does it again with 2, giving n-2. The 19 | result is returned 20 | 21 | var f = function (input, args, name) { 22 | var i, n=args.length, doc = this, arr = []; 23 | var conf = doc.gcd.scope(name) || {}; 24 | var first = conf[1] || "+"; 25 | var second = conf[2] || "*"; 26 | ops = { 27 | '+' : function (l, r) { return l + r;}, 28 | '*' : function (l, r) { return l*r;} 29 | } 30 | for (i = 0; i < n-1 ; i +=1 ) { 31 | arr.push(ops[first](args[i], args[i+1])); 32 | } 33 | for (i = 0; i < n-2; i +=1 ) { 34 | arr[i] = ops[second](arr[i], arr[i+1]); 35 | } 36 | arr.pop(); //get rid of last one 37 | if (conf.join) { 38 | return arr.join(conf.join); 39 | } else { 40 | return arr; 41 | } 42 | } 43 | 44 | 45 | f = doc.sync("paired", f); 46 | 47 | f.subCommands = Object.create(doc.subCommands); 48 | 49 | f.subCommands.clog = function (text) { 50 | console.log(text); 51 | }; 52 | 53 | 54 | doc.gcd.emit("command defined:paired"); 55 | 56 | [eval](# "eval:") 57 | 58 | ## sli 59 | 60 | This is to test whether things other than text can be piped. 61 | 62 | function (arr, args) { 63 | return arr.slice(args[0], args[1]); 64 | } 65 | 66 | [slice](# "define:") 67 | 68 | --- 69 | 15--35--63 70 | 18! 71 | 1300,2000,1040,1300 72 | -------------------------------------------------------------------------------- /tests/constructor.md: -------------------------------------------------------------------------------- 1 | constructor -- the heading constructor has an issue 2 | --- 3 | # Engine 4 | 5 | TODO: To code engine in requirejs format for module. It should use public/private and defaults 6 | 7 | (function() { 8 | Evo = Evo || {}; 9 | Evo.Csp = Evo.Csp || {}; 10 | 11 | _"Constructor" 12 | })(); 13 | 14 | [out](#engine "save:") 15 | 16 | ## Constructor 17 | 18 | Constructor of the object accepts the csp structure and options. 19 | 20 | awesome stuff. really 21 | 22 | --- 23 | (function() { 24 | Evo = Evo || {}; 25 | Evo.Csp = Evo.Csp || {}; 26 | 27 | awesome stuff. really 28 | })(); 29 | -------------------------------------------------------------------------------- /tests/cycle.md: -------------------------------------------------------------------------------- 1 | cycle -- cycle tester of blocks pointing to each other 2 | --- 3 | # Cycle 4 | 5 | What happens if we have blocks that point to each other? Hopefully nothing. 6 | 7 | 8 | _"block" 9 | 10 | ## Block 11 | 12 | _"cycle" _"block:switch" _"block" 13 | 14 | [switch]() 15 | 16 | _"cycle" 17 | 18 | ## Output 19 | 20 | This actually puts the output that we want to see 21 | 22 | _"|async _"timeout"" 23 | 24 | [out](#output "save:") 25 | 26 | 27 | ## Timeout 28 | 29 | This is where we do a bit of black magic to pop it out of the flow. This 30 | delays it to allow the rest of the stuff to compile and be waiting. 31 | 32 | setTimeout(function () { 33 | var a = doc.parent.simpleReport().join("\n"); 34 | var b = doc.parent.reportwaits().join("\n"); 35 | callback(null, b + "\n" + a); 36 | }, 1); 37 | 38 | --- 39 | NOT SAVED: out AS REQUESTED BY: in NEED: output 40 | PROBLEM WITH: _"block" IN: cycle FILE: in 41 | PROBLEM WITH: _"cycle" IN: block FILE: in 42 | PROBLEM WITH: _"block:switch" IN: block FILE: in 43 | PROBLEM WITH: _"block" IN: block FILE: in 44 | PROBLEM WITH: _"cycle" IN: block FILE: in 45 | PROBLEM WITH: _"|async _"timeout"" IN: output FILE: in 46 | -------------------------------------------------------------------------------- /tests/dash.md: -------------------------------------------------------------------------------- 1 | dash.md -- testing the dash command 2 | --- 3 | # Evaling 4 | 5 | First we need to create two dash objects to check. 6 | 7 | var greet = { 8 | "hello" : function (input, arg1, arg2) { 9 | return "Hi " + arg1 + " " + arg2 + ",\n\n" + input; 10 | }, 11 | "bye" : function (input, arg1, arg2) { 12 | return input + "blah"; 13 | } 14 | }; 15 | var byegreet = Object.create({ 16 | "bye" : function (input, arg1, arg2) { 17 | return input + "\n\nSincerely,\n" + arg1 + " " + arg2 + "\n"; 18 | } 19 | }); 20 | doc.Folder.sync("greetings", function (input, args) { 21 | var method = args[0]; 22 | args[0] = input; 23 | return greet[method].apply(greet, args); 24 | }); 25 | doc.Folder.sync("byegreet", function (input, args) { 26 | var method = args[0]; 27 | args[0] = input; 28 | return byegreet[method].apply(greet, args); 29 | }); 30 | doc.dash.greetings = [greet, 2]; 31 | doc.Folder.dash.byegreet = [byegreet, 1]; 32 | 33 | [greet](# "eval:") 34 | 35 | ## Using 36 | 37 | _"| echo Something or other 38 | | -hello Jack, the Great 39 | | - bye, James, Taylor" 40 | 41 | _"| echo -bye(-hello(ec("Great to see you!") , Jack, the Great), James, Taylor) " 42 | 43 | [out](# "save:") 44 | 45 | --- 46 | Hi Jack the Great, 47 | 48 | Something or other 49 | 50 | Sincerely, 51 | James Taylor 52 | 53 | 54 | Hi Jack the Great, 55 | 56 | Great to see you! 57 | 58 | Sincerely, 59 | James Taylor 60 | -------------------------------------------------------------------------------- /tests/defaults.md: -------------------------------------------------------------------------------- 1 | defaults -- testing a default command maker 2 | --- 3 | # Defaults 4 | 5 | So this tests the function wrapDefaults. 6 | 7 | ["info", "used", function (text, args) { 8 | return text.replace(/used/g, args[0]); 9 | }] 10 | 11 | 12 | [info](# "define: defaults") 13 | 14 | ## Many 15 | 16 | 17 | ["many", "used", "unused", "rocking", function (text, args) { 18 | return text.replace(/used/g, args[0]) + args[2]; 19 | }] 20 | 21 | 22 | [many](# "define: defaults") 23 | 24 | ## rocking 25 | 26 | This is great. 27 | 28 | !!!! 29 | 30 | ## used 31 | 32 | Just something 33 | 34 | pants 35 | 36 | 37 | ## out 38 | 39 | great used 40 | _"|cat used, dude, used |info jack, jill" 41 | _"|cat used, dude, used |many , jill" 42 | _"|cat used, dude, used |many , jill, ???? " 43 | 44 | 45 | [out](# "save: | info ") 46 | 47 | --- 48 | great pants 49 | jackdudejack 50 | pantsdudepants!!!! 51 | pantsdudepants???? 52 | -------------------------------------------------------------------------------- /tests/define.md: -------------------------------------------------------------------------------- 1 | define - testing defining commands 2 | --- 3 | # Define 4 | 5 | Here we will test defining commands. We will have three commands, one for each 6 | kind (async, sync, raw) and one of these will involve threading from other 7 | blocks. 8 | 9 | [out](#start "save:") 10 | 11 | [hot-cool](#hotty "define:raw") 12 | 13 | ## Start 14 | 15 | Alright. We will have three commands that will produce three lines. 16 | 17 | _"cool | beans" 18 | _"warm | blanket two, three| sub two, 2" 19 | _"|hot-cool chocolate" 20 | 21 | 22 | 23 | 24 | ## Cool 25 | 26 | cool crickets 27 | 28 | ## Cmd Beans 29 | 30 | This is the command beans 31 | 32 | function (input) { 33 | var doc = this; 34 | 35 | return doc.file + ": " + input + "! garbanzo beans"; 36 | } 37 | 38 | [be-ans](# "define:") 39 | 40 | ## Warm 41 | 42 | warm 43 | 44 | ## Cmd blanket 45 | 46 | 47 | [blanket](# "define: async| sub --, :") 48 | 49 | function (input, args, cb) { 50 | var doc = this; 51 | setTimeout(function () { 52 | cb(null, doc.file + "-- " + input + " " + args.join(", ")); 53 | }, 1); 54 | } 55 | 56 | ## Hotty 57 | 58 | This is where we get some nice warm drinks 59 | 60 | function (input, args, name) { 61 | var doc = this; 62 | 63 | 64 | doc.gcd.emit("text ready:" + name, doc.file + ": hot " + args[0]); 65 | 66 | } 67 | --- 68 | in: cool crickets! garbanzo beans 69 | in: warm 2, three 70 | in: hot chocolate 71 | -------------------------------------------------------------------------------- /tests/directivesubbing.md: -------------------------------------------------------------------------------- 1 | Directive Subbing -- Checking if local block names work in directives now 2 | ---start:in 3 | # Directive Subbing 4 | 5 | 6 | THIS 7 | 8 | [1](# "save:| sub THIS, _':this'") 9 | 10 | [jack](jack "load:") 11 | 12 | [this]() 13 | 14 | hey 15 | 16 | [other]() 17 | 18 | THIS 19 | 20 | [2](# "save:| sub THIS, _':this'") 21 | 22 | 23 | ## crazy 24 | 25 | bye 26 | 27 | [3](#directive-subbing "save:| sub THIS, _':this'") 28 | 29 | [4](#jack::great "save:| sub THIS, _':this'") 30 | [5](#jack::great:other "save:| sub THIS, _':this'") 31 | ---in:jack 32 | # Great 33 | 34 | THIS 35 | 36 | [this]() 37 | 38 | hey 39 | 40 | [other]() 41 | 42 | THIS 43 | 44 | ---out:1 45 | hey 46 | ---out:2 47 | hey 48 | ---out:3 49 | hey 50 | ---out:4 51 | hey 52 | ---out:5 53 | hey 54 | -------------------------------------------------------------------------------- /tests/direval.md: -------------------------------------------------------------------------------- 1 | Eval directive - testing the eval directive 2 | --- 3 | # Eval directive 4 | 5 | This is immediate eval. 6 | 7 | var gcd = doc.gcd; 8 | gcd.emit("file ready:out", "hi"); 9 | 10 | [](# "eval:") 11 | --- 12 | hi 13 | -------------------------------------------------------------------------------- /tests/dirpush.md: -------------------------------------------------------------------------------- 1 | dirpush -- checking the push directive 2 | --- 3 | # push 4 | 5 | This tests out the push directive. 6 | 7 | The idea is that we have some text spread out that we want to put in a single 8 | location, but we want to push that content there instead of pulling it. 9 | Usually this is a little bits of connective text. 10 | 11 | Some text 12 | 13 | _"awesome| . join, ec(", ")" 14 | 15 | _"awesome| . length" 16 | 17 | [out](# "save:") 18 | 19 | [bit1]() 20 | 21 | 5 for fighting 22 | 23 | [awesome](# "push:") 24 | 25 | [bit2]() 26 | 27 | joe walsh 28 | 29 | [awesome](# "push: | . toUpperCase") 30 | 31 | --- 32 | Some text 33 | 34 | 5 for fighting, JOE WALSH 35 | 36 | 2 37 | -------------------------------------------------------------------------------- /tests/done.md: -------------------------------------------------------------------------------- 1 | # Done -- testing the done abilities 2 | --- 3 | # Done and when 4 | 5 | This tests the ability to have stuff happen using the commands `done` and 6 | `when`. The idea is to support external operations that are not returning 7 | text, but whose actions need to be completed before something else happens. 8 | For example, saving some tex files, generating some pictures, and then calling 9 | the tex compiler on that stuff. 10 | 11 | To do this test, we will define a directive that issues some events that we 12 | will listen for. And then act on it. We will do some nefarious hacking to 13 | ensure that the ordering is faithful. 14 | 15 | _"|cat ct | store fourth| done fourth" 16 | 17 | _"|when first, second, third, fourth| join \ and\ , _"1", _"second", _"3", _"fourth"" 18 | 19 | _"|cat cool |store 3 | done third" 20 | 21 | [out](# "save:") 22 | 23 | ## Directive define 24 | 25 | This defines the directive. It will take in a string and store it manually in 26 | the doc. `[value](# "whenstore: vname, ename")` 27 | 28 | doc.directives.whenstore = function (args) { 29 | var parts = args.input.trim().split(","); 30 | var value = args.link; 31 | var vname = parts[0]; 32 | var ename =parts[1]; 33 | 34 | var doc = this; 35 | doc.vars[vname] = value; 36 | 37 | var dgcd = doc.parent.done.gcd; 38 | dgcd.once(ename, "done"); 39 | process.nextTick(function () { 40 | dgcd.emit(ename); 41 | }); 42 | 43 | }; 44 | 45 | [](# "eval:") 46 | 47 | [jack](# "whenstore:1,first") 48 | [diane](# "whenstore:second,second") 49 | 50 | 51 | --- 52 | ct 53 | 54 | jack and diane and cool and ct 55 | 56 | cool 57 | -------------------------------------------------------------------------------- /tests/echo.md: -------------------------------------------------------------------------------- 1 | Echo - the echo subcommand has a problem 2 | --- 3 | # Main 4 | The echo subcommand allows one to have strings without problems 5 | 6 | Actually, the problem is with the sub command. It was not being run through 7 | the sync wrapper and thus the arguments were not being prepped. 8 | 9 | _"| echo Cool beank | sub ec("k", 's'), echo('b','')" 10 | 11 | [out](# "save:") 12 | 13 | --- 14 | Cool eans 15 | -------------------------------------------------------------------------------- /tests/emitcache.md: -------------------------------------------------------------------------------- 1 | Emit Cache -- testing the emit cache feature 2 | --- 3 | We want to test being able to attach once events to a full "text ready" event 4 | emitting. We will do this by having a command that will call a hard 5 | coded gcd.once on a section that gets called after that section is completed. 6 | 7 | This should return _"wait | reademit" 8 | 9 | ## wait 10 | 11 | soMEthing 12 | 13 | ## reademit 14 | 15 | function (text, args, cb) { 16 | let gcd = this.gcd; 17 | text = text.toLowerCase(); 18 | gcd.once("text ready:in:wait", (data) => { 19 | cb(null, text + data.toUpperCase()); 20 | }); 21 | } 22 | 23 | [reademit](# "define: async") 24 | --- 25 | This should return somethingSOMETHING 26 | -------------------------------------------------------------------------------- /tests/empty-main.md: -------------------------------------------------------------------------------- 1 | Empty Main - testing that we can call the empty section 2 | ---start:in 3 | # Something wicked 4 | 5 | _"emptyhead::" 6 | 7 | _"emptyhead:::weird" 8 | 9 | _"emptyhead::^" 10 | 11 | _"emptyhead::^:weird" 12 | 13 | [emptyhead](emptyhead "load:") 14 | 15 | [out](# "save:") 16 | 17 | ---in:emptyhead 18 | This is great 19 | 20 | Bob 21 | 22 | 23 | [weird]() 24 | 25 | yeah 26 | 27 | ---out:out 28 | Bob 29 | 30 | yeah 31 | 32 | Bob 33 | 34 | yeah 35 | -------------------------------------------------------------------------------- /tests/empty-minor.md: -------------------------------------------------------------------------------- 1 | Empty Minor - does an empty minor work 2 | --- 3 | # Main 4 | 5 | What's up 6 | 7 | This is great. 8 | 9 | _":dude" 10 | 11 | _":bye" 12 | 13 | [out](# "save:") 14 | 15 | [dude]() 16 | 17 | [bye]() 18 | 19 | hey 20 | 21 | --- 22 | This is great. 23 | 24 | 25 | 26 | hey 27 | -------------------------------------------------------------------------------- /tests/empty.md: -------------------------------------------------------------------------------- 1 | empty -- what if stuff is empty? 2 | ---start:empty 3 | 4 | ---start:headless 5 | No header. What happens? 6 | 7 | just little me 8 | 9 | [out](# "save:") 10 | ---out:out 11 | just little me 12 | -------------------------------------------------------------------------------- /tests/erroreval.md: -------------------------------------------------------------------------------- 1 | error eval -- testing evals for errors 2 | --- 3 | # Errors 4 | 5 | Wanted to catch and report eval errors. 6 | 7 | _":text|eval join(\n, _"ev", _"more", _"and")" 8 | _":text|async join(\n, _"ev", _"more", _"and")" 9 | _"log1" 10 | _"log2" 11 | 12 | [out](# "save:") 13 | 14 | [text]() 15 | 16 | Some text. 17 | 18 | ## Define 19 | 20 | _"more" 21 | 22 | [junk](# "define:") 23 | 24 | 25 | ## Log surgery 26 | 27 | So we need to intercept `doc.log` calls and store them into incrementing 28 | variables. Well, need is a bit strong, but this is neat, yeah? 29 | 30 | var inc = 1; 31 | doc.log = function (text) { 32 | doc.store("log"+inc, text); 33 | inc += 1; 34 | }; 35 | 36 | [](# "eval:") 37 | 38 | ## Ev 39 | 40 | a = 1+2; 41 | 42 | ## More 43 | 44 | b = c; 45 | 46 | [](# "eval:") 47 | 48 | ## And 49 | 50 | d= 5; 51 | --- 52 | ReferenceError:c is not defined 53 | a = 1+2; 54 | b = c; 55 | d= 5; 56 | 57 | ACTING ON: 58 | Some text. 59 | ReferenceError:c is not defined 60 | a = 1+2; 61 | b = c; 62 | d= 5; 63 | 64 | ACTING ON: 65 | Some text. 66 | ReferenceError:c is not defined 67 | b = c; 68 | ReferenceError:c is not defined 69 | f=b = c; 70 | -------------------------------------------------------------------------------- /tests/eval.md: -------------------------------------------------------------------------------- 1 | eval - eval test along with commands 2 | --- 3 | # Evaling 4 | 5 | So we want to eval some stuff. Let's write some code to do that. 6 | 7 | [out](#code "save:") 8 | 9 | ## Code 10 | 11 | We want to compute the sum _"sum". We add the numbers up and get 12 | _"sum|eval text = eval(text)". 13 | 14 | ## sum 15 | 16 | 1 + 2 + 3 + 4 + 5 17 | 18 | --- 19 | We want to compute the sum 1 + 2 + 3 + 4 + 5. We add the numbers up and get 20 | 15. 21 | -------------------------------------------------------------------------------- /tests/failure.mdn: -------------------------------------------------------------------------------- 1 | Failure -- getting helpful messages on failure 2 | --- 3 | # Marked Failure 4 | 5 | This is longer necessary since commonmark does not seem to generate thrown 6 | errors upon syntax issues. 7 | 8 | This deals with failure while parsing marked. The test will be to have three 9 | sections with the middle one having a failure of a directive (missing end 10 | quote). Then upon failure of that, the log should go to the out file. 11 | 12 | doc.log = function (text) { 13 | var gcd = doc.gcd; 14 | gcd.emit("file ready:out", text); 15 | } 16 | 17 | [](# "eval:") 18 | 19 | 20 | # Just a section 21 | 22 | hi there 23 | 24 | # Middle one 25 | 26 | This should fail 27 | 28 | adf 29 | 30 | [a sub]() 31 | 32 | more good stuff 33 | 34 | [good](# "define:) 35 | 36 | # Never seen 37 | 38 | This section should never get seen. 39 | 40 | left blank 41 | 42 | --- 43 | Markdown parsing error. Last heading seen: middle one⫶a sub 44 | -------------------------------------------------------------------------------- /tests/first.md: -------------------------------------------------------------------------------- 1 | first - the most basic example. Just do a quick stitch and save 2 | --- 3 | # [First](# "version:") **great** 4 | 5 | This is a first test. We save it with a command in the section Begin to show 6 | that it the saving can happen after the section heading with capitalization 7 | issues. 8 | 9 | ## End 10 | 11 | Let's start at the end 12 | 13 | great. Wonderful. 14 | 15 | [p.s.]() 16 | 17 | Just a postscript 18 | 19 | 20 | P.S. This works. 21 | 22 | # Begin Here 23 | - [out](#BeGin---HERE "save:") 24 | 25 | And now for the beginning. 26 | 27 | ``` 28 | Big deal. Let's get this working. You are _"end"ha 29 | 30 | In between. 31 | 32 | _"End:P.S. |" 33 | ``` 34 | 35 | --- 36 | Big deal. Let's get this working. You are great. Wonderful.ha 37 | 38 | In between. 39 | 40 | P.S. This works. 41 | -------------------------------------------------------------------------------- /tests/fsubcommand.md: -------------------------------------------------------------------------------- 1 | fsubcommand.md -- testing defining a subcommand 2 | --- 3 | So we want to use a subcommand defined on a function. We use the plugins to do 4 | this. 5 | 6 | _"| cool report(dude), pig(dude) " 7 | 8 | 9 | ## cool 10 | 11 | function (text, args) { 12 | return "cool as " + args[0] + " " + args[1]; 13 | } 14 | 15 | [cool](# "define:") 16 | 17 | ## subcommand 18 | 19 | Subcommands for functions can be stored in .plugins 20 | 21 | function (arg1) { 22 | return arg1; 23 | } 24 | 25 | 26 | [report](#cool "subcommand:") 27 | 28 | ## pig 29 | 30 | This takes a word, puts the first letter at the end with ay appended. 31 | 32 | doc.Folder.defSubCommand( "pig", function (arg) { 33 | return arg.slice(1) + arg[0] + "ay"; 34 | }); 35 | 36 | [pig](# "eval:") 37 | --- 38 | cool as dude udeday 39 | 40 | -------------------------------------------------------------------------------- /tests/funify.md: -------------------------------------------------------------------------------- 1 | funify - checking the use of function defining 2 | --- 3 | ## Object 4 | 5 | We will do a reduce here 6 | 7 | jack : 2 8 | ka : 7 9 | jilli : 3 10 | 11 | [out](# "save: | objectify | forin _'f', num(0), true() ") 12 | 13 | ## Function 14 | 15 | This takes the length of the key and multiplies it by the value and we sum 16 | over that. 17 | 18 | function (prop, key, val) { 19 | return val + ( key.length * parseInt(prop,10) ); 20 | } 21 | 22 | [f](# "store: | funify ") 23 | --- 24 | 37 25 | -------------------------------------------------------------------------------- /tests/h5.md: -------------------------------------------------------------------------------- 1 | h5 and h6 -- checking how h5 and h6 headings behave 2 | --- 3 | # h5 and h6 4 | 5 | How do the h5 and h6 work out? And how should they work? 6 | 7 | 8 | _"simple/doc/great" 9 | _"simple" 10 | _"simple/doc" 11 | 12 | [out](# "save:") 13 | 14 | ## Simple 15 | 16 | Just a simple test. 17 | 18 | _"./test" 19 | 20 | ##### test 21 | 22 | hi 23 | 24 | ##### doc 25 | 26 | This is where we document stuff 27 | _"./great" 28 | _"../more:yo" 29 | 30 | ###### great 31 | 32 | Yay! 33 | _"../../more/dude" 34 | 35 | ##### more 36 | 37 | _":yo" 38 | 39 | [yo]() 40 | 41 | hey 42 | 43 | ###### dude 44 | 45 | add _"../:yo" 46 | 47 | --- 48 | Yay! 49 | add hey 50 | hi 51 | This is where we document stuff 52 | Yay! 53 | add hey 54 | hey 55 | -------------------------------------------------------------------------------- /tests/h5push.md: -------------------------------------------------------------------------------- 1 | h5 push -- testing the array creation from h5 2 | --- 3 | # h5 push 4 | 5 | So this will see about h5 stuff 6 | 7 | _"awesome | .join \n" 8 | _"fullawe | .map eval(`ret=function(el) {return el[1];}`) | 9 | .join \n" 10 | _"once|.join" 11 | 12 | [out](# "save:") 13 | 14 | [awesome](#cool "h5: | .map eval(`ret = function (el) { 15 | return 'working ' + el;};`)") 16 | 17 | [fullawe](#hot "h5: full") 18 | 19 | [once](#once "h5:"); 20 | 21 | ##### Cool 22 | 23 | great 24 | 25 | ##### Once 26 | 27 | just one time 28 | 29 | ## blah 30 | 31 | ##### cool 32 | 33 | cool 34 | 35 | ## blah blah 36 | 37 | ##### COol 38 | 39 | thrice 40 | 41 | ##### hot 42 | 43 | cool beans 44 | 45 | 46 | [awesome](#cool "h5: off") 47 | 48 | ## wha 49 | 50 | ##### cool 51 | 52 | not seen 53 | 54 | ##### hot 55 | 56 | seen 57 | 58 | --- 59 | working great 60 | working cool 61 | working thrice 62 | cool beans 63 | seen 64 | just one time 65 | -------------------------------------------------------------------------------- /tests/h5pushodd.md: -------------------------------------------------------------------------------- 1 | h5 edge cases - two h5 of same name in section and no h5 2 | ---start:in 3 | # H5 is cool 4 | 5 | So we like the h5 paradigm, but we need to account for oddities. 6 | 7 | [nostuff](#no "h5:") 8 | [hstuff](#h "h5:") 9 | [this](#this "h5: | .join \n ") 10 | 11 | ##### h 12 | 13 | some code 14 | 15 | ##### h 16 | 17 | some more code 18 | 19 | 20 | ##### this 21 | 22 | hi 23 | 24 | ## Result 25 | 26 | _"hstuff | .join \n " 27 | _"nostuff | .join -" 28 | 29 | [out](# "save:") 30 | 31 | [dude|what](# "store: | sub what, _'this'") 32 | 33 | [read](#dude "save:") 34 | 35 | ##### h 36 | 37 | har matey 38 | 39 | ##### this 40 | 41 | Bye 42 | 43 | ---out:out 44 | some code 45 | some more code 46 | har matey 47 | ---out:read 48 | hi 49 | Bye 50 | -------------------------------------------------------------------------------- /tests/headless.md: -------------------------------------------------------------------------------- 1 | headless - testing save options with no heading 2 | --- 3 | # Headless 4 | 5 | No heading was a problem when processing pipes in a save reference 6 | 7 | dude this rocks 8 | 9 | _":great" 10 | 11 | _"| echo raw " 12 | 13 | [out](# "save: | sub this, that | sub raw, _':raw' ") 14 | 15 | [great]() 16 | 17 | Wow, that's great. 18 | 19 | [raw]() 20 | 21 | Weird man 22 | 23 | --- 24 | dude that rocks 25 | 26 | Wow, that's great. 27 | 28 | Weird man 29 | -------------------------------------------------------------------------------- /tests/html-helpers.md: -------------------------------------------------------------------------------- 1 | html-helpers - testing html helpers 2 | --- 3 | # html 4 | 5 | It's a drag sometimes. Here is some help 6 | 7 | _"|echo great | html-wrap div, wow, very, id=jack " 8 | 9 | _"some crazy text | html-escape " 10 | 11 | _"some escaped text | html-unescape " 12 | 13 | _"table | matrixify | html-table arr(name, place), signs, data-grid=tom" 14 | 15 | [out](# "save:") 16 | 17 | ## some crazy text 18 | 19 | 5 < x & y > 7 20 | 21 | ## some escaped text 22 | 23 | A & I is > you can believe. Betch you <> 24 | 25 | ## table 26 | 27 | jack, zeke 28 | jane, sw 29 | --- 30 |
great
31 | 32 | 5 < x & y > 7 33 | 34 | A & I is > you can believe. Betch you <> 35 | 36 | 37 | 38 | 39 | 40 |
nameplace
jackzeke
janesw
41 | -------------------------------------------------------------------------------- /tests/if.md: -------------------------------------------------------------------------------- 1 | if -- testing the if constructs 2 | ---start:in 3 | # If 4 | 5 | We test the if setup 6 | 7 | doc.out = ''; 8 | 9 | [](# "eval:") 10 | 11 | [out](#out "save:") 12 | 13 | ## Cmd jack 14 | 15 | This should execute after the flag is read 16 | 17 | _":some text 18 | | if ?flag(jack), eval, _":some code" 19 | | if ?flag(jill), eval, _":bad code" 20 | | store first " 21 | 22 | 23 | _"first| eval _":reporting" | store out" 24 | 25 | [some text]() 26 | 27 | Just a bit of text 28 | 29 | _"res::boy" 30 | 31 | 32 | 33 | [some code]() 34 | 35 | doc.out += "\n" + text; 36 | 37 | 38 | [bad code]() 39 | 40 | doc.out = "boo"; 41 | 42 | [reporting]() 43 | 44 | text = doc.out; 45 | 46 | ## No jack 47 | 48 | doc.out += 'not added'; 49 | 50 | [](# "if: jack; eval:") 51 | 52 | 53 | [jack](# "flag:") 54 | 55 | 56 | ## Jacked 57 | 58 | doc.out += 'this is added'; 59 | 60 | 61 | [](# "if: jack; eval:") 62 | 63 | [res](yes "if: jack; load:") 64 | [res](not "if: jill; load:") 65 | [dude](res::boy "if: jack; save:| sub loaded, cool") 66 | ---in:not 67 | # Hey 68 | 69 | Not loaded 70 | ---in:yes 71 | # Boy 72 | 73 | Very loaded 74 | 75 | ---out:out 76 | this is added 77 | Just a bit of text 78 | 79 | Very loaded 80 | ---out:dude 81 | Very cool 82 | 83 | 84 | -------------------------------------------------------------------------------- /tests/ife.md: -------------------------------------------------------------------------------- 1 | ife - immediate function expression 2 | --- 3 | # fun 4 | 5 | for (i = 0; i < n; i+=1) { 6 | jack += 7; 7 | } 8 | 9 | [out](# "save: | ife i, n=7, jack=jill") 10 | --- 11 | (function ( i, n, jack ) {for (i = 0; i < n; i+=1) { 12 | jack += 7; 13 | } 14 | } ( i,7,jill ) ) 15 | -------------------------------------------------------------------------------- /tests/ifelse.md: -------------------------------------------------------------------------------- 1 | ifelse -- tests the ifelse and boolean commands 2 | --- 3 | 4 | This should test the ifelse command. 5 | 6 | _"| echo something 7 | | ifelse arr(?and(true(), false()), sub, thing, dude), 8 | arr(?flag(whatever), sub, thing, last), 9 | arr(?==(num(1), 1), sub, thing, finally) " 10 | 11 | _"|echo something 12 | | if-else arr(?!=(2, 3, 4, 5, 5, 7), sub, some, stone), 13 | arr(?!=(2, 3, 4, 5, 6, 7), sub, some, rock) " 14 | 15 | --- 16 | somefinally 17 | 18 | rockthing 19 | -------------------------------------------------------------------------------- /tests/ignore.md: -------------------------------------------------------------------------------- 1 | ignore -- ignore languages 2 | --- 3 | # Ignore 4 | 5 | [javascript](# "ignore:") 6 | 7 | ```js 8 | for (i = 0; i < n; i+= 1) { 9 | console.log(i); 10 | } 11 | ``` 12 | 13 | Then we could do something like 14 | 15 | ```javascript 16 | if (k>0) { 17 | sum += i*i; 18 | } 19 | ``` 20 | 21 | [out](# "save:") 22 | --- 23 | for (i = 0; i < n; i+= 1) { 24 | console.log(i); 25 | } 26 | -------------------------------------------------------------------------------- /tests/indents.md: -------------------------------------------------------------------------------- 1 | indents - want substitution indentation to go well 2 | --- 3 | # Indents 4 | 5 | This is to see if we can get code indented correctly. 6 | 7 | if () { 8 | var f = _":fun"; 9 | } 10 | 11 | [out](# "save:") 12 | 13 | [fun]() 14 | 15 | A simple function 16 | 17 | function (a, b) { 18 | var hello; 19 | if () { 20 | _":truth" 21 | } 22 | } 23 | 24 | [truth]() 25 | 26 | a = b; 27 | c = d; 28 | --- 29 | if () { 30 | var f = function (a, b) { 31 | var hello; 32 | if () { 33 | a = b; 34 | c = d; 35 | } 36 | }; 37 | } 38 | -------------------------------------------------------------------------------- /tests/join-filter.md: -------------------------------------------------------------------------------- 1 | join filter -- testing the join and filter commands 2 | --- 3 | We want to test the join and filter functions 4 | 5 | 0^^^ 6 | _"obj | join \n, dud, cool " 7 | 1^^^ 8 | _"obj | filter dud, cool | join \n" 9 | 2^^^ 10 | _"obj | join \n, eval(`ret = /dud/`), eval(`ret=/dud$/`) " 11 | 3^^^ 12 | _"obj | filter eval(`ret = /dud/`), eval(`ret=/dud$/`) | join \n " 13 | 4^^^ 14 | _"obj | join \n, fun(`function(key, val) { 15 | if (typeof(val) === 'number') { 16 | return true; 17 | } }`) " 18 | 5^^^ 19 | _"obj | filter fun(`function(key, val) { 20 | if (typeof(val) === 'number') { 21 | return true; 22 | } }`) | join \n " 23 | 6^^^ 24 | _"arr | join \,\ " 25 | 7^^^ 26 | _"arr | join \,\ , num(1), 2" 27 | 8^^^ 28 | _"arr | filter num(1), 3 | join \,\ " 29 | 9^^^ 30 | _"arr | join \,\ , 1:2" 31 | 10^^^ 32 | _"arr | filter :1 | join \,\ " 33 | 11^^^ 34 | _"arr | filter 2: | join \,\ " 35 | 12^^^ 36 | _"arr | filter 2x-3 | join \,\ " 37 | 13^^^ 38 | _"arr | filter -2x-1 | join \,\ " 39 | 14^^^ 40 | _"arr | join \,\ , 3x" 41 | 15^^^ 42 | _"arr | join \,\ , x-2, 2x+1, 1:3" 43 | 16^^^ 44 | _"arr | join \,\ , 3:1" 45 | 17^^^ 46 | _"arr | filter fun(`function(el, ind) { 47 | return (el[0] === 'j'); 48 | }`) | join \,\ " 49 | 50 | 51 | 52 | [to load]() 53 | 54 | [obj](# "store: | echo kv(dude, num(1), dud, what, cool, hah)") 55 | [arr](# "store: | echo arr(num(4), jack, jane, kate, num(6)) ") 56 | 57 | --- 58 | 0^^^ 59 | what 60 | hah 61 | 1^^^ 62 | hah 63 | what 64 | 2^^^ 65 | what 66 | 1 67 | what 68 | 3^^^ 69 | what 70 | 1 71 | 4^^^ 72 | 1 73 | 5^^^ 74 | 1 75 | 6^^^ 76 | 4, jack, jane, kate, 6 77 | 7^^^ 78 | jack, jane 79 | 8^^^ 80 | jack, kate 81 | 9^^^ 82 | jack, jane 83 | 10^^^ 84 | 4, jack 85 | 11^^^ 86 | jane, kate, 6 87 | 12^^^ 88 | jane, 6 89 | 13^^^ 90 | 6, jane, 4 91 | 14^^^ 92 | 4, kate 93 | 15^^^ 94 | kate, 6, jack, kate, jack, jane, kate 95 | 16^^^ 96 | kate, jane, jack 97 | 17^^^ 98 | jack, jane 99 | -------------------------------------------------------------------------------- /tests/js-string.md: -------------------------------------------------------------------------------- 1 | js-string - long strings for js 2 | --- 3 | # js-string 4 | 5 | text 1 6 | text 2 7 | text 3 8 | 9 | [out](# "save: | js-string ") 10 | --- 11 | "text 1" + 12 | "text 2" + 13 | "text 3" 14 | 15 | -------------------------------------------------------------------------------- /tests/lineterm.md: -------------------------------------------------------------------------------- 1 | Line Terminate - allow line terminators 2 | --- 3 | # Line terminate 4 | 5 | Terminating a line with a command with no blanks is a problem. This errors out 6 | below in old ways. 7 | 8 | _"dude | sub k, s |trim 9 | | sub j, r" 10 | 11 | [out](# "save:") 12 | 13 | # dude 14 | 15 | What? 16 | 17 | something 18 | 19 | --- 20 | something 21 | -------------------------------------------------------------------------------- /tests/linkquotes.md: -------------------------------------------------------------------------------- 1 | Link Quotes -- link quotes 2 | --- 3 | # Links 4 | 5 | This tests out whether there are any issues with quotes in links. 6 | Specifically, if we use a pipe command with a substitution, can we use any of 7 | the quotes? 8 | 9 | [out](# "save: | join \ \\,\n\ ,_'|cmd1', _`|cmd1` , _'|cmd1'") 10 | 11 | 12 | [cmd1](# 'define:| cat _"Cmd 1"') 13 | 14 | ## Cmd 1 15 | 16 | function (text) { 17 | return text + "1"; 18 | } 19 | --- 20 | 1 , 21 | 1 , 22 | 1 23 | -------------------------------------------------------------------------------- /tests/load.md: -------------------------------------------------------------------------------- 1 | load - loading multiple files 2 | ---start:first 3 | # Loading 4 | 5 | We want to have multiple files accessing each other's stuff. 6 | 7 | [s](second "load:") 8 | 9 | 10 | [out](# "save:utf-16") 11 | 12 | 13 | This is a great setup 14 | 15 | _"s::cool" 16 | 17 | _"t::rickets | sub !, c" 18 | 19 | _"t::last:sound" 20 | 21 | 22 | [t](third "load:abc") 23 | 24 | ## Sound 25 | 26 | chirp 27 | ---in:second 28 | 29 | # Cool 30 | 31 | Nice and simple 32 | 33 | cool 34 | 35 | ---in:third 36 | 37 | # Rickets 38 | 39 | !rickety _"first::sound" _"s::cool" 40 | 41 | 42 | ## Last 43 | 44 | [sound]() 45 | 46 | crush 47 | 48 | ---out:out 49 | This is a great setup 50 | 51 | cool 52 | 53 | crickety chirp cool 54 | 55 | crush 56 | -------------------------------------------------------------------------------- /tests/log.md: -------------------------------------------------------------------------------- 1 | log - testing log features 2 | ---start:hi 3 | # Logging 4 | 5 | This will test the logging features, both the log directive, the out directive 6 | (Save, but logging), and the log command. 7 | 8 | [nothing](#start "save:") 9 | 10 | [start](#start "out:") 11 | 12 | [out piping](#other "out:|sub !, c") 13 | 14 | 15 | ## Start 16 | 17 | Just some stuff 18 | 19 | great sound 20 | _":cool|log dude, to" 21 | 22 | [hi:start\\:12](# "monitor: start") 23 | 24 | [cool]() 25 | 26 | COOL 27 | 28 | [](# "monitor:") 29 | 30 | ## Other 31 | 32 | !ool !rickets 33 | ---out:nothing 34 | great sound 35 | COOL 36 | ---log: 37 | !EVENT: block needs compiling:hi:start⫶cool DATA: undefined 38 | !EVENT: text ready:hi:start⫶12⫶20⫶24 DATA: dude 39 | !EVENT: text ready:hi:start⫶12⫶20⫶30 DATA: to 40 | !EVENT: command parsed:hi:start⫶12⫶20 DATA: hi,log,text ready:hi:start⫶12⫶20 41 | !EVENT: stitch fragment:hi:start⫶cool⫶0 DATA: COOL 42 | !EVENT: block substitute parsing done:hi:start⫶cool DATA: undefined 43 | !EVENT: ready to stitch:hi:start⫶cool DATA: block substitute parsing done:hi:start⫶cool,,stitch fragment:hi:start⫶cool⫶0,COOL 44 | !EVENT: minor ready:hi:start⫶cool DATA: COOL 45 | !EVENT: text stored:hi:start⫶cool DATA: COOL 46 | !EVENT: text ready:hi:start⫶cool DATA: COOL 47 | !EVENT: text ready:hi:start⫶12⫶14 DATA: COOL 48 | !EVENT: arguments ready:hi:start⫶12⫶20 DATA: text ready:hi:start⫶12⫶14,COOL,command parsed:hi:start⫶12⫶20,hi,log,text ready:hi:start⫶12⫶20,text ready:hi:start⫶12⫶20⫶24,dude,text ready:hi:start⫶12⫶20⫶30,to 49 | !COOL 50 | ~~~ 51 | dude 52 | ~~~ 53 | to 54 | !EVENT: text ready:hi:start⫶12⫶20 DATA: COOL 55 | !EVENT: substitution chain done:hi:start⫶12 DATA: text ready:hi:start⫶12⫶14,COOL,text ready:hi:start⫶12⫶20,COOL 56 | !EVENT: text ready:hi:start⫶12 DATA: COOL 57 | !out piping: 58 | cool crickets 59 | ~~~ 60 | 61 | !EVENT: stitch fragment:hi:start⫶12 DATA: COOL 62 | !start: 63 | great sound 64 | COOL 65 | ~~~ 66 | 67 | ! 68 | -------------------------------------------------------------------------------- /tests/logs-doc.md: -------------------------------------------------------------------------------- 1 | logs, warn, error -- testing out the doc commands 2 | ---start:in 3 | # Eval logs 4 | 5 | Let's do some evaling 6 | 7 | doc.warn("what", "just a little something", 5); 8 | doc.warn("great", "just a little more"); 9 | doc.log("message", 2, 'arg1', 'arg2'); 10 | doc.log("whatever", "jshint", 9, 11); 11 | doc.logs.out.big = "hey, hey"; 12 | ret = "bye"; 13 | 14 | [out](# "save: | evil") 15 | 16 | ---out:out 17 | bye 18 | ---reports: 19 | # DOC: in 20 | ## 2 21 | * message 22 | * arg1 23 | * arg2 24 | ## WARN 25 | ### what 26 | just a little something 27 | 5 28 | ### great 29 | just a little more 30 | 31 | ## OUT 32 | ### big 33 | ````` 34 | hey, hey 35 | ````` 36 | ## JSHINT 37 | * whatever 38 | * 9 39 | * 11 40 | -------------------------------------------------------------------------------- /tests/logs-reports.md: -------------------------------------------------------------------------------- 1 | Reporting Logs - Tests the reportOut 2 | ---start:in 3 | Need to call dir log and cmd log. 4 | 5 | _"|echo great work people | log " 6 | _"|echo great work dogs | log animals " 7 | _"|echo great work cats | log animals, true(), ec("whatever,doc") " 8 | 9 | [something](# "log:") 10 | [val](# "log: dude | sub d, !") 11 | 12 | ---out:out 13 | great work people 14 | great work dogs 15 | great work cats 16 | ---reports: 17 | # DOC: in 18 | ## COMMAND LOG 19 | ### 20 | great work people 21 | * * * 22 | ### animals 23 | great work dogs 24 | * * * 25 | great work cats 26 | ~~~ 27 | true 28 | ~~~ 29 | whatever,doc 30 | ## DIRECTIVE LOG 31 | val 32 | ````` 33 | !u!e 34 | ````` 35 | * * * 36 | something 37 | ````` 38 | great work people 39 | great work dogs 40 | great work cats 41 | ````` 42 | -------------------------------------------------------------------------------- /tests/mainblock.md: -------------------------------------------------------------------------------- 1 | mainblock -- getting main blocks 2 | --- 3 | # Header 4 | This checks for obtaining the mainblocks via reference syntax. 5 | 6 | Awesome dude 7 | _"./cool" 8 | 9 | [works]() 10 | 11 | _":" 12 | _"./dude" 13 | 14 | ##### Cool 15 | 16 | Pulling in 17 | 18 | ##### Top block 19 | 20 | _"../:works" 21 | 22 | [out](# "save:") 23 | 24 | ##### Dude 25 | 26 | _"../" 27 | 28 | --- 29 | Awesome dude 30 | Pulling in 31 | Awesome dude 32 | Pulling in 33 | -------------------------------------------------------------------------------- /tests/mapc-gymnastics.md: -------------------------------------------------------------------------------- 1 | Mapc and minors -- testing a bunch of iterative features 2 | --- 3 | Tests that replace miniaugment. 4 | 5 | _"just some text| echo ignore it all" 6 | 7 | _"just some text | array 1, 2, 3 | .join -- " 8 | 9 | _"splitting | .split -- | *trim | 10 | *.split / | *pget 1 | *trim | *rev | .join ! " 11 | 12 | _"splitting | .split \n--\n | *trim | 13 | *.split / | minors title | *trim | 14 | | push | clone | 15 | apply some, echo, great | store obj | 16 | *store nav:*KEY* | echo _"temp" | compile nav 17 | | store final | 18 | | pop | pset new, rad | *store cool:*KEY* | echo _"final" " 19 | 20 | _"cool:some" 21 | 22 | _"cool:new" 23 | 24 | _"obj | pget title " 25 | 26 | 27 | ## Temp 28 | 29 | \_":title" 30 | 31 | \_":this is" 32 | 33 | \_":some" 34 | 35 | [sub]() 36 | 37 | hey 38 | 39 | ## just some text 40 | 41 | Huh? 42 | 43 | Text and more 44 | 45 | this is great 46 | 47 | ## splitting 48 | 49 | this is / geese 50 | -- 51 | some / 52 | text 53 | -- 54 | kicking 55 | 56 | ## Command 57 | 58 | Let's define a command to use for mapc 59 | 60 | function (input) { 61 | return input.split('').reverse().join(''); 62 | } 63 | 64 | [rev](# "define:") 65 | 66 | --- 67 | ignore it all 68 | 69 | Text and more 70 | 71 | this is great--1--2--3 72 | 73 | eseeg!txet! 74 | 75 | kicking 76 | 77 | geese 78 | 79 | great 80 | 81 | text 82 | 83 | rad 84 | 85 | kicking 86 | -------------------------------------------------------------------------------- /tests/mapc.md: -------------------------------------------------------------------------------- 1 | Augmented array single - exploring mapc 2 | --- 3 | 4 | So apparently mapc is returning a value instead of an array when there is only 5 | one entry. This is to run a test that demonstrates this so we can squash this 6 | bug. 7 | 8 | _"arr" 9 | _"obj" 10 | _"str" 11 | 12 | ## Array 13 | 14 | This 15 | is 16 | crazy 17 | 18 | [arr](# "store: | .split \n | mapc rev | .join \n") 19 | 20 | [str](# "store: | mapc rev") 21 | 22 | ## Object 23 | 24 | well:cool 25 | dude:looks 26 | fine:you 27 | 28 | [obj](# "store: | objectify | mapc rev | keymap") 29 | 30 | 31 | ## Command 32 | 33 | Let's define a command to use for mapc 34 | 35 | function (input) { 36 | return input.split('').reverse().join(''); 37 | } 38 | 39 | [rev](# "define:") 40 | 41 | ## keymap 42 | 43 | function (input) { 44 | var ret = ''; 45 | var keys = Object.keys(input).sort(); 46 | keys.forEach(function (key) { 47 | ret += key + ':' + input[key] + "\n"; 48 | }); 49 | return ret; 50 | } 51 | 52 | [keymap](# "define:") 53 | 54 | --- 55 | sihT 56 | si 57 | yzarc 58 | dude:skool 59 | fine:uoy 60 | well:looc 61 | 62 | yzarc 63 | si 64 | sihT 65 | -------------------------------------------------------------------------------- /tests/matrix-row-col.md: -------------------------------------------------------------------------------- 1 | matrix row col - testing the row col stuff 2 | --- 3 | 4 | _"data | matrixify 5 | | .rows _"f | funify" 6 | | .cols _"g | funify" 7 | | .print ec(','), \n" 8 | 9 | # data 10 | 11 | 4, 5, 7, 8 12 | 2, 3, 4, 5 13 | 9,10, 12, 23 14 | 15 | # f 16 | 17 | function (row, ind) { 18 | return row.map(function (el) { 19 | return el * 5*(ind+1); 20 | }); 21 | } 22 | 23 | # g 24 | 25 | function (col, ind) { 26 | return col.map(function (el) { 27 | return el - 7*(ind+1); 28 | }); 29 | } 30 | 31 | 32 | --- 33 | 13,11,14,12 34 | 13,16,19,22 35 | 128,136,159,317 36 | -------------------------------------------------------------------------------- /tests/matrixify.md: -------------------------------------------------------------------------------- 1 | matrixify - testing the matrix commands 2 | --- 3 | # Matrix 4 | 5 | This is to test out the matrix commands. 6 | 7 | ## data 8 | 9 | 4, 5, 7, 8 10 | 2, 3, 4, 5 11 | 9,10, 12, 23 12 | 13 | [out](# "save: | matrixify | .transpose | .num | .scale 2 | html-table") 14 | --- 15 | 16 | 17 | 18 | 19 | 20 |
8418
10620
14824
161046
21 | -------------------------------------------------------------------------------- /tests/merge.md: -------------------------------------------------------------------------------- 1 | merge - checking the merge algorithms 2 | --- 3 | # Merge 4 | 5 | a = {a:1, b:{e:2, f:4}, c: 3}; 6 | b = {a:5, b:{e:3} }; 7 | 8 | var merge = doc.Folder.requires.merge; 9 | merge(a, b); 10 | ret = JSON.stringify(a); 11 | 12 | 13 | [out](# "save: |evil ") 14 | --- 15 | {"a":5,"b":{"e":3},"c":3} 16 | -------------------------------------------------------------------------------- /tests/moresubcommands.md: -------------------------------------------------------------------------------- 1 | Testing more subcommands -- date, function, dot 2 | --- 3 | 4 | This tests the new additions to subcommands: fun, date, and dot. The dash will 5 | be tested in the dash test. 6 | 7 | _"| echo .getUTCFullYear(date(num(277510050003))) " 8 | 9 | _"| echo arr(3, 4, 5) 10 | | .map fun(`function (el) {return el*args[0];}`, num(3)) 11 | | .join ec(",") " 12 | 13 | --- 14 | 1978 15 | 16 | 9,12,15 17 | -------------------------------------------------------------------------------- /tests/nameafterpipe.md: -------------------------------------------------------------------------------- 1 | nameafterpipe.md -- testing for storing names after pipes 2 | --- 3 | ## Name after pipe 4 | 5 | This tests the name after pipe idea. It should be done in two transforms and 6 | one eval. 7 | 8 | _"hot" 9 | _"cool" 10 | _"just right" 11 | 12 | [out](# "save:") 13 | 14 | ## Eval 15 | 16 | For our eval test, we will get mama bear. 17 | 18 | ret = "mama bear" 19 | 20 | [|cool](# "eval:") 21 | 22 | ## Transform 23 | 24 | NAME bear 25 | 26 | [|hot](# ":|sub NAME, papa") 27 | 28 | ## Other 29 | 30 | [|just right](#transform ":| sub NAME, baby") 31 | 32 | --- 33 | papa bear 34 | mama bear 35 | baby bear 36 | -------------------------------------------------------------------------------- /tests/objectify.md: -------------------------------------------------------------------------------- 1 | objectify - testing the objectify method 2 | --- 3 | # Basic 4 | 5 | _":object | objectify | pget this is great " 6 | _":object 7 | | objectify 8 | | forin fun(` (val, key, ret) => ret + key + '!' + val + '&'`), 9 | ec(''), key" 10 | _":object | objectify | toJSON" 11 | _":json | fromJSON | pget c" 12 | 13 | 14 | [out](# "save:") 15 | 16 | [object]() 17 | 18 | 5: jack 19 | jack :jane 20 | this is great : whatever 21 | 22 | 23 | [json]() 24 | 25 | {"a":"b","c":"d"} 26 | 27 | 28 | --- 29 | whatever 30 | 5!jack&jack!jane&this is great!whatever& 31 | {"5":"jack","jack":"jane","this is great":"whatever"} 32 | d 33 | -------------------------------------------------------------------------------- /tests/partial.md: -------------------------------------------------------------------------------- 1 | Partial - exploring the partial directive 2 | --- 3 | # Partials 4 | 5 | Let's start simple. Let's make a stub of join and one of subs 6 | 7 | To be or not to be 8 | That is the question 9 | 10 | [joinc](# "partial: join | echo :") 11 | [subr](# "partial: sub, 1 | echo r") 12 | [dude](# "partial: soli ") 13 | 14 | ## Using it 15 | 16 | This is cool. 17 | 18 | _"|echo 5 |dude 9" 19 | 20 | [out](# "save: | joinc two, five | subr o") 21 | 22 | 23 | ## Cmd define 24 | 25 | This defines soli 26 | 27 | function (input, args) { 28 | return args[0] + input + args[1]; 29 | } 30 | 31 | [soli](# "define: sync") 32 | 33 | --- 34 | This is crrl. 35 | 36 | Tr be rr nrt tr be 37 | That is the questirn59:twr:five 38 | -------------------------------------------------------------------------------- /tests/psetgetstore.md: -------------------------------------------------------------------------------- 1 | Property set, get, store -- testing these commands 2 | --- 3 | 4 | _"obj | pget a, 1 " 5 | _"obj | pset c, 5 | pget b, j | done c " 6 | _"obj | when c | pget c " 7 | _"|echo Awesome | pstore _"obj", d, num(2) | echo _'obj' | pget d, 2" 8 | 9 | 10 | [storing]() 11 | 12 | Nothing really 13 | 14 | [obj](# "store: | echo kv(a, arr(0, 3), b, kv(j, 45, l, 9)) ") 15 | --- 16 | 3 17 | 45 18 | 5 19 | Awesome 20 | -------------------------------------------------------------------------------- /tests/pushpop.md: -------------------------------------------------------------------------------- 1 | Push Pop -- pusing and popping state variables in the pipes 2 | --- 3 | # Push and Pop 4 | 5 | This is a bit excessive, but this takes the incoming text and pushes it on a 6 | stack and then pops it out again. 7 | 8 | some text. THIS 9 | 10 | [out](# "save: |push 11 | | sub THIS, bye 12 | | store modified 13 | | pop 14 | | cat \n, _'modified' 15 | ") 16 | --- 17 | some text. THIS 18 | some text. bye 19 | -------------------------------------------------------------------------------- /tests/raw.md: -------------------------------------------------------------------------------- 1 | raw - Raw cutting of the text 2 | --- 3 | # Raw 4 | 5 | The raw command and unspacing a shifted header all need testing. So here we 6 | are. 7 | 8 | _"|raw start here, end here | sub -#, # | trim" 9 | 10 | [out](# "save:") 11 | 12 | start here 13 | -# rock me 14 | 15 | great. some stuff 16 | 17 | -## more 18 | 19 | and more 20 | 21 | end here 22 | --- 23 | # rock me 24 | 25 | great. some stuff 26 | 27 | ## more 28 | 29 | and more 30 | -------------------------------------------------------------------------------- /tests/repeatheaders.md: -------------------------------------------------------------------------------- 1 | Repeat Headers - what happens 2 | --- 3 | # Great 4 | 5 | Whatever 6 | 7 | First line 8 | 9 | ## Another block 10 | 11 | _"great" 12 | 13 | [out](# "save:") 14 | 15 | ## Great 16 | 17 | Another line 18 | 19 | --- 20 | First line 21 | Another line 22 | -------------------------------------------------------------------------------- /tests/reports.md: -------------------------------------------------------------------------------- 1 | reports -- testing the report mechanism 2 | --- 3 | # Reports 4 | 5 | Want to try to get some reports going. 6 | 7 | [out](#output "save:") 8 | 9 | [never](#hopeless "save:") 10 | 11 | ## Hopeless 12 | 13 | Here we ask for some things that will never happen. 14 | 15 | _"dude" 16 | 17 | _"|bogus art, dee" 18 | 19 | _"|sub *, _"not here"" 20 | 21 | _"hey now" 22 | 23 | _"just::kidding" 24 | 25 | _"actual" 26 | 27 | _"actual:not here" 28 | 29 | _"not a var" 30 | 31 | 32 | [just::kidding](# "store:hi there") 33 | 34 | ### Actual 35 | 36 | This works. 37 | 38 | ### hey now 39 | 40 | And one more hopelessness 41 | 42 | _"|async _":ev"" 43 | 44 | [ev]() 45 | 46 | This does not call the callback. 47 | 48 | 1 + 1; 49 | 50 | ## Output 51 | 52 | This actually puts the output that we want to see 53 | 54 | _"|async _"timeout"" 55 | 56 | ## Timeout 57 | 58 | This is where we do a bit of black magic to pop it out of the flow. This 59 | delays it to allow the rest of the stuff to compile and be waiting. 60 | 61 | setTimeout(function () { 62 | var a = doc.parent.simpleReport().join("\n"); 63 | var b = doc.parent.reportwaits().join("\n"); 64 | callback(null, b + "\n" + a); 65 | }, 1); 66 | 67 | --- 68 | NOT SAVED: out AS REQUESTED BY: in NEED: output 69 | NOT SAVED: never AS REQUESTED BY: in NEED: hopeless 70 | NEED SCOPE: just FOR SAVING: kidding IN FILE: in 71 | NEED SCOPE: just FOR RETRIEVING: kidding IN FILE: in 72 | PROBLEM WITH: _"dude" IN: hopeless FILE: in 73 | PROBLEM WITH: _"|bogus art, dee" IN: hopeless FILE: in 74 | PROBLEM WITH: _"|sub *, _"not here"" IN: hopeless FILE: in 75 | PROBLEM WITH: _"hey now" IN: hopeless FILE: in 76 | PROBLEM WITH: _"just::kidding" IN: hopeless FILE: in 77 | PROBLEM WITH: _"actual:not here" IN: hopeless FILE: in 78 | PROBLEM WITH: _"not a var" IN: hopeless FILE: in 79 | PROBLEM WITH: _"|async _":ev"" IN: hey now FILE: in 80 | PROBLEM WITH: _"|async _"timeout"" IN: output FILE: in 81 | COMMAND REQUESTED: bogus BUT NOT DEFINED. REQUIRED IN: hopeless FILE: in 82 | -------------------------------------------------------------------------------- /tests/savepipe.md: -------------------------------------------------------------------------------- 1 | save pipe -- dealing with pipe saves 2 | --- 3 | # Save pipes 4 | 5 | Here we want to demonstrate doing piped commands with a save command. 6 | 7 | !ool ?rickets 8 | 9 | [out](# "save:|sub !, c|sub ?, k") 10 | --- 11 | cool krickets 12 | -------------------------------------------------------------------------------- /tests/scope.md: -------------------------------------------------------------------------------- 1 | scope - an attempt to test scope creation and variable storage, retrieval 2 | --- 3 | # Scope 4 | 5 | Let's create some scopes and variables and then use them. 6 | 7 | _"a" _"b" _"other :: c" 8 | 9 | _"more" _"another :: more" 10 | 11 | _"more" _"yester::more" 12 | 13 | [out](#scope "save:") 14 | 15 | ## Variables for storing 16 | 17 | We use directives to do the storing for this first bit. 18 | 19 | [a](# "store:!!") 20 | 21 | [b](# "store:??") 22 | 23 | [yester](# "link scope:another") 24 | 25 | [other::c](# "store:--") 26 | 27 | [other](# "new scope:") 28 | 29 | [another](# "link scope:other") 30 | 31 | 32 | ## less 33 | 34 | This is a bit that will store some stuff into a variable using a command 35 | 36 | _"less:fodder|sub !, k|store more" 37 | 38 | _"less:fodder|sub !, c|store other::more" 39 | 40 | [fodder]() 41 | 42 | !ool !rickets 43 | 44 | --- 45 | !! ?? -- 46 | 47 | kool krickets cool crickets 48 | 49 | kool krickets cool crickets 50 | -------------------------------------------------------------------------------- /tests/scopeexists.md: -------------------------------------------------------------------------------- 1 | scope exists -- test for scope exists problem 2 | --- 3 | # Scope exists 4 | 5 | So there was a problem with asking for a variable before the scope exists. 6 | This is to test for that problem. 7 | 8 | _"butter::tasty" 9 | 10 | [out](# "save:") 11 | 12 | ## Eval 13 | 14 | We create the scope and the variable using a timeout 15 | 16 | setTimeout(function () { 17 | var folder = doc.parent; 18 | folder.createScope("butter"); 19 | doc.store(doc.colon.escape("butter::tasty"), "hi"); 20 | }, 1); 21 | 22 | [](#, "eval:") 23 | 24 | --- 25 | hi 26 | -------------------------------------------------------------------------------- /tests/snippets.md: -------------------------------------------------------------------------------- 1 | Snippets - testing out a snippet 2 | ---start:in 3 | # default 4 | 5 | We need to add a snippet. This should be done in lprc.js 6 | 7 | doc.plugins.snippets["js-t"] = 8 | 'ARG0 = (typeof ARG0 !== "undefined") : ARG0 ? ARG1' 9 | doc.plugins.snippets["dashes"] = function () { 10 | return Array.prototype.join.call(arguments, "---"); 11 | } 12 | 13 | [snips](# "eval:") 14 | 15 | ## Actual text 16 | 17 | function (a) { 18 | _'|s js-t, a, "flowers"'; 19 | } 20 | _'|s dashes, k, l, m, n' 21 | _'|s unk, jr, dude' 22 | 23 | [out](# "save:") 24 | ---out:out 25 | function (a) { 26 | a = (typeof a !== "undefined") : a ? "flowers"; 27 | } 28 | k---l---m---n 29 | jr,dude 30 | ---log: 31 | !Unknown snippet: jr, dude 32 | ! 33 | -------------------------------------------------------------------------------- /tests/store-pipe.md: -------------------------------------------------------------------------------- 1 | storing -- testing the storing directive with pipes 2 | --- 3 | # Storing 4 | 5 | This tests the directive for storing. 6 | 7 | Jack runs up 8 | Jack runs down 9 | 10 | [](# "transform: |sub Jack, Jill | store subbed") 11 | 12 | [](# ": |sub Jack, Jane | store janed") 13 | 14 | [generic:great|dude](# "store: ") 15 | 16 | [ pushy me |1](# "push: ") 17 | [pushy me| 2](# "push:") 18 | 19 | [just one | a](# "push:") 20 | 21 | ## Cat 22 | 23 | _"storing" 24 | 25 | _"subbed" 26 | 27 | _"generic:great" 28 | 29 | _"janed" 30 | 31 | _"pushy me| .join +" 32 | 33 | _"just one | .join -" 34 | 35 | [out](# "save:") 36 | 37 | --- 38 | Jack runs up 39 | Jack runs down 40 | 41 | Jill runs up 42 | Jill runs down 43 | 44 | dude 45 | 46 | Jane runs up 47 | Jane runs down 48 | 49 | 1+2 50 | 51 | a 52 | -------------------------------------------------------------------------------- /tests/store.md: -------------------------------------------------------------------------------- 1 | storing -- testing the storing directive 2 | ---start:in 3 | # Storing 4 | 5 | This tests the directive for storing. 6 | 7 | Jack runs up 8 | Jack runs down 9 | 10 | [](# "transform: |sub Jack, Jill | store subbed") 11 | 12 | [](# ": |sub Jack, Jane | store janed") 13 | 14 | [generic:great](# "store:dude") 15 | 16 | [:good](# "store:programming") 17 | 18 | [whatever]() 19 | 20 | [:bad](# "store:work") 21 | 22 | ## Cat 23 | 24 | _"storing" 25 | 26 | _"subbed" 27 | 28 | _"generic:great" 29 | 30 | _"janed" 31 | 32 | _"storing:bad" 33 | 34 | _"storing:good" 35 | 36 | _"first::head:right" 37 | 38 | [out](# "save:") 39 | [first](first.md "load:") 40 | 41 | ---in:first.md 42 | # Head 43 | 44 | This is to check that the storage directive works with multiple files. 45 | 46 | something 47 | 48 | [:right](# "store:") 49 | 50 | ---out:out 51 | Jack runs up 52 | Jack runs down 53 | 54 | Jill runs up 55 | Jill runs down 56 | 57 | dude 58 | 59 | Jane runs up 60 | Jane runs down 61 | 62 | work 63 | 64 | programming 65 | 66 | something 67 | -------------------------------------------------------------------------------- /tests/sub-input-match.md: -------------------------------------------------------------------------------- 1 | Sub-input-match -- Testing subcommand input and boolean match 2 | --- 3 | 4 | _":text | if ?match(input(), some), sub, some, wow" 5 | _":text | if ?not(?match(input(), reg('ae'))), sub, rand, !!!!" 6 | 7 | _"sum | ifelse arr(?>(input(), num(15)), echo, Time to make a chart), 8 | arr(?<=(input(), num(15)), echo, Expand out each point)" 9 | 10 | 11 | [text]() 12 | 13 | This is some random text 14 | 15 | [sum](# "store: 0 | echo arr(num(1, 2, 3)) 16 | | # we want to add them up. should be 16 with the start of 10 17 | | .reduce fun(`function (sum, el) { return sum + el; }`), num(10) ") 18 | 19 | 20 | --- 21 | This is wow random text 22 | This is some !!!!om text 23 | 24 | Time to make a chart 25 | -------------------------------------------------------------------------------- /tests/sub-reg.md: -------------------------------------------------------------------------------- 1 | Sub reg -- testing the regular expression part of the sub command 2 | --- 3 | Substitutes with regexs 4 | 5 | _"| echo This is great | sub reg(s\s), S-" 6 | _"| echo This is great | sub reg(_"reg"), _"rep | funify" " 7 | _"| echo This is greater | sub _"creg", 8 | ec("Reverse and some scrambling: $'-$1-$`-$&-$1:") " 9 | 10 | 11 | # reg 12 | 13 | A reg 14 | 15 | ([aeiou])(?:[aeiou]) 16 | 17 | [creg](# "store:| regify ") 18 | 19 | # rep 20 | 21 | function (match, one) { 22 | return one.toUpperCase() + 9; 23 | } 24 | 25 | --- 26 | ThiS-iS-great 27 | This is grE9t 28 | This is grReverse and some scrambling: ter-e-This is gr-ea-e:ter 29 | -------------------------------------------------------------------------------- /tests/sub.md: -------------------------------------------------------------------------------- 1 | sub - this tests the sub command 2 | --- 3 | # Sub 4 | 5 | Great. We have substituions. 6 | 7 | [out](#subbed "save:") 8 | 9 | ## Start 10 | 11 | Let's look at our *~. We start with :c. 12 | 13 | ## Subbed 14 | 15 | This will be unneeded once save: pipes implemented. 16 | 17 | _"start|sub *~, alphabet|sub :, a, :c, _"cb"" 18 | 19 | ## CB 20 | 21 | Let's put c in there as a block. 22 | 23 | iv 24 | 25 | --- 26 | Let's look at our alphabet. We start with iv. 27 | -------------------------------------------------------------------------------- /tests/subcommands.md: -------------------------------------------------------------------------------- 1 | subCommands -- testing our subcommands 2 | --- 3 | 4 | _"echo" 5 | 6 | _"join" 7 | 8 | _"json" 9 | 10 | _"act" 11 | 12 | _"eval" 13 | 14 | _"set" 15 | 16 | _"prop" 17 | 18 | _"primitives" 19 | 20 | _"regexp" 21 | 22 | 23 | 24 | ## echo 25 | 26 | _"|join echo(' :: ', `first up`), ec("Cool, beans."), ec(koo\"like)" 27 | 28 | ## join 29 | 30 | _"|cat join(ec(" -- "), arr(this, that), the other)" 31 | 32 | ## json 33 | 34 | _"|cat json( merge( obj({"a" : 2, "c" : "j"}), 35 | kv(b, merge(arr(3, 4), arr(t, f)), c, k ) ) )" 36 | 37 | ## act 38 | 39 | _"|join :, args(act(arr (4, 5, 6), slice, num(1) ) )" 40 | 41 | ## eval 42 | 43 | _"|join :, eval(_":code", arr(num(1, 2, 3, 4, 5))), 44 | ev(`ret = 70;`)" 45 | 46 | 47 | 48 | [code]() 49 | 50 | ret = args[0].reduce(function (prev, cur) { 51 | return prev + cur; 52 | }); 53 | 54 | ## set 55 | 56 | This is going to see if the get and sets work 57 | 58 | _"| cat 5, gSet(obj({"a": [1, 2, 3]})) | 59 | join :=:, set(kv(cool, gGet(a))), 60 | args(eval( `ret = args[0].concat(args[1]);`, 61 | get(cool, cool)))" 62 | 63 | ## prop 64 | 65 | _"|join :, property(doc(), colon, v ), property(doc(), cmdName)" 66 | 67 | ## primitives 68 | 69 | _"|join :, arr(true(), true() skip(5), false(), false(), null())" 70 | 71 | ## regexp 72 | 73 | This tests the regexp construct. 74 | 75 | _"| echo Awesome | .replace reg(e, g), i" 76 | 77 | --- 78 | first up :: Cool, beans. :: koo"like 79 | 80 | this -- that -- the other 81 | 82 | {"a":2,"c":"k","b":["3","4","t","f"]} 83 | 84 | 5:6 85 | 86 | 15:70 87 | 88 | 5:=:1:=:2:=:3:=:1:=:2:=:3 89 | 90 | ⫶:in:prop⫶0⫶3 91 | 92 | true,true,false,false, 93 | 94 | Awisomi 95 | -------------------------------------------------------------------------------- /tests/subindent.md: -------------------------------------------------------------------------------- 1 | sub indent -- indenting code well 2 | --- 3 | # Sub indent 4 | 5 | This checks to see whether indenting works for the sub command. 6 | 7 |
8 | LIST 9 |
10 | 11 | [out](# "save:| sub LIST, _`some stuff`") 12 | 13 | ## some stuff 14 | 15 | 18 | --- 19 |
20 | 23 |
24 | -------------------------------------------------------------------------------- /tests/switch.md: -------------------------------------------------------------------------------- 1 | switch - testing the switch piping 2 | --- 3 | # Switching 4 | 5 | Here we want to explore the minor switch piping. 6 | 7 | _":awesome.cri" 8 | 9 | [out](#switching "save:") 10 | 11 | [awesome](# ":cri|sub !, k|sub ?, c") 12 | 13 | !ool ?rickets _":dude" asdf 14 | 15 | [dude]() 16 | 17 | jump 18 | 19 | --- 20 | kool crickets jump asdf 21 | -------------------------------------------------------------------------------- /tests/switchcmd.md: -------------------------------------------------------------------------------- 1 | switch command -- testing for switch commands to see larger block 2 | --- 3 | # Switch command testing 4 | 5 | jack 6 | 7 | [out](#:first "save:") 8 | 9 | [first](# ":| sub THIS, _':second'") 10 | 11 | THIS _":" 12 | 13 | [second]() 14 | 15 | bye 16 | --- 17 | bye jack 18 | -------------------------------------------------------------------------------- /tests/templateexample.md: -------------------------------------------------------------------------------- 1 | template example -- from the readme 2 | ---start:in 3 | ## Top 4 | 5 | After the first compile, the numbers will be decremented, but the blocks 6 | will not be evaluated. 7 | 8 | \1_":first" 9 | 10 | \2_":second" 11 | 12 | \1_":final" 13 | 14 | 15 | This is now a template. We could use it as 16 | 17 | [jack](# "store:| compile basic ") 18 | 19 | [happy.txt](#jack "save:| compile great") 20 | [sad.txt](# "save:| compile basic | compile grumpy") 21 | 22 | 23 | # Basic 24 | 25 | [first]() 26 | 27 | Greetings and Salutations 28 | 29 | [final]() 30 | 31 | Sincerely, 32 | Jack 33 | 34 | # Great 35 | 36 | [second]() 37 | 38 | You are great. 39 | 40 | # Grumpy 41 | 42 | [second]() 43 | 44 | You are grumpy. 45 | 46 | # Middle 47 | 48 | [second]() 49 | 50 | You are okay. 51 | 52 | ## Another 53 | 54 | \_":first" 55 | 56 | \_"$2:second" 57 | 58 | \_":final" 59 | 60 | [middle.txt](# "save:| sub $2, middle | compile basic") 61 | 62 | ---out:happy.txt 63 | Greetings and Salutations 64 | 65 | You are great. 66 | 67 | Sincerely, 68 | Jack 69 | ---out:sad.txt 70 | Greetings and Salutations 71 | 72 | You are grumpy. 73 | 74 | Sincerely, 75 | Jack 76 | ---out:middle.txt 77 | Greetings and Salutations 78 | 79 | You are okay. 80 | 81 | Sincerely, 82 | Jack 83 | -------------------------------------------------------------------------------- /tests/templating.md: -------------------------------------------------------------------------------- 1 | templating -- testing out various templates 2 | ---start:first 3 | # Templating 4 | 5 | Here we want to test some of the templating features. 6 | 7 | _"woot | compile jack::crown" 8 | 9 | [out](# "save:") 10 | 11 | [jack](jack "load:") 12 | 13 | ## Woot 14 | 15 | \_":this" jill 16 | 17 | 18 | ---in:jack 19 | # Crown 20 | 21 | [this]() 22 | 23 | hey 24 | ---out:out 25 | hey jill 26 | -------------------------------------------------------------------------------- /tests/trailingunderscore.md: -------------------------------------------------------------------------------- 1 | Trailing Underscore - blocks ending in underscore 2 | --- 3 | Not sure why one would end a block with an underscore, but apparently it 4 | happens. 5 | 6 | cool 7 | _"more issues" 8 | this is great_ 9 | 10 | 11 | ## more issues 12 | 13 | just another with a \_" cool _"what" 14 | 15 | ## what 16 | 17 | dude \_" 18 | 19 | --- 20 | cool 21 | just another with a _" cool dude _" 22 | this is great_ 23 | 24 | -------------------------------------------------------------------------------- /tests/transform.md: -------------------------------------------------------------------------------- 1 | transform -- testing transform syntax 2 | --- 3 | # Transform 4 | 5 | This tests transforming text. 6 | 7 | this is cool 8 | 9 | [](# ":|store wish ") 10 | 11 | [|b](# ":| sub cool, dude| store a") 12 | 13 | 14 | [crazy](# ": ") 15 | 16 | Last one right 17 | 18 | [|c](# ":| sub one, two | store star ") 19 | 20 | ## Out 21 | 22 | _"wish" 23 | 24 | _"a" 25 | 26 | _"star" 27 | 28 | _"transform:crazy" 29 | 30 | 31 | [out](#out "save:") 32 | 33 | --- 34 | this is cool 35 | 36 | this is dude 37 | 38 | Last two right 39 | 40 | Last one right 41 | -------------------------------------------------------------------------------- /tests/version.md: -------------------------------------------------------------------------------- 1 | version -- testing version and npminfo command 2 | --- 3 | # [litpro-version-test](# "Version: 0.4.2 ; A tagline appears") 4 | 5 | _"g::docname" 6 | 7 | _"g::docversion" 8 | 9 | _"g::authorname" 10 | 11 | _"g::gituser" 12 | 13 | _"g::authoremail" 14 | 15 | _"g::npm dependencies" 16 | 17 | _"g::npm dev dependencies" 18 | 19 | _"g::tagline" 20 | 21 | 22 | [out](# "save:") 23 | 24 | [James Taylor](https://github.com/jostylr "npminfo: jostylr@gmail.com ; deps: ; 25 | dev: literate-programming-cli 0.6.0, tape 3.5.0 ") 26 | --- 27 | litpro-version-test 28 | 29 | 0.4.2 30 | 31 | James Taylor 32 | 33 | jostylr 34 | 35 | jostylr@gmail.com 36 | 37 | 38 | 39 | "literate-programming-cli" : "^0.6.0", 40 | "tape" : "^3.5.0" 41 | 42 | A tagline appears 43 | -------------------------------------------------------------------------------- /tests/wrap.md: -------------------------------------------------------------------------------- 1 | wrap - testing wrap command 2 | --- 3 | # wrap 4 | 5 | some great content 6 | 7 | [out](# "save: | wrap << , }} ") 8 | --- 9 | <