First version of textlang, using state to eliminate newlines
svn: r11552 original commit: 672a37150d5a67a36714c8211799bd645a5cf37f
This commit is contained in:
parent
970dcd1ab0
commit
60377e2c3e
|
@ -1,32 +1,9 @@
|
|||
#lang scheme/base
|
||||
#lang s-exp syntax/module-reader
|
||||
|
||||
(require "../../text.ss")
|
||||
scribble/text/textlang
|
||||
|
||||
(provide (rename-out [*read read])
|
||||
(rename-out [*read-syntax read-syntax]))
|
||||
#:read scribble:read-inside
|
||||
#:read-syntax scribble:read-syntax-inside
|
||||
#:whole-body-readers? #t
|
||||
|
||||
(define (*read [inp (current-input-port)])
|
||||
(wrap inp (at:read-inside inp)))
|
||||
|
||||
(define (*read-syntax [src #f] [port (current-input-port)])
|
||||
(wrap port (at:read-syntax-inside src port)))
|
||||
|
||||
(define (wrap port body)
|
||||
(define (strip-leading-newlines stxs)
|
||||
(if (null? stxs)
|
||||
stxs
|
||||
(let ([p (syntax-property (car stxs) 'scribble)])
|
||||
(if (and (pair? p) (eq? (car p) 'newline))
|
||||
(strip-leading-newlines (cdr stxs))
|
||||
stxs))))
|
||||
(let* ([p-name (object-name port)]
|
||||
[name (if (path? p-name)
|
||||
(let-values ([(base name dir?) (split-path p-name)])
|
||||
(string->symbol (path->string (path-replace-suffix
|
||||
name #""))))
|
||||
'page)]
|
||||
[id 'doc]
|
||||
[body (if (syntax? body)
|
||||
(strip-leading-newlines (syntax->list body))
|
||||
body)])
|
||||
`(module ,name scribble/text . ,body)))
|
||||
(require (prefix-in scribble: "../../reader.ss"))
|
||||
|
|
45
collects/scribble/text/textlang.ss
Normal file
45
collects/scribble/text/textlang.ss
Normal file
|
@ -0,0 +1,45 @@
|
|||
#lang scheme/base
|
||||
|
||||
(require (for-syntax scheme/base syntax/kerncase)
|
||||
scheme/promise "../text.ss")
|
||||
|
||||
(provide (except-out (all-from-out scheme/base) #%module-begin)
|
||||
(rename-out [module-begin #%module-begin])
|
||||
(all-from-out scheme/promise "../text.ss"))
|
||||
|
||||
(begin-for-syntax
|
||||
(define definition-ids ; ids that don't require forcing
|
||||
(syntax->list #'(define-values define-syntaxes define-values-for-syntax
|
||||
require provide #%require #%provide)))
|
||||
(define stoplist (append definition-ids (kernel-form-identifier-list)))
|
||||
(define (definition-id? id)
|
||||
(and (identifier? id)
|
||||
(ormap (lambda (i) (free-identifier=? id i)) definition-ids)))
|
||||
(define (newline-stx? stx)
|
||||
(let ([p (syntax-property stx 'scribble)])
|
||||
(and (pair? p) (eq? (car p) 'newline))))
|
||||
(define swallow-newlines? #t))
|
||||
|
||||
;; use `swallow-newlines?' for state, to get rid of newlines that follow
|
||||
;; definition expressions (must do that, since we need to expand expressions
|
||||
;; one-by-one, so #%module-begin will do its job) -- this relies on
|
||||
;; left-to-right macro expansion.
|
||||
|
||||
(define-syntax (toplevel-decorate stx)
|
||||
(let ([context (syntax-local-context)])
|
||||
(syntax-case stx ()
|
||||
[(this expr)
|
||||
(let ([expr* (local-expand #'expr context stoplist)])
|
||||
(syntax-case expr* (begin)
|
||||
[(begin x ...) #'(begin (this x) ...)]
|
||||
[(id . rest) (definition-id? #'id)
|
||||
(begin (set! swallow-newlines? #t) expr*)]
|
||||
[_ (if (and swallow-newlines? (newline-stx? expr*))
|
||||
#'(begin)
|
||||
(begin (set! swallow-newlines? #f) #`(output #,expr*)))]))])))
|
||||
|
||||
(define-syntax (module-begin stx)
|
||||
(syntax-case stx ()
|
||||
[(_ expr ...)
|
||||
(begin (set! swallow-newlines? #t) ; not really necessary
|
||||
#'(#%module-begin (toplevel-decorate expr) ...))]))
|
Loading…
Reference in New Issue
Block a user