diff options
-rw-r--r-- | .gitignore | 7 | ||||
-rw-r--r-- | README.md | 35 | ||||
-rw-r--r-- | chicken-scratch.egg | 12 | ||||
-rwxr-xr-x | chicken-scratch.mod.scm | 78 | ||||
-rwxr-xr-x | chicken-scratch.scm | 98 | ||||
-rw-r--r-- | makefile | 22 |
6 files changed, 174 insertions, 78 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8b6a74a --- /dev/null +++ b/.gitignore | |||
@@ -0,0 +1,7 @@ | |||
1 | chicken-scratch | ||
2 | *.link | ||
3 | *.so | ||
4 | *.o | ||
5 | *.build.sh | ||
6 | *.import.scm | ||
7 | *.install.sh \ No newline at end of file | ||
diff --git a/README.md b/README.md new file mode 100644 index 0000000..6aec41f --- /dev/null +++ b/README.md | |||
@@ -0,0 +1,35 @@ | |||
1 | # CHICKEN-SCRATCH --- heredocs for CHICKEN | ||
2 | |||
3 | written by Case Duckworth <acdw@acdw.net> off an idea by evhan | ||
4 | |||
5 | Licensed under BSD-3. See COPYING for details. | ||
6 | |||
7 | CHICKEN has "[Multiline string constants with embedded expressions][multiline]" | ||
8 | syntax, which is basically shell here-doc syntax but schemier and with a real | ||
9 | programming langugage to embed. evhan's [beaker tool][beaker] (which is great, | ||
10 | btw) uses this facility to do a quick-and-dirty templating for wiki generation. | ||
11 | I realized that I could use the same facility for the same kind of heredoc-style | ||
12 | templating I have done in various other SSGs like [unk][] and [vienna][], but | ||
13 | with scheme. Thus, CHICKEN-SCRATCH was born. | ||
14 | |||
15 | [multiline]: http://wiki.call-cc.org/man/5/Extensions%20to%20the%20standard#multiline-string-constant-with-embedded-expressions | ||
16 | [beaker]: https://git.sr.ht/~evhan/beaker | ||
17 | [unk]: https://git.acdw.net/unk/ | ||
18 | [vienna]: https://git.acdw.net/vienna/ | ||
19 | |||
20 | ## Usage | ||
21 | |||
22 | `expand-string` is the main entry point to this module. It takes a string and | ||
23 | returns a string with all `#( ... )` forms expanded according to the CHICKEN | ||
24 | rules. `expand-port` is a port version of `expand-string`. | ||
25 | |||
26 | To enable truly invisible definitions within the expanded string, the `def` | ||
27 | macro is provided which performs a `set!` on its variables, then returns a | ||
28 | string guaranteed not to be in the input string, which is then filtered out | ||
29 | in the expanded string. | ||
30 | |||
31 | Finally, to enable CHICKEN-SCRATCH to be used in a shebang, if the first line | ||
32 | of the input string begins with `#!`, it's deleted from the input. | ||
33 | |||
34 | ## Installation | ||
35 | |||
diff --git a/chicken-scratch.egg b/chicken-scratch.egg new file mode 100644 index 0000000..37bd9bd --- /dev/null +++ b/chicken-scratch.egg | |||
@@ -0,0 +1,12 @@ | |||
1 | ;; chicken-scratch.egg --- heredoc-style expansion for CHICKEN -*- scheme -*- | ||
2 | |||
3 | ((synopsis "Heredoc-style expansion for CHICKEN") | ||
4 | (author "Case Duckworth") | ||
5 | (category io) | ||
6 | (license "BSD-3") | ||
7 | (components | ||
8 | (extension chicken-scratch-lib | ||
9 | (source "chicken-scratch.mod.scm") | ||
10 | (install-name chicken-scratch)) | ||
11 | (program chicken-scratch | ||
12 | (source "chicken-scratch.scm")))) | ||
diff --git a/chicken-scratch.mod.scm b/chicken-scratch.mod.scm new file mode 100755 index 0000000..e47ad67 --- /dev/null +++ b/chicken-scratch.mod.scm | |||
@@ -0,0 +1,78 @@ | |||
1 | ;;; CHICKEN-SCRATCH --- heredocs for CHICKEN | ||
2 | ;; written by Case Duckworth <acdw@acdw.net> off an idea by evhan | ||
3 | ;; Licensed under BSD-3. See COPYING for details. | ||
4 | |||
5 | ;; CHICKEN has "Multiline string constants with embedded expressions" syntax, | ||
6 | ;; which is basically shell here-doc syntax but schemier and with a real | ||
7 | ;; programming langugage to embed. evhan's beaker tool (which is great, btw) | ||
8 | ;; uses this facility to do a quick-and-dirty templating for wiki generation. I | ||
9 | ;; realized that I could use the same facility for the same kind of | ||
10 | ;; heredoc-style templating I have done in various other SSGs like unk and | ||
11 | ;; vienna, but with scheme. Thus, CHICKEN-SCRATCH was born. | ||
12 | |||
13 | ;; USAGE | ||
14 | |||
15 | ;; `expand-string' is the main entry point to this module. It takes a string and | ||
16 | ;; returns a string with all #( ... ) forms expanded according to the CHICKEN | ||
17 | ;; rules. `expand-port' is a port version of `expand-string'. | ||
18 | |||
19 | ;; To enable truly invisible definitions within the expanded string, the `def' | ||
20 | ;; macro is provided which performs a `set!' on its variables, then returns a | ||
21 | ;; string guaranteed not to be in the input string, which is then filtered out | ||
22 | ;; in the expanded string. | ||
23 | |||
24 | ;; Finally, to enable CHICKEN-SCRATCH to be used in a shebang, if the first line | ||
25 | ;; of the input string begins with #!, it's deleted from the input. | ||
26 | |||
27 | (module chicken-scratch | ||
28 | (expand-string | ||
29 | expand-port | ||
30 | def | ||
31 | %def/replacer) | ||
32 | |||
33 | (import scheme | ||
34 | (chicken base) | ||
35 | (only (chicken io) | ||
36 | read-string) | ||
37 | (only (chicken irregex) | ||
38 | irregex-replace | ||
39 | irregex-replace/all | ||
40 | irregex-search) | ||
41 | (only (chicken port) | ||
42 | make-concatenated-port) | ||
43 | (only (chicken random) | ||
44 | pseudo-random-real)) | ||
45 | |||
46 | (define %def/replacer (make-parameter #f)) | ||
47 | |||
48 | (define (expand-string str) | ||
49 | (parameterize ((%def/replacer (random-string-not-in str))) | ||
50 | (let* ((delim (random-string-not-in str)) | ||
51 | (template (make-concatenated-port | ||
52 | (open-input-string (string-append "#<#" delim "\n")) | ||
53 | (open-input-string (irregex-replace "^#!.*\n" str "")) | ||
54 | (open-input-string (string-append "\n" delim "\n")))) | ||
55 | (expanded (open-output-string)) | ||
56 | (output (begin | ||
57 | (display (eval (read template)) expanded) | ||
58 | (get-output-string expanded)))) | ||
59 | (irregex-replace/all `(seq ,(%def/replacer) (* "\n")) | ||
60 | output | ||
61 | "")))) | ||
62 | |||
63 | (define (expand-port #!optional port) | ||
64 | (let ((port (or port (current-input-port)))) | ||
65 | (expand-string (read-string #f port)))) | ||
66 | |||
67 | (define-syntax def | ||
68 | (syntax-rules () | ||
69 | ((def var val) | ||
70 | ;; I think this only works in CHICKEN. | ||
71 | (begin (set! var val) | ||
72 | (%def/replacer))))) | ||
73 | |||
74 | (define (random-string-not-in str) | ||
75 | (let ((attempt (number->string (pseudo-random-real)))) | ||
76 | (if (irregex-search attempt str) | ||
77 | (random-string-not-in str) | ||
78 | attempt)))) | ||
diff --git a/chicken-scratch.scm b/chicken-scratch.scm index e47ad67..6d06fb6 100755 --- a/chicken-scratch.scm +++ b/chicken-scratch.scm | |||
@@ -1,78 +1,20 @@ | |||
1 | ;;; CHICKEN-SCRATCH --- heredocs for CHICKEN | 1 | #!/bin/sh |
2 | ;; written by Case Duckworth <acdw@acdw.net> off an idea by evhan | 2 | #| -*- scheme -*- |
3 | ;; Licensed under BSD-3. See COPYING for details. | 3 | exec csi -ss "$0" "$@" |
4 | 4 | CHICKEN-SCRATCH: here-doc templating for CHICKEN scheme | |
5 | ;; CHICKEN has "Multiline string constants with embedded expressions" syntax, | 5 | (C) Case Duckworth <acdw@acdw.net> |
6 | ;; which is basically shell here-doc syntax but schemier and with a real | 6 | License: BSD-3. See COPYING for details. |
7 | ;; programming langugage to embed. evhan's beaker tool (which is great, btw) | 7 | |# |
8 | ;; uses this facility to do a quick-and-dirty templating for wiki generation. I | 8 | |
9 | ;; realized that I could use the same facility for the same kind of | 9 | (import chicken-scratch |
10 | ;; heredoc-style templating I have done in various other SSGs like unk and | 10 | (chicken file) |
11 | ;; vienna, but with scheme. Thus, CHICKEN-SCRATCH was born. | 11 | (chicken process-context)) |
12 | 12 | ||
13 | ;; USAGE | 13 | (define (main args) |
14 | 14 | (for-each (lambda (file) | |
15 | ;; `expand-string' is the main entry point to this module. It takes a string and | 15 | (when (file-exists? file) |
16 | ;; returns a string with all #( ... ) forms expanded according to the CHICKEN | 16 | (display (with-input-from-file file expand-port)) |
17 | ;; rules. `expand-port' is a port version of `expand-string'. | 17 | (newline))) |
18 | 18 | args)) | |
19 | ;; To enable truly invisible definitions within the expanded string, the `def' | 19 | |
20 | ;; macro is provided which performs a `set!' on its variables, then returns a | 20 | (main (command-line-arguments)) |
21 | ;; string guaranteed not to be in the input string, which is then filtered out | ||
22 | ;; in the expanded string. | ||
23 | |||
24 | ;; Finally, to enable CHICKEN-SCRATCH to be used in a shebang, if the first line | ||
25 | ;; of the input string begins with #!, it's deleted from the input. | ||
26 | |||
27 | (module chicken-scratch | ||
28 | (expand-string | ||
29 | expand-port | ||
30 | def | ||
31 | %def/replacer) | ||
32 | |||
33 | (import scheme | ||
34 | (chicken base) | ||
35 | (only (chicken io) | ||
36 | read-string) | ||
37 | (only (chicken irregex) | ||
38 | irregex-replace | ||
39 | irregex-replace/all | ||
40 | irregex-search) | ||
41 | (only (chicken port) | ||
42 | make-concatenated-port) | ||
43 | (only (chicken random) | ||
44 | pseudo-random-real)) | ||
45 | |||
46 | (define %def/replacer (make-parameter #f)) | ||
47 | |||
48 | (define (expand-string str) | ||
49 | (parameterize ((%def/replacer (random-string-not-in str))) | ||
50 | (let* ((delim (random-string-not-in str)) | ||
51 | (template (make-concatenated-port | ||
52 | (open-input-string (string-append "#<#" delim "\n")) | ||
53 | (open-input-string (irregex-replace "^#!.*\n" str "")) | ||
54 | (open-input-string (string-append "\n" delim "\n")))) | ||
55 | (expanded (open-output-string)) | ||
56 | (output (begin | ||
57 | (display (eval (read template)) expanded) | ||
58 | (get-output-string expanded)))) | ||
59 | (irregex-replace/all `(seq ,(%def/replacer) (* "\n")) | ||
60 | output | ||
61 | "")))) | ||
62 | |||
63 | (define (expand-port #!optional port) | ||
64 | (let ((port (or port (current-input-port)))) | ||
65 | (expand-string (read-string #f port)))) | ||
66 | |||
67 | (define-syntax def | ||
68 | (syntax-rules () | ||
69 | ((def var val) | ||
70 | ;; I think this only works in CHICKEN. | ||
71 | (begin (set! var val) | ||
72 | (%def/replacer))))) | ||
73 | |||
74 | (define (random-string-not-in str) | ||
75 | (let ((attempt (number->string (pseudo-random-real)))) | ||
76 | (if (irregex-search attempt str) | ||
77 | (random-string-not-in str) | ||
78 | attempt)))) | ||
diff --git a/makefile b/makefile new file mode 100644 index 0000000..ffa747a --- /dev/null +++ b/makefile | |||
@@ -0,0 +1,22 @@ | |||
1 | # CHICKEN-SCRATCH: here-doc templating for CHICKEN scheme | ||
2 | # (C) Case Duckworth <acdw@acdw.net> | ||
3 | # License: BSD-3. See COPYING for details. | ||
4 | |||
5 | PREFIX = /usr | ||
6 | |||
7 | SOURCES = chicken-scratch.scm chicken-scratch.mod.scm | ||
8 | |||
9 | chicken-scratch: $(SOURCES) | ||
10 | chicken-install -n | ||
11 | |||
12 | .PHONY: install | ||
13 | install: chicken-scratch | ||
14 | install -Dt $(PREFIX)/bin $< | ||
15 | |||
16 | .PHONY: chicken-install | ||
17 | chicken-install: chicken-scratch | ||
18 | chicken-install | ||
19 | |||
20 | .PHONY: clean | ||
21 | clean: | ||
22 | rm -f *.link *.so *.o *.build.sh *.import.scm *.install.sh | ||