aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md157
-rwxr-xr-xlrep6
2 files changed, 163 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..1b4c10e
--- /dev/null
+++ b/README.md
@@ -0,0 +1,157 @@
+# lrep: literate read-eval-print
+
+`lrep` is a simple Unix filter for "literate repl" or "notebooks".
+Documentation and input commands can be interleaved linewise, and the
+commands drive a session whose output is merged into the document.
+
+The syntax is Markdown compatible.
+
+## Usage
+
+ lrep [-z] [-t N] [FILES...]
+
+* `-z`: zap, don't run any commands, and remove the former output
+* `-t N`: adjust timeout to `N` seconds (default: 0.04),
+ after which `lrep` will assume no further output happened.
+ The initial command has `20*N` seconds time to display a prompt.
+
+When no `FILES` are give, `lrep` reads from STDIN.
+
+## Syntax
+
+There are three kinds of lines of interest to `lrep`:
+
+ <TAB>!!!CMD...
+
+Non-interactive session: just display output of `CMD`.
+When `CMD` ends with `>-`, no output is shown.
+
+ <TAB>!PS1!PS2!CMD...
+
+Starts a new session for `CMD...`. The `!PS2` part is optional.
+`PS1` is the first prompt considered, `PS2` the second prompt.
+Note that prompts often end with a space in practice!
+When `CMD` ends with `>-`, no output of startup is shown.
+
+When `PS1` is empty, `PS2` needs to be provided. Prompt-finding is
+disabled and only timeouts are used to detect when new input can be sent.
+Lines to input are marked using `PS2`.
+
+ <TAB><PS1>INPUT...
+ <TAB><PS2>INPUT...
+
+Send a line to the session, and display the output.
+When `CMD` ends with `>-`, no output is shown.
+
+ <TAB>...
+
+Other lines starting with `<TAB>` are assumed to be former output of
+`lrep` and dropped. Use four spaces for non-`lrep` verbatim code
+(or fenced blocks).
+
+## Algorithm
+
+`lrep` runs the command in a PTY, and reads according to the following scheme:
+
+1. Read as many bytes as possible without blocking.
+2. If the last line of the string read contains PS1 or PS2 at the end, break.
+3. Else, read as many bytes as possible without blocking or until timeout passed,
+ and go to step 2.
+
+(When PS1 is empty, the algorithm starts at step 3.)
+
+## Example
+
+For example, we can spawn a shell:
+
+ !$ !sh
+
+To send a line to the interpreter, start it with `<TAB>PS1`
+
+ $ uname
+ Linux
+
+Commands also can generate more than one output line:
+
+ $ printf '%s\n' foo bar baz
+ foo
+ bar
+ baz
+
+All commands run in the same session, so you can refer to previous results:
+
+ $ x=foo
+ $ y=bar
+ $ echo ${x}${y}
+ foobar
+
+To just one-shot show the output of a non-interactive program, use
+`<TAB>!!!CMD`
+
+ !!! uname
+ Linux
+
+Let's try something in dc(1). But since it doesn't have a prompt, we'll need
+to use timed mode which is less robust and waits for 40ms without output.
+Since `lrep` still needs to find the input strings, pass an alternate prompt
+using `<TAB>!!PS2!CMD...`:
+
+ !!> !dc
+ > 6 7
+ > +
+ > p
+ 13
+
+Perhaps Ruby is better. This is also an example of how to use two prompts:
+
+ !>> !?> !irb --simple-prompt
+ >> 6 +
+ ?> 7
+ => 13
+ >> 6 + 7
+ => 13
+
+To use `lrep`, simply filter the file through the program:
+
+ !!:!ed
+ :a
+ :A simple lrep example
+ : !!!echo elpmaxe na tsuj | rev
+ :.
+ :w try1.lrep
+ 53
+ :q
+ :# test death detection
+
+ !!!./lrep <try1.lrep
+ A simple lrep example
+ !!!echo elpmaxe na tsuj | rev
+ just an example
+
+Note that is exactly how this file was created.
+
+## Editor integration
+
+Vi:
+
+ map \e :!%./lrep<CR>``
+
+Emacs:
+
+ C-x h C-u M-| lrep <RET>
+
+## Caveat
+
+`lrep` will execute arbitary code in the input files, that's exactly
+its job. Be careful what you run it on.
+
+## Copyright
+
+`lrep` is in the public domain.
+
+To the extent possible under law,
+Christian Neukirchen <chneukirchen@gmail.com>
+has waived all copyright and related or
+neighboring rights to this work.
+
+http://creativecommons.org/publicdomain/zero/1.0/
diff --git a/lrep b/lrep
index 399d858..dafc644 100755
--- a/lrep
+++ b/lrep
@@ -2,6 +2,12 @@
# lrep [-z] [-t SECS] [FILES...] - literate read-eval-print
# -*- ruby -*-
+#
+# To the extent possible under law,
+# Christian Neukirchen <chneukirchen@gmail.com>
+# has waived all copyright and related or neighboring rights to this work.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
require 'pty'
require 'io/console'
require 'optparse'