1 | # literate-programming-lib [![Build Status](https://travis-ci.org/jostylr/literate-programming-lib.png)](https://travis-ci.org/jostylr/literate-programming-lib)
|
2 |
|
3 | Write your code anywhere and in any order with as much explanation as you
|
4 | like. literate-programming will weave it all together to produce your project.
|
5 |
|
6 | This is a modificaiton of and an implementation of
|
7 | [Knuth's Literate Programming](http://www-cs-faculty.stanford.edu/~uno/lp.html)
|
8 | technique. It is
|
9 | perhaps most in line with [noweb](http://tex.loria.fr/litte/ieee.pdf).
|
10 |
|
11 | It uses markdown as the basic document format with the code to be weaved
|
12 | together being markdown code blocks. GitHub flavored code fences can also be used
|
13 | to demarcate code blocks. In particular, [commonmark](http://commonmark.org/)
|
14 | is the spec that the parsing of the markdown is used. Anything considered code
|
15 | by it will be considered code by literate programming.
|
16 |
|
17 | This processing does not care what language(s) your are programming in. But it
|
18 | may skew towards more useful for the web stack.
|
19 |
|
20 | This is the core library that is used as a module. See
|
21 | [-cli](https://github.com/jostylr/literate-programming-cli) for the command
|
22 | line client. The [full](https://github.com/jostylr/literate-programming)
|
23 | version has a variety of useful standard
|
24 | plugins ("batteries included").
|
25 |
|
26 | ## Installation
|
27 |
|
28 | This requires [node.js](http://nodejs.org) and [npm](https://npmjs.org/) to be
|
29 | installed. See [nvm](https://github.com/creationix/nvm) for a recommend
|
30 | installation of node; it allows one to toggle between different versions. This
|
31 | has been tested on node.js .10, .12, and io.js. It is basic javascript and
|
32 | should work pretty much on any javascript engine.
|
33 |
|
34 | Then issue the command:
|
35 |
|
36 | npm install literate-programming-lib
|
37 |
|
38 | Since this is the library module, typically you use the client version install
|
39 | and do not install the lib directly. If you are hacking with modules, then you
|
40 | already know that you will want this in the package.json file.
|
41 |
|
42 | ## Using as a module
|
43 |
|
44 | You can use `Folder = require('literate-programming-lib');` to get
|
45 | a constructor that will create what I think of as a folder.
|
46 | The folder will handle all the documents and scopes and etc.
|
47 |
|
48 | To actually use this library (as opposed to the command line client),
|
49 | you need to establish how it fetches documents and tell
|
50 | it how to save documents. An example is below. If you just want to compile
|
51 | some documents, use the command line client and ignore this. Just saying the
|
52 | following is not pretty. At least, not yet!
|
53 |
|
54 | The thing to keep in mind is
|
55 | that this library is strutured around events
|
56 | using my [event-when](https://github.com/jostylr/event-when) library. The
|
57 | variable gcd is the event emitter (dispatcher if you will).
|
58 |
|
59 |
|
60 | var fs = require('fs');
|
61 | var Folder = require('literate-programming-lib');
|
62 | var folder = new Folder();
|
63 | var gcd = folder.gcd;
|
64 | var colon = folder.colon;
|
65 |
|
66 | gcd.on("need document", function (rawname) {
|
67 | var safename = colon.escape(rawname);
|
68 | fs.readfile(rawname, {encoding:'utf8'}, function (err, text) {
|
69 | if (err) {
|
70 | gcd.emit("error:file not found:" + safename);
|
71 | } else {
|
72 | folder.newdoc(safename, text);
|
73 | }
|
74 | });
|
75 | });
|
76 |
|
77 | gcd.on("file ready", function(text, evObj) {
|
78 | var filename = evObj.pieces[0];
|
79 | fs.writefile(filename, text);
|
80 | });
|
81 |
|
82 | gcd.emit("need document:first.md");
|
83 |
|
84 | This last line should start the whole chain of compilation with first.md being read in
|
85 | and then any of its files being called, etc., and then any files to save will
|
86 | get saved.
|
87 |
|
88 | The reason the lib does not have this natively is that I separated it out
|
89 | specifically to avoid requiring file system access. Instead you can use any kind of
|
90 | function that provides text, or whatever. It should be fine to also use
|
91 | `folder.newdoc` directly on each bit of text as needed; everything will
|
92 | patiently wait until the right stuff is ready. I think.
|
93 |
|
94 | Note that live code can be run from a literate program as well. So be
|
95 | careful!
|
96 |
|
97 | ## Example
|
98 |
|
99 | Let's give a quick example of what a sample text might look like.
|
100 |
|
101 | # Welcome
|
102 |
|
103 | So you want to make a literate program? Let's have a program that outputs
|
104 | all numbers between 1 to 10.
|
105 |
|
106 | Let's save it in file count.js
|
107 |
|
108 | [count.js](#Structure "save:")
|
109 |
|
110 | ## Structure
|
111 |
|
112 | We have some intial setup. Then we will generate the array of numbers. We
|
113 | end with outputting the numbers.
|
114 |
|
115 | var numarr = [], start=1, end = 11, step = 1;
|
116 |
|
117 | _"Loop"
|
118 |
|
119 | _"Output"
|
120 |
|
121 | ## Output
|
122 |
|
123 | At this point, we have the array of numbers. Now we can join them with a
|
124 | comma and output that to the console.
|
125 |
|
126 | console.log("The numbers are: ", numarr.join(", ") );
|
127 |
|
128 | ## Loop
|
129 |
|
130 | Set the loop up and push the numbers onto it.
|
131 |
|
132 | var i;
|
133 | for (i = start; i < end; i += step) {
|
134 | numarr.push(i);
|
135 | }
|
136 |
|
137 | A full example of a literate program is lp.md in this repository. It compiles
|
138 | to this library.
|
139 |
|
140 |
|
141 | ## Document syntax
|
142 |
|
143 | A literate program is a markdown document with some special conventions.
|
144 |
|
145 | The basic idea is that each header line (regardless of level, either atx # or
|
146 | seText underline ) demarcates a full block. Code blocks within a full block
|
147 | are the bits that are woven together.
|
148 |
|
149 | ### Code Block
|
150 |
|
151 | Each code block can contain whatever kind of code, but there is a primary special
|
152 | syntax.
|
153 |
|
154 | `_"Block name"` This tells the compiler to compile the block with "Block
|
155 | name" and then replace the `_"Block name"` with that code.
|
156 |
|
157 | Note the the allowed quotes are double, single, and backtick. Matching types
|
158 | are expected. And yes, it is useful to have three different types.
|
159 |
|
160 | The full syntax is something of the form
|
161 | `_"scope name::block name:minor block name | cmd arg 1, arg 2 | cmd2 |cmd3 ..."`
|
162 | where the scope name allows us to refer to other documents (or artificial
|
163 | common scopes) and the commands run the output of one to the input of the
|
164 | other, also taking in arguments which could they themselves be block
|
165 | substitutions.
|
166 |
|
167 | Note that one can also backslash escape the underscore. To have multiple
|
168 | escapes (to allow for multiple compiling), one can use `\#_"` where the number
|
169 | gets decremented by one on each compile and, when it is compiled with a 0 there,
|
170 | the sub finally gets run.
|
171 |
|
172 | A block of the form `_":first"` would look for a minor block, i.e., a block
|
173 | that has been created by a switch directive. See next section.
|
174 |
|
175 | ### Directive
|
176 |
|
177 | A directive is a command that interacts with external input/output. Just about
|
178 | every literate program has at least one save directive that will save some
|
179 | compiled block to a file.
|
180 |
|
181 | The syntax for the save directive is
|
182 |
|
183 | [file.ext](#name-the-heading "save: encoding | pipe commands")
|
184 |
|
185 | where
|
186 |
|
187 | * `file.ext` is the name of the file to save to
|
188 | * `name-the-heading` is the heading of the block whose compiled version is being saved.
|
189 | Spaces in the heading get converted to dashes for id linking purposes. Colons can be used
|
190 | to reference other scopes and/or minor blocks. In particular, `#:jack` will
|
191 | refernce the `jack` minor in the current heading block where the save
|
192 | directive is located.
|
193 | * `save:` is there to say this is the directive to save a file
|
194 | * `encoding` is any valid encoding of
|
195 | [iconv-lite](https://github.com/ashtuchkin/iconv-lite/wiki/Supported-Encodings).
|
196 | This is relevant more in the command line module, but is here as the save
|
197 | directive is here.
|
198 | * `pipe commands` optional commands to process the text before saving. See
|
199 | next section.
|
200 |
|
201 |
|
202 | For other directives, what the various parts mean depends, but it is always
|
203 |
|
204 | [some](#stuff "dir: whatever")
|
205 |
|
206 | where the `dir` should be replaced with a directive name. If dir is absent,
|
207 | but the colon is there, then this demarcates a minor block start.
|
208 |
|
209 | ### Pipes
|
210 |
|
211 | One can also use pipes to pipe the compiled text through a command to do
|
212 | something to it. For example, `_"Some JS code | jshint"` will take the code
|
213 | in block `some JS code` and pipe it into the jshint command which can be a
|
214 | thin wrapper for the jshint module and report errors to the console.
|
215 | That command would then return the text in an untouched fashion. We can also use
|
216 | pipe commands to modify the text.
|
217 |
|
218 | Commands can be used in block substitutions, minor block directive switches, and
|
219 | other directives that are setup to use them such as the save and out directive:
|
220 | `[code.js](#some-js-code "save: | jstidy)` will tidy up the code
|
221 | before storing it in the file `code.js`.
|
222 |
|
223 | If you want your own directive to process pipes, see the [save directive](https://github.com/jostylr/literate-programming-lib/blob/master/lp.md#save) in
|
224 | lp.md. Pay particular attention to the "process" and "deal with start" minor
|
225 | blocks. The functionality of pipe parsing is in the `doc.pipeParsing` command,
|
226 | but there events that need to be respected in the setup.
|
227 |
|
228 | Commands take arguments separated by commas and commands end with pipes or the
|
229 | block naming quote. One can also use a named code block as an argument, using
|
230 | any of the quote marks (same or different as surroung block name). To
|
231 | escape commas, quotes, pipes, underscores, spaces (spaces get trimmed from the
|
232 | beginning and ending of an argument), newlines, one can use a backslash, which
|
233 | also escapes itself. Note that the commonmark parser will escape all
|
234 | backslash-punctuation combinations outside of code blocks. So you may need a
|
235 | double backslash in directive command pipings.
|
236 |
|
237 | You can also use `\n` to puta newline in line or `\u...` where the ... is a
|
238 | unicode codepoint per javascript spec implemented by [string.fromcodepoint](https://github.com/mathiasbynens/String.fromCodePoint).
|
239 |
|
240 |
|
241 | ### Minor Block
|
242 |
|
243 | Finally, you can use distinct code blocks within a full block. If you simply
|
244 | have multiple code blocks with none of the switching syntax below, then they
|
245 | will get concatenated into a single code block.
|
246 |
|
247 | You can also switch to have what I call minor blocks within a main heading. This is mainly
|
248 | used for small bits that are just pushed out of the way for convenience. A
|
249 | full heading change is more appropriate for something that merits separate attention.
|
250 |
|
251 | To create a minor block, one can either use a link of the form `[code name]()` or
|
252 | `[code name](#whatever ":|cmd ...")` Note this is a bit of a break from
|
253 | earlier versions in which a link on its own line would create a minor block. Now it is
|
254 | purely on the form and not on placement.
|
255 |
|
256 |
|
257 | Example: Let's say in heading block `### Loopy` we have `[outer loop]()`
|
258 | Then it will create a code block that can be referenced by
|
259 | `_"Loopy:outer loop"`.
|
260 |
|
261 | Note: If the switch syntax is `[](#... ":|...")` then this just transforms
|
262 | whatever is point to in href using the pipe commands. That is, it is not a
|
263 | switch, but fills in a gap for main blocks not having pipe switch syntax. The
|
264 | key is the empty link text.
|
265 |
|
266 | #### Templating
|
267 |
|
268 | One use of minor blocks is as a templating mechanism.
|
269 |
|
270 | ## Top
|
271 |
|
272 | After the first compile, the numbers will be decremented, but the blocks
|
273 | will not be evaluated.
|
274 |
|
275 | \1_":first"
|
276 |
|
277 | \2_":second"
|
278 |
|
279 | \1_":final"
|
280 |
|
281 |
|
282 | This is now a template. We could use it as
|
283 |
|
284 | [happy.txt](# "save:| compile basic, great")
|
285 | [sad.txt](# "save:| compile basic, grumpy")
|
286 |
|
287 |
|
288 | # Basic
|
289 |
|
290 | [first]()
|
291 |
|
292 | Greetings and Salutations
|
293 |
|
294 | [final]()
|
295 |
|
296 | Sincerely,
|
297 | Jack
|
298 |
|
299 | # Great
|
300 |
|
301 | [second]()
|
302 |
|
303 | You are great.
|
304 |
|
305 | # Grumpy
|
306 |
|
307 | [second]()
|
308 |
|
309 | You are grumpy.
|
310 |
|
311 | This would produce two text files
|
312 |
|
313 |
|
314 | happy.txt:
|
315 |
|
316 | Greetings and Salutations
|
317 |
|
318 | You are great.
|
319 |
|
320 | Sincerely,
|
321 | Jack
|
322 |
|
323 | sad.txt:
|
324 |
|
325 |
|
326 | Greetings and Salutations
|
327 |
|
328 | You are grumpy.
|
329 |
|
330 |
|
331 | Sincerely,
|
332 | Jack
|
333 |
|
334 |
|
335 | Note that you need to be careful about feeding in the escaped commands into
|
336 | other parsers. For example, I was using Jade to generate HTML structure and
|
337 | then using this templating to inject content (using markdown). Well, Jade
|
338 | escapes quotes and this was causing troubles. So I used backticks to delimit
|
339 | the block name instead of quotes and it worked fine. Be flexible.
|
340 |
|
341 |
|
342 | ## Nifty parts of writing literate programming
|
343 |
|
344 | * You can have your code in any order you wish.
|
345 | * You can separate out flow control from the processing. For example,
|
346 |
|
347 | if (condition) {
|
348 | _"Truth"
|
349 | } else {
|
350 | _"Beauty"
|
351 | }
|
352 |
|
353 | The above lets you write the if/else statement with its logic and put the
|
354 | code in the code blocks `truth` and `beauty`. This can help keep one's
|
355 | code to within a single screenful per notion.
|
356 | * You can write code in the currently live document that has no effect, put in
|
357 | ideas in the future, etc.
|
358 | * You can "paste" multiple blocks of code using the same block name. This is
|
359 | like DRY, but the code does get repeated for the computer. You can also
|
360 | substitute in various values in the substitution process so that code
|
361 | blocks that are almost the same but with different names can come from the
|
362 | same root structure.
|
363 | * You can put distracting data checks/sanitation/transformations into another
|
364 | block and focus on the algorithm without the use of functions (which can be
|
365 | distracting).
|
366 | * You can process the blocks in any fashion you want. So for example, to
|
367 | create a JSON object, one could use a simpler setup appropriate for the
|
368 | particular data and then transform it into JSON. It's all good.
|
369 | * This brings DSL and grunt power, written in the same place as your code. It
|
370 | is really about coding up an entire project.
|
371 | * Getting the length of functions right is difficult. Too short functions,
|
372 | and boilerplate and redirection becomes quite the bother. Too long, and it
|
373 | is hard to understand what all a function is doing. Too long and we lose
|
374 | composability. Too short, the chain of composing them becomes too long.
|
375 | Literate programming can help somewhat in that we can have longer functions
|
376 | and still have it understood. We could also potentially use the litpro
|
377 | blocks again allowing for some composability though that that should be
|
378 | rare. I think the rule of thumb is that if breaking it up seems good from a
|
379 | usability stance, do it. If breaking it up is more about keeping a function
|
380 | to a readable length, use litpro blocks. Another advantage of using litpro
|
381 | blocks is that we get the benefit of small parts when coding, but when
|
382 | debugging, we can see a much larger flow of code all at once in the compiled
|
383 | version.
|
384 |
|
385 | I also like to use it to compile an entire project from a single file, pulling
|
386 | in other literate program files as needed. That is, one can have a
|
387 | command-and-control literate program file and a bunch of separate files for
|
388 | separate concerns. But note that you need not split the project into any
|
389 | pre-defined ways. For example, if designing a web interface, you can organize
|
390 | the files by widgets, mixing in HTML, CSS, and JS in a single file whose
|
391 | purpose is clear. Then the central file can pull it all in to a single web
|
392 | page (or many) as well as save the CSS and JS to their own files as per the
|
393 | reommendation, lessing the CSS, tanspiling ES6, linting, and minifying all as
|
394 | desired. Or you could just write each output file separate in its own litpro
|
395 | document.
|
396 |
|
397 | It's all good. You decide the order and grouping. The structure of your litpro
|
398 | documents is up to you and is **independent** of the needed structures of the
|
399 | output.
|
400 |
|
401 | ## Built in directives
|
402 |
|
403 | There are a variety of directives that come built in.
|
404 |
|
405 | * **Save** `[filename](#start "save:options|commands")` Save the text from start
|
406 | into file filename. The options can be used in different ways, but in the
|
407 | command client it is an encoding string for saving the file; the default
|
408 | encoding is utf8.
|
409 | * **Store** `[name](#start "store:value|...")` If the value is present, then
|
410 | it is sent through the pipes. If there is no
|
411 | value, then the `#start` location is used for the value and that gets piped.
|
412 | The name is used to store the value.
|
413 | * **Transform** `[des|name](#start "transform:|...)` or `[des|name](#start ":|...")`.
|
414 | This takes the value that start points to and transforms it using the pipe
|
415 | commands. Note one can store the transformed values by placing the variable
|
416 | name after a pipe in the link text.
|
417 | The description of link text has no role. For the syntax
|
418 | with no transform, it can be link text that starts with a pipe or it can be
|
419 | completely empty. Note that if it is empty, then it does not appear and is
|
420 | completely obscure to the reader.
|
421 | * **Load** `[alias](url "load:options")` This loads the file, found at the url
|
422 | (file name probably) and stores it in the alias scope as well as under the
|
423 | url name. We recommend using a short alias and not relying on the filename
|
424 | path since the alias is what will be used repeatedly to reference the blocks
|
425 | in the loaded file. Options are open, but for the command line client it is
|
426 | the encoding string with default utf8. Note there are no pipes since there
|
427 | is no block to act on it.
|
428 | * **Define** `[command name](#start "define: async/sync/raw|cmd")` This allows one
|
429 | to define commands in a lit pro document. Very handy. Order is irrelevant;
|
430 | anything requiring a command will wait for it to be defined. This is
|
431 | convenient, but also a bit more of a bother for debugging. Anyway, the start
|
432 | is where we find the text for the body of the command. The post colon, pre
|
433 | pipe area expects one of three options which is explained below in plugins.
|
434 | The default is sync which if you return the text you want to pass along from
|
435 | the command, then it is all good. Start with that. You can also pipe your
|
436 | command definition through pipe commands before finally installing the
|
437 | function as a live function. Lots of power, lots of headaches :) The
|
438 | signature of a command is `function (input, args, name)` where the input is
|
439 | the text being piped in, the args are the arguments array (all text) of the
|
440 | command, and name is the name to be emitted when done. For async, name is a
|
441 | callback function that should be called when done. For sync, you probably
|
442 | need not worry about a name. The doc that is calling the command is the
|
443 | `this`.
|
444 | * **Block**s on/off `[off](# "block:")` Stops recording code blocks. This is
|
445 | good when writing a bunch of explanatory code text that you do not want
|
446 | compiled. You can turn it back on with the `[on](# "block:")` directive.
|
447 | Directives and headings are still actively being run and used. These can be
|
448 | nested. Think "block comment" sections. Good for turning off troublesome
|
449 | sections.
|
450 | * **Eval** `[des|name](# "eval:)` Whatever block the eval finds itself, it will eval. It
|
451 | will eval it only up to the point where it is placed. This is an immediate
|
452 | action and can be quite useful for interventions. The eval will have access
|
453 | to the doc object which gives one access to just about everything else. This
|
454 | is one of those things that make running a literate progamming insecure. The
|
455 | return value is nonexistent and the program will not usually wait for any async
|
456 | actions to complete. If you put a pipe in the link name text, then the
|
457 | anything after the pipe will become a name that the variable `ret` will be
|
458 | stored in.
|
459 | * **Ignore** `[language](# "ignore:")` This ignores the `language` code blocks.
|
460 | For example, by convention, you could use code fence blocks with language js
|
461 | for compiled code and ignore those with javascript. So you can have example
|
462 | code that will not be seen and still get your syntax highlighting and
|
463 | convenience. Note that this only works with code fences, obviously. As soon
|
464 | as this is seen, it will be used and applied there after.
|
465 | * **Out** `[outname](#start "save:|commands")` Sends the text from start
|
466 | to the console, using outname as a label.
|
467 | * **New scope** `[scope name](# "new scope:")` This creates a new scope (stuff
|
468 | before a double colon). You can use it to store variables in a different
|
469 | scope. Not terribly needed, but it was easy to expose the underlying
|
470 | functionality.
|
471 | * **Link Scope** `[alias name](# "link scope:scopename")` This creates an alias for
|
472 | an existing scope. This can be useful if you want to use one name and toggle
|
473 | between them. For example, you could use the alias `v` for `dev` or `deploy`
|
474 | and then have `v::title` be used with just switching what `v` points to
|
475 | depending on needs. A bit of a stretch, I admit.
|
476 | * **Log** `[match string](# "log:")` This is a bit digging into the system. You
|
477 | can monitor the events being emitted by using what you want to match for.
|
478 | For example, you could put in a block name (all lower cased) and monitor all
|
479 | events for that. This gets sent to `doc.log` which by default prints to
|
480 | `console.log`. If you use `\:` in the match string, this becomes the triple
|
481 | colon separator that we use for techinical reasons for `block:minor` name syntax.
|
482 | This directive's code gives a bit of insight as to how to get
|
483 | more out of the system.
|
484 | * **If** `[...](... "if: flag; directive:...")` If flag holds true (think build
|
485 | flag), then the driective is executed with the arguments as given. A couple
|
486 | of great uses are conditional evaling which allows for a great deal of
|
487 | flexibility and conditional block on/off which may be useful if there is
|
488 | extensive debugging commands involved.
|
489 | * **Flag** `[flag name](# "flag:")` This sets the named flag to true. Note
|
490 | there is no way to turn a flag off easily.
|
491 | * **Version** `[name](# "version: number ; tagline")` This gives the name and version of
|
492 | the program. Note the semicolon separator.
|
493 | Saves `g::docname`, `g::docversion`, `g::tagline`.
|
494 | * **npminfo** `[author name](github/gituser "npminfo: author email; deps: ;
|
495 | dev: " )` This takes in a string for some basic author information and
|
496 | dependencies used. To add on or modify how it handles the deps, dev, etc.,
|
497 | modify the `types` object on `Folder.directives.npminfo`.
|
498 | Saves `g::authorname`, `g::gituser`, `g::authoremail`, `g::npm
|
499 | dependencies`, `g::npm dev dependencies`.
|
500 |
|
501 | ## Built in commands
|
502 |
|
503 | Note commands need to be one word.
|
504 |
|
505 | * **Eval** `code, arg1,...` The first argument is the text of the code to
|
506 | eval. In its scope, it will have the incoming text as the `text` variable
|
507 | and the arguments, which could be objects, will be in the `args` array. The
|
508 | code is eval'd (first argument). The code text itself is available in the
|
509 | `code` variable. The variable `text` is what is passed along. This should
|
510 | make for quick hacking on text. The doc variable is also available for
|
511 | inpsecting all sorts of stuff, like the current state of the blocks. If you
|
512 | want to evaluate the incoming text and use the result as text, then the line
|
513 | `text = eval(text)` as the first argument should work.
|
514 | * **Async** (async eval) `code1, code2, ...` Same deal as eval, except this
|
515 | code expects a callback function to be called. It is in the variable
|
516 | callback. So you can read a file and have its callback call the callback to
|
517 | send the text along its merry way.
|
518 | * **Compile** This compiles a block of text as if it was in the document
|
519 | originally. The compiled text will be the output. The arguments give the
|
520 | names of blocknames that are used if short-hand minor blocks are
|
521 | encountered. This is useful for templating.
|
522 | * **Sub** `key1, val1, key2, val2, ...` This replaces `key#` in the text with
|
523 | `val#`. The replacement is sorted based on the length of the key value. This
|
524 | is to help with SUBTITLE being replaced before TITLE, for example, while
|
525 | allowing one to write it in an order that makes reading make sense. A little
|
526 | unorthodox. We'll see if I regret it.
|
527 | * **Store** `variable name` This stores the incoming text into the variable
|
528 | name. This is good for stashing something in mid computation. For example,
|
529 | `...|store temp | sub THIS, that | store awe | _"temp"` will stash the
|
530 | incoming text into temp, then substitute out THIS for that, then store that
|
531 | into awe, and finally restore back to the state of temp. Be careful that the
|
532 | variable temp could get overwritten if there are any async operations
|
533 | hanging about. Best to have unique names. See push and pop commands for a
|
534 | better way to do this.
|
535 | * **Log** This will output a concatenated string to doc.log (default
|
536 | console.log) with the incoming text and the arguments. This is a good way to
|
537 | see what is going on in the middle of a transformation.
|
538 | * **Raw** `start, end` This will look for start in the raw text of the file
|
539 | and end in the file and return everything in between. The start and end are
|
540 | considered stand-alone lines.
|
541 | * **Trim** This trims the incoming text, both leading and trailing whitespace.
|
542 | Useful in some tests of mine.
|
543 | * **Join** This will concatenate the incoming text and the arguments together
|
544 | using the first argument as the separator. Note one can use `\n` as arg1 and
|
545 | it should give you a newline (use `\\n` if in a directive due to parser
|
546 | escaping backslashes!). No separator can be as easy as `|join ,1,2,...`.
|
547 | * **Cat** The arguments are concatenated with the incoming text as is. Useful
|
548 | for single arguments, often with no incoming text.
|
549 | * **Push** Simply pushes the current state of the incoming text on the stack
|
550 | for this pipe process.
|
551 | * **Pop** Replaces the incoming text with popping out the last unpopped pushed
|
552 | on text.
|
553 | * **If** `flag, cmd, arg1, arg2, ....` If the flag is present (think build
|
554 | flag), then the command will execute with the given input text and
|
555 | arguments. Otherwise, the input text is passed on.
|
556 | * **When** `name1, name2, ...` This takes in the event names and waits for
|
557 | them to be emitted by done or manually with a
|
558 | `doc.parent.done.gcd.once(name, "done")`. That would probably be used in
|
559 | directives. The idea of this setup is to wait to execute a cli command for
|
560 | when everything is setup. It passes through the incoming text.
|
561 | * **Done** `name` This is a command to emit the done event for name. It just
|
562 | passes through the incoming text. The idea is that it would be, say, a
|
563 | filename of something that got saved.
|
564 |
|
565 | ## Built-in Subcommands
|
566 |
|
567 | With command arguments, one can run commands on arguments to get them in some
|
568 | appropriate form or use, including passing in objects or arrays. You can use
|
569 | them as `cmd a, subcmd(arg1, arg2, arg3)` would have subcmd acting on the args
|
570 | and the result of that would be the argument place
|
571 | The `a` would be passed into cmd as the first
|
572 | argument, but anything might get passed into cmd by subcmd's return value. It
|
573 | could also store an object into a state for configuration.
|
574 |
|
575 | There are several built-in subcommands. Note that these are case insensitive.
|
576 |
|
577 | * `e` or `echo` This expects a quote-delimited string to be passed in and
|
578 | will strip the quotes. This is useful as the appearance of a quote will mask
|
579 | all other mechanics. So `e("a, b and _this")` will produce a literal
|
580 | argument of `a, b, and _this`. Multiple arguments will be stripped and
|
581 | passed on as multipel arguments.
|
582 | * `j` or `join` The first entry is the joiner separator and it joins the rest
|
583 | of the arguments. For arrays, they are flattened with the separator as well
|
584 | (just one level -- then it gets messy and wrong, probably).
|
585 | * `a` or `arr` or `array` This creates an array of the arguments.
|
586 | * `arguments` or `args` Inverse of array. This expects an array and each
|
587 | element becomes a separate argument that the command will see. E.g., `cmd
|
588 | arguments(arr(3, 4))` is equivalent to `cmd 3, 4`. This is useful for
|
589 | constructing the args elsewhere. In particular, `args(obj(_"returns json of
|
590 | an array"))` will result in the array from the subsitution becoming the
|
591 | arguments to pass in.
|
592 | * `o` or `obj` or `object` This presumes that a JSON stringed object is ready
|
593 | to be made into an object.
|
594 | * `merge` Merge arrays or objects, depending on what is there.
|
595 | * `kv` or `key-value` This produces an object based on the assumption that a
|
596 | `key, value` pairing are the arguments. The key should be text. Multiple
|
597 | pairs welcome.
|
598 | * `act` This allows one to do `obj, method, args` to apply a method to an
|
599 | object with the slot 2 and above being arguments. For example, one could do
|
600 | `act( arr(3, 4, 5), slice, 2, 3)` to slice the array to `[5]`.
|
601 | * `prop` or `property`. This will take the arguments as a property chain to
|
602 | extract the value being pointed to.
|
603 | * `json` This will convert an object to JSON representation.
|
604 | * `set` The presumption is that an object is passed in whose key:values should
|
605 | be added to the command state. `gSet` does this in a way that other
|
606 | commands in the pipe chain can see it. `set(kv(name, val, ...))` would
|
607 | probably be the typical way.
|
608 | * `get` This retrieves the value for the given key argument. `gGet` does the
|
609 | same for the pipe chain. Multiple keys can be given and each associated
|
610 | value will be returned as distinct arguments.
|
611 | * `n` or `#` or `number` This converts the argument(s) to numbers, using js
|
612 | Number function. `n(1, 2, 3)` will create three arguments of integers. To
|
613 | get an array, use `arr(n(1, 2, 3)`
|
614 | * `eval` will evaluate the argument and use the magic `ret` variable as the
|
615 | value to return. This can also see doc (and doc.cmdName) and args has the
|
616 | arguments post code. Recommend using backticks for quoting the eval; it
|
617 | will check for that automatically (just backticks, can do echo for the
|
618 | others if needed).
|
619 | * `log` This logs the argument and passes them along as arguments.
|
620 | * `t` or `true`. This returns the true value.
|
621 | * `f` or `false`. This returns the false value.
|
622 | * `null`. This returns the null value.
|
623 | * `doc`. This returns the doc variable. This could be useful in connection to
|
624 | the property method and the log subcommand.
|
625 | * `skip`. This returns no arguments.
|
626 |
|
627 | To build one's own command, you can attach a function whose arguments will be
|
628 | the arguments passed in. The `this` is the doc object. The current name (say
|
629 | for scope storing) is in doc.cmdName. This will point to within a whole pipe
|
630 | chunk. Pop off the last part (delimited by triple colon) to get to the whole
|
631 | command scope. The return value will be used as in an argument into the
|
632 | command or another subcommand. If it is an array and the flag `args` is set to
|
633 | true, then each entry in the array will be expanded into a set of arguments.
|
634 | So instead of 1 argument, several could be returned. If nothing is returned,
|
635 | then no arguments are passed on and it is as if it wasn't there.
|
636 |
|
637 |
|
638 | ## h5 and h6
|
639 |
|
640 | So this design treats h5 and h6 headings differently. They become subheadings
|
641 | of h1-4 headings. So for example, if we have `# top` and then `##### doc` and
|
642 | `###### something` then the sections would be recorded as `top, top/doc,
|
643 | top/doc/something` and we have a path syntax such as `../` which would yield
|
644 | `top/doc` if placed in `top/doc/something`. Ideally, this should work as you
|
645 | imagine. See `tests/h5.md` for the test examples.
|
646 |
|
647 |
|
648 | ## Plugins
|
649 |
|
650 | This is a big topic which I will only touch on here. You can define commands
|
651 | in the text of a literate program, and we will discuss this a bit here, but
|
652 | mostly, both commands and directives get defined in module plugins or the `lprc.js`
|
653 | file if need be.
|
654 |
|
655 | ### Defining Commands
|
656 |
|
657 | The define directive allows one to create commands within a document. This is
|
658 | a good place to start getting used to how things work.
|
659 |
|
660 | A command has the function signature `function (input, args, name)-> void`
|
661 | where the input is the incoming text (we are piping along when evaluating
|
662 | commands), args are the arguments that are comma separated after the command
|
663 | name, and the name is the name of the event that needs to be emitted with the
|
664 | outgoing text. The function context is the `doc` example.
|
665 |
|
666 | A minimal example is
|
667 |
|
668 | function ( input, args, name) {
|
669 | this.gcd.emit(name, input);
|
670 | }
|
671 |
|
672 | We simply emit the name with the incoming text as data. We usually use `doc`
|
673 | for the `this` variable. This is the `raw` option in the define directive.
|
674 |
|
675 | The default is `sync` and is very easy.
|
676 |
|
677 | function ( input, args, name) {
|
678 | return input;
|
679 | }
|
680 |
|
681 | That is, we just return the text we want to return. In general, the name is
|
682 | not needed though it may provide context clues.
|
683 |
|
684 | The third option is an `async` command. For those familiar with node
|
685 | conventions, this is easy and natural.
|
686 |
|
687 | function (input, args, callback, name) {
|
688 | callback(null, input);
|
689 | }
|
690 |
|
691 | The callback takes in an error as first argument and, if no error, the text to
|
692 | output. One should be able to use this as a function callback to pass into
|
693 | other callback async setups in node.
|
694 |
|
695 | So that's the flow. Obviously, you are free to do what you like with the text
|
696 | inside. You can access the document as `this` and from there get to the event
|
697 | emitter `gcd` and the parent, `folder`, leading to other docs. The scopes are
|
698 | available as well. Synchronous is the easiest, but asynchronous control flow
|
699 | is just as good and is needed for reading files, network requests, external
|
700 | process executions, etc.
|
701 |
|
702 | ### Plugin convention.
|
703 |
|
704 | I recommend the following npm module conventions for plugins for
|
705 | literate-programming.
|
706 |
|
707 | 1. litpro-... is the name. So all plugins would be namespaced to litpro.
|
708 | Clear, but short.
|
709 | 2. Set `module.exports = function(Folder, other)` The first argument is the
|
710 | Folder object which construts folders which constructs documents. By
|
711 | accessing Folder, one can add a lot of functionality. This access is
|
712 | granted in the command line client before any `folder` is created.
|
713 |
|
714 | The other argument depends on context, but for the command line client it
|
715 | is the parsed in arguments object. It can be useful for a number of
|
716 | purposes, but one should limit its use as it narrows the context of the
|
717 | use.
|
718 | 3. Define commands and, less, directives. Commands are for transforming text,
|
719 | directives are for doing document flow maipulations. Other hacks on
|
720 | `Folder` should be even less rare than adding directives.
|
721 | 4. Commands and directives are globally defined.
|
722 | 5. `Folder.commands[cmd name] = function (input, args, name)...` is how to add a
|
723 | command function. You can use `Folder.sync(cmdname, cmdfun)` and
|
724 | `Folder.async` to install sync and async functions directly in the same
|
725 | fashion as used by the define directive.
|
726 | 6. `Folder.directives[directive name] = function (args)` is how to install a
|
727 | directive. There are no helper functions for directives. These are more for
|
728 | controlling the flow of the compiling in the large. The arg keys are read
|
729 | off from `[link](href "directive:input")`. Also provided is the current
|
730 | block name which is given by the key `cur`.
|
731 | 7. If you want to do stuff after folder and its event emitter, gcd, is
|
732 | created, then you can modify Folder.postInit to be a function that does
|
733 | whatever you want on a folder instance. Think of it as a secondary
|
734 | constructor function.
|
735 | 8. The Folder has a plugins object where one can stash whatever under the
|
736 | plugin's name. This is largely for options and alternatives. The folder and
|
737 | doc object have prototyped objects on this as well which allows one to
|
738 | choose the scope of applicability of objects. But beware that subobjects
|
739 | are not prototyped (unless setup in that way; you may want to implement
|
740 | that by Object.creating what is there, if anything). Think of it as deciding
|
741 | where options should live when creating them.
|
742 |
|
743 | ### Structure of Doc and Folder
|
744 |
|
745 | To really hack the doc compiling, one should inspect the structure of Folder,
|
746 | folder, and doc. The Folder is a constructor and it has a variety of
|
747 | properties on it that are global to all folders. But it also has several
|
748 | prototype properties that get inherited by the folder instances. Some of those
|
749 | get inherited by the docs as well. For each folder, there is also a gcd object
|
750 | which is the event emitter, which comes from the, ahem, magnificient event-when
|
751 | library (I wrote it with this use in mind). In many ways, hacking on gcd will
|
752 | manipulate the flow of the compiling.
|
753 |
|
754 | I wrote the folder instance to maintain flexibility, but typically (so far at
|
755 | least), one folder instance per run is typical. Still, there might be a use
|
756 | for it in say have a development and production compile separate but running
|
757 | simultaneously?
|
758 |
|
759 |
|
760 | #### Folder
|
761 |
|
762 | These are the properties of Folder that may be of interest.
|
763 |
|
764 | * commands. This is an object that is prototyped onto the instance of a
|
765 | folder. Changing this adds commands to all created folder instances.
|
766 | * directives. This holds the directives. Otherwise same as commands.
|
767 | * reporter. This holds the functions that report out problems. See
|
768 | reporters below. This is not prototyped and is shared across instances.
|
769 | * postInit. This does modification of the instance. Default is a noop.
|
770 | * sync, async. These install sync and async commands, respectively.
|
771 | * plugins. This is a space to stash stuff for plugins. Use the plugin sans
|
772 | litpr as the key. Then put there whatever is of use. The idea is if you
|
773 | require something like jshint and then want default options, you can put
|
774 | that there. Then in a lprc file, someone can override those options it will
|
775 | be applied across the project.
|
776 |
|
777 |
|
778 | #### folder
|
779 |
|
780 | Each instance of folder comes with its own instances of:
|
781 |
|
782 | * docs. Holds all the documents.
|
783 | * scopes. Holds all the scopes which are the stuff before the double colon. It
|
784 | includes the blocks from the compiled docs but also any created scopes.
|
785 | * reports. This holds all the reports of stuff waiting. As stuff stops
|
786 | waiting, the reports go away. Ideally, this should be empty when all is
|
787 | done.
|
788 | * stack. This is for the push and pop of text piping.
|
789 | * gcd. This is the event-emitter shared between docs, but not folders. Default
|
790 | actions are added during the instantiation, largely related to the parsing
|
791 | which sets up later. If you want to log what goes on, you may want to look
|
792 | at the event-when docs (makeLog is a good place to start).
|
793 | * flags. This holds what flags are present.
|
794 |
|
795 | and shares via the prototype
|
796 |
|
797 | * parse. This parses the text of docs using commonmark spec
|
798 | * newdoc. This creates a new document. Kind of a constructor, but simply
|
799 | called as a function. it calls the constructor Doc.
|
800 | * colon. We replace colons with a unicode triple colon for emitting purposes
|
801 | of block names (event-when uses colon as separators too). This contains the
|
802 | escape (does replacement), restore (undoes it), and v which is the unicode
|
803 | tripe colon. If the v is replaced entirely, everything should hopefully work
|
804 | just fine with a new separator.
|
805 | * createScope. Creating a scope.
|
806 | * join. What is used to concatenate code blocks under same block heading.
|
807 | Default is "\n"
|
808 | * log. What to do with logging. Defaults to console.log.
|
809 | * indicator. An internal use to allow escaping of whitespace in command
|
810 | arguments that would otherwisebe trimmed.
|
811 | * wrapSync, wrapAsync. These wrap functions up for command sync, async, but do
|
812 | not install them. Not sure why not install them.
|
813 | * subnameTransform. A function that deals with shorthand minor substitutions
|
814 | that avoid using the main block heading. This can be overwritten if you want
|
815 | some custom behavior.
|
816 | * reportwaits. This is a function that produces the reports of what is still
|
817 | waiting. Very useful for debugging. This returns an array.
|
818 | * simpleReport. This reports on the substitutions that did not get resolved.
|
819 | This returns an array. It also includes any commands that were called but
|
820 | not defined. Subcommands throw errors when not defined, but since commands
|
821 | can be defined later, they will not. Hence this mechanism.
|
822 | * Doc. This is the constructor for documents.
|
823 |
|
824 |
|
825 | and uses Object.create to kind of share
|
826 |
|
827 | * commands
|
828 | * directives
|
829 | * plugins
|
830 |
|
831 | and direct copying from
|
832 |
|
833 | * reporters
|
834 |
|
835 | #### doc
|
836 |
|
837 | Each file leads to a doc which is stored in the folder. Each doc has a variety
|
838 | of stuff going on.
|
839 |
|
840 | Unique to each instance
|
841 |
|
842 | * file. The actual path to the file. It is treated as unique and there is a
|
843 | scope dedicated to it. Don't mess with it. It is also how docs are keyed in
|
844 | the folder.docs object.
|
845 | * text. The actual text of the file.
|
846 | * blockOff. This tracks whether to take in code blocks as usual. See blocks
|
847 | directive. If 0, code blocks are queued up. If greater than 1, code blocks
|
848 | are ignored.
|
849 | * levels. This tracks the level of the heading that is currently being used.
|
850 | See h5/h6 description
|
851 | * blocks. Each heading gets its own key in the blocks and the raw code blocks
|
852 | are put here.
|
853 | * heading, curname. These are part of the block parsing. curname is the full
|
854 | name while heading excludes minor block names.
|
855 | * vars. This is where the variables live. As each code block is compiled,
|
856 | its result gets stored here. But one can also add any bit of var name and
|
857 | text to this.
|
858 | * parent. This is the folder that contains this doc.
|
859 |
|
860 |
|
861 | Inherited from folder
|
862 |
|
863 | * commands, modifications affect all
|
864 | * directives, modifications affect all
|
865 | * scopes, modifications affect all
|
866 | * gcd, modifications affect all. Be careful to scope added events to files,
|
867 | etc.
|
868 | * plugins, modifications affect all
|
869 | * colon, Object.created
|
870 | * join, overwriting will only affect doc
|
871 | * log, overwriting will only affect doc
|
872 | * subnameTransform, overwriting will only affect doc
|
873 | * indicator, overwriting will only affect doc
|
874 | * wrapSync, wrapAsync, overwriting will only affect doc
|
875 |
|
876 | Prototyped on Doc. Almost all are internal and are of little to no interest.
|
877 |
|
878 | * pipeParsing. This parses the pipes. This may be useful if you want to do
|
879 | something like in the save or define directives. Check them out in the
|
880 | source if you want to see how to use it.
|
881 | * blockCompiling. This is what the compile command taps into. See how it is
|
882 | done there.
|
883 | * getscope. Looks up a scope and does appropriate async waiting for an
|
884 | existing scope if need be.
|
885 | * retrieve. retrieves variable.
|
886 | * createLinkedScope. Creates a link to a scope and notifies all.
|
887 | * indent. This is the default indenting function for subbing in multi-line
|
888 | blocks. The default idea is to indent up to the indent of the line that
|
889 | contains the block sub; further existing indentation in sublines is
|
890 | respected on top of that.
|
891 | * getIndent. Figuring out the indent
|
892 | * substituteParsing
|
893 | * regexs. Some regular expressions that are used in the parsing of the code
|
894 | blocks.
|
895 | * backslash. The backslash function applied to command arguments.
|
896 | * whitespaceEscape. Handlingwhitespace escaping in conjunction with
|
897 | backslash. Putting the whitespace back.
|
898 | * store. stores a variable.
|
899 |
|
900 | #### Reporting
|
901 |
|
902 | A key feature of any programming environment is debugging. It is my hope that
|
903 | this version has some better debugging information. The key to this is the
|
904 | reporting function of what is waiting around.
|
905 |
|
906 | The way it works is that when an event of the form `waiting for:type:...` is
|
907 | emitted with data `[evt, reportname, ...]` then reporters gets a key of the
|
908 | event string wthout the `waiting for:`, and when the `evt` is emitted, it is
|
909 | removed.
|
910 |
|
911 | If it is still waiting around when all is done, then it gets reported. The
|
912 | reportname is used to look up which reporter is used. Then that reporter takes
|
913 | in the remaining arguments and produces a string that will be part of the
|
914 | final report that gets printed out.
|
915 |
|
916 |
|
917 | ## LICENSE
|
918 |
|
919 | [MIT-LICENSE](https://github.com/jostylr/literate-programming-lib/blob/master/LICENSE-MIT)
|