Skip to content
223 changes: 100 additions & 123 deletions scribble-lib/scribble/base.rkt
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
#lang racket/base

(require "decode.rkt"
(require (for-syntax racket/base)
racket/class
racket/contract/base
racket/contract/combinator
racket/list
"core.rkt"
"manual-struct.rkt"
"decode-struct.rkt"
"decode.rkt"
"html-properties.rkt"
"tag.rkt"
"manual-struct.rkt"
"private/tag.rkt"
racket/list
racket/class
racket/contract/base
racket/contract/combinator
(for-syntax racket/base))
"tag.rkt")

(provide (all-from-out "tag.rkt"))

Expand All @@ -29,23 +29,22 @@
#:rest (listof pre-content?)
part-start?))

(provide/contract
[title (->* ()
(#:tag (or/c #f string? (listof string?))
#:tag-prefix (or/c #f string? module-path? hash?)
#:style (or/c style? string? symbol? (listof symbol?) #f)
#:version (or/c string? #f)
#:date (or/c string? #f)
#:index-extras desc-extras/c)
#:rest (listof pre-content?)
title-decl?)]
[section (title-like-contract)]
[subsection (title-like-contract)]
[subsubsection (title-like-contract)]
[subsubsub*section (->* ()
(#:tag (or/c #f string? (listof string?)))
#:rest (listof pre-content?)
block?)])
(provide (contract-out
[title
(->* ()
(#:tag (or/c #f string? (listof string?))
#:tag-prefix (or/c #f string? module-path? hash?)
#:style (or/c style? string? symbol? (listof symbol?) #f)
#:version (or/c string? #f)
#:date (or/c string? #f)
#:index-extras desc-extras/c)
#:rest (listof pre-content?)
title-decl?)]
[section (title-like-contract)]
[subsection (title-like-contract)]
[subsubsection (title-like-contract)]
[subsubsub*section
(->* () (#:tag (or/c #f string? (listof string?))) #:rest (listof pre-content?) block?)]))
(provide include-section)

(define (title #:tag [tag #f] #:tag-prefix [prefix #f] #:style [style plain]
Expand Down Expand Up @@ -131,9 +130,8 @@

;; ----------------------------------------

(provide/contract
[author (->* (content?) () #:rest (listof content?) block?)]
[author+email (->* (content? string?) (#:obfuscate? any/c) element?)])
(provide (contract-out [author (->* (content?) () #:rest (listof content?) block?)]
[author+email (->* (content? string?) (#:obfuscate? any/c) element?)]))

(define (author . auths)
(make-paragraph
Expand All @@ -142,10 +140,9 @@
(case (length auths)
[(1) auths]
[(2) (list (car auths) nl "and " (cadr auths))]
[else (let ([r (reverse auths)])
(append (add-between (reverse (cdr r))
(make-element #f (list "," nl)))
(list "," nl "and " (car r))))]))))
[else (define r (reverse auths))
(append (add-between (reverse (cdr r)) (make-element #f (list "," nl)))
(list "," nl "and " (car r)))]))))

(define (author+email name email #:obfuscate? [obfuscate? #f])
(make-element #f
Expand Down Expand Up @@ -173,17 +170,11 @@

(provide items/c)

(provide/contract
[itemlist (->* ()
(#:style (or/c style? string? symbol? #f))
#:rest (listof items/c)
itemization?)]
[item (->* ()
()
#:rest (listof pre-flow?)
item?)])
(provide/contract
[item? (any/c . -> . boolean?)])
(provide (contract-out
[itemlist
(->* () (#:style (or/c style? string? symbol? #f)) #:rest (listof items/c) itemization?)]
[item (->* () () #:rest (listof pre-flow?) item?)]))
(provide (contract-out [item? (any/c . -> . boolean?)]))

(define (itemlist #:style [style plain] . items)
(let ([flows (let loop ([items items])
Expand Down Expand Up @@ -218,33 +209,27 @@
;; ----------------------------------------

(define elem-like-contract
(->* () () #:rest (listof pre-content?) element?))

(provide/contract
[linebreak (-> element?)]
[nonbreaking elem-like-contract]
[hspace (-> exact-nonnegative-integer? element?)]
[elem (->* ()
(#:style element-style?)
#:rest (listof pre-content?)
element?)]
[italic elem-like-contract]
[bold elem-like-contract]
[smaller elem-like-contract]
[larger elem-like-contract]
[emph elem-like-contract]
[tt elem-like-contract]
[subscript elem-like-contract]
[superscript elem-like-contract]

[literal (->* (string?) () #:rest (listof string?) element?)]

[image (->* ((or/c path-string? (cons/c 'collects (listof bytes?))))
(#:scale real?
#:suffixes (listof (and/c string? #rx"^[.]"))
#:style element-style?)
#:rest (listof content?)
image-element?)])
(-> pre-content? ... element?))

(provide (contract-out
[linebreak (-> element?)]
[nonbreaking elem-like-contract]
[hspace (-> exact-nonnegative-integer? element?)]
[elem (->* () (#:style element-style?) #:rest (listof pre-content?) element?)]
[italic elem-like-contract]
[bold elem-like-contract]
[smaller elem-like-contract]
[larger elem-like-contract]
[emph elem-like-contract]
[tt elem-like-contract]
[subscript elem-like-contract]
[superscript elem-like-contract]
[literal (->* (string?) () #:rest (listof string?) element?)]
[image
(->* ((or/c path-string? (cons/c 'collects (listof bytes?))))
(#:scale real? #:suffixes (listof (and/c string? #rx"^[.]")) #:style element-style?)
#:rest (listof content?)
image-element?)]))

(define hspace-cache (make-vector 100 #f))

Expand Down Expand Up @@ -292,11 +277,10 @@
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)))))
(make-element #f (for/list ([s (in-list l)])
(if (or (string? s) (symbol? s))
(make-element 'tt (list s))
s))))))

(define (span-class classname . str)
(make-element classname (decode-content str)))
Expand Down Expand Up @@ -325,33 +309,30 @@
;; ----------------------------------------

(define (cell-spec/c c)
(define rc
(recursive-contract (or/c c
empty
(cons/c rc rc))))
rc)
(recursive-contract (or/c c empty (cons/c rc rc))))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoa!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jackfirth this needs a side condition to make sure that rc doesn't occur in the body of define.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the inlined definition binds a (non-recursive) lambda expression, would the name be lost?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but that doesn't happen because first those get rewritten into function definitions of the form (define (f) ...) (as opposed to (define f (lambda () ...))). Then, there's a check in the inlining rule to not inline function definitions, only variable definitions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, this is very cool!


(provide/contract
[para (->* ()
(#:style (or/c style? string? symbol? #f ))
#:rest (listof pre-content?)
paragraph?)]
[nested (->* ()
(#:style (or/c style? string? symbol? #f ))
#:rest (listof pre-flow?)
nested-flow?)]
[compound (->* ()
(#:style (or/c style? string? symbol? #f ))
(provide (contract-out
[para
(->* ()
(#:style (or/c style? string? symbol? #f))
#:rest (listof pre-content?)
paragraph?)]
[nested
(->* () (#:style (or/c style? string? symbol? #f)) #:rest (listof pre-flow?) nested-flow?)]
[compound
(->* ()
(#:style (or/c style? string? symbol? #f))
#:rest (listof pre-flow?)
compound-paragraph?)]
[tabular (->* ((listof (listof (or/c 'cont block? content?))))
(#:style (or/c style? string? symbol? #f)
#:sep (or/c content? block? #f)
#:column-properties (listof any/c)
#:row-properties (listof any/c)
#:cell-properties (listof (listof any/c))
#:sep-properties (or/c list? #f))
table?)])
[tabular
(->* ((listof (listof (or/c 'cont block? content?))))
(#:style (or/c style? string? symbol? #f)
#:sep (or/c content? block? #f)
#:column-properties (listof any/c)
#:row-properties (listof any/c)
#:cell-properties (listof (listof any/c))
#:sep-properties (or/c list? #f))
table?)]))

(define (convert-block-style style)
(cond
Expand Down Expand Up @@ -385,25 +366,22 @@
[(3) "rd"]
[else "th"]))
(unless (null? cells)
(let ([n (length (car cells))])
(for ([row (in-list (cdr cells))]
[pos (in-naturals 2)])
(unless (= n (length row))
(raise-mismatch-error
'tabular
(format "bad length (~a does not match first row's length ~a) for ~a~a row: "
(length row)
n
pos
(nth-str pos))
row)))))
(define n (length (car cells)))
(for ([row (in-list (cdr cells))]
[pos (in-naturals 2)])
(unless (= n (length row))
(raise-mismatch-error
'tabular
(format "bad length (~a does not match first row's length ~a) for ~a~a row: "
(length row)
n
pos
(nth-str pos))
row))))
(for ([row (in-list cells)]
[pos (in-naturals 1)])
(when (and (pair? row) (eq? (car row) 'cont))
(raise-mismatch-error
'tabular
(format "~a~a row starts with 'cont: " pos (nth-str pos))
row)))
[pos (in-naturals 1)]
#:when (and (pair? row) (eq? (car row) 'cont)))
(raise-mismatch-error 'tabular (format "~a~a row starts with 'cont: " pos (nth-str pos)) row))
(make-table (let ([s (convert-block-style style)])
(define n-orig-cols (if (null? cells)
0
Expand All @@ -429,12 +407,11 @@
"cell properties list is too long: "
cell-properties))
(unless (null? cells)
(for ([row (in-list cell-properties)])
(when ((length row) . > . n-orig-cols)
(raise-mismatch-error
'tabular
"row list within cell properties list is too long: "
row))))
(for ([row (in-list cell-properties)]
#:when ((length row) . > . n-orig-cols))
(raise-mismatch-error 'tabular
"row list within cell properties list is too long: "
row)))
;; Expand given column and cell properties lists to match
;; the dimensions of the given `cells` by duplicating
;; the last element of a list as needed (and ignoring
Expand Down
10 changes: 8 additions & 2 deletions scribble-test/tests/scribble/main.rkt
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
#lang racket/base

(require tests/eli-tester
"reader.rkt" "text-collect.rkt" "text-lang.rkt" "text-wrap.rkt"
"docs.rkt" "render.rkt" "xref.rkt" "markdown.rkt")
"docs.rkt"
"markdown.rkt"
"reader.rkt"
"render.rkt"
"text-collect.rkt"
"text-lang.rkt"
"text-wrap.rkt"
"xref.rkt")

(test do (reader-tests)
do (begin/collect-tests)
Expand Down
32 changes: 17 additions & 15 deletions scribble-test/tests/scribble/markdown.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,26 @@

;; Use text renderer to check some Scribble functionality

(require scribble/base-render (prefix-in markdown: scribble/markdown-render)
racket/file racket/class racket/runtime-path tests/eli-tester)
(require racket/class
racket/file
racket/runtime-path
scribble/base-render
tests/eli-tester
(prefix-in markdown: scribble/markdown-render))

(define-runtime-path source-dir "markdown-docs")
(define work-dir (build-path (find-system-path 'temp-dir)
"scribble-docs-tests"))

(define (build-markdown-doc src-file dest-file)
(let* ([renderer (new (markdown:render-mixin render%) [dest-dir work-dir])]
[docs (list (dynamic-require src-file 'doc))]
[fns (list (build-path work-dir dest-file))]
[fp (send renderer traverse docs fns)]
[info (send renderer collect docs fns fp)]
[r-info (send renderer resolve docs fns info)])
(send renderer render docs fns r-info)
(send renderer get-undefined r-info)))
(define renderer (new (markdown:render-mixin render%) [dest-dir work-dir]))
(define docs (list (dynamic-require src-file 'doc)))
(define fns (list (build-path work-dir dest-file)))
(define fp (send renderer traverse docs fns))
(define info (send renderer collect docs fns fp))
(define r-info (send renderer resolve docs fns info))
(send renderer render docs fns r-info)
(send renderer get-undefined r-info))

(provide markdown-tests)
(module+ main (markdown-tests))
Expand All @@ -40,11 +44,9 @@
(define (contents file)
(regexp-replace #rx"\n+$" (file->string file) ""))
(define undefineds (build-markdown-doc src-file "gen.md"))
(for ([u (in-list undefineds)])
(when (eq? 'tech (car u))
(test #:failure-message
(format "undefined tech: ~e" u)
#f)))
(for ([u (in-list undefineds)]
#:when (eq? 'tech (car u)))
(test #:failure-message (format "undefined tech: ~e" u) #f))
(test #:failure-message
(format
"mismatch for: \"~a\", expected text in: \"~a\", got:\n~a"
Expand Down
16 changes: 8 additions & 8 deletions scribble-test/tests/scribble/reader.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -947,14 +947,14 @@ END-OF-TESTS
(define m
(or (regexp-match #px"^(.*)\n\\s*(-\\S+->)\\s*\n(.*)$" t)
(regexp-match #px"^(.*\\S)\\s+(-\\S+->)\\s+(\\S.*)$" t)))
(if (not (and m (= 4 (length m))))
(error 'bad-test "~a" t)
(let-values ([(x y) ((string->tester (caddr m)) (cadr m) (cadddr m))])
(test #:failure-message (format "bad result in\n ~a\n results:\n ~s != ~s"
(regexp-replace* #rx"\n" t "\n ")
x
y)
(matching? x y)))))))
(unless (and m (= 4 (length m)))
(error 'bad-test "~a" t))
(let-values ([(x y) ((string->tester (caddr m)) (cadr m) (cadddr m))])
(test #:failure-message (format "bad result in\n ~a\n results:\n ~s != ~s"
(regexp-replace* #rx"\n" t "\n ")
x
y)
(matching? x y))))))

;; Check static versus dynamic readtable for command (dynamic when "c" in the
;; name) and datum (dynamic when "d" in the name) parts:
Expand Down
2 changes: 1 addition & 1 deletion scribble-test/tests/scribble/text-lang.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,4 @@
(call-with-trusted-sandbox-configuration
(lambda ()
(for ([t (in-list (doc:tests))])
(begin (apply text-test t))))))
(apply text-test t)))))
Loading