about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--.gitignore7
-rw-r--r--README.md35
-rw-r--r--chicken-scratch.egg12
-rwxr-xr-xchicken-scratch.mod.scm78
-rwxr-xr-xchicken-scratch.scm98
-rw-r--r--makefile22
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 @@
1chicken-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
3written by Case Duckworth <acdw@acdw.net> off an idea by evhan
4
5Licensed under BSD-3. See COPYING for details.
6
7CHICKEN has "[Multiline string constants with embedded expressions][multiline]"
8syntax, which is basically shell here-doc syntax but schemier and with a real
9programming langugage to embed. evhan's [beaker tool][beaker] (which is great,
10btw) uses this facility to do a quick-and-dirty templating for wiki generation.
11I realized that I could use the same facility for the same kind of heredoc-style
12templating I have done in various other SSGs like [unk][] and [vienna][], but
13with 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
23returns a string with all `#( ... )` forms expanded according to the CHICKEN
24rules. `expand-port` is a port version of `expand-string`.
25
26To enable truly invisible definitions within the expanded string, the `def`
27macro is provided which performs a `set!` on its variables, then returns a
28string guaranteed not to be in the input string, which is then filtered out
29in the expanded string.
30
31Finally, to enable CHICKEN-SCRATCH to be used in a shebang, if the first line
32of 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. 3exec csi -ss "$0" "$@"
4 4CHICKEN-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 6License: 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
5PREFIX = /usr
6
7SOURCES = chicken-scratch.scm chicken-scratch.mod.scm
8
9chicken-scratch: $(SOURCES)
10 chicken-install -n
11
12.PHONY: install
13install: chicken-scratch
14 install -Dt $(PREFIX)/bin $<
15
16.PHONY: chicken-install
17chicken-install: chicken-scratch
18 chicken-install
19
20.PHONY: clean
21clean:
22 rm -f *.link *.so *.o *.build.sh *.import.scm *.install.sh