From c258fe7f2347f03bf7b0ab02ac1596c65a072c1e Mon Sep 17 00:00:00 2001 From: Case Duckworth Date: Thu, 8 Jun 2023 23:27:32 -0500 Subject: Add egg and makefile and program --- .gitignore | 7 ++++ README.md | 35 ++++++++++++++++++ chicken-scratch.egg | 12 ++++++ chicken-scratch.mod.scm | 78 +++++++++++++++++++++++++++++++++++++++ chicken-scratch.scm | 98 ++++++++++--------------------------------------- makefile | 22 +++++++++++ 6 files changed, 174 insertions(+), 78 deletions(-) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 chicken-scratch.egg create mode 100755 chicken-scratch.mod.scm create mode 100644 makefile diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8b6a74a --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +chicken-scratch +*.link +*.so +*.o +*.build.sh +*.import.scm +*.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 @@ +# CHICKEN-SCRATCH --- heredocs for CHICKEN + +written by Case Duckworth off an idea by evhan + +Licensed under BSD-3. See COPYING for details. + +CHICKEN has "[Multiline string constants with embedded expressions][multiline]" +syntax, which is basically shell here-doc syntax but schemier and with a real +programming langugage to embed. evhan's [beaker tool][beaker] (which is great, +btw) uses this facility to do a quick-and-dirty templating for wiki generation. +I realized that I could use the same facility for the same kind of heredoc-style +templating I have done in various other SSGs like [unk][] and [vienna][], but +with scheme. Thus, CHICKEN-SCRATCH was born. + +[multiline]: http://wiki.call-cc.org/man/5/Extensions%20to%20the%20standard#multiline-string-constant-with-embedded-expressions +[beaker]: https://git.sr.ht/~evhan/beaker +[unk]: https://git.acdw.net/unk/ +[vienna]: https://git.acdw.net/vienna/ + +## Usage + +`expand-string` is the main entry point to this module. It takes a string and +returns a string with all `#( ... )` forms expanded according to the CHICKEN +rules. `expand-port` is a port version of `expand-string`. + +To enable truly invisible definitions within the expanded string, the `def` +macro is provided which performs a `set!` on its variables, then returns a +string guaranteed not to be in the input string, which is then filtered out +in the expanded string. + +Finally, to enable CHICKEN-SCRATCH to be used in a shebang, if the first line +of the input string begins with `#!`, it's deleted from the input. + +## Installation + 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 @@ +;; chicken-scratch.egg --- heredoc-style expansion for CHICKEN -*- scheme -*- + +((synopsis "Heredoc-style expansion for CHICKEN") + (author "Case Duckworth") + (category io) + (license "BSD-3") + (components + (extension chicken-scratch-lib + (source "chicken-scratch.mod.scm") + (install-name chicken-scratch)) + (program chicken-scratch + (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 @@ +;;; CHICKEN-SCRATCH --- heredocs for CHICKEN +;; written by Case Duckworth off an idea by evhan +;; Licensed under BSD-3. See COPYING for details. + +;; CHICKEN has "Multiline string constants with embedded expressions" syntax, +;; which is basically shell here-doc syntax but schemier and with a real +;; programming langugage to embed. evhan's beaker tool (which is great, btw) +;; uses this facility to do a quick-and-dirty templating for wiki generation. I +;; realized that I could use the same facility for the same kind of +;; heredoc-style templating I have done in various other SSGs like unk and +;; vienna, but with scheme. Thus, CHICKEN-SCRATCH was born. + +;; USAGE + +;; `expand-string' is the main entry point to this module. It takes a string and +;; returns a string with all #( ... ) forms expanded according to the CHICKEN +;; rules. `expand-port' is a port version of `expand-string'. + +;; To enable truly invisible definitions within the expanded string, the `def' +;; macro is provided which performs a `set!' on its variables, then returns a +;; string guaranteed not to be in the input string, which is then filtered out +;; in the expanded string. + +;; Finally, to enable CHICKEN-SCRATCH to be used in a shebang, if the first line +;; of the input string begins with #!, it's deleted from the input. + +(module chicken-scratch + (expand-string + expand-port + def + %def/replacer) + + (import scheme + (chicken base) + (only (chicken io) + read-string) + (only (chicken irregex) + irregex-replace + irregex-replace/all + irregex-search) + (only (chicken port) + make-concatenated-port) + (only (chicken random) + pseudo-random-real)) + + (define %def/replacer (make-parameter #f)) + + (define (expand-string str) + (parameterize ((%def/replacer (random-string-not-in str))) + (let* ((delim (random-string-not-in str)) + (template (make-concatenated-port + (open-input-string (string-append "#<#" delim "\n")) + (open-input-string (irregex-replace "^#!.*\n" str "")) + (open-input-string (string-append "\n" delim "\n")))) + (expanded (open-output-string)) + (output (begin + (display (eval (read template)) expanded) + (get-output-string expanded)))) + (irregex-replace/all `(seq ,(%def/replacer) (* "\n")) + output + "")))) + + (define (expand-port #!optional port) + (let ((port (or port (current-input-port)))) + (expand-string (read-string #f port)))) + + (define-syntax def + (syntax-rules () + ((def var val) + ;; I think this only works in CHICKEN. + (begin (set! var val) + (%def/replacer))))) + + (define (random-string-not-in str) + (let ((attempt (number->string (pseudo-random-real)))) + (if (irregex-search attempt str) + (random-string-not-in str) + 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 @@ -;;; CHICKEN-SCRATCH --- heredocs for CHICKEN -;; written by Case Duckworth off an idea by evhan -;; Licensed under BSD-3. See COPYING for details. - -;; CHICKEN has "Multiline string constants with embedded expressions" syntax, -;; which is basically shell here-doc syntax but schemier and with a real -;; programming langugage to embed. evhan's beaker tool (which is great, btw) -;; uses this facility to do a quick-and-dirty templating for wiki generation. I -;; realized that I could use the same facility for the same kind of -;; heredoc-style templating I have done in various other SSGs like unk and -;; vienna, but with scheme. Thus, CHICKEN-SCRATCH was born. - -;; USAGE - -;; `expand-string' is the main entry point to this module. It takes a string and -;; returns a string with all #( ... ) forms expanded according to the CHICKEN -;; rules. `expand-port' is a port version of `expand-string'. - -;; To enable truly invisible definitions within the expanded string, the `def' -;; macro is provided which performs a `set!' on its variables, then returns a -;; string guaranteed not to be in the input string, which is then filtered out -;; in the expanded string. - -;; Finally, to enable CHICKEN-SCRATCH to be used in a shebang, if the first line -;; of the input string begins with #!, it's deleted from the input. - -(module chicken-scratch - (expand-string - expand-port - def - %def/replacer) - - (import scheme - (chicken base) - (only (chicken io) - read-string) - (only (chicken irregex) - irregex-replace - irregex-replace/all - irregex-search) - (only (chicken port) - make-concatenated-port) - (only (chicken random) - pseudo-random-real)) - - (define %def/replacer (make-parameter #f)) - - (define (expand-string str) - (parameterize ((%def/replacer (random-string-not-in str))) - (let* ((delim (random-string-not-in str)) - (template (make-concatenated-port - (open-input-string (string-append "#<#" delim "\n")) - (open-input-string (irregex-replace "^#!.*\n" str "")) - (open-input-string (string-append "\n" delim "\n")))) - (expanded (open-output-string)) - (output (begin - (display (eval (read template)) expanded) - (get-output-string expanded)))) - (irregex-replace/all `(seq ,(%def/replacer) (* "\n")) - output - "")))) - - (define (expand-port #!optional port) - (let ((port (or port (current-input-port)))) - (expand-string (read-string #f port)))) - - (define-syntax def - (syntax-rules () - ((def var val) - ;; I think this only works in CHICKEN. - (begin (set! var val) - (%def/replacer))))) - - (define (random-string-not-in str) - (let ((attempt (number->string (pseudo-random-real)))) - (if (irregex-search attempt str) - (random-string-not-in str) - attempt)))) +#!/bin/sh +#| -*- scheme -*- +exec csi -ss "$0" "$@" +CHICKEN-SCRATCH: here-doc templating for CHICKEN scheme +(C) Case Duckworth +License: BSD-3. See COPYING for details. +|# + +(import chicken-scratch + (chicken file) + (chicken process-context)) + +(define (main args) + (for-each (lambda (file) + (when (file-exists? file) + (display (with-input-from-file file expand-port)) + (newline))) + args)) + +(main (command-line-arguments)) diff --git a/makefile b/makefile new file mode 100644 index 0000000..ffa747a --- /dev/null +++ b/makefile @@ -0,0 +1,22 @@ +# CHICKEN-SCRATCH: here-doc templating for CHICKEN scheme +# (C) Case Duckworth +# License: BSD-3. See COPYING for details. + +PREFIX = /usr + +SOURCES = chicken-scratch.scm chicken-scratch.mod.scm + +chicken-scratch: $(SOURCES) + chicken-install -n + +.PHONY: install +install: chicken-scratch + install -Dt $(PREFIX)/bin $< + +.PHONY: chicken-install +chicken-install: chicken-scratch + chicken-install + +.PHONY: clean +clean: + rm -f *.link *.so *.o *.build.sh *.import.scm *.install.sh -- cgit 1.4.1-21-gabe81