diff --git a/collects/scribble/basic.ss b/collects/scribble/basic.ss index c9b9775d..5da997d9 100644 --- a/collects/scribble/basic.ss +++ b/collects/scribble/basic.ss @@ -89,7 +89,24 @@ (make-element 'bold (decode-content str))) (define (tt . str) - (make-element 'tt (decode-content str))) + (let ([l (decode-content str)]) + (let ([l (let ([m (and (pair? l) + (string? (car l)) + (regexp-match-positions #rx"^ +" (car l)))]) + (if m + (cons (hspace (- (cdar m) (caar m))) + (cons + (substring (car l) (cdar m)) + (cdr l))) + l))]) + (if (andmap string? l) + (make-element 'tt l) + (make-element #f (map (lambda (s) + (if (or (string? s) + (symbol? s)) + (make-element 'tt (list s)) + s)) + l)))))) (define (span-class classname . str) (make-element classname (decode-content str))) diff --git a/collects/scribble/latex-render.ss b/collects/scribble/latex-render.ss index 9b2e87be..ce088300 100644 --- a/collects/scribble/latex-render.ss +++ b/collects/scribble/latex-render.ss @@ -54,6 +54,7 @@ (define-color "schemestdout" "OutputColor") (define-color "schememeta" "IdentifierColor") (define-color "schememod" "black") + (define-color "schemereader" "black") (define-color "schemevariablecol" "IdentifierColor") (printf "\\newcommand{\\schemevariable}[1]{{\\schemevariablecol{\\textsl{#1}}}}\n") (define-color "schemeerrorcol" "red") diff --git a/collects/scribble/scheme.ss b/collects/scribble/scheme.ss index ac59fc5c..74622b0a 100644 --- a/collects/scribble/scheme.ss +++ b/collects/scribble/scheme.ss @@ -22,7 +22,7 @@ (struct just-context (val ctx))) (define no-color "schemeplain") - (define reader-color "schemeplain") + (define reader-color "schemereader") (define keyword-color "schemekeyword") (define comment-color "schemecomment") (define paren-color "schemeparen") @@ -253,7 +253,7 @@ [(and (pair? (syntax-e c)) (memq (syntax-e (car (syntax-e c))) '(quote quasiquote unquote unquote-splicing - syntax unsyntax))) + quasisyntax syntax unsyntax unsyntax-splicing))) (advance c init-line!) (let-values ([(str quote-delta) (case (syntax-e (car (syntax-e c))) @@ -262,7 +262,9 @@ [(unquote-splicing) (values ",@" -1)] [(quasiquote) (values "`" +1)] [(syntax) (values "#'" 0)] - [(unsyntax) (values "#," 0)])]) + [(quasisyntax) (values "#`" 0)] + [(unsyntax) (values "#," 0)] + [(unsyntax-splicing) (values "#,@" 0)])]) (out str (if (positive? (+ quote-depth quote-delta)) value-color reader-color)) @@ -308,7 +310,9 @@ c)]) (cond [(and (syntax? l) - (pair? (syntax-e l))) + (pair? (syntax-e l)) + (not (memq (syntax-e (car (syntax-e l))) + '(quote unquote syntax unsyntax quasiquote quasiunsyntax)))) (lloop (syntax-e l))] [(or (null? l) (and (syntax? l) @@ -318,6 +322,7 @@ ((loop init-line! quote-depth) (car l)) (lloop (cdr l))] [else + (advance l init-line! -2) (out ". " (if (positive? quote-depth) value-color paren-color)) (set! src-col (+ src-col 3)) diff --git a/collects/scribble/scribble.css b/collects/scribble/scribble.css index a4406c92..76a9151e 100644 --- a/collects/scribble/scribble.css +++ b/collects/scribble/scribble.css @@ -238,6 +238,10 @@ background-color: #eeeeee; } + .schemereader { + font-family: Courier; font-size: 80%; + } + .schemeparen { color: #843c24; font-family: Courier; font-size: 80%; diff --git a/collects/scribblings/scribble/reader.scrbl b/collects/scribblings/scribble/reader.scrbl index 16cbe187..8c4dcb06 100644 --- a/collects/scribblings/scribble/reader.scrbl +++ b/collects/scribblings/scribble/reader.scrbl @@ -1,7 +1,9 @@ #reader(lib "docreader.ss" "scribble") @require[(lib "manual.ss" "scribble")] @require[(lib "bnf.ss" "scribble")] +@require[(lib "eval.ss" "scribble")] @require["utils.ss"] +@require-for-syntax[mzscheme] @title[#:tag "reader"]{The Scribble Reader} @@ -112,16 +114,23 @@ When the above @"@"-forms appear in a Scheme expression context, the lexical environment must provide bindings for @scheme[foo] (as a procedure or a macro). -@; FIXME: need to show evaluation here (with the scribble syntax) -@schemeblock[ +@; FIXME: unfortunate code duplication +@interaction[ +(eval:alts (let* ([formatter (lambda (fmt) (lambda args (format fmt (apply string-append args))))] [bf (formatter "*~a*")] [it (formatter "/~a/")] [ul (formatter "_~a_")] [text string-append]) - @text{@it{Note}: @bf{This is @ul{not} a pipe}.}) - --> "/Note/: *This is _not_ a pipe*." + #,(tt "@text{@it{Note}: @bf{This is @ul{not} a pipe}.}")) + (let* ([formatter (lambda (fmt) + (lambda args (format fmt (apply string-append args))))] + [bf (formatter "*~a*")] + [it (formatter "/~a/")] + [ul (formatter "_~a_")] + [text string-append]) + @text{@it{Note}: @bf{This is @ul{not} a pipe}.})) ] If you want to see the expression that is actually being read, you can @@ -310,15 +319,15 @@ This is particularly useful with strings, which can be used to include arbitrary text. @scribble-examples|==={ - @foo{This @"}" is a closing brace} + @foo{@"}" is a closing brace} }===| Note that the escaped string is (intentionally) merged with the rest of the text. This works for @litchar["@"] too: @scribble-examples|==={ - @foo{The command prefix is @"@".} - @foo{@"@foo{bar}" reads as (foo "bar")} + @foo{Command prefix: @"@".} + @foo{@"@f{b}" -> (f "b")} }===| @subsubsub*section{Alternative Body Syntax} @@ -340,7 +349,7 @@ prefixed with a @litchar["|"]: @foo|{Maze |@bar{is} Life!}| - @foo|{Works for |@bar|{subforms}| too}| + @foo|{|@bar|{subforms}| ok}| }===| Note that the subform uses its own delimiters, @litchar["{...}"] or @@ -357,8 +366,8 @@ in reverse order with paren-like characters (@litchar["("], @litchar["["], @litchar["<"]) mirrored. @scribble-examples|==={ - @foo|<<<{Some @x{more} |@{text}|.}>>>| - @foo|!!{Blah |!!@bold{blah}...}!!| + @foo|<<<{@x{m} |@{t}|.}>>>| + @foo|!!{B |!!@bold{b}...}!!| }===| Finally, remember that you can use an expression escape with a Scheme @@ -430,7 +439,7 @@ rules for @"@"-forms), and @litchar["@;..."] is a line-comment. @scribble-examples|==={ @foo{First line@;{there is still a - newline at this point;} + newline here;} Second line} }===| @@ -439,10 +448,8 @@ of the line @italic{and} all following spaces (or tabs). Using this, you can get further control of the subforms. @scribble-examples|==={ - @foo{This is @; - a pretty long @; - single string-@; - argument.} + @foo{A long single-@; + string arg.} }===| Note how this is different from using @litchar["@||"]s in that strings @@ -467,7 +474,7 @@ A single newline that follows an open brace or precedes a closing brace is discarded, unless there are only newlines in the body; other newlines are read as a @scheme["\n"] string -@;FIXME empty lines are ignored in generated HTML output +@;FIXME empty lines are ignored in generated HTML output (with IE?) @scribble-examples|==={ @foo{bar } @@ -497,20 +504,23 @@ In the parsed S-expression syntax, a single newline string is used for all newlines; you can use @scheme[eq?] to identify this line. This can be used to identify newlines in the original @nonterm{text-body}. -@; FIXME: need to show printout here (with the scribble syntax) -@schemeblock[ +@; FIXME: unfortunate code duplication (again): +@interaction[ +(eval:alts + (let ([nl (car #, @tt["@'{"] + #, @tt[" }"])]) + (for-each (lambda (x) (display (if (eq? x nl) "\n... " x))) + #, @tt["@`{foo"] + #, @elem[@tt[" @"] @scheme[,@(list "bar" "\n" "baz")]] + #, @tt[" blah}}"]) + (newline)) (let ([nl (car @'{ })]) (for-each (lambda (x) (display (if (eq? x nl) "\n... " x))) @`{foo @,@(list "bar" "\n" "baz") blah}) - (newline)) - --prints--> - foo - ... bar - baz - ... blah + (newline))) ] Spaces at the beginning of body lines do not appear in the resulting @@ -543,7 +553,6 @@ syntax object used for indentation). This makes sense when formatting structured code as well as text (see the last example in the following block). -@;FIXME: last example too long, messes up output @scribble-examples|==={ @foo{bar baz @@ -560,8 +569,8 @@ block). @foo{ bar baz bbb} - @text{Some text@footnote{And a - footnote comment.}. More text.} + @text{Text@note{And + note.}. More.} }===| Note that each @"@"-form is parsed to an S-expression that has its own @@ -634,28 +643,33 @@ To implement a verbatim environment you need to drop indentation strings, and use the original newline strings instead of the single-newline string. Here is an example of this. -@; FIXME: need to show evaluation here (with the scribble syntax) -@schemeblock[ +@; FIXME: a bit of code duplication here +@def+int[ (define-syntax (verb stx) (syntax-case stx () [(_ cmd item ...) - ;;FIXME: show a "#`" in the rendering of the following line - #`(cmd . - ;;FIXME: the next line should begin with a #, - ,(let loop ([items (syntax->list #'(item ...))]) - (if (null? items) - '() - (let* ([fst (car items)] - [prop (syntax-property fst 'scribble)] - [rst (loop (cdr items))]) - (cond [(not prop) (cons fst rst)] - [(eq? prop 'indentation) rst] - [else (cons (datum->syntax-object - fst (cadr prop) fst) - rst)])))))])) + #`(cmd + #,@(let loop ([items (syntax->list #'(item ...))]) + (if (null? items) + '() + (let* ([fst (car items)] + [prop (syntax-property fst 'scribble)] + [rst (loop (cdr items))]) + (cond [(not prop) (cons fst rst)] + [(eq? prop 'indentation) rst] + [else (cons (datum->syntax-object + fst (cadr prop) fst) + rst)])))))])) +(eval:alts + + (code:line + #, @tt["@verb[string-append]{"] + #, @tt[" foo"] + #, @tt[" bar"] + #, @tt["}"]) + @verb[string-append]{ foo bar - } - --> "foo\n bar" + }) ]