From: Christopher Allan Webber Date: Mon, 23 Jan 2017 17:50:37 +0000 (-0600) Subject: Add new basic scrubl system (not using it yet though) X-Git-Tag: fosdem-2017~100 X-Git-Url: https://jxself.org/git/?a=commitdiff_plain;h=c4a8d7380659f15dbeea2928773f1ec36bd35776;p=mudsync.git Add new basic scrubl system (not using it yet though) --- diff --git a/mudsync/scrubl.scm b/mudsync/scrubl.scm new file mode 100644 index 0000000..cf585b9 --- /dev/null +++ b/mudsync/scrubl.scm @@ -0,0 +1,106 @@ +;;; Mudsync --- Live hackable MUD +;;; Copyright © 2017 Christopher Allan Webber +;;; +;;; This file is part of Mudsync. +;;; +;;; Mudsync is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or +;;; (at your option) any later version. +;;; +;;; Mudsync is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with Mudsync. If not, see . + +;;; SCRUBL: S-exps Can Really Undermine Basic Language +;;; a micro-"skribe-like" system + +(define-module (mudsync scrubl) + #:use-module (ice-9 match) + #:use-module (srfi srfi-9) + #:use-module (srfi srfi-9 gnu) + #:use-module (sxml simple) + #:use-module (oop goops)) + +(define (order-symlist-args symlist-args) + "Orders the args in a symlist so keyword pairs are at the end" + (define new-args + (let lp ((remaining symlist-args) + (args '()) + (kwargs '())) + (match remaining + ('() (cons (reverse args) + kwargs)) + (((? keyword? kw) val rest ...) + (lp rest + args + (cons* kw val kwargs))) + ((arg rest ...) + (lp rest + (cons arg args) + kwargs))))) + new-args) + +(define-immutable-record-type + (make-scrubl field-writers meta-write) + scrubl? + (field-writers scrubl-field-writers) + (meta-write scrubl-meta-write)) + +(define (scrubl-extend-fields scrubl new-field-writers) + "Returns a new instance extending SCRUBL's field-writers with +NEW-FIELD-WRITERS." + (set-field scrubl (scrubl-field-writers) + (append new-field-writers (scrubl-field-writers scrubl)))) + +(define (scrubl-write scrubl obj . args) + "Write out OBJ via SCRUBL + +Pass in optional extra ARGS to the main META-WRITE" + (apply (scrubl-meta-write scrubl) scrubl obj args)) + +(define* (scrubl-write-obj scrubl obj) + (match obj + (((? symbol? sym) args ...) + (let* ((field-writers (scrubl-field-writers scrubl)) + (field-writer (assoc-ref field-writers sym)) + (ordered-args (order-symlist-args args))) + (when (not field-writer) + (throw 'scrubl-unknown-field + #:field sym + #:args args)) + (apply field-writer scrubl ordered-args))) + ((items ...) + (map (lambda (item) + (scrubl-write-obj scrubl item)) + items)) + (any-obj any-obj))) + + + +;;; SXML scrubl writer + +(define (sxml-write scrubl obj) + (call-with-output-string + (lambda (p) + (sxml->xml (scrubl-write-obj scrubl obj) p)))) + + +(define (sxml-simple-field sym) + (lambda (scrubl args) + ;; sxml handles inlining automatically in case we have nested + ;; lists of strings, so we don't have to worry about that... + (cons sym (map (lambda (arg) + (scrubl-write-obj scrubl arg)) + args)))) + +(define sxml-scrubl + (make-scrubl `((p . ,(sxml-simple-field 'p)) + (bold . ,(sxml-simple-field 'b)) + (it . ,(sxml-simple-field 'it)) + (emph . ,(sxml-simple-field 'it))) + sxml-write))