Compare commits

...

94 Commits

Author SHA1 Message Date
Suzanne Soy
24fd9ca7ca Renamed main branch 2021-04-04 07:22:30 +01:00
Suzanne Soy
a6226feee5 Added e-mail address 2021-03-04 21:00:35 +00:00
Suzanne Soy
05270bf10e Changed my name :) 2021-03-04 20:37:39 +00:00
Georges Dupéron
ebdeed4cd3 Updated Racket versions in .travis.yml 2019-04-24 22:49:08 +02:00
Georges Dupéron
ae57a0d043 Correctly render spoilers with TeX 2017-06-08 23:44:04 +02:00
Georges Dupéron
1fc9c43010 Small improvements on spoilers 2017-05-30 23:13:41 +02:00
Georges Dupéron
51c7b9aed8 Possitility to toggle between a short and expanded version of the code (undocumented for now) 2017-05-29 13:31:10 +02:00
Georges Dupéron
a8a0eb8a28 Found quick&dirty way to embed the result of (init) whenever hlite is used. Added removed-but-with-another-style modes -/ -= -+ 2017-05-22 04:25:23 +02:00
Georges Dupéron
ddf8b602b2 Fix in the documentation 2017-05-18 16:10:41 +02:00
Georges Dupéron
4ca6172660 Changed the section in which the documentation appears on the main page 2017-05-16 12:09:45 +02:00
Georges Dupéron
741a761476 Quick documentation & passable LaTeX support 2017-05-16 00:26:48 +02:00
Georges Dupéron
b495e59300 Cleanup; added example 2017-05-15 23:49:42 +02:00
Georges Dupéron
7d9ba126b7 Highlighting improvements 2017-05-15 23:44:56 +02:00
Georges Dupéron
4e19426d90 Bug fixes concerning handling of rest elements when removing parts of code. 2017-05-15 22:52:06 +02:00
Georges Dupéron
35871c47c9 Correctly handle added / kept elements within removed elements, for @hlite. 2017-05-15 22:05:06 +02:00
Georges Dupéron
a499901ead Added support for highlighting parts of literate programs. 2017-05-15 21:38:49 +02:00
Georges Dupéron
d0a3a0b255 Allow the last expresion of the lang-line to span multiple lines. Stop providing #%top-interaction, so that one from the user's language is used instead (still can't access the bindings without providing them + (require (submod .)), but it's a step forward) 2017-05-11 23:38:46 +02:00
Georges Dupéron
a0e807ce43 Pulled the options out of the (lang . chain₊) 2017-04-26 14:20:58 +02:00
Georges Dupéron
08cb9cb52c syntax colorer support for the custom command character. 2017-04-26 01:30:29 +02:00
Georges Dupéron
f7ec1fbb5f Allow customization of the at-exp character. 2017-04-25 17:51:20 +02:00
Georges Dupéron
8e95ce9deb Note: maybe we should use the 'scribble property instead of 'first-comments and 'comments-after 2017-02-01 07:56:13 +01:00
Georges Dupéron
5c75120b28 Closes FB case 174 Fix chunk arrows in hyper-literate => use syntax-local-introduce on the value of 'disappeared-use and 'disappeared-binding 2017-01-20 14:01:34 +01:00
Georges Dupéron
835e565e0e Closes FB case 173 Fix arrows in hyper-literate. I Used a module-like scope when nesting the whole module body to allow overriding build-ins, as DrRacket doesn't draw the arrows properly when a (make-syntax-introducer) is used. 2017-01-20 13:47:17 +01:00
Georges Dupéron
40068c6410 Use only typed-map-lib, not typed-map 2017-01-13 01:52:14 +01:00
Georges Dupéron
674af96a89 Attempt at typing hide-#%comment, it looks horrible. 2017-01-13 00:56:08 +01:00
Georges Dupéron
0fbcd59af2 Build with fewer CPUS, to avoid OOM 2017-01-12 22:17:02 +01:00
Georges Dupéron
99c63ecd55 Moved typed-syntax files to tr-immutable. 2017-01-12 19:03:27 +01:00
Georges Dupéron
deca84c956 Finally managed to get syntax-properties-typed.rkt to typecheck, without relying on (Syntaxof Any) in the First-Comments and Comments-After types. The predicates are horrible to write, though :-( 2017-01-12 05:03:10 +01:00
Georges Dupéron
a110b20df1 Attempt at cross-phase structs, didn't work out well. 2017-01-12 02:27:00 +01:00
Georges Dupéron
b79ec821d4 Wrote wrappers for the configurable functions any->isyntax* syntax->isyntax* any->isyntax-e* 2017-01-11 20:39:47 +01:00
Georges Dupéron
503044660b Made any->isyntax and similar functions configurable, to choose how non-syntax and non-sexp cases should be handled 2017-01-11 03:59:28 +01:00
Georges Dupéron
dc1561e595 Further work on typed syntax 2017-01-11 03:58:37 +01:00
Georges Dupéron
3b59681010 Provide stuff 2017-01-10 23:04:17 +01:00
Georges Dupéron
2fa55c0d3f Mostly correct version of *->isyntax* 2017-01-10 21:17:20 +01:00
Georges Dupéron
10a5663ddf Cleaned up hiding/restoring comments, partially typed 2017-01-10 15:54:34 +01:00
Georges Dupéron
eb586b1ddd Bugfix: use (code:comment (unsyntax …)) in @chunk, and (code:comment (UNSYNTAX …)) in @CHUNK 2017-01-07 00:14:56 +01:00
Georges Dupéron
a51bf4c1a1 Support for comments with the new comment-reader 2017-01-06 19:02:30 +01:00
Georges Dupéron
5145a9cb7e Copied comment-reader.rkt from 531ad440b7/scribble-lib/scribble/comment-reader.rkt 2017-01-04 19:59:40 +01:00
Georges Dupéron
66551c6901 Temporarily disable the "color the nested language in black" feature for hyper-literate, as it gives incorrect coloring and indentation on large files (I guess the parser is not always called from the start of the file) 2016-12-27 19:10:49 +01:00
Georges Dupéron
37a6b9a680 Don't build on older versions, as we now need a very recent patch 2016-12-16 17:19:57 +01:00
Georges Dupéron
2a8ee4f8d4 Removed debugging output 2016-12-16 17:19:23 +01:00
Georges Dupéron
fef2ed1769 Fixed potential conflicts with the injected (require lang). 2016-12-16 16:40:01 +01:00
Georges Dupéron
ae152d4ab9 Remove -x option on raco test in .travis.yml, so that all modules are run, including those without a test submodule. 2016-10-11 00:24:55 +02:00
Georges Dupéron
397680acb0 Workaround to be able to use @include-section to include several hyper-literate programs into a single document. 2016-09-30 16:30:58 +02:00
Georges Dupéron
a7f15cdfd5 Cleanup 2016-09-20 22:10:40 +02:00
Georges Dupéron
6f5e7d92ff Added auto-parentheses for repeated chunks, and finally (hopefully) fixed the link numbering problems (last bug was that the save-as chunks had numbers total+i, but the references within the code were made to the number 1 which did not exist). 2016-09-20 07:12:44 +02:00
Georges Dupéron
fe2b582def Cleaned up the definition of @chunk and @CHUNK. Fixed issues with subscript numbers on chunks, links, and conflicting tags. Now it's possible to re-print a chunk several times without problem. 2016-09-20 03:12:58 +02:00
Georges Dupéron
148ec8da08 Fixed bad bug when a #:save-as chunk contained a ... 2016-09-19 03:12:01 +02:00
Georges Dupéron
57a4d0184d Closed #2 Wrong order of chunks: all @CHUNKs are inserted first, then the @chunks 2016-09-16 23:06:25 +02:00
Georges Dupéron
d5f2514925 Added Racket 6.6 to Travis build. The scribble-enhanced package was updated for compatibility with Racket < 6.4, so this should fix the previous commit. 2016-09-15 20:28:58 +02:00
Georges Dupéron
9b918351e7 Use the enhancements from scribble-enhanced (they might be merged in this repository at one point). 2016-09-15 19:34:15 +02:00
Georges Dupéron
20ee397610 Speed up --check-pkg-deps 2016-08-30 22:47:57 +02:00
Georges Dupéron
beb57b757d Test documentation coverage 2016-08-30 22:46:19 +02:00
Georges Dupéron
1f45a1b30b Added Installation section to README 2016-08-17 15:09:48 +02:00
Georges Dupéron
98eb5c4430 Typo in README. 2016-08-17 12:59:51 +02:00
Georges Dupéron
2cc3a6b5e0 Documentation changes suggested by O. Andreescu. Thanks! 2016-08-15 01:24:18 +02:00
Georges Dupéron
861f1524f6 Added link to docs in README. 2016-08-13 18:50:59 +02:00
Georges Dupéron
75e6a99a9f A few small changes. 2016-08-06 00:04:30 +02:00
Georges Dupéron
c64512bc29 Improved documentation 2016-08-05 00:52:49 +02:00
Georges Dupéron
f3e5295aff Fixed missing dependency 2016-08-04 22:39:35 +02:00
Georges Dupéron
68f15df96b Documented the bindings provided by hyper-literate and the syntax for the #lang. Fixed spelling in README. 2016-08-04 20:43:57 +02:00
Georges Dupéron
f6facffe7a Fixes bug with … (again) 2016-08-01 18:58:27 +02:00
Georges Dupéron
4bc45f2f0c Fixes issue with ... ? 2016-08-01 18:52:06 +02:00
Georges Dupéron
0a0505f504 Fixes typo 2016-08-01 18:51:54 +02:00
Georges Dupéron
32821668c0 Added #:no-auto-require, added partial support for #, in chunks. 2016-08-01 18:13:37 +02:00
Georges Dupéron
d62546af81 While trying to remove the use-scope which causes problem with my implementation of #, in chunks. Found the solution: syntax-local-identifier-as-binding 2016-08-01 17:27:18 +02:00
Georges Dupéron
213253f531 Bug #1402 on phc-adt/test/test-structure-low-level.rkt 43fd1bad4173baad0ede84e8ed88f917eec7b327 2016-07-29 17:12:57 +02:00
Georges Dupéron
d949cf9606 Added #%top-interaction (not the right one, though) 2016-06-23 21:42:57 +02:00
Georges Dupéron
f907f59b32 Fixed bug introduced by last commit. 2016-06-23 21:19:24 +02:00
Georges Dupéron
b9037c3c06 Fixes lots of issues. Fixes scribble bug #25 (last commit didn't fix it in the end). Fixes arrows in DrRacket. Fixes some identifier conflicts. 2016-06-23 21:11:17 +02:00
Georges Dupéron
dbebe7b60a Moved hyper-literate/typed to hyper-literate, as it is now parameterizable. 2016-06-17 20:27:53 +02:00
Georges Dupéron
32c6abb01e Fixes scribble bug #25 2016-06-17 19:59:40 +02:00
Georges Dupéron
3121eaec9d Improved test example. 2016-06-17 19:58:46 +02:00
Georges Dupéron
456d2557c8 Fixed issue with racketblock vs RACKETBLOCK (racketblock was always used) 2016-06-17 19:58:25 +02:00
Georges Dupéron
076bd1a750 Fixed requires 2016-06-17 18:31:54 +02:00
Georges Dupéron
4e99f8cf59 Improved explanations in test. 2016-06-17 18:27:19 +02:00
Georges Dupéron
f2b9a03ee4 Improved test coverage, require racket/base for-syntax. 2016-06-17 18:22:10 +02:00
Georges Dupéron
31f02fcd0b Added badges to README file 2016-06-17 17:19:01 +02:00
Georges Dupéron
33a205b3d8 Fixed missing dependency 2016-06-17 17:18:04 +02:00
Georges Dupéron
d78626c8ed Improved test coverage 2016-06-17 16:47:02 +02:00
Georges Dupéron
027d3f4a6c Fixed missing dependency, removed older Racket versions from build matrix. 2016-06-17 16:33:39 +02:00
Georges Dupéron
0bbbb12b5a Removed my-reader.rkt, it shouldn't be needed if I manage to fix http://stackoverflow.com/questions/37867859/module-meta-language-in-racket 2016-06-17 16:25:53 +02:00
Georges Dupéron
bd6ffb9b6a Added a test that requires the 'doc submodule. Normally this is done while building the document with scribble anyway. 2016-06-17 16:21:55 +02:00
Georges Dupéron
0ed3923079 Cleanup 2016-06-17 16:19:18 +02:00
Georges Dupéron
be223efb48 Fixed scribble bug #15. Also cleaned up code by currying the racketblock vs RACKETBLOCK parameter for chunk and CHUNK instead of calling define-syntax-rule twice. 2016-06-17 15:23:54 +02:00
Georges Dupéron
1b15bce0c7 Works, but needs a workaround for typed/racket to work. 2016-06-17 13:42:41 +02:00
Georges Dupéron
e785765209 First step towards a parameterizable meta-language 2016-06-16 18:47:16 +02:00
Georges Dupéron
21cd1f3ae3 various tests, before cleanup 2016-06-16 18:38:55 +02:00
Georges Dupéron
b895378a51 Improved README 2016-06-16 16:28:33 +02:00
Georges Dupéron
6098afd1bd Added README 2016-06-16 16:28:33 +02:00
Georges Dupéron
36faaad4ff Merge branch 'scribble-upstream-master-extract' 2016-06-16 16:28:14 +02:00
Georges Dupéron
b2f9117912 Pulled out scribble-lib/scribble/lp/lang/common.rkt and scribble-lib/scribble/lp/lang/lang2.rkt and scribble-lib/scribble/lp/lang/reader.rkt and scribble-lib/scribble/private/lp.rkt. 2016-06-16 16:27:55 +02:00
Georges Dupéron
ee0aaf2740 Added a couple of utilities: defck and repeat-chunk 2016-06-16 14:24:17 +02:00
Georges Dupéron
872000aff3 Initial commit 2016-06-16 14:21:44 +02:00
388 changed files with 2923 additions and 47318 deletions

10
.gitignore vendored
View File

@ -1,10 +1,6 @@
# Racket compiled files
compiled/
# common backups, autosaves, lock files, OS meta-files
*~
\#*
.#*
.\#*
.DS_Store
*.bak
TAGS
compiled/
/doc/

69
.travis.yml Normal file
View File

@ -0,0 +1,69 @@
language: c
# Based from: https://github.com/greghendershott/travis-racket
# Optional: Remove to use Travis CI's older infrastructure.
sudo: false
env:
global:
# Supply a global RACKET_DIR environment variable. This is where
# Racket will be installed. A good idea is to use ~/racket because
# that doesn't require sudo to install and is therefore compatible
# with Travis CI's newer container infrastructure.
- RACKET_DIR=~/racket
matrix:
# Supply at least one RACKET_VERSION environment variable. This is
# used by the install-racket.sh script (run at before_install,
# below) to select the version of Racket to download and install.
#
# Supply more than one RACKET_VERSION (as in the example below) to
# create a Travis-CI build matrix to test against multiple Racket
# versions.
#- RACKET_VERSION=6.0
#- RACKET_VERSION=6.1
#- RACKET_VERSION=6.1.1
#- RACKET_VERSION=6.2
#- RACKET_VERSION=6.3
#- RACKET_VERSION=6.4
#- RACKET_VERSION=6.5
#- RACKET_VERSION=6.6
#- RACKET_VERSION=6.7
- RACKET_VERSION=6.8
- RACKET_VERSION=6.9
- RACKET_VERSION=6.10
- RACKET_VERSION=6.10.1
- RACKET_VERSION=6.11
- RACKET_VERSION=6.12
- RACKET_VERSION=7.0
- RACKET_VERSION=7.1
- RACKET_VERSION=7.2
- RACKET_VERSION=HEAD
matrix:
allow_failures:
# - env: RACKET_VERSION=HEAD
fast_finish: true
before_install:
- git clone https://github.com/greghendershott/travis-racket.git ~/travis-racket
- cat ~/travis-racket/install-racket.sh | bash # pipe to bash not sh!
- export PATH="${RACKET_DIR}/bin:${PATH}" #install-racket.sh can't set for us
install:
- raco pkg install -j 2 --deps search-auto
before_script:
# Here supply steps such as raco make, raco test, etc. You can run
# `raco pkg install --deps search-auto` to install any required
# packages without it getting stuck on a confirmation prompt.
script:
- raco test -p hyper-literate
- raco setup --check-pkg-deps --no-zo --no-launcher --no-install --no-post-install --no-docs --pkgs hyper-literate
- raco pkg install --deps search-auto doc-coverage
- raco doc-coverage hyper-literate
after_success:
- raco pkg install --deps search-auto cover cover-coveralls
- raco cover -b -f coveralls -d $TRAVIS_BUILD_DIR/coverage .

View File

@ -1,8 +1,8 @@
scribble
Copyright (c) 2010-2014 PLT Design Inc.
hyper-literate
Copyright (c) 2016 Suzanne Soy
This package is distributed under the GNU Lesser General Public
License (LGPL). This means that you can link this package into proprietary
License (LGPL). This means that you can link hyper-literate into proprietary
applications, provided you follow the rules stated in the LGPL. You
can also modify this package; if you distribute a modified version,
you must distribute it under the terms of the LGPL, which in

41
README.md Normal file
View File

@ -0,0 +1,41 @@
[![Build Status,](https://img.shields.io/travis/jsmaniac/hyper-literate/main.svg)](https://travis-ci.org/jsmaniac/hyper-literate)
[![Coverage Status,](https://img.shields.io/coveralls/jsmaniac/hyper-literate/main.svg)](https://coveralls.io/github/jsmaniac/hyper-literate)
[![Build Stats,](https://img.shields.io/badge/build-stats-blue.svg)](http://jsmaniac.github.io/travis-stats/#jsmaniac/hyper-literate)
[![Online Documentation.](https://img.shields.io/badge/docs-online-blue.svg)](http://docs.racket-lang.org/hyper-literate/)
hyper-literate
==============
Some tools which help build hyper-literate programs.
Hyper-literate programming is to literate programming exactly what hypertext
documents are to regular books and texts. Literate programming is about
telling other programmers how the program works (instead of just telling the
compiler what it does). Telling this story can be done using non-linear,
hyperlinked documents.
For now these utilities only help with manipulating LP chunks (e.g. repeating
the same chunk in several places in the output document, but keeping a single
copy in the source code).
Ultimately, the reading experience should be closer to viewing an interactive
presentation, focusing on the parts of the program that are of interest to
you: expand on-screen the chunks you are curious about, run some tests and see
their result, etc.
* Imagine something like [code
bubbles](http://www.andrewbragdon.com/codebubbles_site.asp), but with
explanatory text coming along with the source code.
* Imagine something like [Inform](http://inform7.com/), but focused on
exploring a program instead of exploring an imaginary world — after all, a
program is some kind of imaginary world.
Installation
------------
Install with:
```
raco pkg install --deps search-auto hyper-literate
```

View File

@ -1,3 +1,10 @@
;; Copied and modified from https://github.com/racket/scribble/blob/
;; 31ad440b75b189a2b0838aab011544d44d6b580/
;; scribble-lib/scribble/comment-reader.rkt
;;
;; Maybe this should use instead the 'scribble property? See
;; https://docs.racket-lang.org/scribble/
;; reader-internals.html#%28part._.Syntax_.Properties%29
(module comment-reader scheme/base
(require (only-in racket/port peeking-input-port))
@ -23,42 +30,51 @@
(begin (read port) (read port))
'unsyntax)))
(define (make-comment-readtable #:readtable [rt (current-readtable)])
(define (make-comment-readtable #:readtable [rt (current-readtable)]
#:comment-wrapper [comment-wrapper 'code:comment]
#:unsyntax [unsyntax? #t])
(make-readtable rt
#\; 'terminating-macro
(case-lambda
[(char port)
(do-comment port (lambda () (read/recursive port #\@)))]
(do-comment port
(lambda () (read/recursive port #\@))
#:comment-wrapper comment-wrapper
#:unsyntax unsyntax?)]
[(char port src line col pos)
(let ([v (do-comment port (lambda () (read-syntax/recursive src port #\@)))])
(let ([v (do-comment port
(lambda () (read-syntax/recursive src port #\@))
#:comment-wrapper comment-wrapper
#:unsyntax unsyntax?)])
(let-values ([(eline ecol epos) (port-next-location port)])
(datum->syntax
#f
v
(list src line col pos (and pos epos (- epos pos))))))])))
(define (do-comment port recur)
(let loop ()
(when (equal? #\; (peek-char port))
(read-char port)
(loop)))
(when (equal? #\space (peek-char port))
(read-char port))
`(code:comment
(,(unsyntaxer)
(t
(define (do-comment port
recur
#:comment-wrapper [comment-wrapper 'code:comment]
#:unsyntax [unsyntax? #t])
(define comment-text
`(t
,@(append-strings
(let loop ()
(let ([c (read-char port)])
(cond
[(or (eof-object? c)
(char=? c #\newline))
null]
[(char=? c #\@)
(cons (recur) (loop))]
[else
(cons (string c)
(loop))]))))))))
[(or (eof-object? c)
(char=? c #\newline))
null]
[(char=? c #\@)
(cons (recur) (loop))]
[else
(cons (string c)
(loop))]))))))
(define comment-unsyntax
(if unsyntax?
`(,(unsyntaxer) ,comment-text)
comment-text))
`(,comment-wrapper ,comment-text))
(define (append-strings l)
(let loop ([l l][s null])

View File

@ -0,0 +1,140 @@
#lang typed/racket
(require (rename-in syntax/parse [...+ …+])
syntax/stx
racket/match
racket/set
racket/list
racket/function
racket/vector
racket/contract
sexp-diff
racket/pretty
rackunit
(only-in racket/base [... ])
(for-syntax (rename-in racket/base [... ]))
tr-immutable/typed-syntax
"syntax-properties-typed.rkt")
(provide hide-#%comment)
;; ([#%comment c1] a [#%comment c2] . ([#%comment c3] b [#%comment c4]))
;; => (aᶜ² . (bᶜ⁴)⁻ᶜ³)⁻ᶜ¹
;; (c1 a c2 . (c3 . (c4 b c5)))
;; => (aᶜ² . (bᶜ⁵)⁻ᶜ³⁻⁻ᶜ⁴)⁻ᶜ¹
;; (c1 a c2 . (c3 . (c4 c5)))
;; => (aᶜ² . ()⁻ᶜ³⁻⁻ᶜ⁴ᶜ⁵)⁻ᶜ¹
;; (c1 a (c2) b)
;; => (a ()⁻ᶜ² b)⁻ᶜ¹
;; (c1 a (c2 . b) c)
;; => (a b⁻ᶜ² c)⁻ᶜ¹
;; (c1 a (c2 . (c3 c4)) c)
;; => (a ()⁻ᶜ²⁻⁻ᶜ³ᶜ⁴ c)⁻ᶜ¹
(: hide-#%comment ( ISyntax/Non-Stx ISyntax/Non-Stx))
(define (hide-#%comment stx)
(cond
[(pair? (syntax-e stx))
(hide-in-pair (syntax-e stx))]
[else
;; TODO: recurse down vectors etc.
stx]))
(define-type ISyntax/Non-List*
(Rec L (U ISyntax/Non
Null
(Pairof ISyntax/Non L))))
(define pair (ann cons ( (A B) ( A B (Pairof A B)))))
(: hide-in-pair ( ISyntax/Non-List*
ISyntax/Non-Stx))
(define (hide-in-pair e*)
(let loop ([rest : ISyntax/Non-List* e*]
[groups : (Pairof (Listof Comment)
(Listof (Pairof ISyntax/Non (Listof Comment))))
'(())])
(if (pair? rest)
(if (comment? (car rest))
(loop (cdr rest)
(pair (pair (ann (car rest) Comment) (car groups))
(cdr groups)))
(loop (cdr rest)
(pair (ann '() (Listof Comment))
(pair (pair (car rest) (reverse (car groups)))
(cdr groups)))))
(values rest groups)))
(error "TODOrtfdsvc"))
(define-type Comment (Syntaxof (Pairof (Syntaxof '#%comment) Any)))
(define comment? (make-predicate Comment))
#;(if ((make-predicate (Rec R (Pairof (Syntaxof (Pairof (Syntaxof '#%comment) Any))
(U Boolean
Char
Number
Keyword
Null
String
Symbol
BoxTop
VectorTop
R))))
e*)
(error "TODOwa" e*)
(error "TODOwa" e*))
#|
(: listof? ( (A) ( Any ( Any Boolean : A) Boolean : (Listof A))))
(define (listof? l p?)
(pair? l
p?
(ann (λ (a)
(list*? a p?))
( Any Boolean : ))
|#
#;(match (syntax-e stx)
[(not (? pair?))
;; TODO: recurse down vectors etc.
stx]
[(list* e* ... rest)
(error "TODO")
#;(syntax-parse e*
#:datum-literals (#%comment)
[({~and c₀ [#%comment . _]}
{~seq {~and eᵢ {~not [#%comment . _]}}
{~and cᵢⱼ [#%comment . _]} }
…+)
(define new-e* (map with-comments-after
(map hide-#%comment
(syntax->list #'(eᵢ )))
(map syntax->list
(syntax->list #'((cᵢⱼ ) )))))
(define new-rest (if (null? rest)
rest
(hide-#%comment rest)))
(with-first-comments
(datum->syntax stx (append new-e* new-rest) stx stx)
(cons #f (syntax->list #'(c₀ ))))]
[({~and c₀ [#%comment . _]} )
(define new-rest (if (null? rest)
rest
(hide-#%comment rest)))
(with-first-comments
(with-comments-after
(datum->syntax stx new-rest stx stx)
(if (syntax? new-rest)
(syntax-property new-rest 'comments-after)
'()))
(cons (if (syntax? new-rest)
(cons (datum->syntax new-rest
'saved-props+srcloc
new-rest
new-rest)
(or (syntax-property new-rest 'first-comments)
;; TODO: I'm dubious about this, better typecheck
;; everything…
(cons #f null)))
#f)
(syntax->list #'(c₀ ))))])])

View File

@ -0,0 +1,75 @@
#lang racket
(require (rename-in syntax/parse [...+ …+])
syntax/stx
racket/match
racket/set
racket/list
racket/function
racket/vector
racket/contract
sexp-diff
racket/pretty
rackunit
(only-in racket/base [... ])
(for-syntax (rename-in racket/base [... ]))
"syntax-properties.rkt")
(provide hide-#%comment)
;; ([#%comment c1] a [#%comment c2] . ([#%comment c3] b [#%comment c4]))
;; => (aᶜ² . (bᶜ⁴)⁻ᶜ³)⁻ᶜ¹
;; (c1 a c2 . (c3 . (c4 b c5)))
;; => (aᶜ² . (bᶜ⁵)⁻ᶜ³⁻⁻ᶜ⁴)⁻ᶜ¹
;; (c1 a c2 . (c3 . (c4 c5)))
;; => (aᶜ² . ()⁻ᶜ³⁻⁻ᶜ⁴ᶜ⁵)⁻ᶜ¹
;; (c1 a (c2) b)
;; => (a ()⁻ᶜ² b)⁻ᶜ¹
;; (c1 a (c2 . b) c)
;; => (a b⁻ᶜ² c)⁻ᶜ¹
;; (c1 a (c2 . (c3 c4)) c)
;; => (a ()⁻ᶜ²⁻⁻ᶜ³ᶜ⁴ c)⁻ᶜ¹
(define (hide-#%comment stx)
(match (syntax-e stx)
[(not (? pair?))
;; TODO: recurse down vectors etc.
stx]
[(list* e* ... rest)
(syntax-parse e*
#:datum-literals (#%comment)
[({~and c₀ [#%comment . _]}
{~seq {~and eᵢ {~not [#%comment . _]}}
{~and cᵢⱼ [#%comment . _]} }
…+)
(define new-e* (map with-comments-after
(map hide-#%comment
(syntax->list #'(eᵢ )))
(map syntax->list
(syntax->list #'((cᵢⱼ ) )))))
(define new-rest (if (null? rest)
rest
(hide-#%comment rest)))
(with-first-comments
(datum->syntax stx (append new-e* new-rest) stx stx)
(cons #f (syntax->list #'(c₀ ))))]
[({~and c₀ [#%comment . _]} )
(define new-rest (if (null? rest)
rest
(hide-#%comment rest)))
(with-first-comments
(with-comments-after
(datum->syntax stx new-rest stx stx)
(if (syntax? new-rest)
(syntax-property new-rest 'comments-after)
'()))
(cons (if (syntax? new-rest)
(cons (datum->syntax new-rest
'saved-props+srcloc
new-rest
new-rest)
(or (syntax-property new-rest 'first-comments)
;; TODO: I'm dubious about this, better typecheck
;; everything…
(cons #f null)))
#f)
(syntax->list #'(c₀ ))))])]))

View File

@ -0,0 +1,130 @@
#lang racket
(require (rename-in syntax/parse [...+ …+])
syntax/stx
racket/match
racket/set
racket/list
racket/function
racket/vector
racket/contract
sexp-diff
racket/pretty
rackunit
(only-in racket/base [... ])
(for-syntax (rename-in racket/base [... ]))
"syntax-properties.rkt")
(provide restore-#%comment)
(define/contract (restore-#%comment stx
#:replace-with (replace-with #f)
#:scope [scope (datum->syntax #f 'zero)])
(->* (syntax?)
(#:replace-with [or/c #f syntax? (-> syntax? syntax?)]
#:scope identifier?)
syntax?)
(define (erase-props stx)
(define stx* (if (syntax-property stx 'first-comments)
(syntax-property stx 'first-comments #f)
stx))
(if (syntax-property stx* 'comments-after)
(syntax-property stx* 'comments-after #f)
stx*))
(define (recur stx)
(restore-#%comment stx #:replace-with replace-with #:scope scope))
(define (replace-in commentᵢ)
(syntax-parse commentᵢ
#:datum-literals (#%comment)
[({~and c #%comment} . rest)
(if (syntax? replace-with)
(datum->syntax commentᵢ
`(,(datum->syntax #'c replace-with #'c #'c)
. ,((make-syntax-delta-introducer
scope
(datum->syntax #f 'zero))
#'rest
'add))
commentᵢ
commentᵢ)
(replace-with
(datum->syntax commentᵢ
`(,#'c
. ,((make-syntax-delta-introducer
scope
(datum->syntax #f 'zero))
#'rest
'add))
commentᵢ
commentᵢ)))]
[_
commentᵢ]))
(define (replace-in-after comments)
(if replace-with
(if (eq? comments #f)
comments
(stx-map replace-in comments))
comments))
(define (replace-in-first first-comments)
(define (replace-in-first1 first-comments)
(if (eq? first-comments #f)
first-comments
(cons (cons (caar first-comments)
(replace-in-first1 (cdar first-comments)))
(stx-map replace-in (cdr first-comments)))))
(if replace-with
(if (eq? first-comments #f)
first-comments
(cons (replace-in-first1 (car first-comments))
(stx-map replace-in (cdr first-comments))))
first-comments))
(match (syntax-e stx)
[(list* e* ... rest)
;; TODO: when extracting the comments properties, check that they have
;; the right shape (listof syntax?) or (*list/c syntax? (list/c R))
;; Or append-map when stx is a stx-list (not in a tail position for the
;; comments-after)
(define new-e*
(append-map (λ (eᵢ)
(cons (recur eᵢ)
(or (replace-in-after (extract-comments-after eᵢ))
'())))
e*))
(define new-rest
(if (syntax? rest)
(recur rest)
;; TODO: handle vectors etc. here?
rest))
(define first-comments
(or (replace-in-first (extract-first-comments stx))
#f))
(define (nest first-comments to-nest)
(cond
[(eq? first-comments #f)
to-nest]
[(eq? (car first-comments) #f)
(append (cdr first-comments) to-nest)]
[else
(nest1 first-comments to-nest)]))
(define (nest1 first-comments to-nest)
(if (eq? first-comments #f)
to-nest
(append (cdr first-comments)
(datum->syntax (caar first-comments)
(nest (cdar first-comments) to-nest)))))
(define new-stx
(nest first-comments (append new-e* new-rest)))
(erase-props (datum->syntax stx new-stx stx stx))]
;; TODO: recurse down vectors etc.
[(? vector? v)
;; TODO: what if there is a first-comment property on the vector itself?
(erase-props
(datum->syntax stx
(vector-map (λ (vᵢ)
(recur vᵢ))
v)
stx
stx))]
[other
'TODO…
other]))

View File

@ -0,0 +1,130 @@
#lang racket
(require (rename-in syntax/parse [...+ …+])
syntax/stx
racket/match
racket/set
racket/list
racket/function
racket/vector
racket/contract
sexp-diff
racket/pretty
rackunit
(only-in racket/base [... ])
(for-syntax (rename-in racket/base [... ]))
"syntax-properties.rkt")
(provide restore-#%comment)
(define/contract (restore-#%comment stx
#:replace-with (replace-with #f)
#:scope [scope (datum->syntax #f 'zero)])
(->* (syntax?)
(#:replace-with [or/c #f syntax? (-> syntax? syntax?)]
#:scope identifier?)
syntax?)
(define (erase-props stx)
(define stx* (if (syntax-property stx 'first-comments)
(syntax-property stx 'first-comments #f)
stx))
(if (syntax-property stx* 'comments-after)
(syntax-property stx* 'comments-after #f)
stx*))
(define (recur stx)
(restore-#%comment stx #:replace-with replace-with #:scope scope))
(define (replace-in commentᵢ)
(syntax-parse commentᵢ
#:datum-literals (#%comment)
[({~and c #%comment} . rest)
(if (syntax? replace-with)
(datum->syntax commentᵢ
`(,(datum->syntax #'c replace-with #'c #'c)
. ,((make-syntax-delta-introducer
scope
(datum->syntax #f 'zero))
#'rest
'add))
commentᵢ
commentᵢ)
(replace-with
(datum->syntax commentᵢ
`(,#'c
. ,((make-syntax-delta-introducer
scope
(datum->syntax #f 'zero))
#'rest
'add))
commentᵢ
commentᵢ)))]
[_
commentᵢ]))
(define (replace-in-after comments)
(if replace-with
(if (eq? comments #f)
comments
(stx-map replace-in comments))
comments))
(define (replace-in-first first-comments)
(define (replace-in-first1 first-comments)
(if (eq? first-comments #f)
first-comments
(cons (cons (caar first-comments)
(replace-in-first1 (cdar first-comments)))
(stx-map replace-in (cdr first-comments)))))
(if replace-with
(if (eq? first-comments #f)
first-comments
(cons (replace-in-first1 (car first-comments))
(stx-map replace-in (cdr first-comments))))
first-comments))
(match (syntax-e stx)
[(list* e* ... rest)
;; TODO: when extracting the comments properties, check that they have
;; the right shape (listof syntax?) or (*list/c syntax? (list/c R))
;; Or append-map when stx is a stx-list (not in a tail position for the
;; comments-after)
(define new-e*
(append-map (λ (eᵢ)
(cons (recur eᵢ)
(or (replace-in-after (extract-comments-after eᵢ))
'())))
e*))
(define new-rest
(if (syntax? rest)
(recur rest)
;; TODO: handle vectors etc. here?
rest))
(define first-comments
(or (replace-in-first (extract-first-comments stx))
#f))
(define (nest first-comments to-nest)
(cond
[(eq? first-comments #f)
to-nest]
[(eq? (car first-comments) #f)
(append (cdr first-comments) to-nest)]
[else
(nest1 first-comments to-nest)]))
(define (nest1 first-comments to-nest)
(if (eq? first-comments #f)
to-nest
(append (cdr first-comments)
(datum->syntax (caar first-comments)
(nest (cdar first-comments) to-nest)))))
(define new-stx
(nest first-comments (append new-e* new-rest)))
(erase-props (datum->syntax stx new-stx stx stx))]
;; TODO: recurse down vectors etc.
[(? vector? v)
;; TODO: what if there is a first-comment property on the vector itself?
(erase-props
(datum->syntax stx
(vector-map (λ (vᵢ)
(recur vᵢ))
v)
stx
stx))]
[other
'TODO…
other]))

View File

@ -0,0 +1,81 @@
#lang typed/racket
(provide First-Comments
Comments-After
with-first-comments
with-comments-after
extract-first-comments
extract-comments-after)
(require tr-immutable/typed-syntax
typed-map)
(define-type First-Comments
(Rec R (Pairof (U #f (Pairof (Syntaxof 'saved-props+srcloc)
R))
(Listof ISyntax))))
(define-type Comments-After
(Listof ISyntax))
(: first-comments? ( Any Boolean : (Pairof (U #f (Pairof (Syntaxof 'saved-props+srcloc)
First-Comments))
(Listof ISyntax))))
(define (first-comments? v)
(define p? (inst pairof?
(U #f (Pairof (Syntaxof 'saved-props+srcloc)
First-Comments))
(Listof ISyntax)))
(p? v first-comments1? first-comments2?))
(: first-comments1? ( Any Boolean : (U #f (Pairof (Syntaxof 'saved-props+srcloc)
First-Comments))))
(define (first-comments1? v)
(or (false? v)
(first-comments11? v)))
(: first-comments11? ( Any Boolean : (Pairof (Syntaxof 'saved-props+srcloc)
First-Comments)))
(define (first-comments11? v)
(define p? (inst pairof?
(Syntaxof 'saved-props+srcloc)
First-Comments))
(p? v
(make-predicate (Syntaxof 'saved-props+srcloc))
first-comments?))
(: first-comments2? ( Any Boolean : (Listof ISyntax)))
(define (first-comments2? v)
(and (list? v)
(andmap isyntax? v)))
(: with-first-comments ( (A) ( ISyntax
(U #f First-Comments)
ISyntax)))
(define (with-first-comments e c)
(if (or (not c) (and (= (length c) 1) (not (first c))))
e
(syntax-property e 'first-comments c)))
(: with-comments-after ( (A) ( (Syntaxof A)
(U #f Comments-After)
(Syntaxof A))))
(define (with-comments-after e c)
(if (or (not c) (null? c))
e
(syntax-property e 'comments-after c)))
(: extract-first-comments (-> (Syntaxof Any) (U #f First-Comments)))
(define (extract-first-comments stx)
(define c (syntax-property stx 'first-comments))
(if (first-comments? c)
c
#f))
(: extract-comments-after (-> (Syntaxof Any) (U #f Comments-After)))
(define (extract-comments-after stx)
(define c (syntax-property stx 'comments-after))
(and (list? c)
(andmap isyntax? c)
c))

View File

@ -0,0 +1,37 @@
#lang racket
(provide first-comments/c
comments-after/c
with-first-comments
with-comments-after
extract-first-comments
extract-comments-after)
(define first-comments/c
(flat-rec-contract R (cons/c (or/c #f (cons/c (syntax/c 'saved-props+srcloc)
R)) #| nested |#
(listof syntax?) #| comments |#)))
(define comments-after/c
(listof syntax?))
(define/contract (with-first-comments e c)
(-> syntax?
(or/c #f first-comments/c)
syntax?)
(if (or (not c) (and (= (length c) 1) (not (first c))))
e
(syntax-property e 'first-comments c)))
(define/contract (with-comments-after e c)
(-> syntax? (or/c #f comments-after/c) syntax?)
(if (or (not c) (null? c))
e
(syntax-property e 'comments-after c)))
(define/contract (extract-first-comments stx)
(-> syntax? (or/c #f first-comments/c))
(syntax-property stx 'first-comments))
(define/contract (extract-comments-after stx)
(-> syntax? (or/c #f comments-after/c))
(syntax-property stx 'comments-after))

387
diff1.rkt Normal file
View File

@ -0,0 +1,387 @@
#lang at-exp racket/base
(provide hlite)
(require hyper-literate
(for-syntax syntax/parse
(rename-in racket/base [... ])
racket/match
syntax/srcloc)
scribble/core
scribble/html-properties
scribble/latex-properties
scribble/base)
;; For debugging.
(define-for-syntax (show-stx e)
(define (r e)
(cond
([syntax? e]
(display "#'")
(r (syntax-e e)))
[(pair? e)
(display "(")
(let loop ([e e])
(if (pair? e)
(begin (r (car e))
(display " ")
(loop (cdr e)))
(if (null? e)
(display ")")
(begin
(display ". ")
(r e)
(display ")")))))]
[else
(print (syntax->datum (datum->syntax #f e)))]))
(r e)
(newline)
(newline))
(define the-css-addition
#"
.HyperLiterateNormal {
filter: initial;
background: none;
}
.HyperLiterateDim {
filter: brightness(150%) contrast(30%) opacity(0.7);
background: none; /* rgba(82, 103, 255, 0.36); */
}
.HyperLiterateAdd{
filter: initial;
background: rgb(202, 226, 202);
}
.HyperLiterateRemove {
filter: initial;
background: rgb(225, 182, 182);
}")
(define the-latex-addition
#"
%\\usepackage{framed}% \begin{snugshade}\end{snugshade}
\\definecolor{HyperLiterateDimColor}{RGB}{210,210,210}
\\definecolor{HyperLiterateAddColor}{RGB}{202,226,202}
\\definecolor{HyperLiterateRemoveColor}{RGB}{225,182,182}
\\def\\HyperLiterateNormal#1{#1}
\\def\\HyperLiterateDim#1{\\colorbox{HyperLiterateDimColor}{%
\\vphantom{\\RktPn{(}\\RktValDef{Xj}}#1}}
\\def\\HyperLiterateAdd#1{\\colorbox{HyperLiterateAddColor}{%
\\vphantom{\\RktPn{(}\\RktValDef{Xj}}#1}}
\\def\\HyperLiterateRemove#1{\\colorbox{HyperLiterateRemoveColor}{%
\\vphantom{\\RktPn{(}\\RktValDef{Xj}}#1}}
")
(define (init)
(elem
#:style (style #f
(list (css-addition the-css-addition)
(tex-addition the-latex-addition)))))
(begin-for-syntax
(define (stx-null? e)
(or (null? e)
(and (syntax? e)
(null? (syntax-e e)))))
(define (stx-pair? e)
(or (pair? e)
(and (syntax? e)
(pair? (syntax-e e))))))
(define-syntax (hlite stx)
(syntax-case stx ()
[(self name guide1 . body)
(and (identifier? #'self)
(identifier? #'name))
(let ()
(define (simplify-guide g)
(cond
[(and (identifier? g) (free-identifier=? g #'/)) '/]
[(and (identifier? g) (free-identifier=? g #'=)) '=]
[(and (identifier? g) (free-identifier=? g #'-)) '-]
[(and (identifier? g) (free-identifier=? g #'+)) '+]
[(and (identifier? g) (free-identifier=? g #'-/)) '-/]
[(and (identifier? g) (free-identifier=? g #'-=)) '-=]
[(and (identifier? g) (free-identifier=? g #'-+)) '-+]
[(identifier? g) '_]
[(syntax? g) (simplify-guide (syntax-e g))]
[(pair? g) (cons (simplify-guide (car g))
(simplify-guide (cdr g)))]
[(null? g) '()]))
(define (mode→style m)
(case m
[(/) "HyperLiterateDim"]
[(=) "HyperLiterateNormal"]
[(-) "HyperLiterateRemove"]
[(+) "HyperLiterateAdd"]
[(-/) "HyperLiterateDim"]
[(-=) "HyperLiterateNormal"]
[(-+) "HyperLiterateAdd"]))
(define simplified-guide (simplify-guide #'guide1))
(define (syntax-e? v)
(if (syntax? v) (syntax-e v) v))
(define new-body
(let loop ([mode '=]
[guide simplified-guide]
[body #'body])
(match guide
[(cons (and new-mode (or '/ '= '- '+ '-/ '-= '-+)) rest-guide)
(loop new-mode rest-guide body)]
[(list car-guide rest-guide)
#:when (and (pair? (syntax-e? body))
(memq (syntax-e? (car (syntax-e? body)))
'[quote quasiquote
unquote unquote-splicing
quasisyntax syntax
unsyntax unsyntax-splicing])
(pair? (syntax-e? (cdr (syntax-e? body))))
(null? (syntax-e?
(cdr (syntax-e? (cdr (syntax-e? body))))))
(let ([sp (syntax-span (car (syntax-e? body)))])
(or (= sp 1)
(= sp 2))))
(unless (symbol? car-guide)
(raise-syntax-error 'hlite
(format
"expected pattern ~a, found identifier"
car-guide)
(datum->syntax #f (car (syntax-e? body)))))
(define result
`(,(car (syntax-e? body))
,(loop mode
rest-guide
(car (syntax-e? (cdr (syntax-e? body)))))))
(if (syntax? body)
(datum->syntax body result body body)
body)]
[(cons car-guide rest-guide)
(unless (pair? (syntax-e? body))
(raise-syntax-error 'hlite
(format
"expected pair ~a, found non-pair"
guide)
(datum->syntax #f body)))
(define loop2-result
(let loop2 ([first-iteration? #t]
[guide guide]
[body (if (syntax? body) (syntax-e body) body)]
[acc '()])
(cond
[(and (pair? guide)
(memq (car guide) '(/ = - + -/ -= -+)))
(if first-iteration?
(loop (car guide) (cdr guide) body)
;; produce:
;; ({code:hilite {code:line accumulated ...}} . rest)
(let ([r-acc (reverse acc)]
[after (loop (car guide) (cdr guide) body)])
(define (do after)
(datum->syntax
(car r-acc)
`(code:hilite (code:line ,@r-acc . ,after)
,(mode→style mode))
(build-source-location-list
(update-source-location (car r-acc)
#:span 0))))
(if (stx-pair? body)
;; TODO: refactor the two branches, they are very
;; similar.
(cons (do '())
after)
;; Special case to handle (a . b) when b and a
;; do not have the same highlighting.
;; This assigns to the dot the highlighting for
;; b, although it would be possible to assign
;; andother highliughting (just change the
;; mode→style below)
(let* ([loc1 (build-source-location-list
(update-source-location
(car acc)
#:span 0))]
[loc2 (build-source-location-list
(update-source-location
after
#:column (- (syntax-column after)
3) ;; spc + dot + spc
#:span 0))])
`(,(do `(,(datum->syntax
#f
`(code:hilite
,(datum->syntax
#f `(code:line . ,after) loc2)
,(mode→style (car guide)))
loc1))))))))]
[(and (pair? guide) (pair? body))
;; accumulate the first element of body
(loop2 #f
(cdr guide)
(cdr body)
(cons (loop mode (car guide) (car body)) acc))]
;; If body is not a pair, then we will treat it as an
;; "improper tail" element, unless it is null?
[(null? body)
(unless (null? guide)
(raise-syntax-error
'hlite
;; TODO: thread the syntax version of body, so that
;; we can highlight the error.
"Expected non-null body, but found null"
stx))
;; produce:
;; ({code:hilite {code:line accumulated ...}})
(let* ([r-acc (reverse acc)])
`(,(datum->syntax (car r-acc)
`(code:hilite (code:line . ,r-acc)
,(mode→style mode))
(build-source-location-list
(update-source-location (car r-acc)
#:span 0))))
)]
[else
;; produce:
;; ({code:hilite
;; {code:line accumulated ... . improper-tail}})
(let* ([new-body (loop mode guide body)]
[r-acc+tail (append (reverse acc) new-body)])
`(,(datum->syntax
(car r-acc+tail)
`(code:hilite (code:line . ,r-acc+tail)
,(mode→style mode))
(build-source-location-list
(update-source-location (car r-acc+tail)
#:span 0))))
)
])))
(if (syntax? body)
(datum->syntax body loop2-result body body)
loop2-result)]
[(? symbol?)
(datum->syntax body `(code:hilite (code:line ,body)
,(mode→style mode))
(build-source-location-list
(update-source-location body #:span 0)))]
['()
(unless (stx-null? body)
(raise-syntax-error
'hlite
;; TODO: thread the syntax version of body, so that
;; we can highlight the error.
(format "Expected null body, but found non-null ~a"
(syntax->datum body))
stx))
body])))
(define new-executable-code
(let loop ([mode '=]
[guide simplified-guide]
[body #'body])
(match guide
[(cons (and new-mode (or '/ '= '- '+ '-/ '-= '-+)) rest-guide)
(loop new-mode rest-guide body)]
[(cons car-guide rest-guide)
(define (do-append-last-acc last-acc acc)
;; When nothing is later added to acc, we can
;; simply put r as the last element of the
;; reversed acc. This allows r to be an
;; improper list.
;; do-append-last-acc is called when elements follow
;; the current value of last-acc.
(unless (syntax->list (datum->syntax #f last-acc))
(raise-syntax-error
'hlite
(format
(string-append
"the removal of elements caused a list with a"
"dotted tail to be spliced in a non-final position: ~a")
(syntax->datum (datum->syntax #f last-acc)))
stx))
(append (reverse (syntax->list (datum->syntax #f last-acc)))
acc))
(define loop2-result
(let loop2 ([first-iteration? #t]
[guide guide]
[body (if (syntax? body) (syntax-e body) body)]
[acc '()]
[last-acc '()])
(cond
[(and (pair? guide)
(memq (car guide) '(/ = - + -/ -= -+)))
(if (or first-iteration?
(eq? (car guide) mode))
(loop (car guide) (cdr guide) body)
(let ([r (loop (car guide) (cdr guide) body)])
(if (stx-null? r)
;; produce: (accumulated ... . last-acc)
(append (reverse acc) last-acc)
;; produce: (accumulated ... last-acc ... . rest)
(let ([r-acc (reverse (do-append-last-acc
last-acc
acc))])
(append r-acc r)))))]
[(and (pair? guide) (pair? body))
;; accumulate the first element of body, if mode is not '-
;; which means that the element should be removed.
(cond
[(and (memq mode '(- -/ -= -+))
(or (pair? (car body))
(and (syntax? (car body))
(pair? (syntax-e (car body))))))
(let ([r (loop mode (car guide) (car body))])
(loop2 #f
(cdr guide)
(cdr body)
(do-append-last-acc last-acc acc)
r))]
[(memq mode '(- -/ -= -+))
(loop2 #f
(cdr guide)
(cdr body)
acc
last-acc)]
[else
(loop2 #f
(cdr guide)
(cdr body)
(do-append-last-acc last-acc acc)
(list (loop mode (car guide) (car body))))])]
;; If body is not a pair, then we will treat it as an
;; "improper tail" element, unless it is null?
[(null? body)
;; produce:
;; ((accumulated ...))
(let* ([r-acc (append (reverse acc) last-acc)])
r-acc)]
[else
;; produce:
;; (accumulated ... . improper-tail)
(let* ([new-body (loop mode guide body)]
[r-acc+tail (append
(reverse
(do-append-last-acc last-acc acc))
new-body)])
r-acc+tail)])))
(if (syntax? body)
(datum->syntax body loop2-result body body)
loop2-result)]
[(? symbol?)
body]
['()
body])))
;(displayln new-body)
;(show-stx new-body)
#`(begin
(init)
#,(datum->syntax
stx
`(,(datum->syntax #'here 'chunk #'self)
#:display-only
,#'name
. ,(syntax-e new-body))
stx)
(chunk #:save-as dummy name
. #,new-executable-code)))]))

31
info.rkt Normal file
View File

@ -0,0 +1,31 @@
#lang info
(define collection "hyper-literate")
(define deps '("base"
"rackunit-lib"
"at-exp-lib"
"scheme-lib"
"scribble-lib"
"typed-racket-lib"
"typed-racket-more"
"typed-racket-doc"
"scribble-enhanced"
"sexp-diff"
"tr-immutable"
"typed-map-lib"
"debug-scopes"
"syntax-color-lib"))
(define build-deps '("scribble-lib"
"racket-doc"
"rackunit-doc"
"scribble-doc"
"rackunit-doc"))
(define scribblings '(("scribblings/hyper-literate.scrbl" () ("Scribble Libraries"))
("test/test.hl.rkt" () (omit-start))
("test/test2.hl.rkt" () (omit-start))))
(define pkg-desc
(string-append "Hyper-literate programming is to literate programming exactly"
" what hypertext documents are to regular books and texts."
" For now, this is based on scribble/lp2, and only contains"
" some ε-improvements over it"))
(define version "0.2")
(define pkg-authors '(|Suzanne Soy|))

8
lang.rkt Normal file
View File

@ -0,0 +1,8 @@
#lang racket/base
;; Forked from scribble-lib/scribble/lp/lang/lang2.rkt
(require "private/common.rkt")
(provide (rename-out [module-begin/doc #%module-begin])
;; TODO: this is the #%top-interaction from racket/base, not from the
;; user-specified language.
#;#%top-interaction)

55
lang/first-line-utils.rkt Normal file
View File

@ -0,0 +1,55 @@
#lang racket/base
(require racket/port)
(provide read-whole-first-line
read-syntax-whole-first-line
narrow-to-one-line
read-line-length)
(define (read-line-length port)
(let* ([peeking (peeking-input-port port)]
[start (file-position peeking)]
[_ (read-line peeking)]
[end (file-position peeking)])
(- end start)))
(define (narrow-to-one-line port)
(make-limited-input-port port (read-line-length port)))
(define (read-*-whole-first-line rec-read in)
(define in1 (peeking-input-port (narrow-to-one-line in)))
(define start-pos (file-position in1))
(let loop ([last-good-pos start-pos])
(define res+
;; Try to read (may fail if the last object to read spills onto the next
;; lines. We read from the peeking-input-port, so that we can retry the
;; last read on the full, non-narrowed port.
(with-handlers ([exn:fail:read? (λ (_) 'read-error)])
(list (rec-read in1))))
(cond
[(eq? res+ 'read-error)
;; Last read was unsuccessful, only consume the bytes from the original
;; input port up to the last successful read. Then, re-try one last read
;; on the whole file (i.e. the last read object may span several lines).
(read-bytes (- last-good-pos start-pos) in)
(list (rec-read in))]
[(eof-object? (car res+))
;; Last successful read, actually consume the bytes from the original
;; input port. Technically, last-good-pos and (file-position pk) should
;; be the same, since the last read returned #<eof> (and therefore did
;; not advance the read pointer.
(read-bytes (- (file-position in1) start-pos) in)
'()]
[else
;; One successful read. Prepend it, and continue reading some more.
(cons (car res+)
(loop (file-position in1)))])))
(define (read-whole-first-line in)
(read-*-whole-first-line (λ (in1) (read in1)) in))
(define (read-syntax-whole-first-line source-name in)
(read-*-whole-first-line (λ (in1) (read-syntax source-name in1)) in))

60
lang/meta-first-line.rkt Normal file
View File

@ -0,0 +1,60 @@
#lang racket/base
(require scribble/reader
racket/port
racket/syntax
syntax/stx
syntax/strip-context
"first-line-utils.rkt"
(only-in "../comment-reader.rkt" make-comment-readtable)
"../comments/hide-comments.rkt")
(provide meta-read-inside
meta-read-syntax-inside
get-command-char)
(define (make-at-reader+comments #:syntax? [syntax? #t]
#:inside? [inside? #f]
#:char [command-char #\@])
(make-at-reader
#:syntax? syntax?
#:inside? inside?
#:command-char command-char
#:datum-readtable (λ (rt)
(make-comment-readtable
#:readtable rt
#:comment-wrapper '#%comment
#:unsyntax #f))))
(define (get-command-char rd1)
(define rd1-datum (syntax->datum (datum->syntax #f rd1)))
(if (and (pair? rd1-datum)
(keyword? (car rd1-datum))
(= 1 (string-length (keyword->string (car rd1-datum)))))
(values (string-ref (keyword->string (car rd1-datum)) 0)
(if (syntax? rd1)
(datum->syntax rd1 (stx-cdr rd1) rd1 rd1)
(cdr rd1)))
(values #\@ rd1)))
(define (meta-read-inside in . args)
(define rd1 (read-whole-first-line in))
(define-values (at-exp-char new-rd1) (get-command-char #'rd1))
(define rd (apply (make-at-reader+comments #:syntax? #f
#:inside? #t
#:char at-exp-char)
args))
`(,new-rd1 . ,rd))
(define (meta-read-syntax-inside source-name in . args)
(with-syntax ([rd1 (read-syntax-whole-first-line source-name in)])
(let-values ([(command-char new-rd1) (get-command-char #'rd1)])
(with-syntax* ([new-rd1-stx new-rd1]
[rd (apply (make-at-reader+comments #:syntax? #t
#:inside? #t
#:char command-char)
source-name
in
args)]
[rd-hide (hide-#%comment #'rd)])
#'(new-rd1-stx . rd-hide)))))

87
lang/reader.rkt Normal file
View File

@ -0,0 +1,87 @@
#lang s-exp syntax/module-reader
;; Forked from scribble-lib/scribble/lp/lang/reader.rkt
hyper-literate/lang
#:read meta-read-inside
#:read-syntax meta-read-syntax-inside
#:whole-body-readers? #t
;; don't use scribble-base-info for the #:info arg, since
;; scribble/lp files are not directly scribble'able.
#:language-info (scribble-base-language-info)
#:info (wrapped-scribble-base-reader-info)
(require "meta-first-line.rkt"
(only-in scribble/base/reader
scribble-base-reader-info
scribble-base-language-info)
"first-line-utils.rkt")
(define orig-scribble-base-reader-info
(scribble-base-reader-info))
(require syntax-color/scribble-lexer
syntax-color/racket-lexer
racket/port)
(define (wrapped-scribble-base-reader-info)
(define (read/at-exp in offset x-mode)
(define-values (mode2 lexr command-char mode)
(apply values x-mode))
(define-values (r1 r2 r3 r4 r5 max-back-up new-mode)
(lexr in offset mode))
(define new-x-mode (list 'main lexr command-char new-mode))
(values r1 r2 r3 r4 r5 max-back-up new-x-mode))
(define (make-lexr command-char)
(make-scribble-inside-lexer #:command-char (or command-char #\@)))
(define (read/options in offset x-mode)
(define-values (mode2 command-char depth)
(apply values x-mode))
(define-values (txt type paren start end status) (racket-lexer/status in))
(define new-depth (case status
[(open) (add1 depth)]
[(close) (sub1 depth)]
[else depth]))
;; TODO: limit the number of newlines to a single newline.
(if (or
;; Fallback to scribble mode fast if we get a close-paren too many.
;; This could be because the text starts right after the last "config"
;; expression (which would start on the first line, then continue).
(< new-depth 0)
(and (= new-depth 0)
(and (eq? type 'white-space)
(regexp-match #px"\n" txt))))
(values txt type paren start end
0 (list 'main (make-lexr command-char) command-char #f))
(let ()
(define new-command-char
(or command-char
(if (memq type '(comment sexp-comment white-space))
#f
(if (eq? type 'hash-colon-keyword)
(let ([rd (read (open-input-string txt))])
(if (and (keyword? rd)
(= (string-length (keyword->string rd)) 1))
(string-ref (keyword->string rd) 0)
#\@))
#\@))))
(values txt type paren start end
0 (list 'options new-command-char new-depth)))))
(lambda (key defval default)
(case key
[(color-lexer)
(λ (in offset x-mode)
(cond
[(eq? x-mode #f)
(read/options in offset (list 'options #f 0))]
[(eq? (car x-mode) 'options)
(read/options in offset x-mode)]
[else
(read/at-exp in offset x-mode)]))]
[else
(orig-scribble-base-reader-info key defval default)])))

38
main.rkt Normal file
View File

@ -0,0 +1,38 @@
#lang racket/base
(require (for-syntax racket/base
racket/syntax)
(except-in scribble/lp2 chunk CHUNK))
(require (only-in hyper-literate/private/lp
chunk
CHUNK))
(provide defck
repeat-chunk
chunk
CHUNK)
(define-syntax (defck stx)
(syntax-case stx ()
[(self . rest)
(with-syntax ([(name . content) #'rest]
[chk (datum->syntax #'self 'chunk)])
(with-syntax ([name2 (format-id #'name "~a-repeat" #'name)])
#`(begin
#,(syntax/loc stx (chk . rest))
;(define name2 #'content)
(define-syntax (name2 stx2)
(syntax-case stx2 ()
[(_ prefix (... ...)) #'(prefix (... ...) . content)])))))]))
(define-syntax (repeat-chunk stx)
(syntax-case stx ()
[(self name)
(let ([stripped-name (regexp-replace #px"^<(.*)>$"
(symbol->string (syntax-e #'name))
"\\1")])
(with-syntax ([chk (datum->syntax #'self 'chunk)]
[name2 (format-id #'name "~a-repeat" #'name)]
[name-rep (format-id #'name "(~a)" stripped-name)])
#'(name2 chk name-rep)))]))

View File

@ -0,0 +1,4 @@
#lang racket/base
(provide chunks-toc-prefix)
(define chunks-toc-prefix (make-parameter '()))

270
private/common.rkt Normal file
View File

@ -0,0 +1,270 @@
#lang racket/base
;; Forked from scribble-lib/scribble/lp/lang/common.rkt
(provide (except-out (all-from-out racket/base) #%module-begin)
module-begin/plain
module-begin/doc)
(require (for-syntax racket/base syntax/boundmap racket/list
syntax/strip-context
syntax/srcloc
racket/struct
syntax/srcloc
debug-scopes/named-scopes/exptime))
(begin-for-syntax
(define first-id #f)
(define main-id #f)
(define (mapping-get mapping id)
(free-identifier-mapping-get mapping id (lambda () '())))
;; maps a chunk identifier to its collected expressions
(define chunks (make-free-identifier-mapping))
;; maps a chunk identifier to all identifiers that are used to define it
(define chunk-groups (make-free-identifier-mapping))
(define (get-chunk id) (mapping-get chunks id))
(define (add-to-chunk! id exprs)
(unless first-id (set! first-id id))
(when (eq? (syntax-e id) '<*>) (set! main-id id))
(free-identifier-mapping-put!
chunk-groups id
(cons id (mapping-get chunk-groups id)))
(free-identifier-mapping-put!
chunks id
`(,@(mapping-get chunks id) ,@exprs))))
(define-for-syntax (tangle orig-stx)
(define chunk-mentions '())
(unless first-id
(raise-syntax-error 'scribble/lp "no chunks"))
(define (restore nstx d) (datum->syntax orig-stx d nstx nstx))
(define (shift nstx) (replace-context orig-stx nstx))
(define body
(let ([main-id (or main-id first-id)])
(restore
main-id
(let loop ([block (get-chunk main-id)])
(append-map
(lambda (expr)
(if (identifier? expr)
(let ([subs (get-chunk expr)])
(if (pair? subs)
(begin (set! chunk-mentions (cons expr chunk-mentions))
(loop subs))
(list (shift expr))))
(let ([subs (syntax->list expr)])
(if subs
(list (restore expr (loop subs)))
(list (shift expr))))))
block)))))
(with-syntax ([body (strip-comments body)]
;; Hopefully the scopes are correct enough on the whole body.
[body0 (syntax-case body () [(a . _) #'a] [a #'a])]
;; construct arrows manually
[((b-use b-id) ...)
(append-map (lambda (m)
(map (lambda (u)
(list (syntax-local-introduce m)
(syntax-local-introduce u)))
(mapping-get chunk-groups m)))
chunk-mentions)])
;; TODO: use disappeared-use and disappeared-binding.
;; TODO: fix srcloc (already fixed?).
;#`(#,(datum->syntax #'body0 'begin) (let ([b-id (void)]) b-use) ... body0 body ...)
(syntax-property
(syntax-property #`(#,(datum->syntax #'body0 'begin) . body)
'disappeared-binding (syntax->list (syntax-local-introduce #'(b-id ...))))
'disappeared-use (syntax->list (syntax-local-introduce #'(b-use ...))))))
(define-for-syntax (strip-comments body)
(cond
[(syntax? body)
(define r (strip-comments (syntax-e body)))
(if (eq? r (syntax-e body))
body
(datum->syntax body r body body))]
[(pair? body)
(define a (car body))
(define ad (syntax-e a))
(cond
[(and (pair? ad)
(memq (syntax-e (car ad))
'(code:comment
code:contract)))
(strip-comments (cdr body))]
[(eq? ad 'code:blank)
(strip-comments (cdr body))]
[(and (or (eq? ad 'code:hilite)
(eq? ad 'code:quote))
(let* ([d (cdr body)]
[dd (if (syntax? d)
(syntax-e d)
d)])
(and (pair? dd)
(or (null? (cdr dd))
(and (syntax? (cdr dd))
(null? (syntax-e (cdr dd))))))))
(define d (cdr body))
(define r
(strip-comments (car (if (syntax? d) (syntax-e d) d))))
(if (eq? ad 'code:quote)
`(quote ,r)
r)]
[(and (pair? ad)
(eq? (syntax-e (car ad))
'code:line))
(if (null? (cdr body))
(strip-comments (cdr ad))
(strip-comments (append (cdr ad) (cdr body))))]
[else (cons (strip-comments a)
(strip-comments (cdr body)))])]
[else body]))
(define-for-syntax (extract-chunks exprs)
(let loop ([exprs exprs])
(syntax-case exprs ()
[() (void)]
[(expr . exprs)
(syntax-case #'expr (define-values quote-syntax)
[(define-values (lifted) (quote-syntax (a-chunk id body ...)))
(eq? (syntax-e #'a-chunk) 'a-chunk)
(begin
(add-to-chunk! #'id (syntax->list #'(body ...)))
(loop #'exprs))]
[_
(loop #'exprs)])])))
(require (for-syntax racket/syntax
syntax/parse))
(require (for-syntax racket/pretty
"no-auto-require.rkt"))
(define-for-syntax (strip-source e)
(cond [(syntax? e)
(update-source-location
(datum->syntax e (strip-source (syntax-e e)) e e)
#:source #f)]
[(pair? e) (cons (strip-source (car e)) (strip-source (cdr e)))]
[(vector? e) (list->vector (strip-source (vector->list e)))]
[(prefab-struct-key e)
=> (λ (k) (make-prefab-struct k (strip-source (struct->list e))))]
;; TODO: hash tables
[else e]))
;; Many thanks to Alex Knauth and Matthew Flatt for finding out how to make
;; module meta-languages.
(define-syntax (continue stx)
(syntax-case stx ()
[(_self lang-module-begin maybe-chain₊ . body)
(let ()
(define ch₊ (syntax->list #'maybe-chain₊))
(define expanded (local-expand
(datum->syntax stx
`(,#'lang-module-begin ,@ch₊ . ,#'body)
stx
stx)
'module-begin
(list)))
(define meta-language-nesting
;; Use a module-like scope here, instead of (make-syntax-introducer),
;; otherwise DrRacket stops drawing some arrows (why?).
(make-module-like-named-scope 'meta-language-nesting))
(syntax-case expanded (#%plain-module-begin)
[(#%plain-module-begin . expanded-body)
#`(begin
.
#,(meta-language-nesting #'expanded-body))]))]))
(define-for-syntax ((make-module-begin submod?) stx)
(syntax-parse stx
;; #:no-require-lang is ignored, but still allowed for compatibility.
;; TODO: semantically, the no-require-lang and no-auto-require should be
;; before the lang, as they are arguments to hyper-literate itself.
[(_modbeg {~or (lang:id
{~optional (~and no-require-lang #:no-require-lang)}
{~optional (~and no-auto-require #:no-auto-require)})
({~optional (~and no-auto-require #:no-auto-require)}
(lang:id
. chain₊))}
body0 . body)
(let ()
(define lang-sym (syntax-e #'lang))
(let ([expanded
(expand `(,#'module
scribble-lp-tmp-name hyper-literate/private/lp
(require hyper-literate/private/chunks-toc-prefix
(for-syntax racket/base
hyper-literate/private/no-auto-require))
(begin-for-syntax (set-box! no-auto-require?
,(if (attribute no-auto-require) #t #f))
(set-box! preexpanding? #t))
(define-syntax-rule (if-preexpanding a b) a)
(define-syntax-rule (when-preexpanding . b) (begin . b))
(define-syntax-rule (unless-preexpanding . b) (begin))
,@(strip-context #'(body0 . body))))])
(syntax-case expanded ()
[(module name elang (mb . stuff))
(let ()
(extract-chunks #'stuff)
(define/with-syntax tngl
(tangle #'body0))
(define/with-syntax mb9 (datum->syntax #f '#%module-begin))
(define/with-syntax lang-modbeg (datum->syntax #'lang '#%module-begin))
; See http://stackoverflow.com/questions/37867859/module-meta-language-in-racket :
#;(define expanded-main-mod-stx
(local-expand
(syntax-local-introduce
(datum->syntax #f `(,#'module ignored ,(datum->syntax #f lang-sym #'lang #'lang) (,#'mb9 ,(syntax-local-introduce #'tngl)))))
'top-level
(list)))
;(syntax-case expanded-main-mod-stx ();(module #%plain-module-begin)
;[(module _ lng11 (#%plain-module-begin . mod-body11))
#`(#%plain-module-begin
#,@(if submod?
(list
(with-syntax*
([ctx #'body0 #;(syntax-local-introduce #'body0)]
;; TODO: this is a hack, it would be nice to get
;; the actual source location of the lang.
[bd1 (update-source-location #'body0
#:line #f
#:column #f
#:position 7
#:span 14)]
[lng (datum->syntax #'ctx 'scribble/doclang2 #'bd1 #'bd1)]
[begn (datum->syntax #'ctx 'begin)])
(strip-source
#`(module* doc lng ;module doc scribble/doclang2
#,@(syntax-local-introduce
;; TODO: instead use:
;; (begin-for-syntax (set! preexpanding #f))
;; and make these identifiers exported by
;; hyper-literate
(strip-context
#`((require hyper-literate/private/chunks-toc-prefix
(for-syntax racket/base
hyper-literate/private/no-auto-require))
(begin-for-syntax
(set-box! no-auto-require?
#,(if (attribute no-auto-require) #t #f))
(set-box! preexpanding? #f))
(define-syntax-rule (if-preexpanding a b)
b)
(define-syntax-rule (when-preexpanding . b)
(begin))
(define-syntax-rule (unless-preexpanding . b)
(begin . b))
(require scribble-enhanced/with-manual
hyper-literate))))
(begn body0 . body)))))
'())
(require lang)
(continue lang-modbeg
#,(if (attribute chain₊)
#'(chain₊)
#'())
tngl)) ;; TODO: put . tngl and remove the (begin _)
)])))]))
(define-syntax module-begin/plain (make-module-begin #f))
(define-syntax module-begin/doc (make-module-begin #t))

301
private/lp.rkt Normal file
View File

@ -0,0 +1,301 @@
#lang scheme/base
;; Forked from scribble-lib/scribble/private/lp.rkt
(require scribble/decode
scribble-enhanced/with-manual
scribble/struct
(for-syntax scheme/base
syntax/boundmap
syntax/parse
racket/syntax
racket/struct
syntax/srcloc
"../restore-comments.rkt"))
(begin-for-syntax
;; maps chunk identifiers to a counter, so we can distinguish multiple uses
;; of the same name
(define chunk-numbers (make-free-identifier-mapping))
(define (get-chunk-number id)
(free-identifier-mapping-get chunk-numbers id (lambda () #f)))
(define (inc-chunk-number id)
(free-identifier-mapping-put!
chunk-numbers id
(+ 1 (free-identifier-mapping-get chunk-numbers id))))
(define (init-chunk-number id)
(free-identifier-mapping-put! chunk-numbers id 2))
(define repeat-chunk-numbers (make-free-identifier-mapping))
(define (init-repeat-chunk-number id)
(free-identifier-mapping-put! repeat-chunk-numbers id 1))
(define (get-repeat-chunk-number id)
(free-identifier-mapping-get repeat-chunk-numbers
id
(lambda () 1)))
(define (get+increment-repeat-chunk-number! id)
(let ([current (free-identifier-mapping-get repeat-chunk-numbers
id
(lambda () 1))])
;; note: due to multiple expansions, this does not increase exactly one at
;; a time but instead it can skip numbers. Since this is not visible by
;; the user, and just used as a token in the URL, it's okay as long as
;; compiling the same file twice gives the same numbers (which is
;; hopefully the case but hasn't been tested).
(free-identifier-mapping-put! repeat-chunk-numbers id (add1 current))
current)))
(require (for-syntax "no-auto-require.rkt")
"chunks-toc-prefix.rkt")
(define-for-syntax (make-chunk-code unsyntax?)
(syntax-parser
;; no need for more error checking, using chunk for the code will do that
[(_ name:id expr ...)
;; Lift the code so that it is caught by `extract-chunks` in common.rkt
;(syntax-local-lift-expression #'(quote-syntax (a-chunk name expr ...)))
;; Convoluted trick to allow unsyntax in chunks of code. The unsyntax
;; escapes the chunk so that code can be injected at compile-time.
;; The identifiers inside the escaped portion need to be available both
;; for-syntax i.e. (for-meta 1) and (for-meta 0). This is because the
;; underlying @racketblock expands the code at run-time, but the
;; extract-chunks function in common.rkt looks at the expanded source
;; code.
;; For now, only #, i.e. unsyntax is supported, within @chunk.
;; Later support for UNSYNTAX within @CHUNK may be added.
(define expand-unsyntax
(if unsyntax?
;; New hack:
#'((define-syntax (macro-to-expand-unsyntax _)
(define a #'here)
(define b (syntax-local-identifier-as-binding
(syntax-local-introduce #'here)))
(define intr (make-syntax-delta-introducer b a))
(syntax-local-lift-expression
(intr #'(quote-syntax (a-chunk ((... ...) name)
((... ...) expr) ...))
'flip))
#'(void))
(macro-to-expand-unsyntax))
;; Default (old) behaviour, does not support escaping via #,
(begin (syntax-local-lift-expression
#'(quote-syntax (a-chunk name expr ...)))
#f)))
(with-syntax
;; Extract require forms
([((for-label-mod ...) ...)
(if (unbox no-auto-require?)
#'()
(map (lambda (expr)
(syntax-case expr (require)
[(require mod ...)
(let loop ([mods (syntax->list
#'(mod ...))])
(cond
[(null? mods) null]
[else
(syntax-case (car mods)
(for-syntax quote submod)
[(submod ".." . _)
(loop (cdr mods))]
[(submod "." . _)
(loop (cdr mods))]
[(quote x)
(loop (cdr mods))]
[(for-syntax x ...)
(append (loop (syntax->list
#'(x ...)))
(loop (cdr mods)))]
[x
(cons #'x (loop (cdr mods)))])]))]
[else null]))
(syntax->list #'(expr ...))))])
#`(begin
#,@(if expand-unsyntax expand-unsyntax #'())
#,@(if (null? (syntax-e #'(for-label-mod ... ...)))
#'()
#'((require (for-label for-label-mod ... ...))))))]))
(define-for-syntax (strip-source e)
(cond [(syntax? e)
(update-source-location
(datum->syntax e (strip-source (syntax-e e)) e e)
#:source #f)]
[(pair? e) (cons (strip-source (car e)) (strip-source (cdr e)))]
[(vector? e) (list->vector (strip-source (vector->list e)))]
[(prefab-struct-key e)
=> (λ (k) (make-prefab-struct k (strip-source (struct->list e))))]
;; TODO: hash tables
[else e]))
(define-for-syntax (prettify-chunk-name str)
(regexp-replace #px"^<(.*)>$" str "«\\"))
(define-for-syntax ((make-chunk-display racketblock unsyntax-id) stx)
(syntax-parse stx
;; no need for more error checking, using chunk for the code will do that
[(_ {~optional {~seq #:button button}}
(original-before-expr ...)
original-name:id
name:id
stxn:number
expr ...)
(define n (syntax-e #'stxn))
(define original-name:n (syntax-local-introduce
(format-id #'original-name
"~a:~a"
#'original-name
n)))
(define n-repeat (get+increment-repeat-chunk-number!
original-name:n))
(define str (symbol->string (syntax-e #'name)))
(define str-display (prettify-chunk-name str))
(define/with-syntax tag (format "chunk:~a:~a:~a" str n n-repeat))
(define/with-syntax (rest ...)
;; if the would-be-next number for this chunk name is "2", then there is
;; only one chunk, whose number is "1". Otherwise, if the number is 3 or
;; more, it means that the chunk with number "2" exists, so we should
;; display the subscript numbers.
(if (let ([c (get-chunk-number #'original-name)])
(and c (> c 2)))
#`((subscript #,(format "~a" n)))
#'()))
;; Restore comments which have been read by the modified comment-reader
;; and stashed away by read-syntax in "../lang/meta-first-line.rkt"
(define/with-syntax (_ . expr*+comments)
(restore-#%comment #'(original-before-expr ... expr ...)
#:replace-with
(λ (stx)
(syntax-parse stx
#:datum-literals (#%comment)
[({~and #%comment com} . rest)
#:with c-c (datum->syntax #'com 'code:comment #'com #'com)
(datum->syntax stx `(,#'c-c (,unsyntax-id . ,#'rest)) stx stx)]
[other
#'other]))
#:scope #'original-name))
;; The (list) here could be important, to avoid the code being
;; executed multiple times in weird ways, when pre-expanding.
#`(list
(make-splice
(list (make-toc-element
#f
(list (elemtag '(prefixable tag)
(bold (italic (elemref '(prefixable tag)
#:underline? #f
#,str-display rest ...))
" ::="))
#,@(if (attribute button) #'{button} #'{}))
(list (smaller
(make-link-element "plainlink"
(decode-content
(list #,str-display rest ...))
`(elem (prefixable
,@(chunks-toc-prefix)
tag))))))
(#,racketblock
. #,(strip-source #'expr*+comments)))))]))
(define-for-syntax (make-chunk chunk-code chunk-display)
(syntax-parser
;; no need for more error checking, using chunk for the code will do that
[(_ {~optional {~seq #:save-as save-as:id}}
{~optional {~and #:display-only display-only}}
{~optional {~seq #:button button}}
{~and name:id original-before-expr}
expr ...)
#:with (btn ...) (if (attribute button) #'{#:button button} #'{})
(define n (get-chunk-number (syntax-local-introduce #'name)))
(define/with-syntax name:n (format-id #'name "~a:~a" #'name (or n 1)))
(define/with-syntax stripped-name
(regexp-replace #px"^<(.*)>$"
(symbol->string (syntax-e #'name))
"\\1"))
(when n
(inc-chunk-number (syntax-local-introduce #'name)))
(define/with-syntax stx-n (or n 1))
(define/with-syntax stx-chunk-code chunk-code)
(define/with-syntax stx-chunk-display chunk-display)
#`(begin
#,@(if (attribute display-only)
#'{}
#`{(stx-chunk-code name
. #,(if preexpanding?
#'(expr ...)
#'(expr ...)
#;(strip-source #'(expr ...))))})
#,@(if n
#'()
#'((define-syntax name (make-element-id-transformer
(lambda (stx) #'(chunkref name))))
(define-syntax dummy (init-chunk-number #'name))))
#,(if (attribute save-as)
#`(begin
#,#'(define-syntax (do-for-syntax _)
(init-repeat-chunk-number (quote-syntax name:n))
#'(void))
(do-for-syntax)
(define-syntax (save-as s)
(syntax-case s ()
[(_)
(let* ([local-name (syntax-local-introduce
(quote-syntax name))]
[local-name:n (syntax-local-introduce
(quote-syntax name:n))]
[n-repeat (get-repeat-chunk-number
local-name:n)])
(with-syntax
([name-maybe-paren (if (> n-repeat 1)
(format-id local-name
"(~a)"
stripped-name)
local-name)])
#'(save-as name-maybe-paren)))]
[(_ newname)
(with-syntax ([local-name
(syntax-local-introduce
(quote-syntax name))]
[(local-expr (... ...))
(syntax-local-introduce
(quote-syntax #,(strip-source #'(expr ...))))])
#`(stx-chunk-display
btn ...
(original-before-expr)
local-name
newname
stx-n
local-expr (... ...)))])))
;; The (list) here could be important, to avoid the code being
;; executed multiple times in weird ways, when pre-expanding.
#`(list (stx-chunk-display btn ...
(original-before-expr)
name
name
stx-n
. #,(strip-source #'(expr ...))))))]))
(define-syntax chunk-code (make-chunk-code #t))
(define-syntax CHUNK-code (make-chunk-code #f))
(define-syntax chunk-display (make-chunk-display #'racketblock #'unsyntax))
(define-syntax CHUNK-display (make-chunk-display #'RACKETBLOCK #'UNSYNTAX))
(define-syntax chunk (make-chunk #'chunk-code #'chunk-display))
(define-syntax CHUNK (make-chunk #'CHUNK-code #'CHUNK-display))
(define-syntax (chunkref stx)
(syntax-case stx ()
[(_ id)
(identifier? #'id)
(with-syntax ([tag (format "chunk:~a:1:1" (syntax-e #'id))]
[pretty (prettify-chunk-name (format "~a" (syntax-e #'id)))])
#'(elemref '(prefixable tag) #:underline? #f pretty))]))
(provide (all-from-out scheme/base
scribble-enhanced/with-manual)
chunk
CHUNK
chunks-toc-prefix)

View File

@ -0,0 +1,6 @@
#lang racket/base
(provide no-auto-require?)
(define no-auto-require? (box #f))
(provide preexpanding?)
(define preexpanding? (box #f))

3
restore-comments.rkt Normal file
View File

@ -0,0 +1,3 @@
#lang racket
(require "comments/restore-comments.rkt")
(provide restore-#%comment)

View File

@ -1,11 +0,0 @@
scribble-doc
Copyright (c) 2010-2014 PLT Design Inc.
This package is distributed under the GNU Lesser General Public
License (LGPL). This means that you can link this package into proprietary
applications, provided you follow the rules stated in the LGPL. You
can also modify this package; if you distribute a modified version,
you must distribute it under the terms of the LGPL, which in
particular means that you must release the source code for the
modified software. See http://www.gnu.org/copyleft/lesser.html
for more information.

View File

@ -1,28 +0,0 @@
#lang info
(define collection 'multi)
(define build-deps '("racket-index"
"mzscheme-doc"
"net-doc"
"scheme-lib"
"draw-doc"
"gui-doc"
"slideshow-doc"
"pict-doc"
"typed-racket-doc"
"at-exp-lib"
"base"
"compatibility-lib"
"draw-lib"
"pict-lib"
"sandbox-lib"
"slideshow-lib"
"scribble-lib"
"scribble-text-lib"
"racket-doc"))
(define update-implies '("scribble-lib"))
(define pkg-desc "documentation part of \"scribble\"")
(define pkg-authors '(mflatt eli))

View File

@ -1,793 +0,0 @@
#lang scribble/doc
@(require scribble/manual "utils.rkt"
(for-syntax racket/base)
(for-label setup/main-collects
racket/runtime-path))
@(define-syntax def-section-like
(syntax-rules ()
[(_ id result/c x ...)
(defproc (id [#:tag tag (or/c #f string? (listof string?)) #f]
[#:tag-prefix tag-prefix (or/c #f string? module-path?) #f]
[#:style style (or/c style? #f string? symbol? (listof symbol?)) #f]
[pre-content pre-content?] (... ...+))
result/c
x ...)]))
@(define-syntax def-elem-proc
(syntax-rules ()
[(_ id x ...)
(defproc (id [pre-content pre-content?] (... ...))
element?
x ...)]))
@(define-syntax def-style-proc
(syntax-rules ()
[(_ id)
@def-elem-proc[id]{Like @racket[elem], but with style @racket['id].}]))
@title[#:tag "base"]{Base Document Format}
@defmodulelang[scribble/base]{The @racketmodname[scribble/base]
language provides functions and forms that can be used from code
written either in Racket or with @elem["@"] expressions. It
essentially extends @racketmodname[racket/base], except that top-level
forms within a module using the @racketmodname[scribble/base] language
are treated as document content (like @racketmodname[scribble/doclang]).
The @racketmodname[scribble/base] name can also be used as a library
with @racket[require], in which case it provides only the bindings
defined in this section, and it also does not set the reader or
set the default rendering format to the Racket manual format.}
Functions provided by this library, such as @racket[title] and
@racket[italic], might be called from Racket as
@racketblock[
(title #:tag "how-to"
"How to Design " (italic "Great") " Programs")
]
They can also be called with @elem["@"] notation as
@verbatim[#:indent 2]|{
@title[#:tag "how-to"]{How to Design @italic{Great} Programs}
}|
Although the procedures are mostly designed to be used from @elem["@"]
mode, they are easier to document in Racket mode (partly because we
have @racketmodname[scribble/manual]).
@; ------------------------------------------------------------------------
@section{Document Structure}
@defproc[(title [#:tag tag (or/c #f string? (listof string?)) #f]
[#:tag-prefix tag-prefix (or/c #f string? module-path?) #f]
[#:style style (or/c style? #f string? symbol? (listof symbol?)) #f]
[#:version vers (or/c string? #f) #f]
[#:date date (or/c string? #f) #f]
[pre-content pre-content?] ...+)
title-decl?]{
Generates a @racket[title-decl] to be picked up by @racket[decode] or
@racket[decode-part]. The @tech{decode}d @racket[pre-content] (i.e.,
parsed with @racket[decode-content]) supplies the title content. If
@racket[tag] is @racket[#f], a tag string is generated automatically
from the content. The tag string is combined with the symbol
@racket['part] to form the full tag.
The @racket[style] argument can be a style structure, or it can be one
of the following: a @racket[#f] that corresponds to a ``plain'' style,
a string that is used as a @tech{style name}, a symbol that is used as
a @tech{style property}, or a list of symbols to be used as @tech{style properties}.
For information on styles, see @racket[part]. For example, a style of
@racket['toc] causes sub-sections to be generated as separate pages in
multi-page HTML output.
The @racket[tag-prefix] argument is propagated to the generated
structure (see @secref["tags"]). If @racket[tag-prefix] is a module
path, it is converted to a string using
@racket[module-path-prefix->string].
The @racket[vers] argument is propagated to the @racket[title-decl]
structure. Use @racket[""] as @racket[vers] to suppress version
rendering in the output.
The @racket[date] argument is propagated to the @racket[title-decl]
structure via a @racket[document-date] @tech{style property}. Use
@racket[""] as @racket[date] to suppress date rendering in Latex
output.
The section title is automatically indexed by
@racket[decode-part]. For the index key, leading whitespace and a
leading ``A'', ``An'', or ``The'' (followed by more whitespace) is
removed.}
@def-section-like[section part-start?]{ Like @racket[title], but
generates a @racket[part-start] of depth @racket[0] to be by
@racket[decode] or @racket[decode-part].}
@def-section-like[subsection part-start?]{ Like @racket[section], but
generates a @racket[part-start] of depth @racket[1].}
@def-section-like[subsubsection part-start?]{ Like @racket[section], but
generates a @racket[part-start] of depth @racket[2].}
@def-section-like[subsubsub*section paragraph?]{ Similar to
@racket[section], but merely generates a paragraph that looks like an
unnumbered section heading (for when the nesting gets too deep to
include in a table of contents).}
@defform[(include-section module-path)]{ Requires @racket[module-path]
and returns its @racket[doc] export (without making any imports
visible to the enclosing context). Since this form expands to
@racket[require], it must be used in a module or top-level context.}
@defproc[(author [auth content?] ...) block?]{
Generates a @racket[paragraph] with style name @racket['author] to
show the author(s) of a document, where each author is represented by
@tech{content}. Normally, this function is used after
@racket[title] for the beginning of a document. See also
@racket[author+email].}
@defproc[(author+email [author-name content?]
[email string?]
[#:obfuscate? obfuscate? any/c #f])
element?]{
Combines an author name with an e-mail address. If @racket[obfuscate?]
is true, then the result obscures the e-mail address slightly to avoid
address-harvesting robots.
Note that @racket[author+email] is not a replacement for
@racket[author]. The @racket[author+email] function is often used in
combination with @racket[author].}
@; ------------------------------------------------------------------------
@section{Blocks}
@defproc[(para [#:style style (or/c style? string? symbol? #f) #f]
[pre-content pre-content?] ...) paragraph?]{
Creates a @tech{paragraph} containing the @tech{decode}d
@racket[pre-content] (i.e., parsed with @racket[decode-paragraph]).
The @racket[style] argument can be a style, @racket[#f] to indicate a
``plain'' style, a string that is used as a @tech{style name}, or a
symbol that is used as a @tech{style name}. (Note that
@racket[section] and @racket[para] treat symbols differently as
@racket[style] arguments.)}
@defproc[(nested [#:style style (or/c style? string? symbol? #f) #f]
[pre-flow pre-flow?] ...) nested-flow?]{
Creates a @tech{nested flow} containing the @tech{decode}d
@racket[pre-flow] (i.e., parsed with @racket[decode-flow]).
The @racket[style] argument is handled the same as @racket[para]. The
@racket['inset] and @racket['code-inset] styles cause the nested flow
to be inset compared to surrounding text, with the latter
particularly intended for insetting code. The default style is
specified by the output destination (and tends to inset text for HTML
output and not inset for Latex output).}
@defproc[(centered [pre-flow pre-flow?] ...) nested-flow?]{
Produces a @tech{nested flow} whose content is centered.}
@defproc[(margin-note [pre-flow pre-flow?] ...
[#:left? left? any/c #f])
block?]{
Produces a @tech{nested flow} that is typeset in the margin, instead
of inlined.
If @racket[left?] is true, then the note is shown on the opposite as
it would normally be shown (which is the left-hand side for HTML
output). Beware of colliding with output for a table of contents.}
@defproc[(margin-note* [pre-content pre-content?] ...
[#:left? left? any/c #f])
element?]{
Produces an @racket[element] that is typeset in the margin, instead of
inlined. Unlike @racket[margin-note], @racket[margin-note*] can be
used in the middle of a paragraph; at the same time, its content is
constrained to form a single paragraph in the margin.}
@defproc[(itemlist [itm items/c] ...
[#:style style (or/c style? string? symbol? #f) #f])
itemization?]{
Constructs an @racket[itemization] given a sequence of items. Typical
each @racket[itm] is constructed by @racket[item], but an
@racket[itm] can be a @tech{block} that is coerced to an
@racket[item]. Finally, @racket[itm] can be a list or @racket[splice]
whose elements are spliced (recursively, if necessary) into the
@racket[itemlist] sequence.
The @racket[style] argument is handled the same as @racket[para]. The
@racket['ordered] style numbers items, instead of just using a
bullet.}
@defthing[items/c flat-contract?]{
A contract that is equivalent to the following recursive
specification:
@racketblock[
(or/c item? block? (listof items/c) (spliceof items/c))
]}
@defproc[(item [pre-flow pre-flow?] ...) item?]{
Creates an item for use with @racket[itemlist]. The @tech{decode}d
@racket[pre-flow] (i.e., parsed with @racket[decode-flow]) is the item
content.}
@defproc[(item? [v any/c]) boolean?]{
Returns @racket[#t] if @racket[v] is an item produced by
@racket[item], @racket[#f] otherwise.}
@defproc[(tabular [cells (listof (listof (or/c block? content? 'cont)))]
[#:style style (or/c style? string? symbol? #f) #f]
[#:sep sep (or/c block? content? #f) #f]
[#:column-properties column-properties (listof any/c) '()]
[#:row-properties row-properties (listof any/c) '()]
[#:cell-properties cell-properties (listof (listof any/c)) '()])
table?]{
Creates a @tech{table} with the given @racket[cells] content, which is
supplied as a list of rows, where each row has a list of cells. The
length of all rows must match.
Use @racket['cont] in @racket[cells] as a cell to continue the content
of the preceding cell in a row in the space that would otherwise be
used for a new cell. A @racket['cont] must not appear as the first
cell in a row.
The @racket[style] argument is handled the same as @racket[para].
If @racket[sep] is not @racket[#f], it is inserted as a new column
between every column in the table; note that any
@racket[table-columns] or @racket[table-cells] property in
@racket[style] must take the added columns into account. Otherwise,
the default style places no space between table columns. When @racket[sep]
would be placed before a @racket['cont], a @racket['cont] is inserted,
instead.
The @racket[column-properties], @racket[row-properties], and
@racket[cell-properties] arguments specify @tech{style properties} for
the columns and cells of a table; see @racket[table-columns] and
@racket[table-cells] for a description of recognized properties. The
lists do not contain entries for columns potentially introduced for
@racket[sep], and when non-empty, they are extended as needed to match
the table size determined by @racket[cells]:
@itemlist[
@item{If the length of @racket[column-properties] is less than the
length of each row in @racket[cells], the last item of the list
is duplicated to make the list long enough.}
@item{If the length of @racket[row-properties] is less than the
length of @racket[cells], the last item of the list is
duplicated to make the list long enough.}
@item{If the length of @racket[cell-properties] is less than the
number of rows in @racket[cells], then the last element is
duplicated to make the list long enough. Each list within
@racket[cell-properties] is treated like a
@racket[column-properties] list---expanded as needed to match
the number of columns in each row.}
]
Each element of @racket[column-properties] or @racket[row-properties]
is either a list of @tech{style property} values or a non-list element
that is wrapped as a list. Similarly, for each list that is an element
of @racket[cell-properties], the list's non-list elements are wrapped
as nested lists.
If @racket[column-properties] is non-empty, then its list of property
lists is converted into a @racket[table-columns] @tech{style property}
that is added to the style specified by @racket[style]---or merged
with an existing @racket[table-columns] @tech{style property} that
matches the column shape of @racket[cells]. In addition, if either
@racket[row-properties] or @racket[cell-properties] is non-empty, the
property lists of @racket[column-properties] are merged
with the property lists of @racket[row-properties] and
@racket[cell-properties]. If @racket[row-properties] or
@racket[cell-properties] is non-empty, the merged lists are
converted into a @racket[table-cells] @tech{style property} that is
added to the style specified by @racket[style]---or merged with an
existing @racket[table-cells] @tech{style property} that matches the
shape of @racket[cells].
@margin-note{If the style lists for @racket[column-properties] are
both merged with @racket[cell-properties] and converted to
@racket[table-columns], then @racket[style] will contain some
redundant information. In that case, @racket[column-attributes]
properties will be used from @racket[table-columns], while other
properties will be used from the merger into @racket[table-cells].}
@history[#:changed "1.1" @elem{Added the @racket[#:column-properties],
@racket[#:row-properties],
and @racket[#:cell-properties] arguments.}
#:changed "1.12" @elem{Changed @racket[sep] insertion before a
@racket['cont].}]
Examples:
@codeblock[#:keep-lang-line? #f]|{
#lang scribble/manual
@tabular[#:sep @hspace[1]
(list (list "soup" "gazpacho")
(list "soup" "tonjiru"))]
@tabular[#:style 'boxed
#:column-properties '(left right)
#:row-properties '(bottom-border ())
(list (list @bold{recipe} @bold{vegetable})
(list "caldo verde" "kale")
(list "kinpira gobō" "burdock")
(list "makizushi" 'cont))]
}|
@doc-render-examples[
@tabular[#:sep @hspace[1]
(list (list "soup" "gazpacho")
(list "soup" "tonjiru"))]
@tabular[#:style 'boxed
#:column-properties '(left right)
#:row-properties '(bottom-border ())
(list (list @bold{recipe} @bold{vegetable})
(list "caldo verde" "kale")
(list "kinpira gobō" "burdock")
(list "makizushi" 'cont))]]
}
@defproc[(verbatim [#:indent indent exact-nonnegative-integer? 0] [elem content?] ...+)
block?]{
Typesets string @racket[elem]s in typewriter font with linebreaks
specified by newline characters in string @racket[elem]s. Consecutive spaces in
the string @racket[elem]s are converted to @racket[hspace] to ensure that they
are all preserved in the output. Additional space (via
@racket[hspace]) as specified by @racket[indent] is added to the
beginning of each line. A non-string @racket[elem] is treated as
content within a single line.
The string @racket[elem]s are @emph{not} decoded with @racket[decode-content],
so @racket[(verbatim "---")] renders with three hyphens instead of an
em dash. Beware, however, that @emph{reading}
@litchar["@"]@racket[verbatim] converts @litchar["@"] syntax
within the argument, and such reading occurs well before
arguments to @racket[verbatim] are delivered at run-time. To disable simple
@litchar["@"] notation within the @racket[verbatim] argument,
@racket[verbatim] is typically used with
@litchar["|{"]...@litchar["}|"] or similar brackets, like this:
@verbatim[#:indent 2]|{
@verbatim|{
Use @bold{---} like this...
}|
}|
which renders as
@verbatim[#:indent 2]|{
Use @bold{---} like this...
}|
while
@verbatim[#:indent 2]||{
@verbatim|{
Use |@bold{---} like this...
}|
}||
renders as
@verbatim[#:indent 2]|{
Use |@bold{---} like this...
}|
Even with brackets like @litchar["|{"]...@litchar["}|"], beware that consistent
leading whitespace is removed by the parser; see
@secref["alt-body-syntax"] for more information.
See also @racket[literal].}
@; ------------------------------------------------------------------------
@section{Text Styles and Content}
@defproc[(elem [pre-content pre-content?] ...
[#:style style (or/c style? string? symbol? #f) #f])
element?]{
Wraps the @tech{decode}d @racket[pre-content] as an element with style
@racket[style].}
@def-style-proc[italic]
@def-style-proc[bold]
@defproc[(tt [pre-content pre-content?] ...) element?]{
Similar to @racket[elem], but the @racket['tt] style is used for
immediate strings and symbols among the @racket[pre-content]
arguments.
To apply the @racket['tt] style uniformly to all @racket[pre-content]
arguments, use @racket[(elem #:style 'tt pre-content ...)], instead.}
@def-style-proc[subscript]
@def-style-proc[superscript]
@def-elem-proc[smaller]{Like @racket[elem], but with style
@racket['smaller]. When uses of @racket[smaller] are nested, text
gets progressively smaller.}
@def-elem-proc[larger]{Like @racket[elem], but with style
@racket['larger]. When uses of @racket[larger] are nested, text
gets progressively larger.}
@defproc[(emph [pre-content pre-content?] ...) element?]{
The same as @racket[italic].}
@defproc[(literal [str string?] ...+) element?]{
Produces an element containing literally @racket[str]s with no
decoding via @racket[decode-content].
Beware that @litchar["@"] for a @racket[literal] call performs some
processing before delivering arguments to @racket[literal]. The
@racket[literal] form can be used with @litchar["|{"]...@litchar["}|"]
or similar brackets to disable @litchar["@"] notation within the
@racket[literal] argument, like this:
@verbatim[#:indent 2]|{
@literal|{@bold{---}}|
}|
which renders as
@verbatim[#:indent 2]{
@literal|{@bold{---}}|
}
See also @racket[verbatim].}
@; ------------------------------------------------------------------------
@section[#:tag "images"]{Images}
@defproc[(image [path (or/c path-string? (cons/c 'collects (listof bytes?)))]
[#:scale scale real? 1.0]
[#:suffixes suffixes (listof #rx"^[.]") null]
[#:style style (or/c style? string? symbol? #f) #f]
[pre-content pre-content?] ...)
image-element?]{
Creates an image element from the given path. The @tech{decode}d
@racket[pre-content] serves as the alternate text for contexts where
the image cannot be displayed.
If @racket[path] is a relative path, it is relative to the current
directory, which is set by @exec{raco setup} to
the directory of the main document file. (In general, however, it's
more reliable to express relative paths using
@racket[define-runtime-path].) Instead of a path or string,
the @racket[path] argument can be a result of
@racket[path->main-collects-relative].
The @racket[scale] argument sets the images scale relative to its
default size as determined by the content of @racket[path]. For HTML
output, the resulting @racket[image-element] is rendered with an
@tt{img} or @tt{object} (for SVG) tag, and @racket[scale] adjusts the
@tt{width} and @tt{height} attributes; a class name or other
attributes in @racket[style] can effectively override that size.
The strings in @racket[suffixes] are filtered to those supported by
given renderer, and then the acceptable suffixes are tried in
order. The HTML renderer supports @racket[".png"],
@racket[".gif"], and @racket[".svg"], while the Latex renderer supports @racket[".png"],
@racket[".pdf"], and @racket[".ps"] (but @racket[".ps"] works only
when converting Latex output to DVI, and @racket[".png"] and
@racket[".pdf"] work only for converting Latex output to PDF).
Note that when the @racket[suffixes] list is non-empty, then
the @racket[path] argument should not have a suffix.
@history[#:changed "1.3" @elem{Added the @racket[#:style] argument.}]}
@; ------------------------------------------------------------------------
@section[#:tag "spacing"]{Spacing}
@defproc[(linebreak) element?]{
Produces an element that forces a line break.}
@def-elem-proc[nonbreaking]{Like @racket[elem], but line breaks are
suppressed while rendering the content.}
@defproc[(hspace [n exact-nonnegative-integer?]) element?]{
Produces an element containing @racket[n] spaces and style
@racket['hspace].}
@defthing[~ string?]{
A string containing the non-breaking space character,
which is equivalent to @racket['nbsp] as an element.}
@defthing[-~- string?]{
A string containing the non-breaking hyphen character.}
@defthing[?- string?]{
A string containing the soft-hyphen character (i.e., a suggestion of
where to hyphenate a word to break it across lines when rendering).}
@defthing[._ element?]{
Generates a period that ends an abbreviation in the middle of a
sentence, as opposed to a period that ends a sentence (since the
latter may be typeset with extra space). Use @litchar|{@._}| in a
document instead of just @litchar{.} for an abbreviation-ending period
that is preceded by a lowercase letter and followed by a space.
See @racket[.__] for an example.}
@defthing[.__ element?]{
Generates a period that ends a sentence (which may be typeset with
extra space), as opposed to a period that ends an abbreviation in the
middle of a sentence. Use @litchar|{@.__}| in a document instead of just
@litchar{.} for a sentence-ending period that is preceded by an
uppercase letter.
The following example illustrates both @racket[._] and @racket[.__]:
@codeblock|{
#lang scribble/base
My name is Mr@._ T@.__ I pity the fool who can't typeset punctuation.
}|}
@; ------------------------------------------------------------------------
@section[#:tag "base-links"]{Links}
@defproc[(hyperlink [url string?] [pre-content pre-content?] ...
[#:underline? underline? any/c #t]
[#:style style (or/c style? string? symbol? #f) (if underline? #f "plainlink")])
element?]{
The @tech{decode}d @racket[pre-content] is hyperlinked to
@racket[url]. If @racket[style] is not supplied, then
@racket[underline?] determines how the link is rendered.}
@defproc[(url [dest string?]) element?]{
Generates a literal hyperlinked URL.}
@defproc[(secref [tag string?]
[#:doc module-path (or/c module-path? #f) #f]
[#:tag-prefixes prefixes (or/c (listof string?) #f) #f]
[#:underline? underline? any/c #t])
element?]{
Inserts a reference to the section tagged @racket[tag].
If @racket[#:doc module-path] is provided, the @racket[tag] refers to
a tag with a prefix determined by @racket[module-path]. When
@exec{setup-plt} renders documentation, it automatically adds a tag
prefix to the document based on the source module. Thus, for example,
to refer to a section of the Racket reference,
@racket[module-path] would be @racket['(lib
"scribblings/reference/reference.scrbl")].
The @racket[#:tag-prefixes prefixes] argument similarly supports
selecting a particular section as determined by a path of tag
prefixes. When a @racket[#:doc] argument is provided, then
@racket[prefixes] should trace a path of tag-prefixed subsections to
reach the @racket[tag] section. When @racket[#:doc] is not provided,
the @racket[prefixes] path is relative to any enclosing section (i.e.,
the youngest ancestor that produces a match).
For HTML output, the generated reference is the hyperlinked title of
the elements in the section's title content, except that elements with
the @racket['aux] @tech{style property} are omitted in the hyperlink
label. If @racket[underline?] is @racket[#f], then the hyperlink is
rendered in HTML without an underline.
For Latex output, the generated reference's format depends on the
document style. By default, only the section number is shown in the
reference, but the @racketmodname[scribble/manual] style shows the
title after the section number. Customize the output (see
@secref["config"]) by redefining the @ltx{BookRef}, @|etc|, macros (see
@secref["builtin-latex"]).
In Racket documentation that is rendered to HTML, clicking on a
section title normally shows the @racket[secref] call that is needed
to link to the section.}
@defproc[(Secref [tag string?]
[#:doc module-path (or/c module-path? #f) #f]
[#:tag-prefixes prefixes (or/c (listof string?) #f) #f]
[#:underline? underline? any/c #t])
element?]{
Like @racket[secref], but if the rendered form of the reference starts
with a word (e.g., ``section''), then the word is capitalized.}
@defproc[(seclink [tag string?]
[#:doc module-path (or/c module-path? #f) #f]
[#:tag-prefixes prefixes (or/c (listof string?) #f) #f]
[#:underline? underline? any/c #t]
[#:indirect? indirect? any/c #f]
[pre-content pre-content?] ...) element?]{
Like @racket[secref], but the link label is the @tech{decode}d
@racket[pre-content] instead of the target section's name.
In addition to @racket[secref]'s arguments, @racket[seclink] supports
a @racket[indirect?] argument. When @racket[indirect?] is true, then
the section hyperlink's resolution in HTML is potentially delayed; see
@racket['indirect-link] for @racket[link-element].}
@defproc[(other-doc [module-path module-path?]
[#:underline? underline? any/c #t]
[#:indirect indirect (or/c #f content?) #f])
element?]{
Like @racket[secref] for the document's implicit @racket["top"]
tag. Use this function to refer to a whole manual instead of
@racket[secref], in case a special style in the future is used for
manual titles.
If @racket[indirect] is not @racket[#f], then the link's resolution in
HTML can be delayed, like @racket[seclink] with @racket[#:indirect?
#t]. The @racket[indirect] content is prefixed with ``the'' and
suffixed with ``documentation'' to generate the rendered text of the
link. For example:
@verbatim[#:indent 2]|{
@other-doc['(lib "parsack/parsack/parsack.scrbl")
#:indirect "Parsec implementation in Racket"]
}|
renders as a hyperlink with the text:
@verbatim[#:indent 2]|{
the Parsec implementation in Racket documentation
}|}
@defproc[(elemtag [t (or/c tag? string?)] [pre-content pre-content?] ...) element?]{
The tag @racket[t] refers to the content form of
@racket[pre-content].}
@defproc[(elemref [t (or/c tag? string?)] [pre-content pre-content?] ...
[#:underline? underline? any/c #t]) element?]{
The @tech{decode}d @racket[pre-content] is hyperlinked to @racket[t],
which is normally defined using @racket[elemtag].}
@; ------------------------------------------------------------------------
@section[#:tag "base-indexing"]{Indexing}
@defproc[(index [words (or/c string? (listof string?))]
[pre-content pre-content?] ...)
index-element?]{
Creates an index element given a plain-text string---or list of
strings for a hierarchy, such as @racket['("strings" "plain")] for a
``plain'' entry below a more general ``strings'' entry. As index keys,
the strings are ``cleaned'' using @racket[clean-up-index-strings]. The
strings (without clean-up) also serve as the text to render in the
index. The @tech{decode}d @racket[pre-content] is the text to appear
inline as the index target.
Use @racket[index] when an index entry should point to a specific word
or phrase within the typeset document (i.e., the
@racket[pre-content]). Use @racket[section-index], instead, to create
an index entry that leads to a section, instead of a specific word or
phrase within the section.}
@defproc[(index* [words (listof string?)]
[word-contents (listof list?)]
[pre-content pre-content?] ...)
index-element?]{
Like @racket[index], except that @racket[words] must be a list, and
the list of contents render in the index (in parallel to
@racket[words]) is supplied as @racket[word-contents].
}
@defproc[(as-index [pre-content pre-content?] ...)
index-element?]{
Like @racket[index], but the word to index is determined by applying
@racket[content->string] on the @tech{decode}d @racket[pre-content].}
@defproc[(section-index [word string?] ...)
part-index-decl?]{
Creates a @racket[part-index-decl] to be associated with the enclosing
section by @racket[decode]. The @racket[word]s serve as both the keys
and as the rendered forms of the keys within the index.}
@defproc[(index-section [#:tag tag (or/c #f string?) "doc-index"])
part?]{
Produces a part that shows the index the enclosing document. The
optional @racket[tag] argument is used as the index section's tag.}
@; ------------------------------------------------------------------------
@section{Tables of Contents}
@defproc[(table-of-contents) delayed-block?]{
Returns a delayed flow element that expands to a table of contents for
the enclosing section. For Latex output, however, the table of
contents currently spans the entire enclosing document.}
@defproc[(local-table-of-contents [#:style style (or/c symbol? #f) #f])
delayed-block?]{
Returns a delayed flow element that may expand to a table of contents
for the enclosing section, depending on the output type. For
multi-page HTML output, the flow element is a table of contents; for
Latex output, the flow element is empty.
The meaning of the @racket[style] argument depends on the output type,
but @racket['immediate-only] normally creates a table of contents that
contains only immediate sub-sections of the enclosing section. See
also the @racket['quiet] style of @racket[part] (i.e., in a
@racket[part] structure, not supplied as the @racket[style] argument
to @racket[local-table-of-contents]), which normally suppresses
sub-part entries in a table of contents.}
@; ------------------------------------------------------------------------
@section{Tags}
The exports of @racketmodname[scribble/tag] are all re-exported by
@racketmodname[scribble/base].

View File

@ -1,26 +0,0 @@
#lang scribble/manual
@(require "utils.rkt" (for-label (only-in scribble/basic span-class)))
@(define (compat)
@italic{For backward compatibility.})
@title[#:tag "basic"]{Compatibility Basic Functions}
@defmodule[scribble/basic]{The @racketmodname[scribble/basic]
compatibility library mostly just re-exports
@racketmodname[scribble/base].}
@defproc[(span-class [style-name string?] [pre-content any/c] ...)
element?]{
@compat[] Wraps the @tech{decode}d
@racket[pre-content] as an element with style @racket[style-name].}
@defproc[(itemize [itm (or/c whitespace? an-item?)] ...
[#:style style (or/c style? string? symbol? #f) #f])
itemization?]{
@compat[] Like @racket[itemlist], but whitespace strings among the
@racket[itm]s are ignored.}

View File

@ -1,59 +0,0 @@
#lang scribble/doc
@(require scribble/manual "utils.rkt"
(for-label scribble/core
scribble/blueboxes
racket/contract
setup/xref))
@title[#:tag "blueboxes"]{Blue Boxes Utilities}
@defmodule[scribble/blueboxes]{
The @racketmodname[scribble/blueboxes] provides access
to the content of the ``blue boxes'' that describe
some module's export (but without any styling).}
@defproc[(fetch-blueboxes-strs [tag tag?]
[#:blueboxes-cache blueboxes-cache
blueboxes-cache?
(make-blueboxes-cache #t)])
(or/c #f (non-empty-listof string?))]{
Returns a list of strings that show the content of the blue box
(without any styling information) for the documentation referenced
by @racket[tag].
The first string in the list describes the export (e.g. @racket["procedure"]
when @racket[defproc] is used, or @racket["syntax"] when @racket[defform]
was used to document the export).
}
@defproc[(fetch-blueboxes-method-tags [method-name symbol?]
[#:blueboxes-cache blueboxes-cache
blueboxes-cache?
(make-blueboxes-cache #t)])
(listof method-tag?)]{
Returns the list of tags for all methods that are documented in the documentation
in @racket[blueboxes-cache].
@history[#:added "1.11"]
}
@defproc[(make-blueboxes-cache
[populate? boolean?]
[#:blueboxes-dirs blueboxes-dirs (listof path?) (get-doc-search-dirs)])
blueboxes-cache?]{
Constructs a new (mutable) blueboxes cache.
If @racket[populate?] is @racket[#f], the cache is initially
unpopulated, in which case it is filled in the first time the cache
is passed to @racket[fetch-bluebxoes-strs]. Otherwise, the cache is
populated immediately.
The @racket[blueboxes-dirs] argument is a list of directories that are
looked inside for @filepath{blueboxes.rktd} files. The default value
is only an approximation for where those files usually reside. See
also @racket[get-rendered-doc-directories].
}
@defproc[(blueboxes-cache? [v any/c]) boolean?]{
Determines if @racket[v] is a blueboxes cache.
}

View File

@ -1,97 +0,0 @@
#lang scribble/doc
@(require scribble/manual "utils.rkt" scribble/bnf
(for-label scribble/bnf))
@title[#:tag "bnf"]{BNF Grammars}
@defmodule[scribble/bnf]{The @racket[scribble/bnf] library
provides utilities for typesetting grammars.}
For example,
@verbatim[#:indent 2]|{
@(let ([open @litchar{(}]
[close @litchar{)}])
@BNF[(list @nonterm{expr}
@nonterm{id}
@BNF-seq[open @kleeneplus[@nonterm{expr}] close]
@BNF-seq[open @litchar{lambda}
open @kleenestar[@nonterm{id}] close
@nonterm{expr} close]
@nonterm{val})
(list @nonterm{val}
@BNF-alt[@nonterm{number} @nonterm{primop}])
(list @nonterm{id}
@elem{any name except for @litchar{lambda}})])
}|
produces the output
@(let ([open @litchar{(}]
[close @litchar{)}])
@BNF[(list @nonterm{expr}
@nonterm{id}
@BNF-seq[open @kleeneplus[@nonterm{expr}] close]
@BNF-seq[open @litchar{lambda}
open @kleenestar[@nonterm{id}] close
@nonterm{expr} close]
@nonterm{val})
(list @nonterm{val}
@BNF-alt[@nonterm{number} @nonterm{primop}])
(list @nonterm{id}
@elem{any name except for @litchar{lambda}})])
See also @racket[racketgrammar].
@defproc[(BNF [prod (cons element? (listof (or/c block? element?)))] ...) table?]{
Typesets a grammar table. Each production starts with an element
(typically constructed with @racket[nonterm]) for the non-terminal
being defined, and then a list of possibilities (typically constructed
with @racket[BNF-seq], etc.) to show on separate lines.}
@defproc[(nonterm (pre-content any/c) ...) element?]{
Typesets a non-terminal: italic in angle brackets.}
@defproc[(BNF-seq [elem element?] ...) element?]{
Typesets a sequence.}
@defproc[(BNF-seq-lines [elems (listof element?)] ...) block?]{
Typesets a sequence that is broken into multiple lines, where each
@racket[elems] is one line.}
@defproc[(BNF-group [pre-content any/c] ...) element?]{
Typesets a group surrounded by curly braces (so the entire group can
be repeated, for example).}
@defproc[(optional [pre-content any/c] ...) element?]{
Typesets an optional element: in square brackets.}
@defproc[(kleenestar [pre-content any/c] ...) element?]{
Typesets a 0-or-more repetition.}
@defproc[(kleeneplus [pre-content any/c] ...) element?]{
Typesets a 1-or-more repetition.}
@defproc[(kleenerange [n any/c] [m any/c] [pre-content any/c] ...) element?]{
Typesets a @racket[n]-to-@racket[m] repetition. The @racket[n] and
@racket[m] arguments are converted to a string using @racket[(format
"~a" n)] and @racket[(format "~a" m)].}
@defproc[(BNF-alt [elem element?] ...) element?]{
Typesets alternatives for a production's right-hand side to appear on
a single line. The result is normally used as a single possibility in
a production list for @racket[BNF].}
@defthing[BNF-etc string?]{
A string to use for omitted productions or content.}

View File

@ -1,9 +0,0 @@
#lang scribble/manual
@(require "utils.rkt")
@title{Book Format}
@defmodulelang[scribble/book]{The @racketmodname[scribble/book]
language is like @racketmodname[scribble/base], but configured with
Latex style defaults to use the standard @tt{book} class. Top-level
sections are rendered as Latex chapters.}

View File

@ -1,514 +0,0 @@
#lang racket/base
(require (prefix-in etc: mzlib/etc)
texpict/mrpict
(only-in pict pin-line pin-arrow-line)
(except-in texpict/utils pin-line pin-arrow-line)
racket/class
racket/runtime-path
racket/draw
racket/contract
(only-in racket/list last))
(define the-font-size 12)
(define prim-font-family 'swiss)
;; Was 'modern, but we want font smoothing even for small text:
(define font-family (make-object font% the-font-size 'modern 'normal 'normal #f 'smoothed))
(define prim-types '("int" "String" "float" "double" "boolean"))
;; how far a dot is to the right of a class
(define dot-edge-spacing 10)
(define field-arrowhead-size 10)
(define hierarchy-color "navy")
(define type-link-color "firebrick")
#|
(define font-family "Palatino")
(define-runtime-path afm "afm")
(current-ps-afm-file-paths (cons afm (current-ps-afm-file-paths)))
(let ([id (send the-font-name-directory find-or-create-font-id font-family 'default)])
(send the-font-name-directory set-post-script-name
id 'normal 'normal "Palatino-Roman")
(send the-font-name-directory set-post-script-name
id 'bold 'normal "Palatino-Bold")
(send the-font-name-directory set-post-script-name
id 'normal 'italic "Palatino-Italic"))
|#
(define (user-type-font x) (text x font-family the-font-size))
(define (prim-type-font x) (text x prim-font-family the-font-size))
(define (var-font x) (text x `(bold . ,font-family) the-font-size))
(define (field-name-font x) (text x font-family the-font-size))
(define (comment-font x) (text x font-family the-font-size))
(define (normal-font x) (text x font-family the-font-size))
(define (java-this) (text "this" `(bold . ,font-family) the-font-size))
;; field-spec : string string -> pict
(define (field-spec type fd #:default [default #f] [comment #f])
(let ([code-line
(hbl-append (if type
(hbl-append (type-spec type)
(normal-font " "))
(blank))
(field-name-font fd)
(if default
(hbl-append (normal-font " = ")
(normal-font default))
(blank))
#;
(normal-font ";"))])
(if comment
(hbl-append code-line
(normal-font " ")
(comment-font (format "[in ~a]" comment)))
code-line)))
(define (method-spec range name #:body [body #f] . args)
(unless (even? (length args))
(error 'method-spec "expected a list of types and argument names, but found ~a arguments"
(length args)))
(let ([first-line
(hbl-append
(type-spec range)
(normal-font " ")
(var-font name)
(cond
[(null? args)
(normal-font "()")]
[else
(hbl-append
(normal-font "(")
(let loop ([args args])
(let* ([type (car args)]
[param (cadr args)]
[single-arg
(if param
(hbl-append (type-spec type)
(normal-font " ")
(var-font param))
(type-spec type))])
(cond
[(null? (cddr args))
(hbl-append single-arg (normal-font ")"))]
[else
(hbl-append single-arg
(normal-font ", ")
(loop (cddr args)))]))))])
(if body
(hbl-append (normal-font " {"))
(blank)))])
(if body
(vl-append first-line
(hbl-append (blank 8 0) body (normal-font "}")))
first-line)))
(define (type-spec str)
(cond
[(member str prim-types) (prim-type-font str)]
[else (user-type-font str)]))
;; class-name : string -> pict
(define (class-name txt #:spacing-word [spacing-word txt])
(define p (colorize (lt-superimpose (ghost (var-font spacing-word))
(apply vl-append (map var-font (regexp-split #rx"\n" txt))))
"white"))
(refocus (cc-superimpose (colorize (filled-rectangle (+ class-box-margin class-box-margin (pict-width p))
(+ class-box-margin class-box-margin (pict-height p)))
"black")
p)
p))
(define class-box-margin 4)
;; class-box : pict (or/c #f (listof pict)) (or/c #f (listof pict)) -> pict
(define (class-box name fields methods)
(let* ([mk-blank (λ () (blank 0 (+ class-box-margin class-box-margin)))])
(cond
[(and methods fields)
(let* ([top-spacer (mk-blank)]
[bottom-spacer (mk-blank)]
[main (vl-append name
top-spacer
(if (null? fields)
(blank 0 4)
(apply vl-append fields))
bottom-spacer
(if (null? methods)
(blank 0 4)
(apply vl-append methods)))])
(add-hline
(add-hline (frame (inset main class-box-margin))
top-spacer)
bottom-spacer))]
[fields
(let* ([top-spacer (mk-blank)]
[main (vl-append name
top-spacer
(if (null? fields)
(blank)
(apply vl-append fields)))])
(add-hline (frame (inset main class-box-margin))
top-spacer))]
[methods (class-box name methods fields)]
[else (frame (inset name class-box-margin))])))
(define (add-hline main sub)
(let-values ([(x y) (cc-find main sub)])
(pin-line main
sub (λ (p1 p2) (values 0 y))
sub (λ (p1 p2) (values (pict-width main) y)))))
;; hierarchy : pict (cons pict (listof pict)) (cons pict (listof pict)) -> pict
(define (hierarchy main supers subs)
(let ([supers-bottoms (apply max (map (λ (x) (let-values ([(x y) (cb-find main x)]) y)) supers))]
[subs-tops (apply min (map (λ (x) (let-values ([(x y) (ct-find main x)]) y)) subs))]
[sorted-subs (sort subs (λ (x y) (< (left-edge-x main x) (left-edge-x main y))))])
(unless (< supers-bottoms subs-tops)
(error 'hierarchy "expected supers to be on top of subs, supers bottom is at ~a, and subs tops is at ~a"
supers-bottoms
subs-tops))
(let* ([main-line-y (max (- subs-tops 20) (/ (+ supers-bottoms subs-tops) 2))]
[main-line-start-x (center-x main (car sorted-subs))]
[main-line-end-x (center-x main (last sorted-subs))]
[w/main-line
(pin-line main
main (λ (_1 _2) (values main-line-start-x main-line-y))
main (λ (_1 _2) (values main-line-end-x main-line-y))
#:color hierarchy-color)]
[super-lines
(map (λ (super)
(let-values ([(x y) (cb-find main super)])
(pin-over
(pin-line (ghost main)
super cb-find
main (λ (_1 _2) (values x main-line-y)))
(- x (/ (pict-width triangle) 2))
(- (/ (+ y main-line-y) 2)
(/ (pict-height triangle) 2))
triangle)))
supers)]
[sub-lines
(map (λ (sub)
(let-values ([(x y) (ct-find main sub)])
(pin-line (ghost main)
sub ct-find
main (λ (_1 _2) (values x main-line-y))
#:color hierarchy-color)))
subs)])
(apply cc-superimpose
w/main-line
(append sub-lines
super-lines)))))
(define triangle-width 12)
(define triangle-height 12)
(define triangle
(let ([points (list (make-object point% (/ triangle-width 2) 0)
(make-object point% 0 triangle-height)
(make-object point% triangle-width triangle-height))])
(colorize
(dc (λ (dc dx dy)
(let ([brush (send dc get-brush)])
(send dc set-brush (send brush get-color) 'solid)
(send dc draw-polygon points dx dy)
(send dc set-brush brush)))
triangle-width
triangle-height)
hierarchy-color)))
(define (center-x main pict)
(let-values ([(x y) (cc-find main pict)])
x))
(define (left-edge-x main pict)
(let-values ([(x y) (lc-find main pict)])
x))
(define (add-dot-right main class field) (add-dot-left-right/offset main class field 0 rc-find))
(define add-dot-right/space
(λ (main class field [count 1])
(add-dot-right/offset main class field (* count dot-edge-spacing))))
(define (add-dot-right/offset main class field offset)
(add-dot-left-right/offset main class field offset rc-find))
(define (add-dot-left main class field) (add-dot-left-right/offset main class field 0 lc-find))
(define add-dot-left/space
(λ (main class field [count 1])
(add-dot-left/offset main class field (* count (- dot-edge-spacing)))))
(define (add-dot-left/offset main class field offset)
(add-dot-left-right/offset main class field offset lc-find))
(define (add-dot-left-right/offset main class field offset finder)
(let-values ([(_1 y) (cc-find main field)]
[(x-edge _2) (finder main class)])
(add-dot main (+ x-edge offset) y)))
(define add-dot-junction
(case-lambda
[(main x-pict y-pict) (add-dot-junction main x-pict cc-find y-pict cc-find)]
[(main x-pict x-find y-pict y-find)
(let-values ([(x _1) (x-find main x-pict)]
[(_2 y) (y-find main y-pict)])
(add-dot main x y))]))
(define (add-dot-offset pict dot dx dy)
(let-values ([(x y) (cc-find pict dot)])
(add-dot pict (+ x dx) (+ y dy))))
(define dot-δx (make-parameter 0))
(define dot-δy (make-parameter 0))
(define (add-dot pict dx dy)
(let ([dot (blank)])
(values (pin-over pict
(+ dx (dot-δx))
(+ dy (dot-δy))
dot)
dot)))
(define (connect-dots show-arrowhead? main dot1 . dots)
(let loop ([prev-dot dot1]
[dots dots]
[pict main])
(cond
[(null? dots) pict]
[else
(loop (car dots)
(cdr dots)
(connect-two-dots pict prev-dot (car dots) (null? (cdr dots)) show-arrowhead?))])))
(define (connect-two-dots pict dot1 dot2 arrowhead? show-arrowhead?)
(if arrowhead?
(pin-arrow-line field-arrowhead-size pict
dot1 cc-find
dot2 cc-find
#:hide-arrowhead? (not show-arrowhead?)
#:color type-link-color)
(pin-line pict
dot1 cc-find
dot2 cc-find
#:color type-link-color)))
(define (hierarchy/layout tops bottoms
#:every-other-space [every-other-space 0]
#:top-space [top-space 40]
#:bottom-space [bottom-space 40]
#:vertical-space [vertical-space 60])
(hierarchy
(vc-append (apply ht-append top-space tops)
(blank 0 vertical-space)
(apply ht-append bottom-space
(let loop ([bottoms bottoms]
[every-other? #f])
(cond
[(null? bottoms) '()]
[else
(cons (if every-other?
(vc-append (blank 0 every-other-space)
(car bottoms))
(car bottoms))
(loop (cdr bottoms)
(not every-other?)))]))))
tops
bottoms))
(define (add-dot-delta f dx dy)
(parameterize ([dot-δx dx]
[dot-δy dy])
(f)))
(define (right-right-reference main0 start-class start-field finish-class finish-name
[count 1]
#:connect-dots [connect-dots connect-dots]
#:dot-delta [dot-delta 0])
(let ([going-down? (let-values ([(_1 start-y) (find-cc main0 start-field)]
[(_2 finish-y) (find-cc main0 finish-name)])
(< start-y finish-y))])
(define-values (main1 dot1) (add-dot-delta (λ () (add-dot-right main0 start-class start-field))
0
(if going-down?
dot-delta
(- dot-delta))))
(define-values (main2 dot2) (add-dot-delta (λ () (add-dot-right/space main1 start-class start-field count))
dot-delta
(if going-down?
dot-delta
(- dot-delta))))
(define-values (main3 dot3) (add-dot-delta (λ () (add-dot-right main2 finish-class finish-name))
0
(if going-down?
(- dot-delta)
dot-delta)))
(define-values (main4 dot4) (add-dot-delta (λ () (add-dot-junction main3 dot2 dot3))
0
0))
;; these last two dots are just there for the delta-less arrowhead
(define-values (main5 dot5) (add-dot-right main4 finish-class finish-name))
(define-values (main6 dot6) (add-dot-delta (λ () (add-dot-right main5 finish-class finish-name))
1 ;; just enough to get the arrowhead going the right direction; not enough to see the line
0))
(connect-dots
#t
(connect-dots #f main6 dot1 dot2 dot4 dot3)
dot6
dot5)))
(define left-left-reference
(λ (main0 start-class start-field finish-class finish-name [count 1]
#:connect-dots [connect-dots connect-dots]
#:dot-delta [dot-delta 0])
(let ([going-down? (let-values ([(_1 start-y) (find-cc main0 start-field)]
[(_2 finish-y) (find-cc main0 finish-name)])
(< start-y finish-y))])
(define-values (main1 dot1) (add-dot-delta (λ () (add-dot-left main0 start-class start-field))
0
(if going-down?
dot-delta
(- dot-delta))))
(define-values (main2 dot2) (add-dot-delta (λ () (add-dot-left/space main1 start-class start-field count))
(- dot-delta)
(if going-down?
dot-delta
(- dot-delta))))
(define-values (main3 dot3) (add-dot-delta (λ () (add-dot-left main2 finish-class finish-name))
0
(if going-down?
(- dot-delta)
dot-delta)))
(define-values (main4 dot4) (add-dot-delta (λ () (add-dot-junction main3 dot2 dot3))
0
0))
(define-values (main5 dot5) (add-dot-left main4 finish-class finish-name))
(define-values (main6 dot6) (add-dot-delta (λ () (add-dot-left main5 finish-class finish-name))
-1 ;; just enough to get the arrowhead going the right direction; not enough to see the line
0))
(connect-dots
#t
(connect-dots #f main6 dot1 dot2 dot4 dot3)
dot6
dot5))))
(define left-top-reference
(λ (main0 start-class start-field finish-class [count 1] #:connect-dots [connect-dots connect-dots])
(define-values (main1 dot1) (add-dot-left main0 start-class start-field))
(define-values (main2 dot2) (add-dot-left/space main1 start-class start-field count))
(define-values (main3 dot3) (add-dot-junction main2 dot2 cc-find finish-class ct-find))
(connect-dots #t main3 dot1 dot2 dot3)))
(define right-left-reference
(λ (main0 start-class start-field finish-class finish-name
[offset
(find-middle main0 start-class rc-find finish-class lc-find)]
#:connect-dots [connect-dots connect-dots])
(define-values (main1 dot1) (add-dot-right main0 start-class start-field))
(define-values (main2 dot2) (add-dot-right/offset main1 start-class start-field offset))
(define-values (main3 dot3) (add-dot-left main2 finish-class finish-name))
(define-values (main4 dot4) (add-dot-junction main3 dot2 dot3))
(connect-dots #t main4 dot1 dot2 dot4 dot3)))
(define left-right-reference
(λ (main0 start-class start-field finish-class finish-name
[offset
(- (find-middle main0 start-class lc-find finish-class rc-find))]
#:connect-dots [connect-dots connect-dots])
(define-values (main1 dot1) (add-dot-left main0 start-class start-field))
(define-values (main2 dot2) (add-dot-left/offset main1 start-class start-field offset))
(define-values (main3 dot3) (add-dot-right main2 finish-class finish-name))
(define-values (main4 dot4) (add-dot-junction main3 dot2 dot3))
(connect-dots #t main4 dot1 dot2 dot4 dot3)))
(define (find-middle main p1 find1 p2 find2)
(let-values ([(x1 y1) (find1 main p1)]
[(x2 y2) (find2 main p2)])
(- (/ (+ x1 x2) 2) (min x1 x2))))
(define right-top-reference
(λ (main0 start-class start-field finish-class [count 1] #:connect-dots [connect-dots connect-dots])
(define-values (main1 dot1) (add-dot-right main0 start-class start-field))
(define-values (main2 dot2) (add-dot-right/space main1 start-class start-field count))
(define-values (main3 dot3) (add-dot-junction main2 dot2 cc-find finish-class ct-find))
(connect-dots #t main3 dot1 dot2 dot3)))
(define connect-dots-contract (->* (boolean? pict? pict?) () #:rest (listof pict?) (values pict?)))
(provide type-link-color)
(provide/contract
[field-spec (->* ((or/c #f string?) string?) (string? #:default string?) pict?)]
[class-name (->* (string?) (#:spacing-word string?) pict?)]
[class-box (-> pict? (or/c false/c (listof pict?)) (or/c false/c (listof pict?)) pict?)]
[hierarchy/layout
(->* ((cons/c pict? (listof pict?)) (cons/c pict? (listof pict?)))
(#:top-space
integer?
#:bottom-space integer?
#:vertical-space integer?
#:every-other-space integer?)
pict?)]
[user-type-font (-> string? pict?)]
[prim-type-font (-> string? pict?)]
[var-font (-> string? pict?)]
[normal-font (-> string? pict?)]
[comment-font (-> string? pict?)]
[hierarchy (-> pict?
(cons/c pict? (listof pict?))
(cons/c pict? (listof pict?))
pict?)]
[right-right-reference (->* (pict? pict? pict? pict? pict?)
(number?
#:connect-dots connect-dots-contract
#:dot-delta number?)
pict?)]
[left-left-reference (->* (pict? pict? pict? pict? pict?)
(number?
#:connect-dots connect-dots-contract
#:dot-delta number?)
pict?)]
[right-left-reference (->* (pict? pict? pict? pict? pict?)
(number?
#:connect-dots connect-dots-contract)
pict?)]
[left-right-reference (->* (pict? pict? pict? pict? pict?)
(number?
#:connect-dots connect-dots-contract)
pict?)]
[left-top-reference (->* (pict? pict? pict? pict?)
(number?
#:connect-dots connect-dots-contract)
pict?)]
[right-top-reference (->* (pict? pict? pict? pict?)
(number?
#:connect-dots connect-dots-contract)
pict?)]
[dot-edge-spacing number?]
[connect-dots connect-dots-contract]
[add-dot-right (-> pict? pict? pict? (values pict? pict?))]
[add-dot-right/space (-> pict? pict? pict? (values pict? pict?))]
[add-dot-left (-> pict? pict? pict? (values pict? pict?))]
[add-dot-left/space (-> pict? pict? pict? (values pict? pict?))]
[add-dot-junction
(case->
(-> pict? pict? pict? (values pict? pict?))
(-> pict?
pict? (-> pict? pict? (values number? number?))
pict? (-> pict? pict? (values number? number?))
(values pict? pict?)))]
[add-dot-offset (-> pict? pict? number? number? (values pict? pict?))]
[add-dot (-> pict? number? number? (values pict? pict?))]
[method-spec
(->* (string? string?)
(#:body (or/c false/c pict?))
#:rest (listof (or/c false/c string?))
pict?)]
[java-this (-> pict?)]
[field-arrowhead-size number?])

View File

@ -1,6 +0,0 @@
#lang scribble/manual
@title{Compatibility Libraries}
@include-section["struct.scrbl"]
@include-section["basic.scrbl"]

View File

@ -1,654 +0,0 @@
#lang scribble/doc
@(require scribble/manual scribble/core scribble/decode
scribble/html-properties scribble/latex-properties
"utils.rkt"
(for-label racket/base
scribble/latex-prefix))
@(define (fake-title . str) (apply bold str))
@(define (css s) (tt s))
@(define spacer @hspace[1])
@(define baseline (style #f '(baseline)))
@(define-syntax-rule (css-table [name desc] ...)
(tabular
#:style (style #f (list (table-columns (list baseline baseline baseline baseline))))
(list (list spacer name spacer @smaller[desc]) ...)))
@; ------------------------------------------------------------
@title[#:tag "config" #:style 'toc]{Extending and Configuring Scribble Output}
Sometimes, Scribble's primitives and built-in styles are insufficient
to produce the output that you need. The cases in which you need to
extend or configure Scribble fall into two groups:
@itemize[
@item{You may need to drop into the back-end ``language'' of CSS or
Latex to create a specific output effect. For this kind of
extension, you will mostly likely attach a
@racket[css-addition] or @racket[tex-addition] @tech{style property}
to style, where the addition implements the style name. This
kind of extension is described in @secref["extra-style"].}
@item{You may need to produce a document whose page layout is
different from the Racket documentation style. For that
kind of configuration, you can run the @exec{scribble} command-line
tool and supply flags like @DFlag{prefix} or @DPFlag{style}, or
you can associate a @racket[html-defaults] or
@racket[latex-defaults] @tech{style property} to the main document's
style. This kind of configuration is described in
@secref["config-style"].}
]
@local-table-of-contents[]
@; ------------------------------------------------------------
@section[#:tag "extra-style"
#:style (make-style #f (list (make-css-addition "inbox.css")
(make-tex-addition "inbox.tex")))
]{Implementing Styles}
When a string is used as a style in an @racket[element],
a @racket[multiarg-element], @racket[paragraph], @racket[table],
@racket[itemization], @racket[nested-flow], or
@racket[compound-paragraph], it corresponds to a CSS class for HTML
output or a Latex macro/environment for Latex output. In Latex output,
the string is used as a command name for a @racket[paragraph]
and an environment name for a @racket[table], @racket[itemization],
@racket[nested-flow], or @racket[compound-paragraph]; if the style has
a @racket['command] @tech{style property} for a @racket[nested-flow] or
@racket[compound-paragraph], then the style name is used as a command
instead of an environment; and if the style has
a @racket['multicommand] @tech{style property} for a @racket[nested-flow],
then the style name is used as a command with multiple arguments.
In addition, for an itemization, the style
string is suffixed with @racket["Item"] and used as a CSS class or Latex
macro name to use for the itemization's items (in place of @ltx{item}
in the case of Latex).
To add a mapping from your own style name to a CSS configuration, add
a @racket[css-addition] structure instance to a style's @tech{style property}
list. To map a style name to a Latex macro or environment, add a
@racket[tex-addition] structure instance. A @racket[css-addition] or
@racket[tex-addition] is normally associated with the style whose name
is implemented by the adition, but it can also be added to the style
for an enclosing part.
Scribble includes a number of predefined styles that are used by the
exports of @racket[scribble/base]. You can use them or redefine
them. The styles are specified by @filepath{scribble.css} and
@filepath{scribble.tex} in the @filepath{scribble} collection.
The styles used by @racketmodname[scribble/manual] are implemented by
@filepath{racket.css} and @filepath{racket.tex} in the
@filepath{scribble} collection. Other libraries, such as
@racketmodname[scriblib/autobib], similarly implement styles through files
that are associated by @racket[css-addition] and @racket[tex-addition]
@tech{style properties}.
To avoid collisions with future additions to Scribble, start your
style name with an uppercase letter that is not @litchar{S}. An
uppercase letter helps to avoid collisions with macros defined by
Latex packages, and future styles needed by @racketmodname[scribble/base] and
@racketmodname[scribble/manual] will start with @litchar{S}.
For example, a Scribble document
@verbatim[#:indent 2]|{
#lang scribble/manual
@(require scribble/core
scribble/html-properties
scribble/latex-properties)
@(define inbox-style
(make-style "InBox"
(list (make-css-addition "inbox.css")
(make-tex-addition "inbox.tex"))))
@title{Quantum Pet}
Do not open: @elem[#:style inbox-style]{Cat}
}|
combined with an @filepath{inbox.css} that contains
@verbatim[#:indent 2]|{
.InBox {
padding: 0.2em;
border: 1px solid #000000;
}
}|
and an @filepath{inbox.tex} that contains
@verbatim[#:indent 2]|{
\newcommand{\InBox}[1]{\fbox{#1}}
}|
generates
@nested[#:style 'inset]{
@fake-title{Quantum Pet}
Do not open: @elem[#:style "InBox"]{Cat}
}
@index["HTML Tags and Attributes"]{
Scribble documents can also embed specific html tags and
attributes.} For example, this Scribble document:
@codeblock|{
#lang scribble/base
@(require scribble/core
scribble/html-properties)
@(define external-image
(elem
#:style
(style #f
(list (alt-tag "img")
(attributes
'((src . "http://racket-lang.org/icon.png")))))))
@external-image
}|
renders as the the Racket logo at the url
@url{http://racket-lang.org/logo.png}
when producing html.
@; ------------------------------------------------------------
@section[#:tag "config-style"]{Configuring Output}
The implementation of styles used by libraries depends to some degree
on separately configurable parameters, and configuration is also
possible by replacing style implementations. Latex output is more
configurable in the former way, since a document class determines a
set of page-layout and font properties that are used by other
commands. The style-replacement kind of configuration corresponds to
re-defining Latex macros or overriding CSS class attributes. When
@exec{setup-plt} builds PDF documentation, it uses both kinds of
configuration to produce a standard layout for Racket manuals;
that is, it selects a particular page layout, and it replaces some
@racketmodname[racket/base] styles.
Two kinds of files implement the two kinds of configuration:
@itemize[
@item{A @deftech{prefix file} determines the @tt{DOCTYPE} line for
HTML output or the @ltx{documentclass} configuration (and
perhaps some addition package uses or other configurations) for
Latex output.
The default prefix files are @filepath{scribble-prefix.html}
and @filepath{scribble-prefix.tex} in the @filepath{scribble}
collection.}
@item{A @deftech{style file} refines the implementation of styles
used in the document---typically just the ``built-in'' styles
used by @racketmodname[scribble/base].
The default style files, @filepath{scribble-style.css} and
@filepath{scribble-style.tex} in the @filepath{scribble}
collection, change no style implementations.}
]
For a given configuration of output, typically a particular prefix
file works with a particular style file. Some prefix or style files
may be more reusable. For now, reading the default files is the best
way to understand how they interact. A prefix and/or style file may
also require extra accomanying files; for example, a prefix file for
Latex mode may require a corresponding Latex class file. The default
prefix and style files require no extra files.
When rendering a document through the @exec{scribble} command-line
tool, use flags to select a prefix file, style file, and additional
accompanying files:
@itemize[
@item{Select the prefix file using the @as-index{@DFlag{prefix}}
flag. (Selecting the prefix file also cancels the default list
of accompanying files, if any.)}
@item{Replace the style file using the @as-index{@DFlag{style}}
flag. Add additional style definitions and re-definitions using
the @as-index{@DPFlag{style}} flag.}
@item{Add additional accompanying files with @as-index{@DPFlag{extra}}.}
]
When using the @exec{scribble} command-line utility, a document can
declare its default style, prefix, and extra files through a
@racket[html-defaults] and/or @racket[latex-defaults]
@tech{style property}. In particular, when using the @exec{scribble}
command-line tool to generate Latex or PDF a document whose main part
is implemented with @racket[#, @hash-lang[] #,
@racketmodname[scribble/manual]], the result has the standard
Racket manual configuration, because @racketmodname[scribble/manual]
associates a @racket[latex-defaults] @tech{style property} with the exported
document. The @racketmodname[scribble/sigplan] language similarly
associates a default configuration with an exported document. As
libraries imported with @racket[require], however,
@racketmodname[scribble/manual] and @racketmodname[scribble/sigplan]
simply implement new styles in a composable way.
Whether or not a document has a default prefix- and style-file
configuration through a @tech{style property}, the defaults can be
overridden using @exec{scribble} command-line flags. Furthermore,
languages like @racketmodname[scribble/manual] and
@racketmodname[scribble/sigplan] add a @racket[html-defaults] and/or
@racket[latex-defaults] @tech{style property} to a main-document part only if
it does not already have such a property added through the
@racket[#:style] argument of @racket[title].
@; ------------------------------------------------------------
@section[#:tag "builtin-css"]{Base CSS Style Classes}
The following renderings of @elem[#:style (style #f (list
(link-resource "demo.scrbl")))]{@filepath{demo.scrbl}} demonstrate all
of the CSS style classes used by @racketmodname[scribble/base] forms and
functions:
@itemlist[
@item{@other-doc['(lib "scribblings/scribble/demo-s1.scrbl")] shows
the default style in a single-page rendering without a search
box.}
@item{@other-doc['(lib "scribblings/scribble/demo-m1.scrbl")] shows
the default style in a multi-page rendering without a search
box.}
@item{@other-doc['(lib "scribblings/scribble/demo-s2.scrbl")] shows
the current manual style's adjustments in a single-page
rendering with a search box.}
@item{@other-doc['(lib "scribblings/scribble/demo-m2.scrbl")] shows
the current manual style's adjustments in a multi-page
rendering with a search box.}
]
The style classes:
@(css-table
[@css{maincolumn} @elem{Outer wrapper for all content in the main column.}]
[@css{main} @elem{Inner wrapper for all content in the main column, including navigation bars.}]
[@spacer @spacer]
[@css{refpara} @elem{Outer wrapper for right-hand @racket[margin-note] notes.}]
[@css{refparaleft} @elem{Outer wrapper for left-hand @racket[margin-note] notes.}]
[@css{refelem} @elem{Outer wrapper for right @racket[margin-note*] notes.}]
[@css{refelemleft} @elem{Outer wrapper for left-hand @racket[margin-note*] notes.}]
[@css{refcolumn} @elem{Middle wrapper for right-hand @racket[margin-note] and @racket[margin-note*] notes.}]
[@css{refcolumnleft} @elem{Middle wrapper for left-hand @racket[margin-note] and @racket[margin-note*] notes.}]
[@css{refcontent} @elem{Inner wrapper for @racket[margin-note] and @racket[margin-note*] notes.}]
[@spacer @spacer]
[@css{tocset} @elem{Groups table-of-contents panels: main and ``on this page.''}]
[@spacer @spacer]
[@css{tocview} @elem{Wraps the main (multi-page mode) or only (single-page mode) table-of-contents panel.}]
[@css{tocviewlist} @elem{A hierarchical layer of content in a main table-of-contents panel.}]
[@css{tocviewlisttopspace} @elem{With @css{tocviewlist} for the first layer.}]
[@css{tocviewtoggle} @elem{The always-visible name of a layer.}]
[@css{tocviewtitle} @elem{With @css{tocviewtoggle} for the first layer.}]
[@css{tocviewsublist} @elem{An item in a layer that has multiple items and more items before and after.}]
[@css{tocviewsublistonly} @elem{An item in a single-item layer.}]
[@css{tocviewsublisttop} @elem{The first item in a multi-item layer.}]
[@css{tocviewsublistbottom} @elem{The last item in a multi-item layer.}]
[@css{tocviewlink} @elem{Inner wrapper for an item in a layer when linked to a different page.}]
[@css{tocviewselflink} @elem{Inner wrapper for every item in a layer when linked to the same page.}]
[@spacer @spacer]
[@css{tocsub} @elem{Wraps the ``on this page'' (multi-page mode only) table-of-contents panel.}]
[@css{tocsubtitle} @elem{Wraps the words ``on this page''.}]
[@css{tocsublist} @elem{Inner table for the ``on this page'' panel.}]
[@css{tocsublinknumber} @elem{Number for an entry in an ``on this page'' panel.}]
[@css{tocsubseclink} @elem{Title for a @emph{section} entry in an ``on this page'' panel.}]
[@css{tocsubnonseclink} @elem{Title for a @emph{non-section} entry in an ``on this page'' panel
that has some section links.}]
[@css{tocsublink} @elem{Title for a @emph{non-section} entry in an ``on this page'' panel
that has no section links.}]
[@css{toctoplink} @elem{Top-level entry in an inline (not the panel) table of contents.}]
[@css{toclink} @elem{Nested entry in an inline (not the panel) table of contents.}]
[@spacer @spacer]
[@css{versionbox} @elem{Outer wrapper for version}]
[@css{version} @elem{Inner wrapper for version in the case of search box and/or navigation.}]
[@css{versionNoNav} @elem{Inner wrapper for version in the acse of no search box and navigation.}]
[@spacer @spacer]
[@css{SAuthorListBox} @elem{Outer wrapper for the author list.}]
[@css{SAuthorList} @elem{Inner wrapper for the author list.}]
[@css{author} @elem{Wrapper for an individual author.}]
[@spacer @spacer]
[@css{navsettop} @elem{Wraps the top navigation bar (in multi-page mode or when a search bar is present).}]
[@css{navsetbottom} @elem{Wraps the bottom navigation bar (in multi-page mode or when a search bar is present).}]
[@css{navleft} @elem{Wraps left-side elements within a navigation bar.}]
[@css{navright} @elem{Wraps right-side elements within a navigation bar.}]
[@css{nonavigation} @elem{Disabled links within a navigation bar.}]
[@css{searchform} @elem{Outer wrapper for a search box within the top navigation bar.}]
[@css{searchbox} @elem{Inner wrapper for a search box within the top navigation bar.}]
[@css{nosearchform} @elem{Takes the place of an absent search box within the top navigation bar.}]
[@spacer @spacer]
[@css{SSubSubSubSection} @elem{Deeply nested subsection (below @tt{<h5>}).}]
[@spacer @spacer]
[@css{SIntrapara} @elem{Used with @tt{<div>} instead of @tt{<p>} for a paragraph
within a @racket[compound-paragraph].}]
[@spacer @spacer]
[@css{SubFlow} @elem{For a @racket[nested-flow] with no style name: no inset.}]
[@css{SCodeFlow} @elem{For a @racket[nested-flow] with the @racket['code-inset] style name:
inset suitable for code.}]
[@css{SVInsetFlow} @elem{For a @racket[nested-flow] with the @racket['vertical-inset] style name:
add space before and after suitable for code.}]
[@css{SCentered} @elem{For a @racket[nested-flow] created by @racket[centered]: horizontally
centered.}]
[@spacer @spacer]
[@css{boxed} @elem{For a @racket[table] with the @racket['boxed] style name: as a definition box.}]
[@spacer @spacer]
[@css{compact} @elem{For an @racket[itemlist] with the @racket['compact] style name.}]
[@spacer @spacer]
[@css{techoutside} @elem{Outer wrapper for a technical-term reference.}]
[@css{techinside} @elem{Inner wrapper for a technical-term reference.}]
[@spacer @spacer]
[@css{indexlink} @elem{For an entry in the index.}]
[@spacer @spacer]
[@css{stt} @elem{Fixed-width text.}]
[@css{sroman} @elem{Serif text.}]
[@css{ssanserif} @elem{Sans serif text.}]
[@css{slant} @elem{Oblique (as opposed to italic) text.}]
[@css{Smaller} @elem{Smaller text (as created by @racket[smaller]).}]
[@css{Larger} @elem{Smaller text (as created by @racket[larger]).}]
[@css{hspace} @elem{For whitespace produced by @racket[hspace].}]
[@css{nobreak} @elem{Disable link breaks.}]
[@css{badlink} @elem{Broken cross-reference.}]
[@css{plainlink} @elem{Hyperlink without an underline.}])
In addition, the @css{SIEHidden} style class is built in to all
Scribble HTML output to hide an element on Internet Explorer 6.
@; ------------------------------------------------------------
@section[#:tag "manual-css"]{Manual CSS Style Classes}
The following renderings of @elem[#:style (style #f (list
(link-resource "demo-manual.scrbl")))]{@filepath{demo-manual.scrbl}}
demonstrate all of the CSS style classes used by
@racketmodname[scribble/manual] forms and functions in addition to the
@seclink["builtin-css"]{base style classes}.
@itemlist[
@item{@other-doc['(lib "scribblings/scribble/demo-manual-s1.scrbl")] shows
the original style in a single-page rendering without a search
box.}
@item{@other-doc['(lib "scribblings/scribble/demo-manual-m1.scrbl")] shows
the original style in a multi-page rendering without a search
box.}
@item{@other-doc['(lib "scribblings/scribble/demo-manual-s2.scrbl")] shows
the current manual style's adjustments in a single-page
rendering with a search box.}
@item{@other-doc['(lib "scribblings/scribble/demo-manual-m2.scrbl")] shows
the current manual style's adjustments in a multi-page
rendering with a search box.}
]
The style classes:
@(css-table
[@css{RktSym} @elem{Identifiers with no @racket[for-label] binding.}]
[@css{RktValLink} @elem{Identifier with @racket[for-label] binding to a variable definition.}]
[@css{RktValDef} @elem{Definition site of a variable, normally combined with @css{RktValLink}.}]
[@css{RktStxLink} @elem{Identifier with @racket[for-label] binding to a syntactic-form definition.}]
[@css{RktStxDef} @elem{Definition site of a syntactic form, normally combined with @css{RktStxLink}.}]
[@css{RktSymDef} @elem{Definition site of an identifier without binding (normally a mistake), combined with @css{RktSym}.}]
[@css{RktVar} @elem{Local variable or meta-variable.}]
[@css{RktRes} @elem{REPL result.}]
[@css{RktOut} @elem{Output written to the current output port.}]
[@css{RktErr} @elem{Output written to the current error port.}]
[@css{RktCmt} @elem{A comment in Racket code.}]
[@css{RktVal} @elem{A literal value in Racket code.}]
[@css{RktPn} @elem{Parentheses, keywords, and similar delimiters in Racket code.}]
[@css{RktRdr} @elem{Reader shorthands in Racket code, except for commas.}]
[@css{RktMeta} @elem{An unquoting comma in Racket code.}]
[@css{highlighted} @elem{Hilighlted code (via @racket[code:highlight] in @racket[racketblock], for example).}]
[@css{RktIn} @elem{Foreground for literal characters written with @racket[litchar].}]
[@css{RktInBG} @elem{Background for literal characters written with @racket[litchar].}]
[@css{RktModLink} @elem{A module name linked to the module's definition.}]
[@css{RktMod} @elem{A module name (normally @css{RktModLink}, instead).}]
[@css{RktKw} @elem{A ``keyword;'' not normally used.}]
[@css{RktOpt} @elem{Brackets for optional arguments (in function definitions).}]
[@spacer @spacer]
[@css{RktBlk} @elem{Wrapper for multi-linke Racket code blocks.}]
[@spacer @spacer]
[@css{defmodule} @elem{Module definition block.}]
[@css{RpackageSpec} @elem{Package specification within a module-definition block.}]
[@spacer @spacer]
[@css{RBoxed} @elem{Definition block; always combined with @css{boxed}.}]
[@css{together} @elem{Table within a @racket[together] grouping.}]
[@css{RBackgroundLabel} @elem{Wrapper for ``procedure,'' ``syntax,'' etc., backing in a definition box.}]
[@css{RBackgroundLabelInner} @elem{Wrapper within @css{RBackgroundLabel}.}]
[@css{RForeground} @elem{Wrapper for element to appear over a @css{RBackgroundLabel}.}]
[@css{prototype} @elem{Wrapper for a multi-line procedure-definition prototype.}]
[@css{argcontract} @elem{Wrapper for a multi-line argument contract and default value.}]
[@css{specgrammar} @elem{Wrapper for a grammar with a syntactic-form definition box.}]
[@css{inherited} @elem{Wrapper for a margin ``inherited methods'' table.}]
[@css{inheritedlbl} @elem{Wrapper for ``Inherited methods:'' and ``from'' labels.}]
[@spacer @spacer]
[@css{leftindent} @elem{Left-indented block, such as form @racket[specsubform].}]
[@css{insetpara} @elem{Inset block.}]
[@spacer @spacer]
[@css{Rfilebox} @elem{Wrapper for a file box (via @racket[filebox]),}]
[@css{Rfiletitle} @elem{Outer wrapper for a file box title.}]
[@css{Rfilename} @elem{Inner wrapper for a file box title.}]
[@css{Rfilecontent} @elem{Wrapper for file box content.}]
[@spacer @spacer]
[@css{SHistory} @elem{Wrapper for @racket[history] paragraphs.}]
[@spacer @spacer]
[@css{RBibliography} @elem{Wrapper for a @racket[bibliography] section.}])
@; ------------------------------------------------------------
@section[#:tag "builtin-latex"]{Base Latex Macros}
The @filepath{scribble.tex} Latex configuration includes several
macros and environments that you can redefine to adjust the output
style:
@itemlist[
@item{@ltxd[0]{preDoc} --- called before the document content; the
default does nothing, while the @racketmodname[scribble/manual]
configuration enabled @ltx{sloppy}.}
@item{@ltxd[0]{postDoc} --- called after the document content; the
default does nothing.}
@item{@ltxd[0]{sectionNewpage} --- called before each top-level
section starts; the default does nothing, while the
@racketmodname[scribble/manual] configuration uses
@ltx{newpage} to start each chapter on a new page.}
@item{@ltxd[3]{SecRefLocal} --- the first argument is a Latex label,
the second argument is a section number, and the third argument
is a section title. This macro is used by @racket[secref] to
reference a section (other than a document or top-level section
within a document) that has a number and that is local to the
current document. The default expands to @ltx{SecRef}, passing
along just the second and third arguments (so that the label is
ignored).}
@item{@ltxd[2]{SecRef} --- like @ltx{SecRefLocal}, but used when the
referenced section is in a different document, so that no label
is available. The default shows ``section'' followed by the
section number (ignoring the title). The
@racketmodname[scribble/manual] redefinition of this macro
shows ``§'', the section number, and the title in quotes.}
@item{@ltxd[3]{ChapRefLocal} and @ltxd[2]{ChapRef} --- like
@ltx{SecRefLocal} and @ltx{SecRef}, but for a top-level section
within a document. The default implementation defers to
@ltx{SecRefLocal} or @ltx{SecRef}.}
@item{@ltxd[3]{PartRefLocal} and @ltxd[2]{PartRef} --- like
@ltx{SecRefLocal} and @ltx{SecRef}, but for a top-level section
within a document whose part has the @racket['grouper] style
property. The default @ltx{PartRef} shows ``part'' followed by
the section number (ignoring the title).}
@item{@ltxd[3]{BookRefLocal} and @ltxd[2]{BookRef} --- like
@ltx{SecRefLocal} and @ltx{SecRef}, but for a document (as
opposed to a section within the document). The default
@ltx{BookRef} implementation shows the title in italic.}
@item{@ltxd[3]{SecRefLocalUC} and @ltxd[2]{SecRefUC} --- like
@ltx{SecRefLocal} and @ltx{SecRef}, but for @racket[Secref].
The default @ltx{SecRefUC} shows ``Section'' followed by the
section number.}
@item{@ltxd[3]{ChapRefLocalUC} and @ltxd[2]{ChapRefUC} --- like
@ltx{ChapRefLocal} and @ltx{ChapRef}, but for
@racket[Secref]. The default @ltx{ChapRefUC}implementation
defers to @ltx{SecRefUC}.}
@item{@ltxd[3]{PartRefLocalUC} and @ltxd[2]{PartRefUC} --- like
@ltx{PartRefLocal} and @ltx{PartRef}, but for @racket[Secref].
The default @ltx{PartRefUC} shows ``Part'' followed by the
section number.}
@item{@ltxd[3]{BookRefLocalUC} and @ltxd[2]{BookRefUC} --- like
@ltx{BookRefLocal} and @ltx{BookRef}, but for @racket[Secref].
The default @ltx{BookRefUC} defers to @ltx{BookRef}.}
@item{@ltxd[2]{SecRefLocalUN}, @ltxd[1]{SecRefUCUN},
@ltxd[2]{SecRefLocalUCUN}, @ltxd[1]{SecRefUN},
@ltxd[2]{PartRefLocalUN}, @ltxd[1]{PartRefUN},
@ltxd[2]{PartRefLocalUCUN}, @ltxd[1]{PartRefUCUN},
@ltxd[2]{BookRefLocalUN}, @ltxd[1]{BookRefUN},
@ltxd[2]{BookRefLocalUCUN}, @ltxd[1]{BookRefUCUN},
@ltxd[2]{ChapRefLocalUN}, @ltxd[1]{ChapRefUN},
@ltxd[2]{ChapRefLocalUCUN}, and @ltxd[1]{ChapRefUCUN} --- like
@ltx{SecRefLocal}, etc., but in the case that a
section/part/chapter number is unavailable. The default
implementation of @ltx{BookRefUN} uses @ltx{BookRef} with an
empty first argument. The default @ltx{SecRefLocalUN} expands
to its second argument in quotes followed by ``on page'' as a
@ltx{pageref} using the first argument, while the default
@ltx{SecRefUN} expands to its only argument in quotes. The
default @ltx{PartRef} and @ltx{ChapRef} variants expand to the
corresponding @ltx{SecRef} variant.}
@item{@ltxd[2]{Ssection}, @ltxd[2]{Ssubsection},
@ltxd[2]{Ssubsubsection}, @ltxd[2]{Ssubsubsubsection},
@ltxd[2]{Ssubsubsubsubsection} --- for a top-level section, a
second-level section, etc., where the last variant is used for
all sections that are deeper than four levels. The first
argument corresponds to the optional argument to
@ltx{section}, which is used for the table of contents.}
@item{@ltxd[1]{Ssectionstar}, @ltxd[1]{Ssubsectionstar},
@ltxd[1]{Ssubsubsectionstar}, @ltxd[1]{Ssubsubsubsectionstar},
@ltxd[1]{Ssubsubsubsubsectionstar} --- like @ltx{Ssection},
etc., but for unnumbered sections that are omitted from the
table of contents.}
@item{@ltxd[2]{Ssectionstarx}, @ltxd[1]{Ssubsectionstarx},
@ltxd[2]{Ssubsubsectionstarx},
@ltxd[2]{Ssubsubsubsectionstarx},
@ltxd[2]{Ssubsubsubsubsectionstarx} --- like @ltx{Ssection},
etc., but for unnumbered sections (that nevertheless appear in
the table of contents).}
@item{@ltxd[0]{Sincsection}, @ltxd[0]{Sincsubsection},
@ltxd[0]{Sincsubsubsection}, @ltxd[0]{Sincsubsubsubsection},
@ltxd[0]{Sincsubsubsubsubsection} --- increments the section
counter.}
@item{@ltxd[2]{Spart}, @ltxd[1]{Spartstar}, @ltxd[2]{Spartstarx},
@ltxd[0]{Sincpart} --- like the section commands, but used for
in place of @ltxd[2]{Ssection}, @ltxd[1]{Ssectionstar}, @|etc|
for a part with the @racket['grouper] style property.}
@item{@ltxe{SInsetFlow} environment --- for a @racket[nested-flow]
with the @racket['inset] style name.}
@item{@ltxe{SCodeFlow} environment --- for a @racket[nested-flow]
with the @racket['code-inset] style name.}
@item{@ltxe{SVInsetFlow} environment --- for a @racket[nested-flow]
with the @racket['vertical-inset] style name.}
@item{@ltxd[1]{SCodeBox}, @ltxd[1]{SVInsetBox} --- for a
@racket[nested-flow] with the @racket['code-inset] or
@racket['vertical-inset] style name, respectively, and as the
content of a table cell. The content is installed into a TeX
box using @tt{\setbox1}.}
]
@; ------------------------------------------------------------
@section[#:tag "latex-prefix"]{Latex Prefix Support}
@defmodule[scribble/latex-prefix]{Provides a string that is useful for
constructing a Latex document prefix.}
@defthing[unicode-encoding-packages string?]{
A string containing Latex code that is useful after a
@tt{\documentclass} declaration to make Latex work with Unicode
characters.}

File diff suppressed because it is too large Load Diff

View File

@ -1,228 +0,0 @@
#lang scribble/doc
@(require scribble/manual "utils.rkt")
@title[#:tag "decode"]{Decoding Text}
@defmodule[scribble/decode]{The @racketmodname[scribble/decode]
library helps you write document content in a natural way---more like
plain text, except for @litchar["@"] escapes. Roughly, it processes a
stream of strings to produces instances of the
@racketmodname[scribble/struct] datatypes (see @secref["struct"]).}
At the @tech{flow} level, decoding recognizes a blank line as a
@tech{paragraph} separator. Blocks and paragraphs without blank lines
in between are collected into a @tech{compound paragraph}.
@elemtag['(decode "rules")]{At} the @tech{content} level, decoding
makes just a few special text conversions:
@itemize[
@item{@litchar{---}: converted to @racket['mdash]}
@item{@litchar{--}: converted to @racket['ndash]}
@item{@litchar{``}: converted to @racket['ldquo], which is fancy open quotes: ``}
@item{@litchar{''}: converted to @racket['rdquo], which is fancy closing quotes: ''}
@item{@litchar{'}: converted to @racket['rsquo], which is a fancy apostrophe: '}
@item{@litchar{`}: converted to @racket['lsquo], which is a fancy quote: `}
]
Some functions @deftech{decode} a sequence of @racket[_pre-flow] or
@racket[_pre-content] arguments using @racket[decode-flow] or
@racket[decode-content], respectively. For example, the @racket[bold]
function accepts any number of @racket[_pre-content] arguments, so
that in
@verbatim[#:indent 2]|{@bold{``apple''}}|
the @litchar{``apple''} argument is decoded to use fancy quotes, and
then it is bolded.
@defproc[(pre-content? [v any/c]) boolean?]{
Returns @racket[#t] if @racket[v] is a @deftech{pre-content} value: a
string or other non-list @tech{content}, a list of @tech{pre-content} values, or a @racket[splice]
containing a list of @tech{pre-content} values; otherwise returns
@racket[#f].
Pre-content is decoded into @tech{content} by functions like
@racket[decode-content] and @racket[decode-paragraph].}
@defproc[(pre-flow? [v any/c]) boolean?]{
Returns @racket[#t] if @racket[v] is a @deftech{pre-flow} value: a
string or other non-list @tech{content}, a @racket[block],
@|void-const|, a list of @tech{pre-flow} values, or a @racket[splice] containing a list of
@tech{pre-flow} values; otherwise returns @racket[#f].
Pre-flow is decoded into a @tech{flow} (i.e., a list of @tech{blocks})
by functions like @racket[decode-flow].}
@defproc[(pre-part? [v any/c]) boolean?]{
Returns @racket[#t] if @racket[v] is a @deftech{pre-part} value: a
string or other non-list @tech{content}, a @tech{block}, a
@racket[part], a @racket[title-decl], a @racket[part-start], a
@racket[part-index-decl], a @racket[part-collect-decl], a
@racket[part-tag-decl], @|void-const|, a list of @tech{pre-part} values, or a @racket[splice] containing
a list of @tech{pre-part} values; otherwise returns @racket[#f].
A pre-part sequence is decoded into a @racket[part] by functions like
@racket[decode] and @racket[decode-part].}
@defproc[(decode [lst (listof pre-part?)]) part?]{
Decodes a document, producing a part. In @racket[lst], lists and instances of
@racket[splice] are inlined into the list, and @|void-const|s are dropped. An instance of
@racket[title-decl] supplies the title for the part, plus tag, style
and version information. Instances of @racket[part-index-decl] (that
precede any sub-part) add index entries that point to the
section. Instances of @racket[part-collect-decl] add elements to the
part that are used only during the @techlink{collect pass}. Instances
of @racket[part-tag-decl] add hyperlink tags to the section
title. Instances of @racket[part-start] at level 0 trigger sub-part
parsing. Instances of @racket[section] trigger are used as-is as
subsections, and instances of @racket[paragraph] and other
flow-element datatypes are used as-is in the enclosing flow.
Portions of @racket[lst] are within a part are decoded using
@racket[decode-flow].}
@defproc[(decode-part [lst (listof pre-part?)]
[tags (listof string?)]
[title (or/c #f list?)]
[depth exact-nonnegative-integer?])
part?]{
Like @racket[decode], but given a list of tag string for the part, a
title (if @racket[#f], then a @racket[title-decl] instance is used if
found), and a depth for @racket[part-start]s to trigger sub-part
parsing.
}
@defproc[(decode-flow [lst (listof pre-flow?)]) (listof block?)]{
Decodes a flow. In @racket[lst], lists and instances of
@racket[splice] are inlined into the list. A sequence of two or more
newlines separated only by whitespace is parsed as a
compound-paragraph separator.
Portions of @racket[lst] are within a compound paragraph are decoded using
@racket[decode-compound-paragraph].}
@defproc[(decode-compound-paragraph [lst (listof pre-flow?)]) block?]{
Decodes a compound paragraph. In @racket[lst], lists and instances of
@racket[splice] are inlined into the list. Instances of
@racket[paragraph] and other @tech{block} datatypes are used as-is in
the result. If the compound paragraph contains a single block, the
block is returned without a @racket[compound-paragraph] wrapper.
Portions of @racket[lst] that are separated by @tech{block}s are
decoded using @racket[decode-content].}
@defproc[(decode-paragraph [lst (listof pre-content?)]) paragraph?]{
Decodes a paragraph using @racket[decode-content] to decode
@racket[lst] as the paragraph's content.}
@defproc[(decode-content [lst (listof pre-content?)]) list?]{
Decodes @tech{content}. Elements at the start of the list that are
whitespace (according to @racket[whitespace?]) are dropped.
@margin-note*{Dropping whitespace in nested lists and splices was a poor
implementation choice that is left in place for compatibility. To protect
against it, you can exploit the similarly unfortunate fact that an empty
list does not count as whitespace.}
Lists and splices in @racket[lst] are
flattened into the list, similarly dropping leading whitespace.
Plain strings are @elemref['(decode
"rules")]{decoded}; non-string, non-list @tech{content} is included in
the result as-is.}
@defproc[(decode-elements [lst (listof pre-content?)]) list?]{
An alias for @racket[decode-content].}
@defproc[(decode-string [s string?]) (listof content?)]{
@elemref['(decode "rules")]{Decodes} a single string to produce
@tech{content}.}
@defproc[(whitespace? [v any/c]) boolean?]{
Returns @racket[#t] if @racket[v] is a string that contains only whitespace, @racket[#f]
otherwise.}
@defstruct[title-decl ([tag-prefix (or/c #f string?)]
[tags (listof string?)]
[version (or/c string? #f)]
[style style?]
[content content?])]{
See @racket[decode] and @racket[decode-part]. The @racket[tag-prefix]
and @racketidfont{style} fields are propagated to the resulting
@racket[part]. If the @racketidfont{version} field is not @racket[#f],
it is propagated as a @racket[document-version] style property on the
@racket[part].}
@defstruct[part-start ([depth integer?]
[tag-prefix (or/c #f string?)]
[tags (listof string?)]
[style style?]
[title content?])]{
Like @racket[title-decl], but for a sub-part. See @racket[decode] and
@racket[decode-part].}
@defstruct[part-index-decl ([plain-seq (listof string?)]
[entry-seq list?])]{
See @racket[decode]. The two fields are as for @racket[index-element].}
@defstruct[part-collect-decl ([element (or/c element? part-relative-element?)])]{
See @racket[decode].}
@defstruct[part-tag-decl ([tag tag?])]{
See @racket[decode].}
@defstruct[splice ([run list?])]{
See @racket[decode], @racket[decode-part], and @racket[decode-flow].}
@defproc[(spliceof [ctc flat-contract?]) flat-contract?]{
Produces a contract for a @racket[splice] instance whose
@racketidfont{run} elements satisfy @racket[ctc].}
@defproc[(clean-up-index-string [str string?]) string?]{
Trims leading and trailing whitespace, and converts non-empty
sequences of whitespace to a single space character.}

View File

@ -1,23 +0,0 @@
#lang scribble/base
@(require scribble/manual
(for-label racket/base
racket/class
racket/contract/base
racket/draw))
@(define css tt)
@defclass/title[#:link-target? #f bitmap-dc% object% (dc<%>)]{
In multi-page mode, this class definition gets its own page, and
there's an ``inherited methods'' table in the margin. The table has
style class @css{inherited}, and the words ``inherited methods:'' and
``from'' have style class @css{inheritedlbl}.
@defmethod[#:link-target? #f (set-bitmap [bm any/c]) any]{
A method example; nothing new here, but note how the defined
identifier is not at the start of the box.}
}

View File

@ -1,10 +0,0 @@
#lang racket/base
(require "demo.scrbl"
scribble/core)
(define renamed-doc
(struct-copy part doc
[title-content
(cons "M1 " (part-title-content doc))]))
(provide (rename-out [renamed-doc doc]))

View File

@ -1,12 +0,0 @@
#lang racket/base
(require "demo.scrbl"
scribble/core
scribble/manual)
(define renamed-doc
(struct-copy part doc
[style manual-doc-style]
[title-content
(cons "M2 " (part-title-content doc))]))
(provide (rename-out [renamed-doc doc]))

View File

@ -1,10 +0,0 @@
#lang racket/base
(require "demo-manual.scrbl"
scribble/core)
(define renamed-doc
(struct-copy part doc
[title-content
(cons "M1 " (part-title-content doc))]))
(provide (rename-out [renamed-doc doc]))

View File

@ -1,12 +0,0 @@
#lang racket/base
(require "demo-manual.scrbl"
scribble/core
scribble/manual)
(define renamed-doc
(struct-copy part doc
[style manual-doc-style]
[title-content
(cons "M2 " (part-title-content doc))]))
(provide (rename-out [renamed-doc doc]))

View File

@ -1,10 +0,0 @@
#lang racket/base
(require "demo-manual.scrbl"
scribble/core)
(define renamed-doc
(struct-copy part doc
[title-content
(cons "S1 " (part-title-content doc))]))
(provide (rename-out [renamed-doc doc]))

View File

@ -1,12 +0,0 @@
#lang racket/base
(require "demo-manual.scrbl"
scribble/core
scribble/manual)
(define renamed-doc
(struct-copy part doc
[style manual-doc-style]
[title-content
(cons "S2 " (part-title-content doc))]))
(provide (rename-out [renamed-doc doc]))

View File

@ -1,203 +0,0 @@
#lang scribble/base
@(require scribble/manual
scribble/eval
(for-syntax racket/base)
(for-label racket/base
racket/contract/base
scribble/manual))
@(define css tt)
@(define-syntax (opt-example stx)
;; A #\? 'paren-shape value triggers RktOpt:
#`@racket[#,(syntax-property #'(in-example) 'paren-shape '#\?)])
@title{Manual All-Styles Document}
@table-of-contents[]
@section{Code Styles}
@itemlist[
@item{@css{RktSym} (identifier without @racket[for-label] binding):
@racket[unbound] or @racketidfont{example}}
@item{@css{RktValLink} (link to variable form): @racket[cons]}
@item{@css{RktValDef} (definition of variable, normally combined with @css{RktValLink}):
@racket[list] in
@defproc[#:link-target? #f (list) any/c]
@defthing[#:link-target? #f list any/c]}
@item{@css{RktStxLink} (link to syntactic form): @racket[lambda]}
@item{@css{RktStxDef} (definition of syntactic form, normally combined with @css{RktStxLink}):
@racket[lambda] in
@defform[#:link-target? #f (lambda ...)]}
@item{@css{RktSymDef} (definition without binding, normally a mistake, combined with @css{RktSym}):
@racket[unbound-identifier] in
@defform[#:link-target? #f (unbound-identifier)]}
@item{@css{RktVar} (local variable or meta-variable): @racket[_variable] or @racketvarfont{example}}
@item{@css{RktRes} (REPL result): @racketresult['(1 2 3)] or @racketresultfont{example}}
@item{@css{RktOut} (as written to the current output port): @racketoutput{example}}
@item{@css{RktErr} (errors): @racketerror{example} or the error message in
@interaction[(eval:error (+ 1 'a))]}
@item{@css{RktCmt} (comments): @racketcommentfont{example} or
@racketblock[(code:comment "comment")]}
@item{@css{RktVal} (values): @racket['(1 2 3)] or @racketvalfont{example}}
@item{@css{highlighted} (highlight via background): @racket[(not-this (code:hilite example) nor-this)]}
@item{@css{RktIn} on a @css{RktInBG}: @litchar{example}}
@item{@css{RktPn} (parentheses, etc.): @racket[([{}])] or @racketparenfont{example}}
@item{@css{RktRdr} (reader shorthands): non-parentheses in @racket[(#`() ,@())]}
@item{@css{RktMeta} (the @racket[unquote] comma):
@racket[,1] or @racketmetafont{example} or ``#reader'' below.
@defmodule[@schemeidfont{module} #:module-paths (racket/base) #:reader #:no-declare #:link-target? #f]}
@item{@css{RktMod} (module name; normally @css{RktModLink} instead): @racketmodfont{example}}
@item{@css{RktModLink} (a linked module reference): @racketmodname[racket/base]}
@item{@css{RktOpt} (option-argument brackets): brackets in @opt-example[]}
@item{@css{RktKw} (not normally used): @racketkeywordfont{example}}
]
The @css{RktBlk} style class is used for a table of multiple lines (more
than 1) of Racket code:
@racketblock[
(define x (+ 1 2))
(+ x 3)
]
@section{Definition Blocks}
@defmodule[racket/base #:link-target? #f]
The module-declaration box above is in a @css{defmodule} table. The
package-specification part is in an @css{RpackageSpec} wrapper.
The definitions below are marked so that they are not link targets. If
they were link targets, the table-of-contents panel on the left would
have entries for them.
@defproc[#:link-target? #f (cons [really-long-name-for-the-first-argument
any/c]
[really-long-name-for-the-second-argument
(or/c any/c
any/c)])
pair?]{
This definition box starts with a @css{SVInsetFlow} wrapper, which is a
@racketmodname[scribble/base] style class for the
@racket['vertical-inset] style name on a block; it should give the
block suitable vertical space before and after.
The next layer is a @css{boxed} plus @css{RBoxed} table. The @css{boxed}
style class is from @racketmodname[scribble/base] and the
@racket['boxed] style name on a table. The @css{RBoxed} style class is
from the @racket[scribble/manual] layer. Both @css{boxed} and @css{RBoxed}
are used for all definition boxes by @racket[scribble/manual] forms.
The initial content of the table includes a @css{SubFlow} (a
@racket[scribble/base] style class for non-indented flow) to combine
blocks for the background label with the first line of the table. The
background label ``procedure'' has an @css{RBackgroundLabel} outer
wrapper, which makes the label float right. (The wrapper also has the
@css{SIEHidden} style class, which built-in for all Scribble HTML output
and makes the label hidden on Internet Explorer 6 and earlier.) The
background label has an @css{RBackgroundLabelInner} inner wrapper, which
makes the label suitably faint. The content part of the first line is
wrapped in @css{RForeground}, which ensures that it is in front of the
background label.
In a procedure definition box:
@itemlist[
@item{When the initial ``prototype'' call in the definition box spans
multiple lines, the table that contains the call has the
@css{prototype} style class in addition to @css{RForeground}.}
@item{When the contract or default value for an argument spans
multiple lines, then the contract, the ``='' for a value (if
any), and value (if any) are wrapped in an table with the
@css{argcontract} style class.}
]
Finally, the definition box and all of the associated explanation text
are wrapped in @css{SIntrapara} blocks and grouped into a single
@tt{<p>}.}
@defform[#:link-target? #f
(lambda ...)
#:grammar ([example good
bad])]
When a syntactic-from specification has a grammar, the grammar is in a
table with the @css{specgrammar} style class.
Since no explanation flow is attached to the above @racket[defform] use,
there's no @css{SIntrapara} block around the table (just a @tt{<p>}).
@deftogether[(
@defproc[#:link-target? #f (cons [a any/c] [d any/c]) pair?]
@defform[#:link-target? #f (lambda ...)]
)]{
Putting definitions together with @racket[deftogether] converts the
@css{RBoxed} and @css{boxed} tables that would be generated for the
individual definitions into tables with the @css{together} style
class. The tables are then combined as rows in a new table with the
@css{RBoxed} and @css{boxed} style classes.}
A @racket[defsubform], @racket[specsubform], etc., such as
@specsubform[(lambda ...)]
is indented though a wrapper with a @css{leftindent} style class.
@include-section["demo-class.scrbl"]
@section{Miscellaneous}
In @racket[filebox] rendering,
@(filebox "example.rkt" "This is a file box")
a @css{Rfilebox} wrapper surrounds the file name in a @css{Rfiletitle}
outer wrapper and an @css{Rfilename} inner wrapper, plus the file
content in an @css{Rfilecontent} wrapper.
@inset-flow{The @racket[inset-flow] form generates a
@racket[nested-flow] with style class @css{insetpara}.}
@history[#:changed "1.0" @elem{History paragraphs have the @css{SHistory} style class.}]
@section{Bibliography}
The bibliography table for the citation @cite["Example"] as the
@css{RBibliography} style class.
@bibliography[(bib-entry #:key "Example" #:title "Example bibliography entry")]

View File

@ -1,10 +0,0 @@
#lang racket/base
(require "demo.scrbl"
scribble/core)
(define renamed-doc
(struct-copy part doc
[title-content
(cons "S1 " (part-title-content doc))]))
(provide (rename-out [renamed-doc doc]))

View File

@ -1,12 +0,0 @@
#lang racket/base
(require "demo.scrbl"
scribble/core
scribble/manual)
(define renamed-doc
(struct-copy part doc
[style manual-doc-style]
[title-content
(cons "S2 " (part-title-content doc))]))
(provide (rename-out [renamed-doc doc]))

View File

@ -1,324 +0,0 @@
#lang scribble/base
@(require scribble/core
scribble/manual)
@title[#:tag "top" #:version "1.0" #:style 'toc-hidden]{All-Styles Document, Title in ``H2''}
@author["Jack" "Jill"]
All of this content is within ``maincolumn'', then ``main''.
@"\U2192" The version on the top left of this page is in
``versionbox'' and then either span ``versionNoNav'' (no navigation
bar, as for single-page rendering) or ``version'' (with navigation
bar, as for multi-page rendering).
@"\U2192" The author on the top left of this page is in
``SAuthorListBox'', then ``SAuthorList'', and then a span ``author'',
where @tt{<br/>} separates multiple authors.
@"\U2190" The table-of-contents panels are both in a table ``tocset'':
@margin-note{This note is in ``refpara'', then ``refcolumn'', then
``refcontent''.}
@itemlist[
@item{The top panel is in ``tocview''.
The top panel can have multiple layers of the hierarchy. For a
single-page rendering, only one layer is present. For an
example of multiple layers when rendering this document to
multiple pages, go to @secref["deepest"].
Each layer is in a ``tocviewlist'' that also has the class
``tocviewlisttopspace'' in the case of the first layer. The
always-visible name of a layer is in a span ``tocviewtoggle'',
but that span is also in a ``tocviewtitle'' in the case of the
first layer. Each item under the title is in a
``tocviewsublist'' or a variant: ``tocviewsublistonly'' if only
a single item is present, ``tocviewsublistfirst'' for the first
item of multi, ``tocviewsublistlast'' for the last item of
multiple. Then, each item is in a span ``tocviewlink''.
Each section link in the panel is a span ``tocviewlink'' or a
span ``tocviewselflink'' if the link corresponds to the current
page or on the path to the current page.}
@item{A bottom panel is visible here only for a single-page
rendering. See its description in @secref["h3"].}
]
@margin-note[#:left? #t]{This note is in ``refparaleft'', then
``refcolumnleft'', then ``refcontent''.}
Table of contents uses ``toptoclink'' for the top layer, and
``toclink'' for nested levels:
@table-of-contents[]
@margin-note*{This note is in ``refelem'', then ``refcolumn'', then
``refcontent''.}
@margin-note*[#:left? #t]{This note is in ``refelemleft'', then
``refcolumnleft'', then ``refcontent''.}
@; ======================================================================
@section[#:tag "h3"]{Section in ``H3''}
@"\U2190" For either single-page or multi-page rendering, the
table-of-contents column here has two panels. The top panel is
described in the @seclink["h3"]{starting prose}. For the bottom panel:
@itemlist[
@item{The bottom panel is in a ``tocsub''. For a multi-page
rendering, the on-this-page title is in ``tocsubtitle''. The
rest is always in a table ``tocsublist''. For each entry, the
number part is in a span ``tocsublinknumber'', and the title
part in a span, one of the following: ``tocsubseclink'' if the
link represents a (sub)section, ``tocnonseclink'' if the link is
not a (sub)section but there are (sub)sections in the list (and
there is an example target in this section), or ``tocsublink''
if no links represent a (sub)section (see
@secref["all-non-sec"]).}
]
When a part that corresponds to a page has a @racket['no-toc] style,
the top panel of the table-of-contents column is missing and the
bottom panel is in a ``tocview'' instead of ``tocsub''. See
@secref["no-toc"].
Here is the target for the
@toc-target-element[#f @elem{``tocnonseclink''} `(demo (prefixable "non-sec"))]
link.
@subsection[#:style 'toc]{Subsection in ``H4''}
@local-table-of-contents[]
@subsubsection[#:tag "deepest"]{Subsubsection in ``H5''}
@"\U2190" This page has no on-this-page panel in a multi-page
rendering, because there are no numbered subsections, but it has three
levels shown in the table-of-contents panel.
@subsubsub*section{``SSubSubSubSection''}
@subsection{Second Subsection in ``H4''}
@; ======================================================================
@section[#:tag "no-toc" #:style 'no-toc]{Suppressed ToC Panel}
In multi-page rendering, this page has no gobal table-of-contents
panel, because it is suppressed with @racket['no-toc].
@subsection{Subsection}
@subsection{Another Subsection}
@; ======================================================================
@section[#:tag "all-non-sec"]{Non-Section On-This-Page Links}
This section has only non-section targets in the on-this-page
panel of a multi-page rendering.
Here is the target for the
@toc-target-element[#f @elem{``tocsublink'' 1} `(demo (prefixable "non-sec 1"))]
link.
Here is the target for the
@toc-target-element[#f @elem{``tocsublink'' 2} `(demo (prefixable "non-sec 2"))]
link.
Here is the target for the @as-index{``indexlink''} link in the
@seclink["doc-index"]{index} (where ``indexlink'' is used for the
index entry and not here).
@; ======================================================================
@section{Element Styles}
Some spans:
@itemlist[
@item{@tt{``stt''}}
@item{@elem[#:style 'roman]{``sroman''}}
@item{@elem[#:style "slant"]{``slant''}}
@item{@elem[#:style 'sf]{``ssanserif''}}
@item{@smaller{``Smaller''}}
@item{@larger{``Larger''}}
@item{``hspace'' is used for forced @hspace[3] space}
@item{``url'' is used for URLs: @url{http://racket-lang.org}}
@item{@elem[#:style 'no-break]{``nobreak'', which is used to prevent
line breaks anywhere in the element so that the element may run too
far right}}
@item{@italic{italic} directly sets @tt{font-style} to @tt{italic}}
@item{@bold{bold} directly sets @tt{font-weight} to @tt{bold}}
@item{@elem[#:style 'superscript]{superscript} directly sets
@tt{vertical-align} to @tt{super} and @tt{font-size} to @tt{80%}.}
@item{@elem[#:style 'subscript]{subscript} directly sets
@tt{vertical-align} to @tt{sub} and @tt{font-size} to @tt{80%}.}
]
Link spans:
@itemlist[
@item{@elemref[#:underline? #f '(prefixable "plain-target")]{``plainlink''}
hyperlink to @elemtag['(prefixable "plain-target")]{here}}
@item{@deftech{technical term} definitions are simply italicized by default}
@item{@tech{technical term} references are in ``techoutside'', then ``techinside''}
]
@; ======================================================================
@section{Block Styles}
@nested{This paragraph is in a ``SubFlow'' @tt{<blockquote>}.}
@nested[#:style 'inset]{This paragraph is in a plain @tt{<blockquote>}.}
@nested[#:style 'code-inset]{This paragraph is in a ``SCodeFlow''
@tt{<blockquote>}.}
@nested[#:style 'vertical-inset]{This paragraph is in a
``SVInsetFlow'' @tt{<blockquote>}. This style is useful when space is
not normally included between blocks.}
@centered{This paragraph is in a ``SCentered'' @tt{<blockquote>}.}
@tabular[#:style 'boxed (list (list @t{A ``boxed'' table.}))]
@; ======================================================================
@section{Enumerations}
This one is unordered, so it uses @tt{<ul>}:
@itemlist[
@item{six}
@item{half-dozen}
]
This one is ordered, so it uses @tt{<ol>}:
@itemlist[#:style 'ordered
@item{First}
@item{Second
@itemlist[#:style 'ordered
@item{Second, first half}
@item{Second, second half
@itemlist[#:style 'ordered
@item{First half of that}
@item{Second half of that
@itemlist[#:style 'ordered
@item{Thin-slice start}
@item{Thin-sliced end}
]}
]}
]}
@item{Third}
]
This one is ``compact'':
@itemlist[ #:style 'compact
@item{six}
@item{half-dozen}
]
This paragraph follows the enumeration above.
@; ======================================================================
@section{Paragraph Spacing}
This sentence is a paragraph all by itself.
@t{This sentence is a paragraph.}
@t{This sentence is also a paragraph, but it is connected to the
previous paragraph as a compound paragraph by virtue of having no
paragraph-breaking space before it, and each paragraph is in a
``SIntraPara'' @tt{<div>} instead of a @tt{<p>}.}
This sentence is a paragraph, as is each of A1, B1, A2, B2, A3, B3a,
and B2a in the following table, but B3a and B2a form a compound paragraph.
@;
@tabular[(list (list "A1"
"B1")
(list "A2"
"B2")
(list "A3"
@compound-paragraph[plain (list @t{B3a} @t{B3b})]))]
@;
This sentence is a paragraph, and with the preceding table and
paragraph forms a compound paragraph.
@nested{
@t{This is a first paragraph in a @tt{<blockquote>}.}
@t{This is a second paragraph in a @tt{<blockquote>}.}
}
@; ======================================================================
@section{Navigation Bars}
For multi-page rendering, this page will have a navigation bar at the
top and bottom. The bars are within ``maincolumn'' and ``main''.
The tap bar is in ``navsettop'', and the bottom one is in
``navsetbottom''. Within those divs, ``navsetleft'' wraps content to
be left-aligned and ``navsetright'' wraps content to be right-aligned.
Links that are disabled (such as a next-page link on the last page)
are each in a span ``nonavigation''.
When a search box is included, then it is in ``searchform'' and then
``searchbox''. If no search box is included, then a ``nosearchform''
@tt{div} is used.
Finally, and not part of the nagivation bar, the bottom nagivation bar
is followed by a @tt{div} with the name
``contextindicator''. JavaScript code attached to the page copies the
@tt{ctxtname} query argument, if any, to the @tt{div} and makes it
visible.
@; ======================================================================
@index-section[]

View File

@ -1,117 +0,0 @@
#lang scribble/manual
@(require "utils.rkt")
@title[#:tag "doclang"]{Document Language}
@defmodulelang[scribble/doclang2]{The @racketmodname[scribble/doclang2]
language provides everything from @racket[racket/base], except that it
replaces the @racket[#%module-begin] form.
The @racketmodname[scribble/doclang2] @racket[#%module-begin]
essentially packages the body of the module into a call to
@racket[decode], binds the result to @racket[doc], and exports
@racket[doc].
Any module-level form other than an expression (e.g., a
@racket[require] or @racket[define]) remains at the top level, and
the @racket[doc] binding is put at the end of the module. As usual, a
module-top-level @racket[begin] slices into the module top level.
For example:
@codeblock|{
#lang racket
(module example scribble/doclang2
"hello world, this is"
" an example document")
(require 'example)
doc
}|
The behavior of @racketmodname[scribble/doclang2] can be customized by
providing @racket[#:id], @racket[#:post-process], and @racket[#:exprs]
arguments at the very beginning of the module.
@itemize[
@item{@racket[#:id] names the top-level documentation binding. By default, this
is @racket[doc].}
@item{@racket[#:post-process] processes the body of the module after
@racket[decode]. By default, this is @racket[values].}
@item{@racket[#:exprs] prepends an additional sequence of expressions to the
beginning of the module's body. By default, this is the empty sequence
@racket[()].}
]
This example explicitly uses the defaults for all three keywords:
@codeblock|{
#lang racket
(module example scribble/doclang2
#:id doc
#:post-process values
#:exprs ()
"hello world, this is an example document")
(require 'example)
doc
}|
The next toy example uses a different name for the documentation binding, and
also adds an additional binding with a count of the parts in the document:
@codeblock|{
#lang racket
(module example scribble/doclang2
#:id documentation
#:post-process (lambda (decoded-doc)
(set! number-of-parts (length (part-parts decoded-doc)))
decoded-doc)
#:exprs ((title "My first expression!"))
(require scribble/core
scribble/base)
(define number-of-parts #f)
(provide number-of-parts)
(section "part 1")
"hello world"
(section "part 2")
"this is another document")
(require 'example)
number-of-parts
documentation
}|
}
@section{@racketmodname[scribble/doclang]}
@defmodulelang[scribble/doclang]{The @racketmodname[scribble/doclang] language
provides the same functionality as @racketmodname[scribble/doclang2], where the
configuration options are positional and mandatory. The first three elements
in the @racket[#%module-begin]'s body must be the @racket[id],
@racket[post-process], and @racket[exprs] arguments.
Example:
@codeblock|{
#lang racket
(module* example scribble/doclang
doc
values
()
(require scribble/base)
(provide (all-defined-out))
(define foo (para "hello again"))
"hello world, this is an example document"
(para "note the " (bold "structure")))
(module+ main
(require (submod ".." example))
(printf "I see doc is: ~s\n\n" doc)
(printf "I see foo is: ~s" foo))
}|
}

View File

@ -1,10 +0,0 @@
#lang scribble/doc
@(require scribble/manual scribble/bnf "utils.rkt")
@title[#:tag "docreader"]{Document Reader}
@defmodulelang[scribble/doc]{The @racketmodname[scribble/doc] language is
the same as @racketmodname[scribble/doclang], except that
@racket[read-syntax-inside] is used to read the body of the module. In
other words, the module body starts in Scribble ``text'' mode instead
of S-expression mode.}

View File

@ -1,180 +0,0 @@
#lang scribble/doc
@(require scribble/manual
"utils.rkt"
(for-label scribble/eval
racket/sandbox
racket/pretty
file/convertible
racket/serialize))
@(define-syntax-rule (define-new-examples new-examples)
(begin
(require (for-label scribble/example))
(define new-examples @racket[examples])))
@(define-new-examples new-examples)
@title[#:tag "old-eval"]{Legacy Evaluation}
@defmodule[scribble/eval]{The @racketmodname[scribble/eval] library provides
an older interface to the functionality of @racketmodname[scribble/example].
The @racketmodname[scribble/example] library should be used, instead.}
In addition to the forms listed below, @racket[scribble/eval]
re-exports several functions from @racket[scribble/example]:
@racket[make-base-eval] @racket[make-base-eval-factory],
@racket[make-eval-factory], @racket[make-log-based-eval],
@racket[close-eval], and @racket[scribble-eval-handler].
@defform/subs[(interaction maybe-options datum ...)
([maybe-options maybe-eval maybe-escape maybe-no-errors]
[maybe-eval code:blank
(code:line #:eval eval-expr)]
[maybe-escape code:blank
(code:line #:escape escape-id)]
[maybe-no-errors code:blank
(code:line #:no-errors? no-errors?-expr)])]{
Like @|new-examples| from @racketmodname[scribble/example], except that
@itemlist[
@item{the ``Examples:'' label is always supressed,}
@item{exceptions raised during the evaluation of a @racket[datum] are
always rendered as errors, unless @racket[#:no-errors?] is
specified with a true value; and}
@item{the @racket[#:once] option is never implicitly used.}
]
@history[#:changed "1.14" @elem{Added @racket[#:no-errors?],
@racket[eval:no-prompt], and
@racket[eval:error], and changed
@racket[code:line] to support multiple
@racket[_datum]s.}]}
@defform[(interaction0 maybe-options datum ...)]{
Like @racket[interaction], but without insetting the code via
@racket[nested].
Use @|new-examples| with @racket[#:no-indent], instead.}
@defform[(interaction/no-prompt maybe-eval maybe-escape datum)]{
Like @racket[interaction], but does not render each @racket[datum] with a prompt.
Use @|new-examples| with @racket[#:no-prompt], instead.}
@defform[(interaction-eval maybe-eval datum)]{
Like @racket[interaction], evaluates the @racket[quote]d form of
@racket[datum], but returns the empty string and does not catch
exceptions (so @racket[eval:error] has no effect).
Use @|new-examples| with @racket[#:hidden], instead.}
@defform[(interaction-eval-show maybe-eval datum)]{
Like @racket[interaction-eval], but produces an element representing
the printed form of the evaluation result.
Use @|new-examples| with @racket[#:result-only], instead.}
@defform[(racketblock+eval maybe-eval maybe-escape datum ...)]{
Combines @racket[racketblock] and @racket[interaction-eval].
Use @|new-examples| with @racket[#:no-result], instead.}
@defform[(racketblock0+eval maybe-eval maybe-escape datum ...)]{
Combines @racket[racketblock0] and @racket[interaction-eval].
Use @|new-examples| with @racket[#:no-result] and
@racket[#:no-indent], instead.}
@defform[(racketmod+eval maybe-eval maybe-escape name datum ...)]{
Combines @racket[racketmod] and @racket[interaction-eval].
Use @|new-examples| with @racket[#:lang], instead.}
@defform[(def+int maybe-options defn-datum expr-datum ...)]{
Like @racket[interaction], except the @racket[defn-datum] is
typeset as for @racket[racketblock] (i.e., no prompt) and a line of
space is inserted before the @racket[expr-datum]s.}
@defform[(defs+int maybe-options (defn-datum ...) expr-datum ...)]{
Like @racket[def+int], but for multiple leading definitions.
Use @|new-examples| with @racket[eval:no-prompt] wrappers on
definitions, instead.}
@defform[(examples maybe-options datum ...)]{
Like @racket[interaction], but with an ``Examples:'' label prefixed.
Use @|new-examples| from @racketmodname[scribble/example], instead.}
@defform[(examples* label-expr maybe-options datum ...)]{
Like @racket[examples], but using the result of @racket[label-expr] in
place of the default ``Examples:'' label.
Use @|new-examples| from @racketmodname[scribble/example] with the
@racket[#:label] option, instead.}
@defform[(defexamples maybe-options datum ...)]{
Like @racket[examples], but each definition using @racket[define] or
@racket[define-struct] among the @racket[datum]s is typeset without a
prompt, and with line of space after it.
Use @|new-examples| with @racket[eval:no-prompt] wrappers on
definitions, instead.}
@defform[(defexamples* label-expr maybe-options datum ...)]{
Like @racket[defexamples], but using the result of @racket[label-expr] in
place of the default ``Examples:'' label.
Use @|new-examples| with the @racket[#:label] option and
@racket[eval:no-prompt] wrappers on definitions, instead.}
@defproc*[([(as-examples [b block?]) block?]
[(as-examples [label (or/c block? content?)]
[b block?])
block?])]{
Adds an ``examples'' label to @racket[b], using either a default label
or the given @racket[label].}
@defform[(with-eval-preserve-source-locations expr ...)]{
By default, the evaluation forms provided by this module, such as
@racket[interaction] and @racket[examples], discard the source
locations from the expressions they evaluate. Within a
@racket[with-eval-preserve-source-locations] form, the source
locations are preserved. This can be useful for documenting forms that
depend on source locations, such as Redex's typesetting macros.
Use @|new-examples| with the @racket[#:preserve-source-locations]
option, instead.}

View File

@ -1,304 +0,0 @@
#lang scribble/doc
@(require scribble/manual
"utils.rkt"
(for-label scribble/example
racket/sandbox
racket/pretty
file/convertible
racket/serialize))
@title[#:tag "eval"]{Evaluation and Examples}
@defmodule[scribble/example #:use-sources (scribble/eval scribble/example)]{The
@racket[scribble/example] library provides
utilities for evaluating code at document-build time and incorporating
the results in the document, especially to show example uses of
defined procedures and syntax.}
@history[#:added "1.16"]
@defform/subs[(examples option ... datum ...)
([option (code:line #:eval eval-expr)
#:once
(code:line #:escape escape-id)
(code:line #:label label-expr)
#:hidden
#:result-only
#:no-inset
#:no-prompt
#:preserve-source-locations
#:no-result
(code:line #:lang language-name)])]{
Similar to @racket[racketinput], except that the result for each input
@racket[datum] is shown on the next line. The result is determined by
evaluating the @racket[quote]d form of the @racket[datum] using the
evaluator produced by @racket[eval-expr].
Each keyword option can be provided at most once:
@itemlist[
@item{@racket[#:eval eval-expr] --- Specifies an evaluator, where
@racket[eval-expr] must produce either @racket[#f] or a sandbox
evaluator via @racket[make-evaluator] or
@racket[make-module-evaluator] with the @racket[sandbox-output]
and @racket[sandbox-error-output] parameters set to
@racket['string]. If @racket[eval-expr] is not provided or is
@racket[#f], an evaluator is created using
@racket[make-base-eval]. See also @racket[make-eval-factory].}
@item{@racket[#:once] --- Specifies that the evaluator should be
closed with @racket[close-eval] after the all @racket[datum]s
are evaluated. The @racket[#:once] option is assumed if
@racket[#:eval] is not specified.}
@item{@racket[@#,racket[#:escape] escape-id] --- Specifies an escape
identifier, as in @racket[racketblock].}
@item{@racket[#:label label-expr] --- Specifies a label for the
examples, which defaults to ``Example:'' or ``Examples:''
(depending on the number of @racket[datum]s). A @racket[#f]
value for @racket[label-expr] suppresses the label.}
@item{@racket[#:hidden] --- Specifies that the @racket[datum]s and
results should not be typeset, but instead evaluated for a
side-effect, and disables @racket[eval:error]. Typically, this
option is combined with @racket[#:eval] to configure an
evaluator.}
@item{@racket[#:result-only] --- Specifies that the @racket[datum]
results should be typeset, but not the @racket[datum]s
themselves, and implies @racket[#:label #f].}
@item{@racket[#:no-result] --- Implies @racket[#:no-prompt] and
@racket[#:label #f], specifies that no results should be
typeset, and disables @racket[eval:error].}
@item{@racket[#:no-inset] --- Specifies that the examples should be
typeset without indentation, i.e., like @racket[racketinput0]
instead of @racket[racketinput].}
@item{@racket[#:no-prompt] --- Specifies that each examples should
be typeset without a leading prompt, i.e., like
@racket[racketblock] instead of @racket[racketinput]. A prompt
can be omitted from a specific @racket[_datum] by wrapping it
with @racket[eval:no-prompt].}
@item{@racket[#:preserve-source-locations] --- Specifies that the
original source locations for each @racket[datum] should be
preserved for evaluation. Preserving source locations can be
useful for documenting forms that depend on source locations,
such as Redex's typesetting macros.}
@item{@racket[#:lang] --- Implies @racket[#:no-result] prefixes the
typeset @racket[datum] sequence with a @hash-lang[] line using
@racket[language-name] as the module's language.}
]
Certain patterns in @racket[datum] are treated specially:
@itemlist[
@item{A @racket[datum] of the form
@racket[(@#,indexed-racket[code:line] _code-datum (@#,racketidfont{code:comment} _comment-datum ...))]
is treated as @racket[_code-datum] for evaluation.}
@item{A @racket[datum] of the form
@racket[(@#,indexed-racket[code:line] _code-datum ...)]
evaluates each @racket[_code-datum], but only the last result is used.}
@item{Other uses of @racketidfont{code:comment}, @racketidfont{code:contract}, and
@racketidfont{code:blank} are stripped from each @racket[datum]
before evaluation.}
@item{A @racket[datum] of the form
@racket[(@#,indexed-racket[eval:error] #,(svar eval-datum))] is
treated like @racket[_eval-datum], but @racket[_eval-datum] is
expected to raise an exception, and an error is shown as the
evaluation's result.}
@item{A @racket[datum] of the form
@racket[(@#,indexed-racket[eval:alts] #,(svar show-datum) #,(svar eval-datum))]
is treated as @svar[show-datum] for typesetting and @svar[eval-datum] for evaluation.}
@item{A @racket[datum] of the form
@racket[(@#,indexed-racket[eval:check] #,(svar eval-datum) #,(svar expect-datum))]
is treated like @racket[_eval-datum], but @svar[check-datum] is also
evaluated, and an error is raised if they are not @racket[equal?].}
@item{A @racket[datum] of the form
@racket[(@#,indexed-racket[eval:result] _content-expr _out-expr _err-expr)]
involves no sandboxed evaluation; instead, the @tech{content} result of @racket[_content-expr] is used as the
typeset form of the result, @racket[_out-expr] is treated as output printed
by the expression, and @racket[_err-expr] is error output printed by the
expression. The @racket[_out-expr] and/or @racket[_err-expr] can be omitted,
in which case they default to empty strings.
Normally, @racketidfont{eval:result}
is used in the second part of an @racketidfont{eval:alts} combination. Otherwise,
@racket[_content-expr] is typeset as the input form (which rarely makes sense for
a reader of the example).}
@item{A @racket[datum] of the form
@racket[(@#,indexed-racket[eval:results] _content-list-expr _out-expr _err-expr)]
is treated like an @racketidfont{eval:result} form, except that @racket[_content-list-expr]
should produce a list of @tech{content} for multiple results of evaluation. As
with @racketidfont{eval:result}, @racket[_out-expr] and @racket[_err-expr] are optional.}
@item{A @racket[datum] of the form
@racket[(@#,indexed-racket[eval:no-prompt] _eval-datum ...)]
is treated like @racket[(@#,racket[code:line] _eval-datum ...)], but no prompt is shown before
the group, and a blank line is added before and after
@(svar eval-datum) and its result.}
]
A @racket[datum] cannot be a keyword. To specify a @racket[datum] that
is a keyword, wrap it with @racket[code:line].
When evaluating a @racket[datum] produces an error (and @racket[datum]
does not have an @racket[eval:error] wrapper), an exception is raised
by @racket[examples].
If the value of @racket[current-print] in the sandbox is changed from
its default value, or if @racket[print-as-expression] in the sandbox
is set to @racket[#f], then each evaluation result is formatted to a
port by applying @racket[(current-print)] to the value; the output
port is set to a pipe that supports specials in the sense of
@racket[write-special], and non-character values written to the port
are used as @tech{content}. Otherwise, when the default
@racket[current-print] is in place, result values are typeset using
@racket[to-element/no-color].
As an example,
@codeblock|{
#lang scribble/manual
@(require racket/sandbox
scribble/eval)
@(define my-evaluator
(parameterize ([sandbox-output 'string]
[sandbox-error-output 'string])
(make-evaluator 'typed/racket/base)))
@examples[#:eval my-evaluator
(: my-sqr (Real -> Real))
(define (my-sqr x)
(* x x))
(my-sqr 42)]
}|
uses an evaluator whose language is @racketmodname[typed/racket/base].}
@defproc[(make-base-eval [#:pretty-print? pretty-print? any/c #t]
[#:lang lang
(or/c module-path?
(list/c 'special symbol?)
(cons/c 'begin list?))
'(begin)]
[input-program any/c] ...)
(any/c . -> . any)]{
Creates an evaluator using @racket[(make-evaluator 'racket/base #:lang lang input-program ...)],
setting sandbox parameters to disable limits, setting the outputs to
@racket['string], and not adding extra security guards.
If @racket[pretty-print?] is true, the sandbox's printer is set to
@racket[pretty-print-handler]. In that case, values that are convertible
in the sense of @racket[convertible?] are printed using @racket[write-special],
except that values that are serializable in the sense of @racket[serializable?]
are serialized for tranfers from inside the sandbox to outside (which can avoid
pulling code and support from the sandboxed environment into the document-rendering
environment).
@history[#:changed "1.6" @elem{Changed treatment of convertible values that are
serializable.}]}
@defproc[(make-base-eval-factory [mod-paths (listof module-path?)]
[#:pretty-print? pretty-print? any/c #t]
[#:lang lang
(or/c module-path?
(list/c 'special symbol?)
(cons/c 'begin list?))
'(begin)])
(-> (any/c . -> . any))]{
Produces a function that is like @racket[make-base-eval], except that
each module in @racket[mod-paths] is attached to the evaluator's
namespace. The modules are loaded and instantiated once (when the
returned @racket[make-base-eval]-like function is called the first
time) and then attached to each evaluator that is created.}
@defproc[(make-eval-factory [mod-paths (listof module-path?)]
[#:pretty-print? pretty-print? any/c #t]
[#:lang lang
(or/c module-path?
(list/c 'special symbol?)
(cons/c 'begin list?))
'(begin)])
(-> (any/c . -> . any))]{
Like @racket[make-base-eval-factory], but each module in @racket[mod-paths] is
also required into the top-level environment for each generated evaluator.}
@defproc[(make-log-based-eval [log-file path-string?]
[mode (or/c 'record 'replay)])
(-> any/c any)]{
Creates an evaluator (like @racket[make-base-eval]) that uses a log
file to either record or replay evaluations.
If @racket[mode] is @racket['record], the evaluator records every
interaction to @racket[log-file], replacing @racket[log-file] if it
already exists. The result of each interaction must be
@seclink["serialization" #:doc '(lib
"scribblings/reference/reference.scrbl")]{serializable}.
If @racket[mode] is @racket['replay], the evaluator uses the contents
of @racket[log-file] instead of actually performing evaluatings. For
each interaction, it compares the term to evaluate against the next
interaction recorded in @racket[log-file]. If the term matches, the
stored result is returned; if not, the evaluator raises an error
indicating that it is out of sync with @racket[log-file].
Use @racket[make-log-based-eval] to document libraries when the
embedded examples rely on external features that may not be present or
appropriately configured on all machines.
@history[#:added "1.12"]}
@defproc[(close-eval [eval (any/c . -> . any)]) (one-of/c "")]{
Shuts down an evaluator produced by @racket[make-base-eval]. Use
@racket[close-eval] when garbage collection cannot otherwise reclaim
an evaluator (e.g., because it is defined in a module body).}
@defparam[scribble-eval-handler handler
((any/c . -> . any) any/c boolean? . -> . any)]{
A parameter that serves as a hook for evaluation. The evaluator to use
is supplied as the first argument to the parameter's value, and the
second argument is the form to evaluate. The last argument is
@racket[#t] if exceptions are being captured (to display exception
results), @racket[#f] otherwise.}
@defparam[scribble-exn->string handler (-> (or/c exn? any/c) string?)]{
A parameter that controls how exceptions are rendered by
@racket[interaction]. Defaults to
@racketblock[(λ (e)
(if (exn? e)
(exn-message e)
(format "uncaught exception: ~s" e)))]
}
@; ------------------------------------------------------------
@include-section["eval.scrbl"]

View File

@ -1,14 +0,0 @@
#lang scribble/manual
@(require "utils.rkt")
@title[#:tag "generic-prose" #:style 'toc]{High-Level Scribble API}
@local-table-of-contents[]
@include-section["base.scrbl"]
@include-section["manual-stub.scrbl"]
@include-section["book.scrbl"]
@include-section["report.scrbl"]
@include-section["sigplan.scrbl"]
@include-section["jfp.scrbl"]
@include-section["lncs.scrbl"]

View File

@ -1,10 +0,0 @@
#lang scribble/manual
@title[#:tag "getting-started" #:style 'toc]{Getting Started}
@local-table-of-contents[]
@include-section["how-to-paper.scrbl"]
@include-section["how-to.scrbl"]

View File

@ -1,682 +0,0 @@
#lang scribble/doc
@(require scribble/manual scribble/bnf "utils.rkt"
pict
(for-label scriblib/figure scribble/base scribble/sigplan
(except-in pict table)))
@(define-syntax-rule (samplemod . text) (codeblock . text))
@(define-syntax-rule (sample a . text)
(codeblock #:context #'a #:keep-lang-line? #f
"#lang scribble/base" "\n" a . text))
@(define (result . text) (apply nested #:style 'inset text))
@(define sep @hspace[1])
@(define sub*section subsection)
@title[#:tag "getting-started"]{Getting Started}
No matter what you want to do with Scribble, it's best to start by
generating a few simple HTML and/or PDF documents. This chapter steps
you through the basics, and it ends in @secref["roadmap"] with
goal-specific advice on how to continue.
@section[#:tag "first-example"]{A First Example}
Create a file @filepath{mouse.scrbl} with this content:
@samplemod|{
#lang scribble/base
@title{On the Cookie-Eating Habits of Mice}
If you give a mouse a cookie, he's going to ask for a
glass of milk.
}|
The first line's @racket[#, @hash-lang[] #,
@racketmodname[scribble/base]] indicates that the file implements a
Scribble document. The document starts in ``text mode,'' and the
@litchar["@"] character escapes to operators like @racket[title],
where the curly braces return to text mode for the arguments to the
operator. The rest is document content.
Now run the @exec{scribble} command-line program, specifying a mode
for the kind of document that you want as output:
@itemize[
@item{Run
@commandline{scribble mouse.scrbl}
to generate HTML as @filepath{mouse.html}. You may
notice that the apostrophe in ``he's'' turned into a
curly apostrophe.}
@item{Run
@commandline{scribble --htmls mouse.scrbl}
to generate HTML as @filepath{mouse/index.html}.
Sub-sections (which we add next) will appear as separate
HTML files in the @filepath{mouse} directory.}
@item{Run
@commandline{scribble --pdf mouse.scrbl}
to generate PDF as @filepath{mouse.pdf}. This will
work only if you have @exec{pdflatex} installed.
If you'd like to see the intermediate Latex, try
@commandline{scribble --latex mouse.scrbl}
to generate @filepath{mouse.tex}.}
]
See @secref["running"] for more information on the @exec{scribble}
command-line tool.
@section{Multiple Sections}
Add more text to @filepath{mouse.scrbl} so that it looks like this:
@samplemod|{
#lang scribble/base
@title{On the Cookie-Eating Habits of Mice}
If you give a mouse a cookie, he's going to ask for a
glass of milk.
@section{The Consequences of Milk}
That ``squeak'' was the mouse asking for milk. Let's
suppose that you give him some in a big glass.
He's a small mouse. The glass is too big---way too
big. So, he'll probably ask you for a straw. You might as
well give it to him.
@section{Not the Last Straw}
For now, to handle the milk moustache, it's enough to give
him a napkin. But it doesn't end there... oh, no.
}|
Now, after the first paragraph of the paper, we have two
sub-sections, each created by calling @racket[section] to
generate a sub-section declaration. The first sub-section has
two paragraphs. The second section, as initiated by the result
of the second @racket[section] call, has a single paragraph.
Run the @exec{scribble} command(s) from @secref["first-example"]
again. You may notice the curly double-quotes in the output, and
the @litchar{---} turned into an em dash.
@;----------------------------------------
@section{Splitting the Document Source}
As a document grows larger, it's better to split sections into
separate source files. The @racket[include-section] operation
incorporates a document defined by a @filepath{.scrbl} file into a
larger document.
To split the example document into multiple files, change
@filepath{mouse.scrbl} to just
@samplemod|{
#lang scribble/base
@title{On the Cookie-Eating Habits of Mice}
If you give a mouse a cookie, he's going to ask for a
glass of milk.
@include-section["milk.scrbl"]
@include-section["straw.scrbl"]
}|
Create @filepath{milk.scrbl} and @filepath{straw.scrbl} in the same
directory as @filepath{mouse.scrbl}. In @filepath{milk.scrbl}, put
@samplemod|{
#lang scribble/base
@title{The Consequences of Milk}
That ``squeak'' was the mouse asking for milk...
}|
and in @filepath{straw.scrbl}, put
@samplemod|{
#lang scribble/base
@title{Not the Last Straw}
For now, to handle the milk moustache, ...
}|
Notice that the new files both start with @hash-lang[], like the
original document, and the @racket[section]s from the original
document become @racket[title]s in the new documents. Both
@filepath{milk.scrbl} and @filepath{straw.scrbl} are documents in
their own right with their own titles, and they can be individually
rendered using @exec{scribble}. Running @exec{scribble} on
@filepath{mouse.scrbl}, meanwhile, incorporates the smaller documents
into one document that is the same as before.
@; ----------------------------------------
@section{Document Styles}
Scribble currently supports only one form of HTML output. You can
replace the @filepath{scribble.css} file for the generated pages, and
that's about it. (We expect to add more styles in the future.)
For Latex-based PDF output, Scribble includes support for
multiple page-layout configurations. The @filepath{mouse.scrbl}
example so far uses the default Latex style. If you plan on submitting
the paper to a workshop on programming languages, then---well, you
probably need a different topic. But you can start making the current
content look right by changing the first line to
@samplemod|{
#lang scribble/sigplan
}|
If you're instead working toward Racket library documentation,
try changing the first line to
@samplemod|{
#lang scribble/manual
}|
which produces output with a separate title page, initial content on
that page (intended as a brief orientation to the document), and
top-level sections turned into chapters that each start on a new page.
If you have split the document into multiple files, the first line of
the main document file determines the output format.
Using @racketmodname[scribble/sigplan] or
@racketmodname[scribble/manual] does not change the rendered HTML for
a document---aside from @racketmodname[scribble/manual] adding a
version number---but it changes the set of bindings available in the
document body. For example, with @racketmodname[scribble/sigplan], the
introductory text can be marked as an abstract:
@samplemod|{
#lang scribble/sigplan
@title{On the Cookie-Eating Habits of Mice}
@abstract{If you give a mouse a cookie, he's going to
ask for a glass of milk.}
@section{The Consequences of Milk}
....}|
When rendered as HTML, the abstract shows up as an inset paragraph. If
you try to use @racket[abstract] with the
@racketmodname[scribble/base] or @racketmodname[scribble/manual]
language, then you get an error, because @racket[abstract] is not
defined.
When a document is implemented across multiple files, changing the
language of the main document can set the style for all of the parts,
but it does not introduce bindings into the other part files. For
example, if you change the language of @filepath{mouse.scrbl} to
@racketmodname[scribble/sigplan], then @racket[abstract] becomes
available in @filepath{mouse.scrbl} but not in @filepath{milk.scrbl}
or @filepath{straw.scrbl}. In other words, operator names are
lexically scoped.
@; ----------------------------------------
@section{More Functions}
The @racketmodname[scribble/base] language provides a collection of
basic operations (and The @racketmodname[scribble/sigplan] and
@racketmodname[scribble/manual] are supersets of
@racketmodname[scribble/base]). Many of the operations are style
variations that you can apply to text:
@sample|{
He's a @smaller{small mouse}. The glass is too
@larger{big}---@bold{way @larger{too @larger{big}}}. So, he'll
@italic{probably} ask you for a straw.
}|
which renders as
@result{
He's a @smaller{small mouse}. The glass is too
@larger{big}---@bold{way @larger{too @larger{big}}}. So, he'll
@italic{probably} ask you for a straw.
}
As you would expect, calls to functions like @racket[smaller],
@racket[larger], and @racket[bold] can be nested in other calls. They
can also be nested within calls to @racket[title] or @racket[section]:
@sample|{
@section{@italic{Not} the Last Straw}
}|
@sub*section{Centering}
The @racket[centered] operation centers a flow of text:
@sample|{
If a mouse eats all your cookies, put up a sign that says
@centered{
@bold{Cookies Wanted}
@italic{Chocolate chip preferred!}
}
and see if anyone brings you more.
}|
which renders as
@result{
If a mouse eats all your cookies, put up a sign that says
@centered{
@bold{Cookies Wanted}
@italic{Chocolate chip preferred!}
}
and see if anyone brings you more.
}
@sub*section{Margin Notes}
The @racket[margin-note] operation is used in a similar way, but the
rendered text is moved to the margins.
@margin-note*{If you use @racket[margin-note], then the content shows
up over here.}
@sub*section{Itemizations}
The @racket[itemlist] operation creates a sequence of bulleted text,
where the @racket[item] operation groups text to appear in a single
bullet. The @racket[itemlist] operation is different from the others
that we have seen before, because it only accepts values produced by
@racket[item] instead of arbitrary text. This difference is reflected
in the use of @litchar{[}...@litchar{]} for the arguments to
@racket[itemlist] instead of @litchar["{"]...@litchar["}"]:
@sample|{
@centered{@bold{Notice to Mice}}
@itemlist[@item{We have cookies for you.}
@item{If you want to eat a cookie,
you must bring your own straw.}]
}|
which renders as
@result{
@centered{@bold{Notice to Mice}}
@itemlist[@item{We have cookies for you.}
@item{If you want to eat a cookie,
you must bring your own straw.}]
}
@sub*section{Tables}
The @racket[tabular] function takes a list of lists to organize into a
two-dimensional table. By default, no spacing is added between columns,
so supply a @racket[#:sep] argument to acts as a column separator.
For example,
@sample|{
@tabular[#:sep @hspace[1]
(list (list @bold{Animal} @bold{Food})
(list "mouse" "cookie")
(list "moose" "muffin"))]
}|
renders as
@result{
@tabular[#:sep @hspace[1]
(list (list @bold{Animal} @bold{Food})
(list "mouse" "cookie")
(list "moose" "muffin"))]
}
@; ----------------------------------------
@section{Text Mode vs. Racket Mode for Arguments}
When @litchar{[}...@litchar{]} surrounds the arguments of an
operation, the argument expressions are in Racket mode rather than
text mode. Even in Racket mode, @litchar["@"] can be used to apply
operations; once the @"@" syntax is enabled through a
language like @racketmodname[scribble/base] (as opposed to
@racketmodname[racket]), it behaves the same in both Racket mode and
text mode.
One advantage of using Racket mode for the arguments to
@racket[itemlist] is that we can pass a keyword-tagged optional
argument to @racket[itemlist]. In particular, if you want a list with
numbers instead of bullets, supply the @racket['ordered] style to
@racket[itemlist] using the @racket[#:style] keyword:
@sample|{
@itemlist[#:style 'ordered
@item{Eat cookie.}
@item{Drink milk.}
@item{Wipe mouth.}
@item{...}]
}|
An operation doesn't care whether it's used with
@litchar{[}...@litchar{]} or @litchar["{"]...@litchar["}"]. Roughly,
@litchar["{"]...@litchar["}"] forms an argument that is a
string. (Only roughly, though. Newlines or uses of @litchar["@"]
within @litchar["{"]...@litchar["}"] complicate the picture, and we'll
get back to that soon.) So,
@sample|{
@italic{Yummy!}
}|
is equivalent to
@sample|{
@italic["Yummy!"]
}|
which is equivalent to the Racket expression
@racketblock[
(italic "Yummy!")
]
These equivalences explain why Scribble functions are documented in
Racket notation. If you're reading this in HTML format, you can click
@racket[italic] above to access its documentation. The documentation
won't completely make sense, yet, but it will by the end of this
chapter.
What if you want to provide arguments in text mode, but you also want
to supply other optional arguments? You can use both
@litchar{[}...@litchar{]} and @litchar["{"]...@litchar["}"] for an
operation, as long as the @litchar{[}...@litchar{]} is first, and as
long as no character separate the closing @litchar{]} from the
opening @litchar["{"]. For example, calling @racket[italic] is the
same as using @racket[elem] with the @racket['italic] style:
@sample|{
@elem[#:style 'italic]{Yummy!}
}|
You can also @emph{omit} both @litchar{[}...@litchar{]} and
@litchar["{"]...@litchar["}"]. In that case, the Racket expression
after @litchar["@"] is used directly instead of applied as an
operation. For example,
@sample|{
1 plus 2 is @(number->string (+ 1 2)).
}|
renders as
@result{
1 plus 2 is @(number->string (+ 1 2)).
}
The call to @racket[number->string] is needed because a naked number
is not valid as document content.
@; ----------------------------------------
@section[#:tag "how-to:reader"]{@"@" Syntax Basics}
The @"@" notation provided by Scribble is just another way of
writing Racket expressions. Scribble documents could be constructed
using normal Racket notation, without using @"@" at all, but
that would be inconvenient for most purposes. The @"@"
notation makes dealing with textual content much easier.
Whether in text mode or Racket mode, @litchar["@"] in a document
provides an escape to Racket mode. The basic syntax of @litchar["@"] is
@racketblock[
@#,BNF-seq[@litchar["@"]
@nonterm{cmd}
@litchar{[} @kleenestar{@nonterm{datum}} @litchar{]}
@litchar["{"] @nonterm{text-body} @litchar["}"]]
]
where all three parts after @litchar["@"] are optional, but at least
one must be present. No spaces are allowed between
@itemize[
@item{@litchar["@"] and @nonterm{cmd}, @litchar{[}, or @litchar["{"]}
@item{@nonterm{cmd} and @litchar{[} or @litchar["{"]; or}
@item{@litchar{]} and @litchar["{"].}
]
A @nonterm{cmd} or @nonterm{datum} is normal Racket notation, while a
@nonterm{text-body} is itself in text mode. A @nonterm{cmd} obviously
must not start with @litchar{[} or @litchar["{"], even though Racket
forms could otherwise start with those characters.
The expansion of just @litchar["@"]@nonterm{cmd} into Racket code is
@racketblock[
@#,nonterm{cmd}
]
When either @litchar{[} @litchar{]} or @litchar["{"] @litchar["}"]
are used, the expansion is
@racketblock[
(@#,nonterm{cmd} @#,kleenestar{@nonterm{datum}} @#,kleenestar{@nonterm{parsed-body}})
]
where @kleenestar{@nonterm{parsed-body}} is the parse result of the
@nonterm{text-body}. The @kleenestar{@nonterm{parsed-body}} part often
turns out to be a sequence of Racket strings.
In practice, the @nonterm{cmd} is normally a Racket identifier that is
bound to a procedure or syntactic form. If the procedure or form
expects further text to typeset, then @litchar["{"]...@litchar["}"]
supplies the text. If the form expects other data, typically
@litchar{[}...@litchar{]} is used to surround Racket arguments,
instead. Even if an operation's argument is a string, if the string is
not used as content text (but instead used as, say, a hyperlink
label), then the string is typically provided through
@litchar{[}...@litchar{]} instead of @litchar["{"]...@litchar["}"].
Sometimes, both @litchar{[}...@litchar{]} and
@litchar["{"]...@litchar["}"] are used, where the former surround
Racket arguments that precede text to typeset. Finally, if a form is a
purely Racket-level form with not typeset result, such as a
@racket[require] to import more operations, then typically just
@litchar["@"] is used.
For example the text-mode stream
@sample|{
@(require scriblib/figure)
@section[#:tag "poetry"]{Of Mice and Cookies}
See @secref["milk"].
@section[#:tag "milk"]{@italic{Important} Milk Supplies}
@figure["straw" @elem{A straw}]{@image["straw.png"]}
}|
is equivalent to the Racket-mode sequence
@racketblock[
(require scriblib/figure) "\n"
"\n"
(section #:tag "poetry" "Of Mice and Cookies") "\n"
"See " (secref "milk") "." "\n"
"\n"
(section #:tag "milk" (italic "Important") " Milk Supplies") "\n"
(figure "straw" (elem "A straw") (image "straw.png")) "\n"
]
Besides showing how different argument conventions are used for
different operations, the above example illustrates how whitespace is
preserved in the Racket form of a text-mode stream---including
newlines preserved as their own strings. Notice how the second
@racket[section] gets two arguments for its content, since the
argument content for @racket[section] in the source stream includes
both the use of an operator and additional text. When an operation
like @racket[section] or @racket[italic] accepts content to typeset,
it normally accepts an arbitrary number of arguments that together
form the content.
In addition to its role for command, a @litchar["@"] can be followed
by @litchar{;} to start a @index['("Scribble"
"comments")]{comment}. If the character after @litchar{;} is
@litchar["{"], then the comment runs until a matching @litchar["}"],
otherwise the comment runs until the end-of-line:
@racketblock[
@#,BNF-seq[@litchar["@;{"] @nonterm{comment} @litchar["}"]]
@#,BNF-seq[@litchar["@;"] @nonterm{line-comment}]
]
For more information on the syntax of @litchar["@"], see
@secref["reader"]. The full syntax includes a few more details, such
as brackets like @litchar["|{"]...@litchar["}|"] for text-mode
arguments while disabling @litchar["@"] between the brackets.
@; ----------------------------------------
@section{Decoding Sequences}
In a document that starts @racket[#, @hash-lang[] #,
@racketmodname[scribble/base]], the top level is a text-mode stream,
just like the @nonterm{text-body} in a @litchar["@"] form. As
illustrated in the previous section, such a top-level sequence
corresponds to a mixture of Racket-mode strings and operation
applications. There's an implicit operation, @racket[decode], that
wraps the whole document to consume this mixture of strings and other
values and turn them into a document description.
The @racket[decode] operation implements @defterm{flow decoding},
which takes a document stream and breaks it up into sections and
paragraphs. Blank lines delimit paragraphs, and the results of
operations like @racket[title] and @racket[section] generate ``here's
the title'' or ``a new section starts here'' declarations that are
recognized by @racket[decode].
A different but related @defterm{content decoding} takes place within
a paragraph or section title. Content decoding is responsible for
converting @litchar{---} to an em dash or for converting @litchar{"}
and @litchar{'} to suitable curly quotes.
The decoding process for document's stream is ultimately determined by
the @hash-lang[] line that starts the document. The
@racketmodname[scribble/base], @racketmodname[scribble/manual], and
@racketmodname[scribble/sigplan] languages all use the same
@racket[decode] operation. The @racketmodname[scribble/text] language,
however, acts more like a plain-text generator and preprocessor, and it
does not perform any such decoding rules. (For more on
@racketmodname[scribble/text], see @other-doc['(lib
"scribblings/scribble/scribble-pp.scrbl")].)
@margin-note{More precisely, languages like
@racketmodname[scribble/base] apply @racket[decode] only after
lifting out all definitions and imports from the document
stream.}
When the flow decoder is used, after it breaks the input stream into
paragraphs, it applies content decoding to strings within the
paragraph. When content is wrapped with an operation, however, content
decoding does not apply automatically. An operation is responsible for
calling a content or flow decoder as it sees fit. Most operations call
the decoder; for example, @racket[italic], @racket[bold],
@racket[smaller], etc., all decode their arguments. Similarly,
@racket[title] and @racket[section] decode the given content for the
title or section name. The @racket[literal] and @racket[verbatim]
operators, however, do not decode the given strings. For example,
@sample|{
@verbatim{---}
}|
renders as
@result{
@verbatim{---}
}
Don't confuse decoding with the expansion of @"@"
notation. The source form
@sample|{
@verbatim{@(number->string (+ 1 2))}
}|
renders as
@result{
@verbatim{@(number->string (+ 1 2))}
}
because the source is equivalent to
@racketblock[
(verbatim (number->string (+ 1 2)))
]
where @racket[(number->string (+ 1 2))] is evaluated to produce the
argument to @racket[verbatim]. The @litchar["|{"]...@litchar["}|"]
style of brackets is often used with @racket[verbatim], because
@litchar["|{"]...@litchar["}|"] disables @"@" notation for
arguments. For example,
@sample|{
@verbatim|{@(number->string (+ 1 2))}|
}|
renders as
@result{
@verbatim|{@(number->string (+ 1 2))}|
}
@; ----------------------------------------
@section[#:tag "pictures"]{Pictures}
Any value that is convertable to an image can be used directly within
a Scribble document. Functions from the @racketmodname[pict]
and @racketmodname[2htdp/image #:indirect] libraries, for example, generate
images. For example,
@sample|{
@(require pict)
This cookie has lost its chocolate chips:
@(colorize (filled-ellipse 40 40) "beige").
}|
renders as
@result{
This cookie has lost its chocolate chips:
@(colorize (filled-ellipse 40 40) "beige").
}
@; ----------------------------------------
@section[#:tag "roadmap"]{Next Steps}
If your immediate goal is to document a Racket library or write
literate programs, skip to @secref["how-to-doc"], and then go back to
@secref["reader"] and other chapters.
If you are more interested in producing documents unrelated to
Racket, continue with @secref["reader"] and then
@secref["generic-prose"]. Move on to @secref["internals"] when you
need more power.
If you are interested in text generation and preprocessing, continue
with @secref["reader"], but then switch to
@other-doc['(lib "scribblings/scribble/scribble-pp.scrbl")].

View File

@ -1,381 +0,0 @@
#lang scribble/doc
@(require scribble/manual scribble/bnf "utils.rkt")
@(define pkg-doc '(lib "pkg/scribblings/pkg.scrbl"))
@title[#:tag "how-to-doc"]{Getting Started with Documentation}
Although the @exec{scribble} command-line utility generates output
from a Scribble document, documentation of Racket libraries is
normally built by @exec{raco setup}. This chapter emphasizes the
@exec{raco setup} approach, which more automatically supports links
across documents.
@margin-note{See @secref["getting-started"] for information on using the
@exec{scribble} command-line utility.}
@;----------------------------------------
@section[#:tag "setting-up"]{Setting Up Library Documentation}
To document a collection, including a collection implemented by a
@seclink["getting-started" #:doc pkg-doc]{package}:
@itemize[
@item{Create a file in your collection with the
file extension @filepath{.scrbl}. Beware that the file name
you choose will determine the output directory's name, and
the directory name must be unique across all installed documents. The
remainder of these instructions assume that the file is called
@filepath{manual.scrbl} (but pick a more specific name in practice).}
@item{Start @filepath{manual.scrbl} like this:
@codeblock|{
#lang scribble/manual
@title{My Library}
Welcome to my documentation: @racket[(list 'testing 1 2 3)].
}|
The first line starts the file in ``text'' mode and selects
the Racket manual output format.
It also introduces bindings like @racket[title] and
@racket[racket] for writing Racket documentation.}
@item{Add the following entry to your collection's
@filepath{info.rkt}:
@racketblock[
(define scribblings '(("manual.scrbl" ())))
]
The @racket[()] above is a list of options. When your document
gets large enough that you want it split into multiple pages,
add the @racket['multi-page] option (omitting the quote, since
the whole right-hand side of the definition is already
quoted).
If you do not already have an @filepath{info.rkt} module,
here's a suitable complete module:
@racketmod[
info
(define scribblings '(("manual.scrbl" ())))
]}
@item{Run @exec{raco setup} to build your documentation. For a
collection, optionally supply @Flag{l} followed by the
collection name to limit the build process to that
collection.}
@item{For a collection that is installed as user-specific
(e.g., the user @tech[#:doc pkg-doc]{package scope}), the generated
documentation is @filepath{doc/manual/index.html} within the
collection directory. If the collection is installation-wide,
however, then the documentation
is generated as @filepath{manual/index.html} in the
installation's @filepath{doc} directory.}
]
@; ----------------------------------------
@section[#:tag "racket-hyperlinks"]{Racket Typesetting and Hyperlinks}
In the document source at the start of this chapter
(@secref["setting-up"]), the Racket expression
@racket[(#,(racketidfont "list") 'testing 1 2 3)] is typeset properly,
but the @racketidfont{list} identifier is not hyperlinked to the usual
definition. To cause @racketidfont{list} to be hyperlinked, add a
@racket[require] form like this:
@codeblock[#:keep-lang-line? #f]|{
#lang scribble/base
@(require (for-label racket))
}|
This @racket[require] with @racket[for-label] declaration introduces a
document-time binding for each export of the @racketmodname[racket]
module. When the document is built, the @racket[racket] form detects
the binding for @racket[list], and so it generates a reference to the
specification of @racket[list]. The setup process detects the
reference, and it finds the matching specification in the existing
documentation, and ultimately directs the hyperlink to that
specification.
Hyperlinks based on @racket[for-label] and @racket[racket] are the
preferred mechanism for linking to information outside of a single
document. Such links require no information about where and how a
binding is documented elsewhere:
@codeblock|{
#lang scribble/manual
@(require (for-label racket))
@title{My Library}
See also @racket[list].
}|
The @racket[racket] form typesets a Racket expression for inline text,
so it ignores the source formatting of the expression. The
@racket[racketblock] form, in contrast, typesets inset Racket code,
and it preserves the expression's formatting from the document source.
@codeblock|{
#lang scribble/manual
@(require (for-label racket))
@title{My Library}
Some example Racket code:
@racketblock[
(define (nobody-understands-me what)
(list "When I think of all the"
what
"I've tried so hard to explain!"))
(nobody-understands-me "glorble snop")
]
}|
@; ----------------------------------------
@section[#:tag "section-hyperlinks"]{Section Hyperlinks}
A @racket[section] declaration in a document can include a
@racket[#:tag] argument that declares a hyperlink-target tag. The
@racket[secref] function generates a hyperlink, using the section name
as the text of the hyperlink. Use @racket[seclink] to create a
hyperlink with text other than the section title.
The following example illustrates section hyperlinks:
@codeblock|{
#lang scribble/manual
@(require (for-label racket))
@title{My Library}
Welcome to my documentation: @racket[(list 'testing 1 2 3)].
@table-of-contents[]
@section[#:tag "chickens"]{Philadelphia Chickens}
Dancing tonight!
@section{Reprise}
See @secref{chickens}.
}|
Since the page is so short, the hyperlinks in the above example are
more effective if you change the @filepath{info.rkt} file to add the
@racket['multi-file] flag:
@racketblock[
(define scribblings '(("manual.scrbl" (multi-page))))
]
A section can have a @techlink{tag prefix} that applies to all tags as
seen from outside the section. Such a prefix is automatically given to
each top-level document as processed by @exec{raco setup}. Thus,
referencing a section tag in a different document requires using a
prefix, which is based on the target document's main source file. The
following example links to a section in the Racket reference
manual:
@codeblock|{
#lang scribble/manual
@(require (for-label racket))
@(define ref-src
'(lib "scribblings/reference/reference.scrbl"))
@title{My Library}
See also @italic{@secref[#:doc ref-src]{pairs}}.
}|
As mentioned in @secref{racket-hyperlinks}, however, cross-document
references based on @racket[(require (for-label ....))] and
@racket[racket] are usually better than cross-document references
using @racket[secref].
@; ----------------------------------------
@section{Defining Racket Bindings}
Use @racket[defproc] to document a procedure, @racket[defform] to
document a syntactic form, @racket[defstruct] to document a structure
type, etc. These forms provide consistent formatting of definitions,
and they declare hyperlink targets for @racket[racket]-based
hyperlinks.
To document a @racket[my-helper] procedure that is exported by
@filepath{helper.rkt} in the @filepath{my-lib} collection that contains
@filepath{manual.scrbl}:
@itemize[
@item{Use @racket[(require (for-label "helper.rkt"))] to import the
binding information about the bindings of @filepath{helper.rkt}
for use when typesetting identifiers. A relative reference
@racket["helper.rkt"] works since it is relative to the
documentation source.}
@item{Add a @tt|{@defmodule[my-lib/helper]}| declaration, which
specifies the library that is being documented within the
section. The @racket[defmodule] form needs an absolute module
name @racket[mylib/helper], instead of a relative reference
@racket["helper.rkt"], since the module path given to
@racket[defmodule] appears verbatim in the generated
documentation.}
@item{Use @racket[defproc] to document the procedure.}
]
Adding these pieces to @filepath{manual.scrbl} gives us the
following:
@codeblock|{
#lang scribble/manual
@(require (for-label racket
"helper.rkt"))
@title{My Library}
@defmodule[my-lib/helper]
@defproc[(my-helper [lst list?])
(listof
(not/c (one-of/c 'cow)))]{
Replaces each @racket['cow] in @racket[lst] with
@racket['aardvark].}
}|
In @racket[defproc], a contract is specified with each argument to the
procedure. In this example, the contract for the @racket[_lst]
argument is @racket[list?], which is the contract for a list. After
the closing parenthesis that ends the argument sequence, the contract
of the result must be given; in this case, @racket[my-helper]
guarantees a result that is a list where none of the elements are
@racket['cow].
Some things to notice in this example and the documentation that it
generates:
@itemize[
@item{The @racket[list?], @racket[listof], @|etc| elements of
contracts are hyperlinked to their documentation.}
@item{The result contract is formatted in the generated documentation
in the same way as in the source. That is, the source layout of
contracts is preserved. (In this case, putting the contract all
on one line would be better.)}
@item{In the prose that documents @racket[my-helper], @racket[_lst]
is automatically typeset in italic, matching the typesetting in
the blue box. The @racket[racket] form essentially knows that
it's used in the scope of a procedure with argument
@racket[_lst].}
@item{If you hover the mouse pointer over @racket[my-helper], a popup
reports that it is provided from @racketidfont{my-lib/helper}.}
@item{If you use @racket[my-helper] in any documentation now, as long
as that documentation source also has a @racket[(require
(for-label ....))] of @filepath{helper.rkt}, then the
reference is hyperlinked to the definition above.}
]
See @racket[defproc*], @racket[defform], @|etc| for more information
on forms to document Racket bindings.
@; ----------------------------------------
@section{Showing Racket Examples}
The @racket[examples] form from @racket[scribble/eval] helps you
generate examples in your documentation. To use @racket[examples], the
procedures to document must be suitable for use at documentation time,
but the @racket[examples] form does not use any binding introduced
into the document source by @racket[require]. Instead, create a new
evaluator with its own namespace using @racket[make-base-eval], and
use @racket[interaction-eval] to require @filepath{helper.rkt} in that
evaluator. Finally, supply the same evaluator to @racket[examples]:
@codeblock|{
#lang scribble/manual
@(require scribble/eval
(for-label racket
"helper.rkt"))
@title{My Library}
@defmodule[my-lib/helper]
@defproc[(my-helper [lst list?])
(listof
(not/c (one-of/c 'cow)))]{
Replaces each @racket['cow] in @racket[lst] with
@racket['aardvark].
@(define helper-eval (make-base-eval))
@interaction-eval[#:eval helper-eval
(require "helper.rkt")]
@examples[
#:eval helper-eval
(my-helper '())
(my-helper '(cows such remarkable cows))
]}
}|
@;----------------------------------------
@section{Multi-Page Sections}
Setting the @racket['multi-page] option (see
@secref["section-hyperlinks"]) causes each top-level section of a
document to be rendered as a separate HTML page.
To push sub-sections onto separate pages, use the @racket['toc] style
for the enclosing section (as started by @racket[title],
@racket[section], @racket[subsection], etc.) and use
@racket[local-table-of-contents] to generate hyperlinks to the
sub-sections.
Revising @filepath{cows.scrbl} from the previous section:
@codeblock|{
#lang scribble/manual
@title[#:style '(toc)]{Cows}
@local-table-of-contents[]
@section[#:tag "singing"]{Singing}
Wherever they go, it's a quite a show.
@section{Dancing}
See @secref["singing"].
}|
To run this example, remember to change @filepath{info.rkt} to add the
@racket['multi-page] style. You may also want to add a call to
@racket[table-of-contents] in @filepath{manual.scrbl}.
The difference between @racket[table-of-contents] and
@racket[local-table-of-contents] is that the latter is ignored for
Latex output.
When using @racket[local-table-of-contents], it often makes sense to
include introductory text before the call of
@racket[local-table-of-contents]. When the introductory text is less
important and when local table of contents is short, putting the
introductory text after the call of @racket[local-table-of-contents]
may be appropriate.

View File

@ -1,494 +0,0 @@
#lang scribble/doc
@(require scribble/manual
scribble/core
scribble/eval
(only-meta-in 0 "utils.rkt")
(for-label (except-in racket/base #%top #%module-begin)
racket/contract/base
racket/string
scribble/html))
@(define html-eval (make-base-eval))
@interaction-eval[#:eval html-eval (require scribble/html)]
@interaction-eval[#:eval html-eval (require racket/string)]
@title[#:tag "html" #:style 'toc]{HTML Generation}
@defmodulelang[scribble/html]{The @racketmodname[scribble/html]
language provides a way to generate HTML that is different from
@racketmodname[scribble/base]. The @racketmodname[scribble/base]
approach involves describing a document that can be rendered to HTML,
Latex, or other formats. The @racketmodname[scribble/html] approach,
in contrast, treats the document content as HTML format plus escapes.}
Specifically, @racketmodname[scribble/html] is like
@racketmodname[scribble/text], but with the following changes:
@itemize[
@item{The @racketmodname[scribble/html/html],
@racketmodname[scribble/html/xml], and
@racketmodname[scribble/html/resource] are re-exported,
in addition to @racketmodname[scribble/text].}
@item{Free identifiers that end with @litchar{:} are implicitly
quoted as symbols.}
]
When @racketmodname[scribble/html] is used via @racket[require]
instead of @hash-lang[], then it does not change the printing of
values, and it does not include the bindings of @racket[racket/base].
The @racketmodname[scribble/html/resource],
@racketmodname[scribble/html/xml], and
@racketmodname[scribble/html/html] libraries provide forms for
generating HTML as strings to be output in the same way as
@racketmodname[scribble/text].
@local-table-of-contents[]
@; ----------------------------------------
@section[#:tag "html-html"]{Generating HTML Strings}
@defmodule[scribble/html/html]{The @racketmodname[scribble/html/html]
provides functions for HTML representations that render to string form
via @racket[output-xml].}
@defproc[(doctype [s (or/c string 'html 'xhtml)]) procedure?]{
Produces a value that @tech{XML-renders} as a DOCTYPE declaration.
@examples[#:eval html-eval
(output-xml (doctype "?"))
(output-xml (doctype 'html))
(regexp-split #rx"\n|((?<=\") (?=\"))"
(xml->string (doctype 'xhtml)))]}
@defproc[(xhtml [content outputable/c] ...) procedure?]{
Produces a value that @tech{XML-renders} as the given content wrapped
as XHTML.
@examples[#:eval html-eval
(regexp-split #rx"\n|((?<=\") (?=\"))"
(xml->string (xhtml "Hello")))]}
@(define-syntax-rule (def-tags tag ...)
@deftogether[(
@defproc[(tag [v outputable/c] (... ...)) procedure?] ...
)]{
Like @racket[element/not-empty], but with the symbolic form of the function
name added as the first argument.
@examples[#:eval html-eval
(output-xml (title "The Book"))]})
@(def-tags
html
head
title
style ; style info, which may include CDATA sections
script ; script statements, which may include CDATA sections
noscript ; alternate content container for non script-based rendering
frameset ; only one noframes element permitted per document
frame ; tiled window within frameset
iframe ; inline subwindow
noframes ; alternate content container for non frame-based rendering
body
div ; generic language/style container
p
h1
h2
h3
h4
h5
h6
ul ; Unordered list
ol ; Ordered (numbered) list
menu ; single column list (DEPRECATED)
dir ; multiple column list (DEPRECATED)
li ; list item
dl ; definition lists - dt for term, dd for its definition
dt
dd
address ; information on author
pre
blockquote
center ; center content
ins
del
a ; content is inline; except that anchors shouldn't be nested
span ; generic language/style container
bdo ; I18N BiDi over-ride
em ; emphasis
strong ; strong emphasis
dfn ; definitional
code ; program code
samp ; sample
kbd ; something user would type
var ; variable
cite ; citation
abbr ; abbreviation
acronym ; acronym
q ; inlined quote
sub ; subscript
sup ; superscript
tt ; fixed pitch font
i ; italic font
b ; bold font
big ; bigger font
small ; smaller font
u ; underline
s ; strike-through
strike ; strike-through
font ; local change to font
object ; embeded objects
applet ; Java applet
form ; forms shouldn't be nested
label ; text that belongs to a form control
select ; option selector
optgroup ; option group
option ; selectable choice
textarea ; multi-line text field
fieldset ; group form fields
legend ; fieldset label (one per fieldset)
button ; push button
table ; holds caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+)
caption ; caption text
thead ; header part, holds tr
tfoot ; footer part, holds tr
tbody ; body part, holds tr
colgroup ; column group, olds col
tr ; holds th or td
th ; header cell
td)
@(define-syntax-rule (def-tags/empty tag ...)
@deftogether[(
@defproc[(tag [v outputable/c] (... ...)) procedure?] ...
)]{
Like @racket[element], but with the symbolic form of the function
name added as the first argument.
@examples[#:eval html-eval
(output-xml (hr))]})
@(def-tags/empty
base meta link hr br basefont param img area input isindex col)
@(define-syntax-rule (def-entities ent ...)
@deftogether[(
@defthing[ent procedure?] ...
)]{
The result of @racket[(entity '_id)] for each @racket[_id].
@examples[#:eval html-eval
(output-xml nbsp)]})
@(def-entities
nbsp ndash mdash bull middot sdot lsquo rsquo sbquo ldquo rdquo bdquo
lang rang dagger Dagger plusmn deg)
@defproc[(script/inline [v outputable/c] ...) procedure?]{
Procedures a value that renders as an inline script.
@examples[#:eval html-eval
(output-xml (script/inline type: "text/javascript" "var x = 5;"))]}
@defproc[(style/inline [v outputable/c] ...) procedure?]{
Procedures a value that renders as an inline style sheet.
@examples[#:eval html-eval
(output-xml (style/inline type: "text/css"
".racket { font-size: xx-large; }"))]}
@; ----------------------------------------
@section[#:tag "html-xml"]{Generating XML Strings}
@defmodule[scribble/html/xml]{The @racketmodname[scribble/html/xml]
provides functions for XML representations that @deftech{XML-render} to string form
via @racket[output-xml] or @racket[xml->string].}
@defproc[(output-xml [content outputable/c] [port output-port? (current-output-port)])
void?]{
Renders @racket[content] in the same way as @racket[output], but using
the value of @racket[xml-writer] as the @tech{current writer} so that
special characters are escaped as needed.}
@defproc[(xml->string [content outputable/c]) string?]{
Renders @racket[content] to a string via @racket[output-xml].}
@defparam[xml-writer writer ((string? output-port? . -> . void))]{
A parameter for a function that is used with @racket[with-writer] by
@racket[output-xml]. The default value is a function that escapes
@litchar{&}, @litchar{<}, @litchar{>}, and @litchar{"} to entity form.}
@defproc[(make-element [tag symbol?]
[attrs (listof (cons/c symbol? outputable/c))]
[content outputable/c])
(and/c procedure outputable/c?)]{
Produces a value that @tech{XML-renders} as XML for the
given tag, attributes, and content.
When an attribute in @racket[attrs] is mapped to @racket[#f], then it
is skipped. When an attribute is mapped to @racket[#t], then it is
rendered as present, but without a value.
@examples[#:eval html-eval
(output-xml (make-element 'b '() '("Try" #\space "Racket")))
(output-xml (make-element 'a '((href . "http://racket-lang.org")) "Racket"))
(output-xml (make-element 'div '((class . "big") (overlay . #t)) "example"))
]}
@defproc[(element [tag symbol?] [attrs-and-content any/c] ...)
(and procedure outputable/c?)]{
Like @racket[make-element], but the list of @racket[attrs-and-content]
is parsed via @racket[attributes+body] to separate the attributes and
content.
@examples[#:eval html-eval
(output-xml (element 'b "Try" #\space "Racket"))
(output-xml (element 'a 'href: "http://racket-lang.org" "Racket"))
(output-xml (element 'div 'class: "big" 'overlay: #t "example"))
(require scribble/html)
(output-xml (element 'div class: "big" overlay: #t "example"))
]}
@defproc[(element/not-empty [tag symbol?] [attrs-and-content any/c] ...)
(and/c procedure? outputable/c)]{
Like @racket[element], but the result always renders with an separate
closing tag.
@examples[#:eval html-eval
(output-xml (element 'span))
(output-xml (element/not-empty 'span))
]}
@defproc[(attribute? [v any/c]) (or/c #f symbol?)]{
Returns a symbol without if @racket[v] is a symbol that ends with
@litchar{:}, @racket[#f] otherwise. When a symbol is returned, it is
the same as @racket[v], but without the trailing @litchar{:}.
@examples[#:eval html-eval
(attribute? 'a:)
(attribute? 'a)
(require scribble/html)
(attribute? a:)
]}
@defproc[(attributes+body [lst list?]) (values (listof (cons/c symbol? any/c))
list?)]{
Parses @racket[lst] into an association list mapping attributes to
list elements plus a list of remaining elements. The first
even-positioned (counting from 0) non-@racket[attribute?] element of
@racket[lst] is the start of the ``remaining elements'' list, while
each preceding even-positioned attribute is mapped in the association
list to the immediately following element of @racket[lst]. In the
association list, the trailing @litchar{:} is stripped for each
attribute.}
@defproc[(split-attributes+body [lst list?]) (values list? list?)]{
Like @racket[attributes+body], but produces a flat list (of
alternating attributes and value) instead of an association list as
the first result.}
@defproc[(literal [content any/c] ...) procedure?]{
Produces a value that @tech{XML-renders} without escapes
for special characters.
@examples[#:eval html-eval
(output-xml (literal "a->b"))
(output-xml "a->b")]}
@defproc[(entity [v (or/c exact-integer? symbol?)]) procedure?]{
Produces a value that @tech{XML-renders} as a numeric or
symbolic entity.
@examples[#:eval html-eval
(output-xml (entity 'gt))]}
@defproc[(comment [content outputable/c] ... [#:newlines? newlines? any/c #f])
procedure?]{
Produces a value that @tech{XML-renders} as a comment with
literal content. If @racket[newlines?] is true, then newlines are
inserted before and after the content.
@examples[#:eval html-eval
(output-xml (comment "testing" 1 2 3))]}
@defproc[(cdata [content outputable/c] ...
[#:newlines? newlines? any/c #t]
[#:line-pfx line-pfx any/c #f])
procedure?]{
Produces a value that @tech{XML-renders} as CDATA with
literal content. If @racket[newlines?] is true, then newlines are
inserted before and after the content. The @racket[line-pfx] value is
rendered before the CDATA opening and closing markers.
@examples[#:eval html-eval
(output-xml (cdata "testing" 1 2 3))]}
@defform[(define/provide-elements/empty tag-id ...)]{
Defines and exports @racket[tag-id] as a function that is like
@racket[element], but with @racket['tag-id] added as the first argument.}
@defform[(define/provide-elements/not-empty tag-id ...)]{
Defines and exports @racket[tag-id] as a function that is like
@racket[element/not-empty], but with @racket['_tag-id] added as the
first argument.}
@defform[(define/provide-entities entity-id ...)]{
Defines and exports @racket[entity-id] as the
result of @racket[(entity '_entity-id)].}
@; ----------------------------------------
@section[#:tag "html-resources"]{HTML Resources}
@defmodule[scribble/html/resource]
@defproc[(resource [path string?]
[renderer (or/c (path-string? . -> . any) #f)]
[#:exists exists (or/c 'delete-file #f) 'delete-file])
(and/c resource?
(->* () (outputable/c) -> string?))]{
Creates and returns a new @deftech{resource} value. Creating a
resource registers @racket[renderer] (if non-@racket[#f]) to be called when rendering is
initiated by @racket[render-all], while calling the result resource as
a function generates a URL for the resource.
For example, a typical use of @racket[resource] is to register the
generation of a CSS file, where the value produced by
@racket[resource] itself renders as the URL for the generated CSS
file. Another possible use of @racket[resource] is to generate an HTML
file, where the @racket[resource] result renders as the URL of the
generated HTML page.
The @racket[path] argument specifies the path of the output file,
relative to the working directory, indicating where the resource file
should be placed. Though @racket[url-roots], @racket[path] also
determines the ultimate URL. The @racket[path] string must be a
@litchar{/}-separated relative path with no @litchar{..}, @litchar{.},
or @litchar{//}. The @racket[path] string can end in @litchar{/}, in
which case @racket["index.html"] is effectively added to the string.
Using @racket[resource] with @racket[#f] as @racket[renderer] is
useful for converting a path to a URL according to @racket[url-roots].
The @racket[renderer] argument (when non-@racket[#f]) renders the resource, receiving the
path for the file to be created. The path provided to
@racket[renderer] will be different from @racket[path], because the
function is invoked in the target directory.
The resulting resource value is a function that returns the URL for
the resource. The function accepts an optional boolean; if a true
value is provided, the result is an absolute URL, instead of relative.
Note that the function can be used as a value for @racket[output],
which uses the resource value as a thunk (that renders as the relative
URL for the resource). The default relative resulting URL is, of
course, a value that depends on the currently rendered resource that
uses this value.
When @racket[renderer] is called by @racket[render-all], more
resources can be created while rendering; the newly created resources
will also be rendered, in turn, until no more new resources are
created.
If @racket[exists] is @racket['delete-file] and the target file exists
when @racket[renderer] is to be called, then the file is deleted
before @racket[renderer] is called.}
@defparam[url-roots roots (or/c #f
(listof (cons/c path-string?
(cons/c string?
(listof (or/c 'abs 'index))))))]{
A parameter that determines how resource paths are converted to URLs
for reference. A @racket[#f] value is equivalent to an empty list.
The parameter value is a mapping from path prefixes to URLs (actually,
any string). When two paths have the same prefix, links from one to
the other are relative (unless absolute links are requested); if they
have different prefixes, the full URL is used. The paths enclosed by
two root paths must be disjoint (e.g., the list must not include
both @racket["/colors"] and @racket["/colors/red"], but it can include
both @racket["/colors/red"] and @racket["/colors/blue"]).
If an item in the parameter's list includes @racket['abs], then a
site-local, absolute URL (i.e., a URL that starts with @litchar{/}) is
produced for references among files within the corresponding prefix.
If an item in the parameter's list includes @racket['index], then a
reference to a directory path is converted to a reference to
@filepath{index.html}, otherwise a reference to @filepath{index.html}
is converted to a directory path.}
@defproc[(resource? [v any/c]) boolean?]{
Returns @racket[#t] if @racket[v] is a procedure (that takes 0 or 1
arguments) produced by @racket[resource].}
@defproc[(render-all) void?]{
Generates all resources registered via @racket[resource].}
@defproc[(file-writer [content-writer (outputable/c output-port? . -> . any)]
[content outputable/c])
(path-string? . -> . any)]{
Produces a function that is useful as a @racket[_writer] argument to
@racket[resource]. Given a path, the produced function writes
@racket[content] to the path by passing @racket[content] and an output
port for the file to @racket[content-writer].}
@; ------------------------------------------------------------
@close-eval[html-eval]

View File

@ -1,4 +0,0 @@
.InBox {
padding: 0.2em;
border: 1px solid #000000;
}

View File

@ -1,2 +0,0 @@
\newcommand{\InBox}[1]{\fbox{#1}}

View File

@ -1,14 +0,0 @@
#lang info
(define scribblings '(("scribble.scrbl" (multi-page) (racket-core -24))
("scribble-pp.scrbl" (multi-page) (tool))
("demo-s1.scrbl" (keep-style no-search) (omit-start))
("demo-m1.scrbl" (multi-page keep-style no-search) (omit-start))
("demo-s2.scrbl" (keep-style) (omit-start))
("demo-m2.scrbl" (multi-page keep-style) (omit-start))
("demo-manual-s1.scrbl" (keep-style no-search) (omit-start))
("demo-manual-m1.scrbl" (multi-page keep-style no-search) (omit-start))
("demo-manual-s2.scrbl" (keep-style) (omit-start))
("demo-manual-m2.scrbl" (multi-page keep-style) (omit-start))))

View File

@ -1,19 +0,0 @@
#lang scribble/manual
@(require "utils.rkt")
@title[#:tag "internals" #:style 'toc]{Low-Level Scribble API}
@local-table-of-contents[]
@include-section["layers.scrbl"]
@include-section["reader-internals.scrbl"]
@include-section["core.scrbl"]
@include-section["renderer.scrbl"]
@include-section["decode.scrbl"]
@include-section["doclang.scrbl"]
@include-section["docreader.scrbl"]
@include-section["xref.scrbl"]
@include-section["tag.scrbl"]
@include-section["blueboxes.scrbl"]
@include-section["config.scrbl"]

View File

@ -1,57 +0,0 @@
#lang scribble/manual
@(require (except-in "utils.rkt" author) (for-label scribble/jfp))
@(define-syntax-rule (def base-author)
(begin
(require (for-label scribble/base))
(define base-author @racket[author])))
@(def base-author)
@title{JFP Paper Format}
@defmodulelang[scribble/jfp]{The @racketmodname[scribble/jfp]
language is like @racketmodname[scribble/base], but configured with
Latex style defaults to use the @filepath{jfp1.cls} class
file. The class file is not included with Scribble due to license
issues, but if the file is not manually installed into the
@racket[scribble/jfp] collections, then it is downloaded on demand to
@racket[(find-system-path 'addon-dir)].}
Latex output with @racketmodname[scribble/jfp] uses a main-document
version supplied to @racket[title] as the short-form document name (to
be used in page headers).
@defproc[(abstract [pre-content pre-content?] ...) block?]{
Generates a @tech{nested flow} for a paper abstract.}
@defform[(include-abstract module-path)]{
Similar to @racket[include-section], but incorporates the document in the
specified module as an abstract. The document must have no title or
sub-parts.}
@defproc[(author [name pre-content?] ...)
block?]{
A replacement for @base-author from @racketmodname[scribble/base].}
@defproc[((author/short [short-name pre-content?] ...) [long-name pre-content?] ...)
block?]{
Like @racket[author], but allows the short-form names (to be used in
page headers) to be specified separately from the long-form name.}
@deftogether[(
@defproc[(affiliation [place pre-content?] ...) element?]
@defproc[(affiliation-mark [mark pre-content?] ...) element?]
@defproc[(affiliation-sep) element?]
)]{
Use @racket[affiliation] within @racket[author] or the long-name part
of @racket[author/short] to specify affiliations after all authors.
If different authors have different affiliations, use
@racket[affiliation-mark] with a number after each author, and then
use @racket[affiliation-mark] before each different affiliation within
a single @racket[affiliation], using @racket[(affiliation-sep)] to
separate affiliations.}

View File

@ -1,239 +0,0 @@
#lang scribble/doc
@(require scribble/manual scribble/bnf "utils.rkt")
@title[#:tag "layers"]{Scribble Layers}
Scribble is made of independently usable parts. For example, the
Scribble reader can be used in any situation that requires lots of
free-form text. You can also skip Scribble's special reader support,
and instead use the document-generation structure directly.
@; ----------------------------------------------------------------------
@section{Typical Composition}
A Scribble document normally starts
@racketmod[
scribble/manual
]
but it could also start
@racketmod[
scribble/base
]
or
@racketmod[
scribble/doc
]
The last one introduces the smallest number of typesetting bindings in
the document body. Using @racketmodname[scribble/base] after
@hash-lang[] is the same as using @racketmodname[scribble/doc] plus
@racket[(require scribble/base)], and using
@racketmodname[scribble/manual] after @hash-lang[] is the same as using
@racketmodname[scribble/doc] plus @racket[(require scribble/manual)].
Besides making the file a module, each of the @hash-lang[]
declarations selects the Scribble reader (instead of the usual Racket
reader), and it starts the body of the file in ``text'' mode. The
reader layer mostly leaves text alone, but @tech{@"@"-forms} escape
to S-expression mode.
A module written as
@verbatim[#:indent 2]|{
#lang scribble/doc
@(require scribble/manual)
@(define to-be "To Be")
@title{@|to-be| or Not @|to-be|}
@bold{That} is the question.
Whether 'tis nobler...
}|
reads as
@racketblock[
(module #,(nonterm "name") scribble/doc
(require scribble/manual)
"\n"
(define to-be "To Be") "\n"
"\n"
(title to-be " or Not " to-be) "\n"
"\n"
(bold "That") " is the question." "\n"
"Whether 'tis nobler..." "\n")
]
As shown in this example, the read result is a module whose content
mingles text and definitions. The @racketmodname[scribble/doc]
language lifts definitions, @racket[require]s, and @racket[provide]s
to the beginning of the module, while everything else is collected
into a document bound to the provided identifier @racket[doc]. That
is, the module is transformed to something like this:
@racketblock[
(module #,(nonterm "name") racket/base
(require scribble/decode
scribble/manual)
(define to-be "To Be")
(define doc
(decode
"\n" "\n" "\n"
(title to-be " or Not " to-be) "\n"
"\n"
(bold "That") " is the question." "\n"
"Whether 'tis nobler..." "\n"))
(provide doc))
]
The @racket[decode] function produces a @racket[part] structure
instance that represents the document. To build the @racket[part]
instance, it inspects its arguments to find a @racket[title-decl]
value created by @racket[title] to name the part, @racket[part-start]
values created by @racket[section] to designate sub-parts, etc.
A @racket[part] is the input to a rendering back-end, such as the HTML
renderer. All renderers recognize a fixed structure hierarchy: the
content of a part is a @defterm{flow}, which is a sequence of
@defterm{flow elements}, such as paragraphs and tables; a table, in
turn, consists of a list of list of flows; a paragraph is a list of
@defterm{elements}, which can be instances of the @racket[element]
structure type, plain strings, or certain special symbols.
The value bound to @racket[doc] in the example above is something like
@racketblock[
(make-part ....
(list "To Be" " or Not " "To Be") (code:comment "title")
....
(make-flow
(list
(make-paragraph
(list (make-element 'bold (list "That"))
" is the question." "\n"
"Whether " 'rsquo "tis nobler..."))))
....)
]
Notice that the @litchar{'} in the input's @litchar{'tis} has turned
into @racket['rsquo] (rendered as a curly apostrophe). The conversion to use
@racket['rsquo] was performed by @racket[decode] via
@racket[decode-flow] via @racket[decode-paragraph] via
@racket[decode-content] via @racket[decode-string].
In contrast, @racket[(make-element 'bold (list "That"))] was produced
by the @racket[bold] function. The @racket[decode] operation is a
function, not a syntactic form, and so @racket[bold] has control over
its argument before @racket[decode] sees the result. Also, decoding
traverses only immediate string arguments.
As it turns out, @racket[bold] also decodes its argument, because the
@racket[bold] function is implemented as
@racketblock[
(define (bold . strs)
(make-element 'bold (decode-content strs)))
]
The @racket[verbatim] function, however, does not decode its content,
and instead typesets its text arguments directly.
A document module can construct elements directly using
@racket[make-element], but normally functions like @racket[bold] and
@racket[verbatim] are used to construct them. In particular, the
@racketmodname[scribble/manual] library provides many functions and
forms to typeset elements and flow elements.
The @racket[part] structure hierarchy includes built-in element types
for setting hyperlink targets and references. Again, this machinery is
normally packaged into higher-level functions and forms, such as
@racket[secref], @racket[defproc], and @racket[racket].
@; ----------------------------------------------------------------------
@section{Layer Roadmap}
Working roughly from the bottom up, the Scribble layers are:
@itemize[
@item{@racketmodname[scribble/reader]: A reader that extends the
syntax of Racket with @tech{@"@"-forms} for conveniently embedding a
mixin of text and escapes. See @secref["reader"].}
@item{@racketmodname[scribble/core]: A set of document datatypes
and utilities that define the basic layout and processing of a
document. For example, the @racket[part] datatype is defined in
this layer. See @secref["core"].}
@item{@racketmodname[scribble/base-render] with
@racketmodname[scribble/html-render],
@racketmodname[scribble/latex-render], or
@racketmodname[scribble/text-render]: A base renderer and
mixins that generate documents in various formats from
instances of the @racketmodname[scribble/struct] datatypes. See
@secref["renderer"].}
@item{@racketmodname[scribble/decode]: Processes a stream of text,
section-start markers, etc. to produce instances of the
@racketmodname[scribble/core] datatypes. See
@secref["decode"].}
@item{@racketmodname[scribble/doclang]: A language to be used for the
initial import of a module; processes the module top level
through @racketmodname[scribble/decode], and otherwise provides
all of @racketmodname[racket/base]. See @secref["doclang"].}
@item{@racketmodname[scribble/doc]: A language that combines
@racketmodname[scribble/reader] with
@racketmodname[scribble/doclang]. See @secref["docreader"].}
@item{@racketmodname[scribble/base]: A library of basic document
operators---such as @racket[title], @racket[section], and
@racket[secref]---for use with @racketmodname[scribble/decode]
and a renderer. This library name also can be used as a
language, where it combines @racketmodname[scribble/doc] with
the exports of @racketmodname[scribble/base]. See
@secref["base"].}
@item{@racketmodname[scribble/racket]: A library of functions for
typesetting Racket code. See @secref["scheme"]. These functions
are not normally used directly, but instead used through
@racketmodname[scribble/manual].}
@item{@racketmodname[scribble/manual]: A library of functions for
writing Racket documentation; re-exports
@racketmodname[scribble/base]. Also, the
@racketmodname[scribble/manual-struct] library provides types
for index-entry descriptions created by functions in
@racketmodname[scribble/manual]. See @secref["manual"].}
@item{@racketmodname[scribble/eval]: A library of functions for
evaluating code at document-build time, especially for showing
examples. See @secref["eval"].}
@item{@racketmodname[scribble/bnf]: A library of support functions
for writing grammars. See @secref["bnf"].}
@item{@racketmodname[scribble/xref]: A library of support functions
for using cross-reference information, typically after a
document is rendered (e.g., to search). See @secref["xref"].}
@item{@racketmodname[scribble/text]: A language that uses
@racketmodname[scribble/reader] preprocessing text files.}
]
The @exec{scribble} command-line utility generates output with a
specified renderer. More specifically, the executable installs a
renderer, loads the modules specified on the command line, extracts
the @racket[doc] export of each module (which must be an instance of
@racket[part]), and renders each---potentially with links that span
documents.

View File

@ -1,97 +0,0 @@
#lang scribble/manual
@(require (except-in "utils.rkt" author)
(except-in (for-label scribble/lncs/lang) #%module-begin))
@(define-syntax-rule (def base-author)
(begin
(require (for-label scribble/base))
(define base-author @racket[author])))
@(def base-author)
@title{LNCS Paper Format}
@defmodulelang[scribble/lncs #:use-sources (scribble/lncs/lang)]{
The @racketmodname[scribble/lncs]
language is like @racketmodname[scribble/base], but configured with
Latex style defaults to use the @filepath{llncs.cls} class
file. The class file is not included with Scribble due to license issues,
but if the file is not manually installed into the
@racket[scribble/lncs] collection, then it is downloaded on demand to
@racket[(find-system-path 'addon-dir)].}
@defproc[(abstract [pre-content pre-content?] ...) block?]{
Generates a @tech{nested flow} for a paper abstract.}
@defform[(include-abstract module-path)]{
Similar to @racket[include-section], but incorporates the document in the
specified module as an abstract. The document must have no title or
sub-parts.}
@defform/subs[#:literals (author)
(authors auth ...)
([auth (author pre-content-expr ...)
(author #:inst str-expr pre-content-expr ...)])
#:contracts ([pre-content-expr pre-content?]
[str-expr string?])]{
A replacement for @base-author from @racketmodname[scribble/base].
The @racket[#:inst] should be a number that matches up to one of the
arguments to @racket[institutes].
}
@defidform[author]{For use only in @racket[authors].}
@defform[#:literals (institute)
(institutes (institute pre-content-expr ...) ...)
#:contracts ([pre-content-expr pre-content?])]{
The @racket[pre-content-expr]s are used as the institutions of the authors.
}
@defidform[institute]{For use only in @racket[institutes].}
@defform[(email pre-content-expr ...)]{
Specifies an email address; must be used inside @racket[institute].
}
@section{Example}
Here is an example of a paper written in the LNCS format:
@margin-note{For more randomly generated papers, see SCIgen:
@url["http://pdos.csail.mit.edu/scigen"]}
@codeblock[#:keep-lang-line? #t]|{
#lang scribble/lncs
@authors[@author[#:inst "1"]{Lauritz Darragh}
@author[#:inst "2"]{Nikolaj Kyran}
@author[#:inst "2"]{Kirsten Gormlaith}
@author[#:inst "2"]{Tamaz Adrian}]
@institutes[
@institute["University of Southeast Boston"
@linebreak[]
@email|{darragh@cs.seboston.edu}|]
@institute["University of Albion"
@linebreak[]
@email|{{nkyran,gorm,tamaz}@cs.albion.ac.uk}|]]
@title{Arak: Low-Energy, Interposable Theory}
@abstract{The implications of client-server symmetries have been
far-reaching and pervasive. Given the current status of
constant-time theory, mathematicians daringly desire the synthesis
of rasterization, which embodies the essential principles of
algorithms. In this work, we describe a client-server tool for
investigating flip-flop gates (Arak), verifying that the
producer-consumer problem can be made homogeneous, secure, and
wireless.}
}|

View File

@ -1,4 +0,0 @@
#lang scribble/doc
@(require scribble/lp-include)
@lp-include["lp-ex.rkt"]

View File

@ -1,18 +0,0 @@
#lang scribble/lp2
@(require scribble/manual)
Literate programs have chunks of code, like this one:
@chunk[<f>
(define (f x)
<fs-body>)]
and this one:
@chunk[<fs-body>
(* x x)]
that, when assembled, produce a complete program, in this case:
@racketblock[(define (f x)
(* x x))]

View File

@ -1,4 +0,0 @@
.LPBoxed {
padding: 1ex;
border: 1px solid #000000;
}

View File

@ -1,136 +0,0 @@
#lang scribble/doc
@(require scribble/manual scribble/core scribble/html-properties
scribble/latex-properties
racket/runtime-path
racket/file
"utils.rkt"
(prefix-in lp-ex: "lp-ex-doc.scrbl")
(for-label scribble/lp-include scribble/lp))
@title[#:tag "lp"
#:style (make-style #f
(list (make-css-addition "lp.css")
(make-tex-addition "lp.tex")))
]{Literate Programming}
Programs written using @racketmodname[scribble/lp2] are simultaneously
two things: a program and a document describing the program:
@itemlist[
@item{When the program is run, all of the @racket[chunk] expressions
are collected and stitched together into a program, and the
rest of the module is discarded.}
@item{When the program is provided to Scribble---or used through
@racket[include-section] in another Scribble document with a
@racket[(submod ... doc)] module path---the entire contents of
the module are treated like an ordinary Scribble document,
where @racket[chunk]s are typeset in a manner similar to
@racket[codeblock].}
]
@(define-runtime-path lp-ex "lp-ex.rkt")
For example, consider this program:
@(codeblock (file->string lp-ex))
When this file is @racket[require]d in the normal manner, it defines a
function @racket[f] that squares its argument, and the documentation
is ignored. When it is rendered as a Scribble document, the output
looks like this:
@(make-nested-flow
(make-style "LPBoxed" null)
(part-blocks lp-ex:doc))
@; ------------------------------------------------------------
@section{@racketmodname[scribble/lp2] Language}
@defmodulelang[scribble/lp2 #:use-sources (scribble/lp)]{The
@racketmodname[scribble/lp] language provides core support for
literate programming. It is read like a @racketmodname[scribble/base]
program, but its bindings extend @racketmodname[racket/base] with two
forms: @racket[chunk] and @racket[CHUNK].}
More precisely, a module in @racketmodname[scribble/lp2] has its
@racketmodname[racket/base]-like content in a @racketidfont{doc}
submodule, which is recognized by tools such as @exec{raco scribble}.
The content of the @racket[chunk] and @racket[CHUNK] forms is
stitched together as the immediate content of the module.
The @racket[chunk] and @racket[CHUNK] content is discovered by first
@racket[expand]ing the module as written. The content is collected
into a new module, and then the original module content is placed into
a @racket[doc] submodule that is expanded (so that the content is
effectively re-expanded). The @racketidfont{doc} submodule is declared
with @racket[module*].
@history[#:added "1.8"
#:changed "1.17" @elem{Declared the @racketidfont{doc} submodule with
@racket[module*] instead of @racket[module].}]
@defform[(chunk id form ...)]{
Introduces a chunk, binding @racket[id] for use in other
chunks. Normally, @racket[id] starts with @litchar{<} and ends with
@litchar{>}.
When running the enclosing program, only the code inside the
chunks is run; the rest is ignored.
If @racket[id] is @racketidfont{<*>}, then this chunk is
used as the main chunk in the file. If @racketidfont{<*>}
is never used, then the first chunk in the file is treated
as the main chunk. If some chunk is not referenced from
the main chunk (possibly indirectly via other chunks that
the main chunk references), then it is not included in the
program and thus is not run.
The @racket[form]s are typeset using @racket[racketblock], so
@racket[code:comment], etc., can be used to adjust the output.
Those output-adjusting forms are stripped from each @racket[form]
for running the program.
@history[#:changed "1.17" @elem{Strip @racket[code:comment], etc., for running.}]}
@defform[(CHUNK id form ...)]{
Like @racket[chunk], but typesets with @racket[RACKETBLOCK], so @racket[unsyntax]
can be used normally in each @racket[form]. To escape,
use @racket[UNSYNTAX].
}
@; ------------------------------------------------------------
@section{@racketmodname[scribble/lp] Language}
@defmodulelang[scribble/lp]{Programs written using the older
@racketmodname[scribble/lp] language are similar to
@racketmodname[scribble/lp2] programs, except that the module cannot
be provided directly to Scribble. Instead, the document content must be
extracted using @racket[lp-include].}
The @racketmodname[scribble/lp] language effectively binds only
@racket[chunk] and @racket[CHUNK], while all other bindings for
documentation are taken from the context where @racket[lp-include] is
used.
@; ------------------------------------------------------------
@section{@racketmodname[scribble/lp-include] Module}
@defmodule[scribble/lp-include]{The
@racketmodname[scribble/lp-include] library is normally used within a
Scribble document---that is, a module that starts with something like
@racket[#, @hash-lang[] @racketmodname[scribble/base]] or @racket[#, @hash-lang[]
@racketmodname[scribble/manual]], instead of @racket[#, @hash-lang[] @racketmodname[racket]].}
@defform[(lp-include filename)]{
Includes the source of @racket[filename] as the typeset version of the literate
program.
}

View File

@ -1,3 +0,0 @@
\usepackage{framed}
\newenvironment{LPBoxed}{\begin{framed}}{\end{framed}}

View File

@ -1,8 +0,0 @@
#lang scribble/manual
@(require "utils.rkt" (for-label scribble/sigplan))
@title{Racket Manual Format}
The @racketmodname[scribble/manual] language is a major component of
Scribble, and it is documented in its own chapter:
@secref["plt-manuals"].

File diff suppressed because it is too large Load Diff

View File

@ -1,25 +0,0 @@
#lang scribble/manual
@(require "utils.rkt")
@title[#:tag "plt-manuals" #:style 'toc]{Scribbling Documentation}
The @racketmodname[scribble/manual] language and associated libraries
provide extensive support for documenting Racket libraries. The
most significant aspect of support for documentation is the way that
source-code bindings are connected to documentation sites through the
module namespace---a connection that is facilitated by the fact that
Scribble documents are themselves modules that reside in the same
namespace. @Secref["how-to-doc"] provides an introduction to using
Scribble for documentation, and the remaining sections document the
relevant libraries and APIs in detail.
@local-table-of-contents[]
@include-section["how-to.scrbl"]
@include-section["style.scrbl"]
@include-section["manual.scrbl"]
@include-section["scheme.scrbl"]
@include-section["examples.scrbl"]
@include-section["srcdoc.scrbl"]
@include-section["bnf.scrbl"]
@include-section["compat.scrbl"]

View File

@ -1,335 +0,0 @@
#lang scribble/doc
@(require scribble/manual scribble/bnf scribble/eval "utils.rkt"
(for-syntax racket/base)
(for-label (only-in scribble/reader
use-at-readtable)))
@(define read-eval (make-base-eval))
@(interaction-eval #:eval read-eval (require (for-syntax racket/base)))
@title[#:tag "reader-internals"]{@"@" Reader Internals}
@;--------------------------------------------------------------------
@section{Using the @"@" Reader}
You can use the reader via Racket's @racketfont{#reader} form:
@racketblock[
@#,racketfont|{
#reader scribble/reader @foo{This is free-form text!}
}|]
or use the @racket[at-exp] meta-language as described in
@secref["at-exp-lang"].
Note that the Scribble reader reads @tech{@"@"-forms} as S-expressions. This
means that it is up to you to give meanings for these expressions in
the usual way: use Racket functions, define your functions, or require
functions. For example, typing the above into @exec{racket} is likely
going to produce a ``reference to undefined identifier'' error, unless
@racket[foo] is defined. You can use @racket[string-append] instead,
or you can define @racket[foo] as a function (with variable arity).
A common use of the Scribble @"@"-reader is when using Scribble as a
documentation system for producing manuals. In this case, the manual
text is likely to start with
@racketmod[scribble/doc]
which installs the @"@" reader starting in ``text mode,'' wraps the
file content afterward into a Racket module where many useful Racket
and documentation related functions are available, and parses the body
into a document using @racketmodname[scribble/decode]. See
@secref["docreader"] for more information.
Another way to use the reader is to use the @racket[use-at-readtable]
function to switch the current readtable to a readtable that parses
@tech{@"@"-forms}. You can do this in a single command line:
@commandline{racket -ile scribble/reader "(use-at-readtable)"}
@;--------------------------------------------------------------------
@section{Syntax Properties}
The Scribble reader attaches properties to syntax objects. These
properties might be useful in some rare situations.
Forms that Scribble reads are marked with a @racket['scribble]
property, and a value of a list of three elements: the first is
@racket['form], the second is the number of items that were read from
the datum part, and the third is the number of items in the body part
(strings, sub-forms, and escapes). In both cases, a @racket[0] means
an empty datum/body part, and @racket[#f] means that the corresponding
part was omitted. If the form has neither parts, the property is not
attached to the result. This property can be used to give different
meanings to expressions from the datum and the body parts, for
example, implicitly quoted keywords:
@; FIXME: a bit of code duplication here
@def+int[
#:eval read-eval
(define-syntax (foo stx)
(let ([p (syntax-property stx 'scribble)])
(printf ">>> ~s\n" (syntax->datum stx))
(syntax-case stx ()
[(_ x ...)
(and (pair? p) (eq? (car p) 'form) (even? (cadr p)))
(let loop ([n (/ (cadr p) 2)]
[as '()]
[xs (syntax->list #'(x ...))])
(if (zero? n)
(with-syntax ([attrs (reverse as)]
[(x ...) xs])
#'(list 'foo `attrs x ...))
(loop (sub1 n)
(cons (with-syntax ([key (car xs)]
[val (cadr xs)])
#'(key ,val))
as)
(cddr xs))))])))
(eval:alts
(code:line
@#,tt["@foo[x 1 y (* 2 3)]{blah}"])
;; Unfortunately, expressions are preserved by `def+int'
;; using `quote', not `quote-syntax' (which would create all sorts
;; or binding trouble), so we manually re-attach the property:
(eval (syntax-property #'@foo[x 1 y (* 2 3)]{blah}
'scribble '(form 4 1))))
]
In addition, the Scribble parser uses syntax properties to mark syntax
items that are not physically in the original source --- indentation
spaces and newlines. Both of these will have a @racket['scribble]
property; an indentation string of spaces will have
@racket['indentation] as the value of the property, and a newline will
have a @racket['(newline S)] value where @racket[S] is the original
newline string including spaces that precede and follow it (which
includes the indentation for the following item). This can be used to
implement a verbatim environment: drop indentation strings, and use
the original source strings instead of the single-newline string. Here
is an example of this.
@; FIXME: a bit of code duplication here
@def+int[
#:eval read-eval
(define-syntax (verb stx)
(syntax-case stx ()
[(_ cmd item ...)
#`(cmd
#,@(let loop ([items (syntax->list #'(item ...))])
(if (null? items)
'()
(let* ([fst (car items)]
[prop (syntax-property fst 'scribble)]
[rst (loop (cdr items))])
(cond [(eq? prop 'indentation) rst]
[(not (and (pair? prop)
(eq? (car prop) 'newline)))
(cons fst 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
})
]
@;--------------------------------------------------------------------
@section[#:tag "at-exp-lang"]{Adding @"@"-expressions to a Language}
@defmodulelang[at-exp]{The @racketmodname[at-exp] language installs
@seclink["reader"]{@"@"-reader} support in the readtable used to read
a module, and then chains to the reader of
another language that is specified immediately after
@racketmodname[at-exp].}
For example, @racket[@#,hash-lang[] at-exp racket/base] adds @"@"-reader
support to @racket[racket/base], so that
@racketmod[
at-exp racket/base
(define (greet who) @#,elem{@tt["@"]@racket[string-append]@racketparenfont["{"]@racketvalfont{Hello, }@tt["@|"]@racket[who]@tt["|"]@racketvalfont{.}@racketparenfont["}"]})
(greet "friend")]
reports @racket["Hello, friend."].
In addition to configuring the reader for a module body,
@racketmodname[at-exp] attaches a run-time configuration annotation to
the module, so that it if it used as the main module, the
@racket[current-read-interaction] parameter is adjusted to use the
@seclink["reader"]{@"@"-reader} readtable extension.
@history[#:changed "1.2" @elem{Added @racket[current-read-interaction]
run-time configuration.}]
@;--------------------------------------------------------------------
@section{Interface}
@defmodule[scribble/reader]{The @racketmodname[scribble/reader] module
provides direct Scribble reader functionality for advanced needs.}
@; The `with-scribble-read' trick below shadows `read' and
@; `read-syntax' with for-label bindings from the Scribble reader
@(define-syntax with-scribble-read
(syntax-rules ()
[(_)
(...
(begin
(require (for-label scribble/reader))
@; *** Start reader-import section ***
@deftogether[(
@defproc[(read [in input-port? (current-input-port)]) any]{}
@defproc[(read-syntax [source-name any/c (object-name in)]
[in input-port? (current-input-port)])
(or/c syntax? eof-object?)]
)]{
Implements the Scribble reader using the readtable produced by
@racketblock[(make-at-readtable #:command-readtable 'dynamic
#:datum-readtable 'dynamic)]
@history[#:changed "1.1" @elem{Changed to use @racket['dynamic] for the command and datum readtables.}]}
@deftogether[(
@defproc[(read-inside [in input-port? (current-input-port)]) any]{}
@defproc[(read-syntax-inside [source-name any/c (object-name in)]
[in input-port? (current-input-port)]
[#:command-char command-char char? #\@])
(or/c syntax? eof-object?)]
)]{
Like @racket[read] and @racket[read-syntax], but starting as if
inside a @litchar["@{"]...@litchar["}"] to return a (syntactic) list,
which is useful for implementing languages that are textual by default.
The given @racket[command-char] is used to customize the readtable
used by the reader, effectively passing it along to @racket[make-at-readtable].
@history[#:changed "1.1" @elem{Changed to use @racket['dynamic] for the command and datum readtables.}]
}
@defproc[(make-at-readtable
[#:readtable readtable readtable? (current-readtable)]
[#:command-char command-char char? #\@]
[#:command-readtable command-readtable (or/c readtable? 'dynamic) readtable]
[#:datum-readtable datum-readtable
(or/c readtable?
boolean?
(readtable? . -> . readtable?)
'dynamic)
#t]
[#:syntax-post-processor syntax-post-proc
(syntax? . -> . syntax?)
values])
readtable?]{
Constructs an @"@"-readtable. The keyword arguments can customize the
resulting reader in several ways:
@itemize[
@item{@racket[readtable] --- a readtable to base the @"@"-readtable
on.}
@item{@racket[command-char] --- the character used for @tech{@"@"-forms}.}
@item{@racket[command-readtable] --- determines the readtable that is
extended for reading the command part of an @tech{@"@"-form}:
@itemlist[
@item{a readtable --- extended to make @litchar{|} a delimiter
instead of a symbol-quoting character}
@item{@racket['dynamic] --- extends @racket[(current-readtable)]
at the point where a command is parsed to make @litchar{|} a
delimiter}
]}
@item{@racket[datum-readtable] --- the readtable used for
reading the datum part of an @tech{@"@"-form}:
@itemlist[
@item{@racket[#t] --- uses the constructed @"@"-readtable itself}
@item{a readtable --- uses the given readtable}
@item{a readtable-to-readtable function --- called to construct a readtable
from the generated @"@"-readtable}
@item{@racket['dynamic] --- uses @racket[(current-readtable)] at the
point where the datum part is parsed}
]
The idea is that you may want to have completely
different uses for the datum part, for example, introducing a
convenient @litchar{key=val} syntax for attributes.}
@item{@racket[syntax-post-proc] --- function that is applied on
each resulting syntax value after it has been parsed (but before it
is wrapped quoting punctuations). You can use this to further
control uses of @tech{@"@"-forms}, for example, making the command be the
head of a list:
@racketblock[
(use-at-readtable
#:syntax-post-processor
(lambda (stx)
(syntax-case stx ()
[(cmd rest ...) #'(list 'cmd rest ...)]
[_else (error "@ forms must have a body")])))
]}
]
@history[#:changed "1.1" @elem{Added @racket[#:command-readtable] and
the @racket['dynamic] option for @racket[#:datum-readtable].}]}
@defproc[(make-at-reader [#:syntax? syntax? #t] [#:inside? inside? #f] ...)
procedure?]{
Constructs a variant of a @"@"-readtable. The arguments are the same
as in @racket[make-at-readtable], with two more that determine the
kind of reader function that will be created: @racket[syntax?] chooses
between a @racket[read]- or @racket[read-syntax]-like function, and
@racket[inside?] chooses a plain reader or an @racketid[-inside]
variant.
The resulting function has a different contract and action based on
these inputs. The expected inputs are as in @racket[read] or
@racket[read-syntax] depending on @racket[syntax?]; the function will
read a single expression or, if @racket[inside?] is true, the whole
input; it will return a syntactic list of expressions rather than a
single one in this case.
Note that @racket[syntax?] defaults to @racket[#t], as this is the
more expected common case when you're dealing with concrete-syntax
reading.
Note that if @racket[syntax?] is true, the @racket[read]-like function
is constructed by simply converting a syntax result back into a datum.}
@defproc[(use-at-readtable ...) void?]{
Passes all arguments to @racket[make-at-readtable], and installs the
resulting readtable using @racket[current-readtable]. It also enables
line counting for the current input-port via @racket[port-count-lines!].
This is mostly useful for playing with the Scribble syntax on the REPL.}
@; *** End reader-import section ***
))]))
@with-scribble-read[]
@; --------------------------------------------------
@(close-eval read-eval)

View File

@ -1,742 +0,0 @@
#lang scribble/doc
@(require scribble/manual scribble/bnf scribble/eval "utils.rkt"
(for-syntax racket/base)
(for-label (only-in scribble/reader
use-at-readtable)))
@(define read-eval (make-base-eval))
@(interaction-eval #:eval read-eval (require (for-syntax racket/base)))
@(define (at-exp-racket)
@racket[#, @hash-lang[] #, @racketmodname[at-exp] #, @racketidfont{racket}])
@title[#:tag "reader"]{@"@" Syntax}
The Scribble @"@" notation is designed to be a convenient facility for
free-form text in Racket code, where ``@"@"'' was chosen as one of the
least-used characters in existing Racket code. An @"@"-expression is
simply an S-expression in disguise.
Typically, @"@" notation is enabled through
@racketmodname[scribble/base] or similar languages, but you can also
add @"@" notation to an S-expression-based language using the
@racketmodname[at-exp] meta-language. For example,
@verbatim[#:indent 2]|{
#lang at-exp racket
(define v '@op{str})
}|
is equivalent to
@racketmod[
racket
(define v '(op "str"))
]
Using @at-exp-racket[] is probably the easiest way to try the examples
in this chapter.
@;--------------------------------------------------------------------
@section{The Scribble Syntax at a Glance}
To review @secref["how-to:reader"], the concrete syntax of @deftech{@"@"-forms}
is roughly
@racketblock[
@#,BNF-seq[@litchar["@"]
@nonterm{cmd}
@litchar{[} @kleenestar{@nonterm{datum}} @litchar{]}
@litchar["{"] @kleenestar{@nonterm{text-body}} @litchar["}"]]
]
where all three parts after @litchar["@"] are optional, but at least
one should be present. (Spaces are not allowed between the
three parts.) Roughly, a form matching the above grammar is read as
@racketblock[
(@#,nonterm{cmd} @#,kleenestar{@nonterm{datum}} @#,kleenestar{@nonterm{parsed-body}})
]
where @nonterm{parsed-body} is the translation of each
@nonterm{text-body} in the input. Thus, the initial @nonterm{cmd}
determines the Racket code that the input is translated into. The
common case is when @nonterm{cmd} is a Racket identifier, which reads
as a plain Racket form, with datum arguments and/or string arguments.
Here is one example:
@scribble-examples|==={
@foo{blah blah blah}
}===|
The example shows how an input syntax is read as Racket syntax, not
what it evaluates to. If you want to see the translation of an example
into S-expression form, add a quote in front of it in a
@at-exp-racket[] module. For example, running
@verbatim[#:indent 2]|{
#lang at-exp racket
'@foo{blah blah blah}
}|
in DrRacket prints the output
@nested[#:style 'inset]{@racketresult[(foo "blah blah blah")]}
while omitting the quote
@verbatim[#:indent 2]|{
#lang at-exp racket
@foo{blah blah blah}
}|
triggers a syntax error because @racket[foo] is not bound, and
@verbatim[#:indent 2]|{
#lang at-exp racket
(define (foo str) (printf "He wrote ~s.\n" str))
@foo{blah blah blah}
}|
prints the output
@nested[#:style 'inset]{@racketoutput{He wrote "blah blah blah".}}
Here are more examples of @tech{@"@"-forms}:
@scribble-examples|==={
@foo{blah "blah" (`blah'?)}
@foo[1 2]{3 4}
@foo[1 2 3 4]
@foo[#:width 2]{blah blah}
@foo{blah blah
yada yada}
@foo{
blah blah
yada yada
}
}===|
As seen in the last example, multiple lines and the newlines that
separate them are parsed to multiple Racket strings. More generally,
a @nonterm{text-body} is made of text, newlines, and nested
@tech{@"@"-forms}, where the syntax for @tech{@"@"-forms} is the same whether it's
in a @nonterm{text-body} context as in a Racket context. A
@nonterm{text-body} that isn't an @tech{@"@"-form} is converted to a string
expression for its @nonterm{parsed-body}; newlines and following
indentations are converted to @racket["\n"] and all-space string
expressions.
@scribble-examples|==={
@foo{bar @baz{3}
blah}
@foo{@b{@u[3] @u{4}}
blah}
@C{while (*(p++))
*p = '\n';}
}===|
The command part of an @tech{@"@"-form} is optional as well. In that case,
the @tech{@"@"-form} is read as a list, which usually counts as a function
application, but it also useful when quoted with the usual Racket
@racket[quote]:
@scribble-examples|==={
@{blah blah}
@{blah @[3]}
'@{foo
bar
baz}
}===|
Finally, we can also drop the datum and text parts, which leaves us with
only the command---which is read as is, not within a parenthesized
form. This is not useful when reading Racket code, but it can be used
inside a text block to escape a Racket identifier. A vertical bar
(@litchar{|}) can be used to delimit the escaped identifier when
needed.
@scribble-examples|==={
@foo
@{blah @foo blah}
@{blah @foo: blah}
@{blah @|foo|: blah}
}===|
Actually, the command part can be any Racket expression (that does not
start with @litchar["["], @litchar["{"], or @litchar["|"]), which is
particularly useful with such escapes since they can be used with any
expression.
@scribble-examples|==={
@foo{(+ 1 2) -> @(+ 1 2)!}
@foo{A @"string" escape}
}===|
Note that an escaped Racket string is merged with the surrounding text
as a special case. This is useful if you want to use the special
characters in your string, but escaping braces are not necessary if
they are balanced.
@scribble-examples|==={
@foo{eli@"@"barzilay.org}
@foo{A @"{" begins a block}
@C{while (*(p++)) {
*p = '\n';
}}
}===|
In some cases, a text contains many literal @"@"s, which can be
cumbersome to quote individually. For such case, braces have an
alternative syntax: A block of text can begin with a
``@litchar["|{"]'' and terminated accordingly with a
``@litchar["}|"]''. Furthermore, any nested @tech{@"@"-forms} must begin
with a ``@litchar["|@"]''.
@scribble-examples|==={
@foo|{bar}@{baz}|
@foo|{bar |@x{X} baz}|
@foo|{bar |@x|{@}| baz}|
}===|
In cases when even this is not convenient enough, punctuation
characters can be added between the @litchar{|} and the braces and the
@"@" in nested forms. (The punctuation is mirrored for parentheses
and @litchar{<>}s.) With this extension, @tech{@"@"-form} syntax can be used as a
``here string'' replacement.
@scribble-examples|==={
@foo|--{bar}@|{baz}--|
@foo|<<{bar}@|{baz}>>|
}===|
On the flip side of this is, how can an @"@" sign be used in Racket
code? This is almost never an issue, because Racket strings and
characters are still read the same, and @litchar["@"] is set as a
non-terminating reader macro so it can be used in Racket identifiers
anywhere except in the first character of an identifier. When
@litchar["@"] must appear as the first character of an identifier, you
must quote the identifier just like other non-standard characters in
normal S-expression syntax: with a backslash or with vertical bars.
@scribble-examples|==={
(define \@email "foo@bar.com")
(define |@atchar| #\@)
}===|
Note that spaces are not allowed before a @litchar{[} or a
@litchar["{"], or they will be part of the following text (or Racket
code). (More on using braces in body texts below.)
@scribble-examples|==={
@foo{bar @baz[2 3] {4 5}}
}===|
Finally, remember that @tech{@"@"-forms} are just an alternate form of
S-expressions. Identifiers still get their meaning, as in any
Racket code, through the lexical context in which they appear.
Specifically, when the above @tech{@"@"-form} appears in a Racket expression
context, the lexical environment must provide bindings for
@racket[foo] as a procedure or a macro; it can be defined, required,
or bound locally (with @racket[let], for example).
@; 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])
#,(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}.}))
]
@;--------------------------------------------------------------------
@section{The Command Part}
Besides being a Racket identifier, the @nonterm{cmd} part of an
@tech{@"@"-form} can have Racket punctuation prefixes, which will end up
wrapping the @italic{whole} expression.
@scribble-examples|==={
@`',@foo{blah}
@#`#'#,@foo{blah}
}===|
When writing Racket code, this means that @litchar|{@`',@foo{blah}}|
is exactly the same as @litchar|{`@',@foo{blah}}| and
@litchar|{`',@@foo{blah}}|, but unlike the latter two, the first
construct can appear in body texts with the same meaning, whereas the
other two would not work (see below).
After the optional punctuation prefix, the @nonterm{cmd} itself is not
limited to identifiers; it can be @italic{any} Racket expression.
@scribble-examples|==={
@(lambda (x) x){blah}
@`(unquote foo){blah}
}===|
In addition, the command can be omitted altogether, which will omit it
from the translation, resulting in an S-expression that usually
contains, say, just strings:
@scribble-examples|==={
@{foo bar
baz}
@'{foo bar
baz}
}===|
If the command part begins with a @litchar{;} (with no newline between
the @litchar["@"] and the @litchar{;}), then the construct is a
comment. There are two comment forms, one for arbitrary-text and
possibly nested comments, and another one for line comments:
@racketblock[
@#,BNF-seq[@litchar["@;{"] @kleenestar{@nonterm{any}} @litchar["}"]]
@#,BNF-seq[@litchar["@;"] @kleenestar{@nonterm{anything-else-without-newline}}]
]
In the first form, the commented body must still parse correctly; see
the description of the body syntax below. In the second form, all
text from the @litchar["@;"] to the end of the line @italic{and} all
following spaces (or tabs) are part of the comment (similar to
@litchar{%} comments in TeX).
@scribble-examples|==={
@foo{bar @; comment
baz@;
blah}
}===|
Tip: if you use an editor in some Scheme mode without support for
@tech{@"@"-forms}, balanced comments can be confusing, since the open brace
looks commented out, and the closing one isn't. In such cases it is
useful to ``comment'' out the closing brace too:
@verbatim[#:indent 2]|==={
@;{
...
;}
}===|
so the editor does not treat the file as having unbalanced
parentheses.
If only the @nonterm{cmd} part of an @tech{@"@"-form} is specified, then the
result is the command part only, without an extra set of parenthesis.
This makes it suitable for Racket escapes in body texts. (More on this
below, in the description of the body part.)
@scribble-examples|==={
@foo{x @y z}
@foo{x @(* y 2) z}
@{@foo bar}
}===|
Finally, note that there are currently no special rules for using
@litchar["@"] in the command itself, which can lead to things like:
@scribble-examples|==={
@@foo{bar}{baz}
}===|
@;--------------------------------------------------------------------
@section{The Datum Part}
The datum part can contains arbitrary Racket expressions, which
are simply stacked before the body text arguments:
@scribble-examples|==={
@foo[1 (* 2 3)]{bar}
@foo[@bar{...}]{blah}
}===|
The body part can still be omitted, which is essentially an
alternative syntax for plain (non-textual) S-expressions:
@scribble-examples|==={
@foo[bar]
@foo{bar @f[x] baz}
}===|
The datum part can be empty, which makes no difference, except when
the body is omitted. It is more common, however, to use an empty body
for the same purpose.
@scribble-examples|==={
@foo[]{bar}
@foo[]
@foo
@foo{}
}===|
The most common use of the datum part is for Racket forms that expect
keyword-value arguments that precede the body of text arguments.
@scribble-examples|==={
@foo[#:style 'big]{bar}
}===|
@;--------------------------------------------------------------------
@section{The Body Part}
The syntax of the body part is intended to be as convenient as
possible for free text. It can contain almost any text---the only
characters with special meaning is @litchar["@"] for sub-@tech{@"@"-forms},
and @litchar["}"] for the end of the text. In addition, a
@litchar["{"] is allowed as part of the text, and it makes the
matching @litchar["}"] be part of the text too---so balanced braces
are valid text.
@scribble-examples|==={
@foo{f{o}o}
@foo{{{}}{}}
}===|
As described above, the text turns to a sequence of string arguments
for the resulting form. Spaces at the beginning and end of lines are
discarded, and newlines turn to individual @racket["\n"] strings
(i.e., they are not merged with other body parts); see also the
information about newlines and indentation below. Spaces are
@italic{not} discarded if they appear after the open @litchar["{"]
(before the closing @litchar["}"]) when there is also text that
follows (precedes) it; specifically, they are preserved in a
single-line body.
@scribble-examples|==={
@foo{bar}
@foo{ bar }
@foo[1]{ bar }
}===|
If @litchar["@"] appears in a body, then it is interpreted as Racket
code, which means that the @"@"-reader is applied recursively, and the
resulting syntax appears as part of the S-expression, among other
string contents.
@scribble-examples|==={
@foo{a @bar{b} c}
}===|
If the nested @"@" construct has only a command---no body or datum
parts---it will not appear in a subform. Given that the command part
can be any Racket expression, this makes @"@" a general escape to
arbitrary Racket code.
@scribble-examples|==={
@foo{a @bar c}
@foo{a @(bar 2) c}
}===|
This is particularly useful with strings, which can be used to include
arbitrary text.
@scribble-examples|==={
@foo{A @"}" marks the end}
}===|
Note that the escaped string is (intentionally) merged with the rest
of the text. This works for @litchar["@"] too:
@scribble-examples|==={
@foo{The prefix: @"@".}
@foo{@"@x{y}" --> (x "y")}
}===|
@;--------------------------------------------------------------------
@subsection[#:tag "alt-body-syntax"]{Alternative Body Syntax}
In addition to the above, there is an alternative syntax for the body,
one that specifies a new marker for its end: use @litchar["|{"] for
the opening marker to have the text terminated by a @litchar["}|"].
@scribble-examples|==={
@foo|{...}|
@foo|{"}" follows "{"}|
@foo|{Nesting |{is}| ok}|
}===|
This applies to sub-@tech{@"@"-forms} too---the @litchar["@"] must be
prefixed with a @litchar{|}:
@scribble-examples|==={
@foo|{Maze
|@bar{is}
Life!}|
@t|{In |@i|{sub|@"@"s}| too}|
}===|
Note that the subform uses its own delimiters, @litchar{{...}} or
@litchar{|{...}|}. This means that you can copy and paste Scribble
text with @tech{@"@"-forms} freely, just prefix the @litchar["@"] if the
immediate surrounding text has a prefix.
For even better control, you can add characters in the opening
delimiter, between the @litchar{|} and the @litchar["{"].
Characters that are put there (non alphanumeric ASCII characters only,
excluding @litchar["{"] and @litchar["@"]) should also be used for
sub-@tech{@"@"-forms}, and the end-of-body marker should have these characters
in reverse order with paren-like characters (@litchar{(},
@litchar{[}, @litchar{<}) mirrored.
@scribble-examples|==={
@foo|<<<{@x{foo} |@{bar}|.}>>>|
@foo|!!{X |!!@b{Y}...}!!|
}===|
Finally, remember that you can use an expression escape with a Racket
string for confusing situations. This works well when you only need
to quote short pieces, and the above works well when you have larger
multi-line body texts.
@;--------------------------------------------------------------------
@subsection{Racket Expression Escapes}
In some cases, you may want to use a Racket identifier (or a number or
a boolean etc.) in a position that touches the following text; in
these situations you should surround the escaped Racket expression by
a pair of @litchar{|} characters. The text inside the bars is
parsed as a Racket expression.
@scribble-examples|==={
@foo{foo@bar.}
@foo{foo@|bar|.}
@foo{foo@3.}
@foo{foo@|3|.}
}===|
This form is a generic Racket expression escape, there is no body text
or datum part when you use this form.
@scribble-examples|==={
@foo{foo@|(f 1)|{bar}}
@foo{foo@|bar|[1]{baz}}
}===|
This works for string expressions too, but note that unlike the above,
the string is (intentionally) not merged with the rest of the text:
@scribble-examples|==={
@foo{x@"y"z}
@foo{x@|"y"|z}
}===|
Expression escapes also work with @italic{any} number of expressions,
@scribble-examples|==={
@foo{x@|1 (+ 2 3) 4|y}
@foo{x@|*
*|y}
}===|
It seems that @litchar["@||"] has no purpose---but remember that these escapes
are never merged with the surrounding text, which can be useful when
you want to control the sub expressions in the form.
@scribble-examples|==={
@foo{Alice@||Bob@|
|Carol}
}===|
Note that @litchar["@|{...}|"] can be parsed as either an escape expression or
as the Racket command part of an @tech{@"@"-form}. The latter is used in this case
(since there is little point in Racket code that uses braces.
@scribble-examples|==={
@|{blah}|
}===|
@;--------------------------------------------------------------------
@subsection{Comments}
As noted above, there are two kinds of @tech{@"@"-form} comments: @litchar|{@;{...}}| is
a (nestable) comment for a whole body of text (following the same
rules for @tech{@"@"-forms}), and @litchar|{@;...}| is a line-comment.
@scribble-examples|==={
@foo{First line@;{there is still a
newline here;}
Second line}
}===|
One useful property of line-comments is that they continue to the end
of the line @italic{and} all following spaces (or tabs). Using this,
you can get further control of the subforms.
@scribble-examples|==={
@foo{A long @;
single-@;
string arg.}
}===|
Note how this is different from using @litchar["@||"]s in that strings
around it are not merged.
@;--------------------------------------------------------------------
@subsection{Spaces, Newlines, and Indentation}
The @tech{@"@"-form} syntax treats spaces and newlines in a special way is
meant to be sensible for dealing with text. As mentioned above,
spaces at the beginning and end of body lines are discarded, except
for spaces between a @litchar["{"] and text, or between text and a
@litchar["}"].
@scribble-examples|==={
@foo{bar}
@foo{ bar }
@foo{ bar
baz }
}===|
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 @racket["\n"] string
@scribble-examples|==={
@foo{bar
}
@foo{
bar
}
@foo{
bar
}
@foo{
bar
baz
}
@foo{
}
@foo{
}
@foo{ bar
baz }
}===|
Spaces at the beginning of body lines do not appear in the resulting
S-expressions, but the column of each line is noticed, and all-space
indentation strings are added so the result has the same indentation.
A indentation string is added to each line according to its distance
from the leftmost syntax object (except for empty lines). (Note: if
you try these examples on a Racket REPL, you should be aware that
the reader does not know about the ``@litchar{> }'' prompt.)
@scribble-examples|==={
@foo{
bar
baz
blah
}
@foo{
begin
x++;
end}
@foo{
a
b
c}
}===|
If the first string came from the opening @litchar["{"] line, it is
not prepended with an indentation (but it can affect the leftmost
syntax object used for indentation). This makes sense when formatting
structured code as well as text (see the last example in the following
block).
@scribble-examples|==={
@foo{bar
baz
bbb}
@foo{ bar
baz
bbb}
@foo{bar
baz
bbb}
@foo{ bar
baz
bbb}
@foo{ bar
baz
bbb}
@text{Some @b{bold
text}, and
more text.}
}===|
Note that each @"@"-form is parsed to an S-expression that has its own
indentation. This means that Scribble source can be indented like
code, but if indentation matters then you may need to apply
indentation of the outer item to all lines of the inner one. For
example, in
@litchar/lines|==={
@code{
begin
i = 1, r = 1
@bold{while i < n do
r *= i++
done}
end
}
}===|
a formatter will need to apply the 2-space indentation to the
rendering of the @racket[bold] body.
Note that to get a first-line text to be counted as a leftmost line,
line and column accounting should be on for the input port
(@racket[use-at-readtable] turns them on for the current input port).
Without this,
@litchar/lines|==={
@foo{x1
x2
x3}
}===|
will not have 2-space indentations in the parsed S-expression if
source accounting is not on, but
@litchar/lines|==={
@foo{x1
x2
x3}
}===|
will (due to the last line). Pay attention to this, as it can be a
problem with Racket code, for example:
@litchar/lines|==={
@code{(define (foo x)
(+ x 1))}
}===|
For rare situations where spaces at the beginning (or end) of lines
matter, you can begin (or end) a line with a @litchar["@||"].
@scribble-examples|==={
@foo{
@|| bar @||
@|| baz}
}===|
@; --------------------------------------------------
@(close-eval read-eval)

View File

@ -1,464 +0,0 @@
#lang scribble/doc
@(require scribble/manual
"utils.rkt"
(for-label racket/class
scribble/render
scribble/xref))
@(define-syntax-rule (defmodule/local lib . content)
(begin
(define-syntax-rule (intro)
(begin
(require (for-label lib))
(defmodule lib)
. content))
(intro)))
@(begin
(define-syntax-rule (def-html-render-mixin id mid)
(begin
(require (for-label scribble/html-render))
(define id @racket[render-mixin])
(define mid @racket[render-multi-mixin])))
(def-html-render-mixin html:render-mixin html:render-multi-mixin))
@(begin
(define-syntax-rule (def-latex-render-mixin id)
(begin
(require (for-label scribble/latex-render))
(define id @racket[render-mixin])))
(def-latex-render-mixin latex:render-mixin))
@title[#:tag "renderer"]{Renderers}
A renderer is an object that provides four main methods:
@racket[traverse], @racket[collect], @racket[resolve], and
@racketidfont{render}. Each method corresponds to a pass described in
@secref["core"], and they are chained together by the @racket[render]
function to render a document.
@section{Rendering Driver}
@defmodule[scribble/render]
@defproc[(render [docs (listof part?)]
[names (listof path-string?)]
[#:render-mixin render-mixin (class? . -> . class?) @#,html:render-mixin]
[#:dest-dir dest-dir (or/c #f path-string?) #f]
[#:helper-file-prefix helper-file-prefix (or/c #f string?) #f]
[#:prefix-file prefix-file (or/c #f path-string?) #f]
[#:style-file style-file (or/c #f path-string?) #f]
[#:style-extra-files style-extra-files (listof path-string?) #f]
[#:extra-files extra-files (listof path-string?) #f]
[#:image-preferences image-preferences (listof (or/c 'ps 'pdf 'png 'svg 'gif)) null]
[#:xrefs xrefs (listof xref?) null]
[#:info-in-files info-in-files (listof path-string?) null]
[#:info-out-file info-out-file (or/c #f path-string?) #f]
[#:redirect redirect (or/c #f string?) #f]
[#:redirect-main redirect-main (or/c #f string?) #f]
[#:directory-depth directory-depth exact-nonnegative-integer? 0]
[#:quiet? quiet? any/c #t]
[#:warn-undefined? warn-undefined? any/c (not quiet?)])
void?]{
Renders the given @racket[docs], each with an output name derived from
the corresponding element of @racket[names]. A directory path (if any)
for a name in @racket[names] is discarded, and the file suffix is
replaced (if any) with a suitable suffix for the output format.
The @racket[render-mixin] argument determines the output format. By
default, it is @html:render-mixin from @racketmodname[scribble/html-render].
The @racket[dest-dir] argument determines the output directory, which
is created using @racket[make-directory*] if it is non-@racket[#f] and
does not exist already.
The @racket[helper-file-prefix], @racket[prefix-file],
@racket[style-file], @racket[style-extra-files], and
@racket[extra-files] arguments are passed on to the @racket[render%]
constructor.
The @racket[image-preferences] argument specified preferred formats
for image files and conversion, where formats listed earlier in the
list are more preferred. The renderer specified by
@racket[render-mixin] may not support all of the formats listed in
@racket[image-preferences].
The @racket[xrefs] argument provides extra cross-reference information
to be used during the documents' @tech{resolve pass}. The
@racket[info-in-files] arguments supply additional cross-reference
information in serialized form. When the @racket[info-out-file]
argument is not @racket[#f], cross-reference information for the
rendered documents is written in serialized for to the specified file.
The @racket[redirect] and @racket[redirect-main] arguments correspond
to the @racket[set-external-tag-path] and
@racket[set-external-root-url] methods of @|html:render-mixin| from
@racketmodname[scribble/html-render], so they should be
non-@racket[#f] only for HTML rendering.
The @racket[directory-depth] arguments correspond to the
@racket[set-directory-depth] method of @|html:render-multi-mixin|.
If @racket[quiet?] is a false value, output-file information is
written to the current output port.
If @racket[warn-undefined?] is a true value, then references to
missing cross-reference targets trigger a warning message on the
current error port.
@history[#:changed "1.4" @elem{Added the @racket[#:image-preferences] argument.}]}
@section{Base Renderer}
@defmodule[scribble/base-render]{The
@racketmodname[scribble/base-render] module provides @racket[render%],
which implements the core of a renderer. This rendering class must be
refined with a mixin from @racketmodname[scribble/text-render],
@racketmodname[scribble/markdown-render], or
@racketmodname[scribble/html-render], or
@racketmodname[scribble/latex-render].}
The mixin structure is meant to support document-specific extensions
to the renderers. For example, the @exec{scribble} command-line tool
might, in the future, extract rendering mixins from a document module
(in addition to the document proper).
See the @filepath{base-render.rkt} source for more information about
the methods of the renderer. Documents built with higher layers, such
as @racketmodname[scribble/manual], generally do not call the render
object's methods directly.
@definterface[render<%> ()]{
@defmethod[(traverse [srcs (listof part?)]
[dests (listof path-string?)])
(and/c hash? immutable?)]{
Performs the @techlink{traverse pass}, producing a hash table that
contains the replacements for and @racket[traverse-block]s and
@racket[traverse-elements]s. See @method[render<%> render] for
information on the @racket[dests] argument.}
@defmethod[(collect [srcs (listof part?)]
[dests (listof path-string?)]
[fp (and/c hash? immutable?)]
[demand (tag? collect-info? . -> . any/c) (lambda (_tag _ci) #f)])
collect-info?]{
Performs the @techlink{collect pass}. See @method[render<%> render] for
information on the @racket[dests] arguments. The @racket[fp] argument
is a result from the @method[render<%> traverse] method.
The @racket[demand] argument supplies external tag mappings on demand.
When the @racket[collect-info] result is later used to find a mapping
for a tag and no mapping is already available, @racket[demand] is
called with the tag and the @racket[collect-info]. The @racket[demand]
function returns true to indicate when it adds information to the
@racket[collect-info] so that the lookup should be tried again; the
@racket[demand] function should return @racket[#f] if it does not
extend @racket[collect-info].}
@defmethod[(resolve [srcs (listof part?)]
[dests (listof path-string?)]
[ci collect-info?])
resolve-info?]{
Performs the @techlink{resolve pass}. See @method[render<%> render] for
information on the @racket[dests] argument. The @racket[ci] argument
is a result from the @method[render<%> collect] method.}
@defmethod[(render [srcs (listof part?)]
[dests (listof path-string?)]
[ri resolve-info?])
void?]{
Produces the final output. The @racket[ri] argument is a result from
the @method[render<%> render] method.
The @racket[dests] provide names of files for Latex or single-file
HTML output, or names of sub-directories for multi-file HTML output.
If the @racket[dests] are relative, they're relative to the current
directory; normally, they should indicates a path within the
@racket[_dest-dir] supplied on initialization of the @racket[render%]
object.}
@defmethod[(serialize-info [ri resolve-info?])
any/c]{
Serializes the collected info in @racket[ri].}
@defmethod[(serialize-infos [ri resolve-info?]
[count exact-positive-integer?]
[doc part?])
list?]{
Like @method[render<%> serialize-info], but produces @racket[count] results
that together have the same information as produced by
@method[render<%> serialize-info]. The structure of @racket[doc] is used to
drive the partitioning (on the assumption that @racket[ri] is derived
from @racket[doc]).}
@defmethod[(deserialize-info [v any/c]
[ci collect-info?]
[#:root root-path (or/c path-string? false/c) #f])
void?]{
Adds the deserialized form of @racket[v] to @racket[ci].
If @racket[root-path] is not @racket[#f], then file paths that are
recorded in @racket[ci] as relative to an instantiation-supplied
@racket[root-path] are deserialized as relative instead to the given
@racket[root-path].}
@defmethod[(get-defined [ci collect-info?]) (listof tag?)]{
Returns a list of tags that were defined within the documents
represented by @racket[ci].}
@defmethod[(get-defineds [ci collect-info?]
[count exact-positive-integer?]
[doc part?])
(listof (listof tag?))]{
Analogous to @method[render<%> serialize-infos]: returns a list of
tags for each of @racket[count] partitions of the result of
@method[render<%> get-defined], using the structure of @racket[doc] to
drive the partitioning.}
@defmethod[(get-external [ri resolve-info?]) (listof tag?)]{
Returns a list of tags that were referenced but not defined within the
documents represented by @racket[ri] (though possibly found in
cross-reference information transferred to @racket[ri] via
@racket[xref-transfer-info]).}
@defmethod[(get-undefined [ri resolve-info?]) (listof tag?)]{
Returns a list of tags that were referenced by the resolved documents
with no target found either in the resolved documents represented by
@racket[ri] or cross-reference information transferred to @racket[ri]
via @racket[xref-transfer-info].
If multiple tags were referenced via @racket[resolve-search] and a
target was found for any of the tags using the same dependency key,
then no tag in the set is included in the list of undefined tags.}
}
@defclass[render% object% (render<%>)]{
Represents a renderer.
@defconstructor[([dest-dir path-string?]
[refer-to-existing-files any/c #f]
[root-path (or/c path-string? #f) #f]
[prefix-file (or/c path-string? #f) #f]
[style-file (or/c path-string? #f) #f]
[style-extra-files (listof path-string?) null]
[extra-files (listof path-string?) null]
[image-preferences (listof (or/c 'ps 'pdf 'png 'svg 'gif)) null])]{
Creates a renderer whose output will go to @racket[dest-dir]. For
example, @racket[dest-dir] could name the directory containing the
output Latex file, the HTML file for a single-file output, or the
output sub-directory for multi-file HTML output.
If @racket[refer-to-existing-files] is true, then when a document
refers to external files, such as an image or a style file, then the
file is referenced from its source location instead of copied to the
document destination.
If @racket[root-path] is not @racket[#f], it is normally the same as
@racket[dest-dir] or a parent of @racket[dest-dir]. It causes
cross-reference information to record destination files relative to
@racket[root-path]; when cross-reference information is serialized, it
can be deserialized via @method[render<%> deserialize-info] with a
different root path (indicating that the destination files have
moved).
The @racket[prefix-file], @racket[style-file], and
@racket[style-extra-files] arguments set files that control output
styles in a formal-specific way; see @secref["config-style"] for more
information.
The @racket[extra-files] argument names files to be copied to the
output location, such as image files or extra configuration files.
The @racket[image-preferences] argument specified preferred formats
for image files and conversion, where formats listed earlier in the
list are more preferred. The renderer may not support all of the
formats listed in @racket[image-preferences].
@history[#:changed "1.4" @elem{Added the @racket[image-preferences]
initialization argument.}]}}
@; ----------------------------------------
@section{Text Renderer}
@defmodule/local[scribble/text-render]{
@defmixin[render-mixin (render<%>) ()]{
Specializes a @racket[render<%>] class for generating plain text.}}
@; ----------------------------------------
@section{Markdown Renderer}
@defmodule/local[scribble/markdown-render]{
@defmixin[render-mixin (render<%>) ()]{
Specializes a @racket[render<%>] class for generating Markdown text.
Code blocks are marked using the
@hyperlink["http://github.github.com/github-flavored-markdown/"
"Github convention"] @verbatim{```racket} so that they are lexed and
formatted as Racket code.}}
@; ----------------------------------------
@section{HTML Renderer}
@defmodule/local[scribble/html-render]{
@defmixin[render-mixin (render<%>) ()]{
@defconstructor/auto-super[([search-box? boolean? #f])]{
Specializes a @racket[render<%>] class for generating
HTML output. The arguments are the same as
@racket[render<%>], except for the addition of
@racket[search-box].
If @racket[search-box?] is @racket[#t] and the document
is created with @racket[scribble/manual], then it will be
rendered with a search box, similar to this page. Note
that the @racket[search-box?] argument does not create
the search page itself. Rather, it passes the search
query to whatever page is located at
@tt{search/index.html}. The query is passed as an HTTP
query string in the @tt{q} field.}
@defmethod[(set-external-tag-path [url string?]) void?]{
Configures the renderer to redirect links to external documents via
@racket[url], adding a @tt{tag} query element to the end of the
URL that contains the Base64-encoded, @racket[print]ed, serialized
original tag (in the sense of @racket[link-element]) for the link.
If the link is based on a cross-reference entry that has a
document-identifying string (see @racket[load-xref] and its
@racket[#:doc-id] argument), the document identifier is added as a
@tt{doc} query element, and a path to the target within the
document is added as a @tt{rel} query element.}
@defmethod[(set-external-root-url [url string?]) void?]{
Configures the renderer to redirect links to documents installed in
the distribution's documentation directory to the given URL, using the
URL as a replacement to the path of the distribution's document
directory.}
}
@defmixin[render-multi-mixin (render<%>) ()]{
Further specializes a rendering class produced by
@racket[render-mixin] for generating multiple HTML
files.
@defmethod[(set-directory-depth [depth exact-nonnegative-integer?]) void?]{
Sets the depth of directory structure used when rendering parts that
are own their own pages. A value of @racket[0] is treated the same as
@racket[1].}
}
}
@; ----------------------------------------
@section{Latex Renderer}
@defmodule/local[scribble/latex-render]{
@defmixin[render-mixin (render<%>) ()]{
Specializes a @racket[render<%>] class for generating Latex input.}}
@; ----------------------------------------
@section{PDF Renderer}
@defmodule/local[scribble/pdf-render]{
@defmixin[render-mixin (render<%>) ()]{
Specializes a @racket[render<%>] class for generating PDF output via
Latex, building on @|latex:render-mixin| from @racketmodname[scribble/latex-render].}}
@; ----------------------------------------
@section{Contract (Blue boxes) Renderer}
@defmodule/local[scribble/contract-render]{
@defmixin[override-render-mixin-multi (render<%>) ()]{
Overrides the @method[render<%> render] method of
given renderer to record the content of the
blue boxes (generated by @racket[defproc], @racket[defform], etc)
that appear in the document.
@defmethod[#:mode override
(render [srcs (listof part?)]
[dests (listof path?)]
[ri render-info?])
void?]{
In addition to doing whatever the @racket[super] method
does, also save the content of the blue boxes (rendered
via a @racketmodname[scribble/text-render] renderer).
It saves this information in three pieces in a file
inside the @racket[dests] directories called
@filepath{blueboxes.rktd}. The first piece is
a single line containing a (decimal, ASCII) number. That number
is the number of bytes that the second piece of information
occupies in the file. The second piece of information
is a @racket[hash] that maps @racket[tag?] values to
a list of offsets and line numbers that follow the hash table.
For example, if the @racket[hash] maps
@racket['(def ((lib "x/main.rkt") abcdef))] to
@racket['((10 . 3))], then that means that the documentation
for the @racket[abcdef] export from the @racket[x] collection
starts 10 bytes after the end of the hash table and continues for
@racket[3] lines. Multiple elements in the list mean that that
@racket[tag?] has multiple blue boxes and each shows where one
of the boxes appears in the file.
}}
@defmixin[override-render-mixin-single (render<%>) ()]{
Just like @racket[override-render-mixin-multi], except
it saves the resulting files in a different place.
@defmethod[#:mode override
(render [srcs (listof part?)]
[dests (listof path?)]
[ri render-info?])
void?]{
Just like @method[override-render-mixin-multi render], except
that it saves the file @filepath{blueboxes.rktd} in
the same directory where each @racket[dests] element resides.
}}
}

View File

@ -1,8 +0,0 @@
#lang scribble/manual
@(require "utils.rkt")
@title{Report Format}
@defmodulelang[scribble/report]{The @racketmodname[scribble/report]
language is like @racketmodname[scribble/book], but configured with
Latex style defaults to use the standard @tt{report} class.}

View File

@ -1,212 +0,0 @@
#lang scribble/manual
@(require "utils.rkt"
scribble/bnf
(for-label setup/xref))
@(define fn (italic "fn"))
@title[#:tag "running"]{Running @exec{scribble}}
The @exec{scribble} command-line tool (also available as @as-index{@exec{raco
scribble}}) runs a Scribble document and renders it to a specific
format. Select a format with one of the following flags, where the
output name @|fn| is by default the document source name without
its file suffix:
@itemlist[
@item{@DFlag{html} --- a single HTML page @filepath{@|fn|.html},
plus CSS sources and needed image files; this mode is the
default if no format is specified}
@item{@DFlag{htmls} --- multiple HTML pages (and associated files) in
a @filepath{@|fn|} directory, starting with
@filepath{@|fn|/index.html}}
@item{@DFlag{html-tree} @nonterm{n} --- HTML pages in a directory
tree up to @nonterm{n} layers deep; a tree of depth @exec{0} is
equivalent to using @DFlag{html}, and a tree of depth @exec{1}
is equivalent to using @DFlag{htmls}}
@item{@DFlag{latex} --- LaTeX source @filepath{@|fn|.tex}, plus
any needed additional files (such as non-standard class files)
needed to run @exec{latex} or @exec{pdflatex}}
@item{@DFlag{pdf} --- PDF @filepath{@|fn|.pdf} that is generated
via @exec{pdflatex}}
@item{@DFlag{dvipdf} --- PDF @filepath{@|fn|.pdf} that is generated
via @exec{latex}, @exec{dvips}, and @exec{pstopdf}}
@item{@DFlag{latex-section} @nonterm{n} --- LaTeX source
@filepath{@|fn|.tex} plus additional @filepath{.tex} files to
be included in the enclosing document's preamble, where the
enclosing document must use the UTF-8 input encoding and T1
font encoding; use @tt{1} for @nonterm{n} to make the rendered
document a section, @tt{2} for a subsection, etc.}
@item{@DFlag{text} --- plain text in a single file
@filepath{@|fn|.txt}, with non-ASCII content encoded as UTF-8}
@item{@DFlag{markdown} --- Markdown text in a single file
@filepath{@|fn|.md}, with non-ASCII content encoded as UTF-8}
]
Use @DFlag{dest-name} to specify a @|fn| other than the default name,
but only when a single source file is provided. Use the @DFlag{dest}
flag to specify a destination directory (for any number of source
files). Use @DFlag{dest-base} to add a prefix to the name of each
support file that is generated or copied to the destination.
After all flags, provide one or more document sources, where each
source declares a module. The module should either have a @racket[doc]
@tech[#:doc '(lib "scribblings/reference/reference.scrbl")]{submodule}
that exports @racket[doc] as a @racket[part], or it should directly
export @racket[doc] as a @racket[part]. (The submodule is tried first,
and the main module is not directly loaded or evaluated if the
submodule can be loaded on its own.)
When multiple documents are rendered at the same time, cross-reference
information in one document is visible to the other documents. See
@secref["xref-flags"] for information on references that cross
documents that are built separately.
@history[#:changed "1.4" @elem{Added @DFlag{dvipdf}.}]
@section{Extra and Format-Specific Files}
Use the @DFlag{style} flag to specify a format-specific file to adjust
the output style file for certain formats. For HTML (single-page or
multi-page) output, the style file should be a CSS file that is
applied after all other CSS files, and that may therefore override
some style properties. For Latex (or PDF) output, the style file
should be a @filepath{.tex} file that can redefine Latex commands.
When a particular Scribble function needs particular CSS or Latex
support, however, a better option is to use a @racket[css-addition] or
@racket[tex-addition] style property so that the support is included
automatically; see @secref["config"] for more information.
In rare cases, use the @DFlag{style} flag to specify a format-specific
base style file. For HTML (single-page or multi-page) output, the
style file should be a CSS file to substitute for
@filepath{scribble.css} in the @filepath{scribble} collection. For
Latex (or PDF) output, the style file should be a @filepath{.tex} file
to substitute for @filepath{scribble.tex} in the @filepath{scribble}
collection. The @DFlag{style} flag is rarely useful, because the
content of @filepath{scribble.css} or @filepath{scribble.tex} is
weakly specified; replacements must define all of the same styles, and
the set of styles can change across versions of Racket.
Use @DFlag{prefix} to specify an alternate format-specific start of
the output file. For HTML output, the starting file specifies the
@tt{DOCTYPE} declaration of each output HTML file as a substitute for
@filepath{scribble-prefix.html} in the @filepath{scribble}
collection. For Latex (or PDF) output (but not Latex-section output), the starting file specifies
the @ltx{documentclass} declaration and initial @ltx{usepackage}
declarations as a substitute for @filepath{scribble-prefix.tex} in the
@filepath{scribble} collection. See also @racket[html-defaults],
@racket[latex-defaults], and @secref["config"].
For any output form, use the @DPFlag{extra} flag to add a needed file
to the build destination, such as an image file that is referenced in
the generated output but not included via @racket[image] (which copies
the file automatically).
@section[#:tag "xref-flags"]{Handling Cross-References}
Cross references within a document or documents rendered together are
always resolved. When cross references span documents that are
rendered separately, cross-reference information needs to be saved and
loaded explicitly. Cross-reference information is format-specific, but
HTML-format information is usable for Latex (or PDF) or text rendering.
A Racket installation includes HTML-format cross-reference information
for all installed documentation. Each document's information is in a
separate file, so that loading all relevant files would be tedious.
The @PFlag{m} or @DPFlag{main-xref-in} flag loads cross-reference
information for all installed documentation, so
@commandline{scribble +m mine.scrbl}
renders @filepath{mine.scrbl} to @filepath{mine.html} with
cross-reference links to the Racket installation's documentation.
(The @filepath{racket-index} package must be installed to use
@PFlag{m}/@DPFlag{main-xref-in}.)
The @DPFlag{xref-in} flag loads cross-reference information by calling
a specified module's function. The @racketmodname[setup/xref] module
provides @racket[load-collections-xref] to load cross-reference
information for all installed documentation, and @PFlag{m} or
@DPFlag{main-xref-in} is just a shorthand for @exec{++xref-in
setup/xref load-collections-xref}.
The @DFlag{redirect-main} flag for HTML output redirects links to the local
installation's documentation to a given URL, such as
@tt{http://docs.racket-lang.org/}. Beware that documentation links
sometimes change (although Scribble generates HTML paths and anchors
in a relatively stable way), so
@tt{http://download.racket-lang.org/docs/@italic{version}/html/} may be
more reliable when building with an installation for @italic{version}.
The @DFlag{redirect-main} flag is ignored for non-HTML output.
The @DFlag{redirect} flag is like @DFlag{redirect-main}, except
that it builds on the given URL to indicate a cross-reference tag that
is more stable than an HTML path and anchor (in case the documentation
for a function changes sections, for example). No server currently
exists to serve such tag requests, however.
For cross-references among documentation that is not part of the
Racket installation, use @DFlag{info-out} to save information from a
document build and use @DPFlag{info-in} to load previously saved
information. For example, if @filepath{c.scrbl} refers to information
in @filepath{a.scrbl} and @filepath{b.scrbl}, then
@commandline{scribble --info-out a.sxref a.scrbl}
@commandline{scribble --info-out b.sxref b.scrbl}
@commandline{scribble ++info-in a.sxref ++info-in b.sxref c.scrbl}
builds @filepath{c.html} with cross-reference links into
@filepath{a.html} and @filepath{b.html}.
@section{Selecting an Image Format}
Use the @DPFlag{convert} @nonterm{fmt} flag to select @nonterm{fmt} as
a preferred image format to use when rendering a document that
includes values that can be converted to different image formats. The
@nonterm{fmt} argument can be @exec{pdf}, @exec{ps}, @exec{png},
@exec{svg}, or @exec{gif}, but a renderer typically supports only a
subset of those formats.
Use @DPFlag{convert} @nonterm{fmt} multiple times to specify multiple
preferred formats, where a @nonterm{fmt} earlier in the command line
take precedence over @nonterm{fmt}s specified later.
For example, to generate Latex sources with images in Encapsulated
PostScript format (so that the result works with @exec{latex} instead
of @exec{pdflatex}), combine @DFlag{latex} with @exec{@DPFlag{convert}
ps}. To generate HTML pages with images converted to SVG format
instead of PNG format, combine @DFlag{html} with
@exec{@DPFlag{convert} svg}.
@history[#:changed "1.4" @elem{Added @DPFlag{convert} support.}]
@section{Passing Command-Line Arguments to Documents}
When @exec{scribble} loads and renders a document module, by default
it sets @racket[current-command-line-arguments] to an empty vector.
Use the @DPFlag{arg} flag (any number of times) to add a string to
@racket[current-command-line-arguments].
For example,
@commandline{scribble ++arg --mode ++arg fast turtle.scrbl}
causes @racket[(current-command-line-arguments)] to return
@racket['#("--mode" "fast")] while @filepath{turtle.scrbl} is loaded
and rendered, which could affect the content that
@filepath{turtle.scrbl} generates if it uses
@racket[current-command-line-arguments].
@history[#:changed "1.1" @elem{Added the empty-vector default and @DPFlag{arg} flag.}]

View File

@ -1,223 +0,0 @@
#lang scribble/doc
@(require scribble/manual "utils.rkt" (for-label scribble/racket))
@title[#:tag "scheme"]{Racket}
@defmodule*[(scribble/racket scribble/scheme)]{The
@racket[scribble/racket] library (or @racketmodname[scribble/scheme]
for backward compatibility) provides utilities for typesetting Racket
code. The @racket[scribble/manual] forms provide a higher-level
interface.}
@defform*[[(define-code id typeset-expr)
(define-code id typeset-expr uncode-id)
(define-code id typeset-expr uncode-id d->s-expr)
(define-code id typeset-expr uncode-id d->s-expr stx-prop-expr)]]{
Binds @racket[id] to a form similar to @racket[racket] or
@racket[racketblock] for typesetting code. The form generated by
@racket[define-code] handles source-location information, escapes via
@racket[unquote] by default, preserves binding and property information,
and supports @tech{element transformers}.
The supplied @racket[typeset-expr] expression should produce a
procedure that performs the actual typesetting. This expression is
normally @racket[to-element] or @racket[to-paragraph]. The argument
supplied to @racket[typeset-expr] is normally a syntax object, but
more generally it is the result of applying @racket[d->s-expr].
The optional @racket[uncode-id] specifies the default escape from
literal code to be recognized by @racket[id], and the default for
@racket[uncode-id] is @racket[unsyntax]. A use of the @racket[id] form
can specify an alternate escape via @racket[#:escape], as in
@racket[racketblock] and @racket[racket].
The optional @racket[d->s-expr] should produce a procedure that
accepts three arguments suitable for @racket[datum->syntax]: a syntax
object or @racket[#f], an arbitrary value, and a vector for a source
location. The result should record as much or as little of the
argument information as needed by @racket[typeset-expr] to typeset the
code. Normally, @racket[d->s-expr] is @racket[datum->syntax].
The @racket[stx-prop-expr] should produce a procedure for recording a
@racket['paren-shape] property when the source expression uses with
@racket[id] has such a property. The default is
@racket[syntax-property].}
@defproc[(to-paragraph [v any/c]
[#:expr? expr? any/c #f]
[#:escapes? escapes? any/c #t]
[#:color? color? any/c #t]
[#:wrap-elem wrap-elem (element? . -> . element?) (lambda (e) e)])
block?]{
Typesets an S-expression that is represented by a syntax object, where
source-location information in the syntax object controls the
generated layout. When source-location information is not available,
default spacing is used (in the same single-line style as
@racket[to-element]).
Identifiers that have @racket[for-label] bindings are typeset and
hyperlinked based on definitions declared elsewhere (via
@racket[defproc], @racket[defform], etc.). Unless @racket[escapes?]
is @racket[#f], the identifiers
@racketidfont{code:line}, @racketidfont{code:comment},
@racketidfont{code:blank}, @racketidfont{code:hilite}, and
@racketidfont{code:quote} are handled as in @racket[racketblock], as
are identifiers that start with @litchar{_}.
In addition, the given @racket[v] can contain @racket[var-id],
@racket[shaped-parens], @racket[just-context], or
@racket[literal-syntax] structures to be typeset specially (see each
structure type for details), or it can contain @racket[element]
structures that are used directly in the output.
If @racket[expr?] is true, then @racket[v] is rendered in expression
style, much like @racket[print] with the @racket[print-as-expression]
parameter set to @racket[#t]. In that case, @racket[for-label]
bindings on identifiers are ignored, since the identifiers are all
quoted in the output. Typically, @racket[expr?] is set to true for
printing result values.
If @racket[color?] is @racket[#f], then the output is typeset without
coloring.
The @racket[wrap-elem] procedure is applied to each element
constructed for the resulting block. When combined with @racket[#f]
for @racket[color?], for example, the @racket[wrap-elem] procedure can
be used to give a style to an element.}
@defproc[((to-paragraph/prefix [prefix1 any/c] [prefix any/c] [suffix any/c])
[v any/c] [#:expr? expr? any/c #f] [#:escapes? escapes? any/c #t]
[#:color? color? any/c #f]
[#:wrap-elem wrap-elem (element? . -> . element?) (lambda (e) e)])
block?]{
Like @racket[to-paragraph], but @racket[prefix1] is prefixed onto the
first line, @racket[prefix] is prefix to any subsequent line, and
@racket[suffix] is added to the end. The @racket[prefix1],
@racket[prefix], and @racket[suffix] arguments are used as
@tech{content}, except that if @racket[suffix] is a list of elements,
it is added to the end on its own line.}
@defproc[(to-element [v any/c]
[#:expr? expr? any/c #f]
[#:escapes? escapes? any/c #t]
[#:defn? defn? any/c #f]) element?]{
Like @racket[to-paragraph], except that source-location information is
mostly ignored, since the result is meant to be inlined into a
paragraph. If @racket[defn?] is true, then an identifier is styled as
a definition site.}
@defproc[(to-element/no-color [v any/c]
[#:expr? expr? any/c #f]
[#:escapes? escapes? any/c #t])
element?]{
Like @racket[to-element], but @racket[for-syntax] bindings are
ignored, and the generated text is uncolored. This variant is
typically used to typeset results.}
@defstruct[var-id ([sym (or/c symbol? identifier?)])]{
When @racket[to-paragraph] and variants encounter a @racket[var-id]
structure, it is typeset as @racket[sym] in the variable font, like
@racket[racketvarfont]---unless the @racket[var-id] appears under
quote or quasiquote, in which case @racket[sym] is typeset as a symbol.}
@defstruct[shaped-parens ([val any/c]
[shape char?])]{
When @racket[to-paragraph] and variants encounter a
@racket[shaped-parens] structure, it is typeset like a syntax object
that has a @racket['paren-shape] property with value @racket[shape].}
@defstruct[long-boolean ([val boolean?])]{
When @racket[to-paragraph] and variants encounter a
@racket[long-boolean] structure, it is typeset as @racket[#true] or @racket[#false],
as opposed to @racket[#t] or @racket[#f].}
@defstruct[just-context ([val any/c]
[context syntax?])]{
When @racket[to-paragraph] and variants encounter a
@racket[just-context] structure, it is typeset using the
source-location information of @racket[val] just the lexical context
of @racket[ctx].}
@defstruct[literal-syntax ([stx any/c])]{
When @racket[to-paragraph] and variants encounter a
@racket[literal-syntax] structure, it is typeset as the string form of
@racket[stx]. This can be used to typeset a syntax-object value in the
way that the default printer would represent the value.}
@defproc[(element-id-transformer? [v any/c]) boolean?]{
Provided @racket[for-syntax]; returns @racket[#t] if @racket[v] is an
@tech{element transformer} created by
@racket[make-element-id-transformer], @racket[#f] otherwise.}
@defproc[(make-element-id-transformer [proc (syntax? . -> . syntax?)])
element-id-transformer?]{
Provided @racket[for-syntax]; creates an @deftech{element
transformer}. When an identifier has a transformer binding to an
@tech{element transformer}, then forms generated by
@racket[define-code] (including @racket[racket] and
@racket[racketblock]) typeset the identifier by applying the
@racket[proc] to the identifier. The result must be an expression
whose value, typically an @racket[element], is passed on to functions
like @racket[to-paragraph] .}
@defproc[(variable-id? [v any/c]) boolean?]{
Provided @racket[for-syntax]; returns @racket[#t] if @racket[v] is an
@tech{element transformer} created by @racket[make-variable-id],
@racket[#f] otherwise.}
@defproc[(make-variable-id [sym (or/c symbol? identifier?)])
variable-id?]{
Provided @racket[for-syntax]; like @racket[make-element-id-transformer] for
a transformer that produces @racket[sym] typeset as a variable (like
@racket[racketvarfont])---unless it appears under quote or quasiquote,
in which case @racket[sym] is typeset as a symbol.}
@deftogether[(
@defthing[output-color style?]
@defthing[input-color style?]
@defthing[input-background-color style?]
@defthing[no-color style?]
@defthing[reader-color style?]
@defthing[result-color style?]
@defthing[keyword-color style?]
@defthing[comment-color style?]
@defthing[paren-color style?]
@defthing[meta-color style?]
@defthing[value-color style?]
@defthing[symbol-color style?]
@defthing[variable-color style?]
@defthing[opt-color style?]
@defthing[error-color style?]
@defthing[syntax-link-color style?]
@defthing[value-link-color style?]
@defthing[module-color style?]
@defthing[module-link-color style?]
@defthing[block-color style?]
@defthing[highlighted-color style?]
)]{
Styles that are used for coloring Racket programs, results, and I/O.}

View File

@ -1,26 +0,0 @@
#lang scribble/manual
@(require "utils.rkt")
@title{Scribble as Preprocessor}
@author["Matthew Flatt" "Eli Barzilay"]
@section-index["Preprocessor"]
The @racketmodname[scribble/text] and @racketmodname[scribble/html]
languages act as ``preprocessor'' languages for generating text or
HTML. These preprocessor languages use the same @"@" syntax as the
main Scribble tool (see @other-doc['(lib
"scribblings/scribble/scribble.scrbl")]), but instead of working in
terms of a document abstraction that can be rendered to text and HTML
(and other formats), the preprocessor languages work in a way that is
more specific to the target formats.
@table-of-contents[]
@; ------------------------------------------------------------------------
@include-section["text.scrbl"]
@include-section["html.scrbl"]
@index-section[]

View File

@ -1,32 +0,0 @@
#lang scribble/manual
@(require "utils.rkt")
@title{Scribble: The Racket Documentation Tool}
@author["Matthew Flatt" "Eli Barzilay"]
Scribble is a collection of tools for creating prose
documents---papers, books, library documentation, etc.---in HTML or
PDF (via Latex) form. More generally, Scribble helps you write
programs that are rich in textual content, whether the content is
prose to be typeset or any other form of text to be generated
programmatically.
This document is itself written using Scribble. You can see its source
at
@(let ([url "https://github.com/racket/scribble/tree/master/scribble-doc/scribblings/scribble"])
(link url url)),
starting with the @filepath{scribble.scrbl} file.
@table-of-contents[]
@; ------------------------------------------------------------------------
@include-section["how-to-paper.scrbl"]
@include-section["reader.scrbl"]
@include-section["generic.scrbl"]
@include-section["plt.scrbl"]
@include-section["lp.scrbl"]
@include-section["internals.scrbl"]
@include-section["running.scrbl"]
@index-section[]

View File

@ -1,2 +0,0 @@
\newcommand{\Short}[1]{\begin{minipage}[c]{6ex}#1\end{minipage}}

View File

@ -1,146 +0,0 @@
#lang scribble/manual
@(require "utils.rkt" (for-label scribble/sigplan))
@title{SIGPLAN Paper Format}
@defmodulelang[scribble/sigplan]{The @racketmodname[scribble/sigplan]
language is like @racketmodname[scribble/base], but configured with
Latex style defaults to use the @filepath{sigplanconf.cls} class
file that is included with Scribble.}
@defidform[preprint]{
Enables the @tt{preprint} option. Use @racket[preprint] only on the
same line as @hash-lang[], with only whitespace (or other options) between
@racketmodname[scribble/sigplan] and @racket[preprint]:
@verbatim[#:indent 2]|{
#lang scribble/sigplan @preprint
}|}
@defidform[10pt]{
Enables the @tt{10pt} option. Use @racket[10pt] only on the
same line as @hash-lang[], with only whitespace (or other options) between
@racketmodname[scribble/sigplan] and @racket[10pt]:
@verbatim[#:indent 2]|{
#lang scribble/sigplan @10pt
}|
@defidform[nocopyright]{
Enables the @tt{nocopyright} option. Use @racket[nocopyright] only on the
same line as @hash-lang[], with only whitespace (or other options) between
@racketmodname[scribble/sigplan] and @racket[nocopyright]:
@verbatim[#:indent 2]|{
#lang scribble/sigplan @nocopyright
}|}
@defidform[onecolumn]{
Enables the @tt{onecolumn} option. Use only on the
same line as @hash-lang[], with only whitespace (or other options) between
@racketmodname[scribble/sigplan] and @racket[onecolumn]:
@codeblock|{
#lang scribble/sigplan @onecolumn
}|}
@defidform[notimes]{
Disables the use of @tt{\usepackage@"{"times@"}"} in the generated LaTeX output.
Use only on the same line as @hash-lang[],
with only whitespace (or other options) between
@racketmodname[scribble/sigplan] and @racket[notimes]:
@codeblock|{
#lang scribble/sigplan @notimes
}|}
@defidform[noqcourier]{
Disables the use of @tt{\usepackage@"{"qcourier@"}"} in the generated LaTeX output.
Use only on the same line as @hash-lang[],
with only whitespace (or other options) between
@racketmodname[scribble/sigplan] and @racket[noqcourier]:
@codeblock|{
#lang scribble/sigplan @noqcourier
}|}
The @racket[10pt], @racket[preprint], @racket[nocopyright],
@racket[onecolumn], @racket[notimes], and @racket[noqcourier]
options can be used together and may appear in any order.
}
@defproc[(abstract [pre-content pre-content?] ...) block?]{
Generates a @tech{nested flow} for a paper abstract.}
@defform[(include-abstract module-path)]{
Similar to @racket[include-section], but incorporates the document in the
specified module as an abstract. The document must have no title or
sub-parts.}
@defproc[(subtitle [pre-content pre-content?] ...) element?]{
Use as the last argument to @racket[title] to specify a subtitle.}
@defproc[(authorinfo [name pre-content?]
[affiliation pre-content?]
[email pre-content?])
block?]{
A replacement for @racket[author] that associates an affiliation and
e-mail address with the author name.}
@deftogether[(
@defproc[(conferenceinfo [conference pre-content?] [location pre-content?]) block?]
@defproc[(copyrightyear [content pre-content?] ...) block?]
@defproc[(copyrightdata [content pre-content?] ...) block?]
@defproc[(doi [content pre-content?] ...) block?]
@defproc[(exclusive-license) block?]
)]{
Declares information that is collected into the copyright region of the paper.}
@defproc[(to-appear [content pre-content?] ...) block?]{
Declares alternate content for the copyright region of the paper.
@history[#:added "1.13"]}
@deftogether[(
@defproc[(category [CR-number pre-content?]
[subcategory pre-content?]
[third-level pre-content?]
[fourth-level (or/c #f pre-content?) #f]) content?]
@defproc[(terms [content pre-content?] ...) content?]
@defproc[(keywords [content pre-content?] ...) content?]
)]{
Typesets category, term, and keyword information for the paper, which
is normally placed immediately after an @racket[abstract] form.
See also @url["http://www.acm.org/about/class/how-to-use"].
For @racket[category], the @racket[subcategory] argument should be in
titlecase (i.e., capitalize the first letter of each word) and a
phrase at the level of ``Programming Languages'' or ``Software
Engineering'' (as opposed to a category like ``Software'' or a
third-level name like ``Concurrent Programming'' or ``Processors''). A
@racket[third-level] phrase should be in titlecase. A
@racket[fourth-level] phrase, if any, should not be capitalized.
For @racket[terms], each general term should be in titlecase. Terms
are usually drawn from a fixed list, and they are usually optional.
For @racket[keywords], capitalize only the first letter of the first
word, separate phrases by commas, and do not include ``and'' before
the last one. Keywords should be noun phrases, not adjectives.}

View File

@ -1,258 +0,0 @@
#lang scribble/doc
@(require scribble/manual "utils.rkt"
(for-label scribble/srcdoc scribble/extract racket/contract))
@title[#:tag "srcdoc"]{In-Source Documentation}
The @racketmodname[scribble/srcdoc] and
@racketmodname[scribble/extract] libraries support writing
documentation within the documented code along with an export
contract, similar to using @as-index{JavaDoc}. With this approach, a
single contract specification is used both for the run-time contract
and the documentation of an exported binding.
The @racketmodname[scribble/srcdoc] library provides forms for
exporting a binding with associated documentation. The
@racket[scribble/extract] library is used to pull
@racket[scribble/srcdoc]-based documentation into a Scribble document
(perhaps for multiple libraries).
Although documentation is written with a library's implementation when
using @racketmodname[scribble/srcdoc], the documentation creates no
run-time overhead for the library. Similarly, typesetting the
documentation does not require running the library. The two phases
(run time versus documentation time) are kept separate in much the
same way that the module system keeps expansion-time code separate
from run-time code, and documentation information is recorded in a
submodule to be separately loadable from the enclosing module.
For an example use, see the @filepath{file} collection's
@filepath{gif.rkt} source file and the corresponding extraction in
@filepath{scribblings/gif.scrbl}. As that example illustrates,
starting the module declaration with
@racketblock[
@#,hash-lang[] @#,racketmodname[at-exp]
]
enables the @"@"-reader, which is handy for writing documentation
expressions.
@; ----------------------------------------
@section{Source Annotations for Documentation}
@defmodule[scribble/srcdoc]
Documentation information generated by @racketmodname[scribble/srcdoc]
forms are accumulated into a @racketidfont{srcdoc} submodule. The
generated submodule is accessed by the bindings of
@racketmodname[scribble/extract].
@defform[(for-doc require-spec ...)]{
A @racket[require] sub-form for bindings that are needed at
documentation time (and documentation-expansion time, etc.) instead of
run time (and expansion time, etc.). A @racket[for-doc] import has
no effect on a normal use of the library; it affects only
documentation extraction.
Typically, a library that uses @racketmodname[scribble/srcdoc]
includes at least @racket[(require (for-doc scribble/base scribble/manual))]
to get core Racket forms and basic Scribble functions to use in
documentation expressions.}
@defform*/subs[#:literals (-> ->* case->)
[(proc-doc/names id contract arg-specs (desc-expr ...))]
([arg-specs ((arg-id ...) ((arg-id default-expr) ...))
(arg-id ...)]
[contract (-> arg ... result)
(->* (mandatory ...) (optional ...) result)
(case-> (-> arg ... result) ...)]
[mandatory contract-expr
(code:line keyword contract-expr)]
[optional contract-expr
(code:line keyword contract-expr)])]{
A @racket[provide] sub-form that exports @racket[id] with the
contract described by @racket[contract]
just like using @racket[contract-out].
The @racket[arg-spec] specifies the names of arguments and the
default values, which are not
normally written as part of a contract. They are combined with the
contract expression to generate the description of the binding in the
documentation via @racket[defproc]. The @racket[(arg-id default-expr)]
pairs specify the names and default values of the optional arguments.
If the contract supports optional arguments, then the first
@racket[arg-spec]s form must be used, otherwise the second must be used.
The @racket[desc-expr] is a sequence of documentation-time expressions that
produces prose to describe the exported binding---that is, the last
part of the generated @racket[defproc], so the description can refer
to the @racket[arg-id]s using @racket[racket].
The normal @racket[require]s of the enclosing library are effectively
converted into @racket[for-label] @racket[require]s when generating
documentation, so that identifiers in the @racket[contract]s are
linked to their corresponding documentation. Similarly, any binding
that is available in the run-time phase of the enclosing library
can be referenced in documentation prose using the @racket[racket]
form.}
@defform/subs[#:literals (-> ->i ->d values)
(proc-doc id contract maybe-defs (desc-expr ...))
([contract (-> result)
(->i (arg ...) (opt ...) maybe-pre [id res])
(->i (arg ...) (opt ...) maybe-pre (values [id res] ...))
(->i (arg ...) (opt ...) #:rest rest [id result-expr])
(->d (arg ...) () maybe-pre (values [id result] ...))
(->d (arg ...) () maybe-pre [id result])
(->d (arg ...) () #:rest id rest [id result])]
[maybe-pre (code:line)
(code:line #:pre (pre-id ...) condition)]
[maybe-defs (code:line)
(default-expr default-expr ...)])]{
Like @racket[proc-doc/names], but supporting contract forms that embed
argument identifiers. Only a subset of @racket[->i] and @racket[->d] forms are
currently supported.
If the sequence of optional arguments, @racket[(opt ...)] is empty then
the @racket[maybe-arg-desc] must be not be present. If it is non-empty,
then it must have as many default expressions are there are optional
arguments.
}
@defform[(thing-doc id contract-expr (desc-expr ...))]{
Like @racket[proc-doc], but for an export of an arbitrary value.}
@defform[#:literals (parameter/c)
(parameter-doc id (parameter/c contract-expr) arg-id (desc-expr ...))]{
Like @racket[proc-doc], but for exporting a parameter.}
@defform[(struct*-doc struct-name
([field-name contract-expr-datum] ...)
maybe-omit-constructor
maybe-mutable maybe-non-opaque maybe-constructor
(desc-expr ...))
#:grammar ([maybe-omit-constructor (code:line) #:omit-constructor])]{
Like @racket[proc-doc], but for struct declarations that use @racket[struct].
The @racket[maybe-mutable], @racket[maybe-non-opaque], and @racket[maybe-constructor]
options are as in @racket[defstruct].
}
@defform[(struct-doc struct-name
([field-name contract-expr-datum] ...)
maybe-omit-constructor
maybe-mutable maybe-non-opaque maybe-constructor
(desc-expr ...))]{
Like @racket[struct*-doc], but for struct declarations that use @racket[define-struct].
}
@defform/subs[(form-doc options form-datum
maybe-grammar maybe-contracts
(desc-expr ...))
([options (code:line maybe-kind maybe-link maybe-id maybe-literals)]
[maybe-kind code:blank
(code:line #:kind kind-string-expr)]
[maybe-link code:blank
(code:line #:link-target? link-target?-expr)]
[maybe-id code:blank
(code:line #:id id)
(code:line #:id [id id-expr])]
[maybe-literals code:blank
(code:line #:literals (literal-id ...))]
[maybe-grammar code:blank
(code:line #:grammar ([nonterm-id clause-datum ...+] ...))]
[maybe-contracts code:blank
(code:line #:contracts ([subform-datum contract-expr-datum]
...))])]{
Like @racket[proc-doc], but for an export of a syntactic form. If
@racket[#:id] is provided, then @racket[id] is the exported identifier,
otherwise the exported identifier is extracted from @racket[form-datum].
See @racket[defform] for information on @racket[options],
@racket[form-datum], @racket[maybe-grammar], and
@racket[maybe-contracts].
@history[#:added "1.6"]}
@defform[(begin-for-doc form ...)]{
Like to @racket[begin-for-syntax], but for documentation time instead
of expansion time. The @racket[form]s can refer to binding
@racket[require]d with @racket[for-doc].
For example, a definition in @racket[begin-for-doc]
can be referenced by a @racket[_desc-expr] in
@racket[proc-doc/names].}
@defform[(generate-delayed-documents)]{
Causes documentation information to be recorded as a macro that is
expanded (along with any @racket[for-doc] imports) in the
module that uses @racket[include-extracted] or @racket[provide-extracted],
instead of within (a submodule of) the module that declares the information.
Delaying document generation in this way allows @racket[(for-doc
(for-label ....))] imports that would otherwise create cyclic module
dependencies.
To avoid problems with accumulated @racket[for-doc] imports across
modules, @racket[generate-delayed-documents] declaration should appear
before any @racket[for-doc] import.}
@defform[(require/doc require-spec ...)]{
A legacy shorthand for @racket[(require (for-doc require-spec ...))].}
@defform[(provide/doc spec ...)]{
A legacy alternative to @racket[(provide spec ...)]}
@; ----------------------------------------
@section{Extracting Documentation from Source}
@defmodule[scribble/extract]
@defform[(include-extracted module-path)]{
Expands to a sequence of documentation forms extracted from
@racket[module-path], which is expected to be a module that uses
@racketmodname[scribble/srcdoc] (so that the module has a
@racketidfont{srcdoc} submodule).}
@defform[(provide-extracted module-path)]{
Similar to @racket[include-extracted], but the documentation is
packaged and exported as @racket[exported], instead of left
inline.
Use this form in combination with
@racket[include-previously-extracted] when documentation from a single
source is to be split and typeset among multiple documentation
locations. The @racket[provide-extracted] form extracts the
documentation once, and then @racket[include-previously-extracted]
form extracts documentation for specific bindings as needed.}
@defform[(include-previously-extracted module-path regexp)]{
Similar to @racket[include-extracted], but instead of referring to the
source that contains its own documentation, @racket[module-path]
refers to a module that uses @racket[provide-extracted]. The
@racket[include-previously-extracted] form expands to documentation
forms for all identifiers whose string forms match @racket[regexp].}

View File

@ -1,393 +0,0 @@
#lang racket/base
(require "class-diagrams.rkt"
(only-in pict pin-arrow-line)
texpict/mrpict
(except-in texpict/utils pin-arrow-line)
racket/system
racket/class
racket/draw)
(define (mk-ps-diagram)
;; thicken up the lines for postscript
(linewidth .8 (mk-diagram)))
(provide mk-diagram)
(define (mk-diagram)
(define part-name (class-name "part" #:spacing-word "subparts"))
(define part-blocks-field (field-spec #f "blocks"))
(define part-subparts-field (field-spec #f "subparts"))
(define part-title-field (field-spec #f "title"))
(define part-box (class-box part-name (list part-title-field part-blocks-field part-subparts-field) #f))
(define block-name (class-name "block"))
(define block-box (class-box block-name #f #f))
(define para-name (class-name "paragraph"))
(define para-style (field-spec #f "style"))
(define para-content (field-spec #f "content"))
(define para-box (class-box para-name (list para-style para-content) #f))
(define compound-para-name (class-name "compound-\nparagraph"))
(define compound-para-style (field-spec #f "style"))
(define compound-para-blocks (field-spec #f "blocks"))
(define compound-para-box (class-box compound-para-name (list compound-para-style compound-para-blocks) #f))
(define table-name (class-name "table"))
(define table-style (field-spec #f "style"))
(define table-cells (field-spec #f "cells")) ;; blockss
(define table-box (class-box table-name (list table-style table-cells) #f))
(define itemization-name (class-name "itemization"))
(define itemization-style (field-spec #f "style"))
(define itemization-items (field-spec #f "items")) ;; blockss
(define itemization-box (class-box itemization-name (list itemization-style itemization-items) #f))
(define nested-flow-name (class-name "nested-\nflow"))
(define nested-flow-style (field-spec #f "style"))
(define nested-flow-blocks (field-spec #f "blocks"))
(define nested-flow-box (class-box nested-flow-name (list nested-flow-style nested-flow-blocks) #f))
(define delayed-block-name (class-name "delayed-block"))
(define delayed-block-block (field-spec #f "block"))
(define delayed-block-box (class-box delayed-block-name (list delayed-block-block) #f))
(define traverse-block-name (class-name "traverse-\nblock"))
(define traverse-block-block (field-spec #f "block"))
(define traverse-block-box (class-box traverse-block-name (list traverse-block-block) #f))
(define content-name (class-name "content"))
(define content-box (class-box content-name #f #f))
(define string-name (class-name "string"))
(define string-box (class-box string-name #f #f))
(define symbol-name (class-name "symbol"))
(define symbol-box (class-box symbol-name #f #f))
(define pict-name (class-name "pict"))
(define pict-box (class-box pict-name #f #f))
(define convertible-name (class-name "convertible"))
(define convertible-box (class-box convertible-name #f #f))
(define list-name (class-name "list"))
(define list-box (class-box list-name #f #f))
(define delayed-element-name (class-name "delayed-\nelement"))
(define delayed-element-content (field-spec #f "content"))
(define delayed-element-box (class-box delayed-element-name (list delayed-element-content) #f))
(define render-element-name (class-name "render-\nelement"))
(define render-element-content (field-spec #f "content"))
(define render-element-box (class-box render-element-name (list render-element-content) #f))
(define traverse-element-name (class-name "traverse-\nelement"))
(define traverse-element-content (field-spec #f "content"))
(define traverse-element-box (class-box traverse-element-name (list traverse-element-content) #f))
(define part-relative-element-name (class-name "part-\nrelative-\nelement"))
(define part-relative-element-resolve (field-spec #f "resolve"))
(define part-relative-element-box (class-box part-relative-element-name (list part-relative-element-resolve) #f))
(define element-name (class-name "element"))
(define element-style (field-spec #f "style"))
(define element-content (field-spec #f "content"))
(define element-box (class-box element-name (list element-style element-content) #f))
(define link-element-name (class-name "link-\nelement"))
(define link-tag (field-spec #f "tag"))
(define link-element-box (class-box link-element-name
(list link-tag)
#f))
(define collect-element-name (class-name "collect-\nelement"))
(define collect-element-collect (field-spec #f "collect"))
(define collect-element-box (class-box collect-element-name (list collect-element-collect) #f))
(define index-element-name (class-name "index-\nelement" #:spacing-word "keywords"))
(define index-element-tag (field-spec #f "tag"))
(define index-element-keywords (field-spec #f "keywords"))
(define index-element-box (class-box index-element-name
(list index-element-tag index-element-keywords)
#f))
(define image-element-name (class-name "image-\nelement" #:spacing-word "suffixes"))
(define image-element-path (field-spec #f "path"))
(define image-element-suffixes (field-spec #f "suffixes"))
(define image-element-scale (field-spec #f "scale"))
(define image-element-box (class-box image-element-name
(list image-element-path
image-element-suffixes
image-element-scale)
#f))
(define multiarg-element-name (class-name "multiarg-\nelement"))
(define multiarg-element-tag (field-spec #f "tag"))
(define multiarg-element-box (class-box multiarg-element-name (list multiarg-element-tag) #f))
(define target-element-name (class-name "target-\nelement"))
(define target-tag (field-spec #f "tag"))
(define target-element-box (class-box target-element-name
(list target-tag)
#f))
(define redirect-target-element-name (class-name "redirect-target-\nelement"))
(define redirect-target-alt-path (field-spec #f "alt-path"))
(define redirect-target-alt-anchor (field-spec #f "alt-anchor"))
(define redirect-target-element-box (class-box redirect-target-element-name
(list redirect-target-alt-path redirect-target-alt-anchor)
#f))
(define toc-target-element-name (class-name "toc-target-\nelement"))
(define toc-target-element-box (class-box toc-target-element-name (list) #f))
(define page-target-element-name (class-name "page-target-\nelement"))
(define page-target-element-box (class-box page-target-element-name (list) #f))
(define block-hierarchy
(hierarchy
(vc-append block-box
(blank 0 50)
(ht-append 20
(ht-append 30
compound-para-box
para-box)
(vc-append (blank 0 30) itemization-box)
table-box)
(blank 0 25)
(ht-append nested-flow-box
(blank 120 0)
(vc-append (blank 0 30) delayed-block-box)
(blank 80 0)
traverse-block-box))
(list block-box)
(list compound-para-box
para-box
nested-flow-box
itemization-box
table-box
delayed-block-box
traverse-block-box)))
(define target-element-hierarchy
(hierarchy
(vc-append target-element-box
(blank 0 50)
(ht-append 20
toc-target-element-box
page-target-element-box
redirect-target-element-box))
(list target-element-box)
(list toc-target-element-box
page-target-element-box
redirect-target-element-box)))
(define element-hierarchy
(hierarchy
(vc-append element-box
(blank 0 50)
(inset (ht-append 20
collect-element-box
multiarg-element-box
(refocus target-element-hierarchy target-element-box)
link-element-box
image-element-box
index-element-box)
0 0 -400 0))
(list element-box)
(list collect-element-box
index-element-box
image-element-box
target-element-box
multiarg-element-box
link-element-box
)))
(define render-element-parent-link (blank))
(define delayed-element-parent-link (blank))
(define part-relative-element-parent-link (blank))
(define traverse-element-parent-link (blank))
(define element-parent-link (blank))
(define (drop-and-link box parent-link i)
(vc-append
(blank 0 (+ 40 (* i 20)))
(refocus (ct-superimpose box parent-link)
parent-link)))
(define content-hierarchy
(hierarchy
(vc-append content-box
(blank 0 50)
(ht-append 15
(drop-and-link (refocus element-hierarchy element-box)
element-parent-link
4)
convertible-box
(drop-and-link render-element-box
render-element-parent-link
4)
pict-box
(drop-and-link delayed-element-box
delayed-element-parent-link
3)
symbol-box
(drop-and-link part-relative-element-box
part-relative-element-parent-link
1)
string-box
(drop-and-link traverse-element-box
traverse-element-parent-link
0)
list-box))
(list content-box)
(list element-box
string-box
symbol-box
convertible-box
pict-box
traverse-element-parent-link
part-relative-element-parent-link
delayed-element-parent-link
render-element-parent-link
list-box)))
(define raw
(vc-append part-box
(blank 0 20)
(vc-append block-hierarchy
(blank 0 20)
content-hierarchy)))
(define w/connections
(double
right-right-reference
(double
left-left-reference
(triple
right-right-reference
(triple
right-right-reference
(double
left-left-reference
(double
left-left-reference
(double
right-right-reference
(double
left-left-reference
(double
left-left-reference
(left-left-reference
raw
element-box element-content content-box content-name 1 #:dot-delta -1)
part-box part-title-field content-box content-name 21)
part-box part-blocks-field block-box block-name)
part-box part-subparts-field part-box part-name 2)
para-box para-content content-box content-name 2)
compound-para-box compound-para-blocks block-box block-name 3)
table-box table-cells block-box block-name 2)
itemization-box itemization-items block-box block-name 10)
nested-flow-box nested-flow-blocks block-box block-name 1)
list-box list-box content-box content-name))
(define w/delayed-connections
(dotted-right-right-reference
(dotted-right-right-reference
(dotted-right-right-reference
(dotted-right-right-reference
(dotted-right-right-reference
(dotted-right-right-reference
w/connections
render-element-box render-element-content content-box content-name 30)
traverse-block-box traverse-block-block block-box block-name 1)
delayed-block-box delayed-block-block block-box block-name 17)
traverse-element-box traverse-element-content content-box content-name 3)
delayed-element-box delayed-element-content content-box content-name 22)
part-relative-element-box part-relative-element-resolve content-box content-name 12))
;; one extra pixel on the right so we get the
;; line drawn to the outermost turning point
(inset (panorama w/delayed-connections) 0 0 1 0))
(define (double f p0 a b c d [count 1])
(let ([arrows1 (launder (f (ghost p0) a b c d count #:dot-delta 1))]
[arrows2 (launder (f (ghost p0) a b c d count #:dot-delta -1))])
(cc-superimpose p0
arrows1
arrows2)))
(define (triple f p0 a b c d [count 1])
(let ([arrows (launder (f (ghost p0) a b c d count))]
[up-arrows (launder (f (ghost p0) a b c d count #:dot-delta 2))]
[down-arrows (launder (f (ghost p0) a b c d count #:dot-delta -2))])
(cc-superimpose p0
arrows
up-arrows
down-arrows)))
(define (connect-circly-dots show-arrowhead? main dot1 . dots)
(let loop ([prev-dot dot1]
[dots dots]
[pict main])
(cond
[(null? dots) pict]
[else
(loop (car dots)
(cdr dots)
(connect-two-circly-dots pict prev-dot (car dots) (null? (cdr dots))))])))
;; this is a hack -- it will only work with right-right-reference
(define (connect-two-circly-dots pict dot1 dot2 arrowhead?)
(let ([base
(let*-values ([(sx sy) (cc-find pict dot1)]
[(raw-ex ey) (cc-find pict dot2)]
[(ex) (if arrowhead?
(+ raw-ex 2)
raw-ex)])
(cc-superimpose
(dc
(λ (dc dx dy)
(let ([pen (send dc get-pen)])
(send dc set-pen
type-link-color ;(send pen get-color)
(if (is-a? dc post-script-dc%)
4
2)
'dot)
(send dc draw-line
(+ dx sx) (+ dy sy)
(+ dx ex) (+ dy ey))
(send dc set-pen pen)))
(pict-width pict)
(pict-height pict))
pict))])
(if arrowhead?
(pin-arrow-line field-arrowhead-size
base
dot1 (λ (ignored1 ignored2)
(let-values ([(x y) (cc-find pict dot2)])
(values (+ x 2) y)))
dot2 cc-find
#:color type-link-color)
base)))
(define (dotted-right-right-reference p0 a b c d [count 1])
(right-right-reference p0 a b c d count #:connect-dots connect-circly-dots))
(module+ slideshow
(require slideshow)
(define p (inset (mk-diagram) 0 0 0 1))
(define c (blank client-w client-h))
(slide (lt-superimpose (t "top") (clip (refocus (ct-superimpose p c) c))))
(slide (lt-superimpose (t "bottom") (clip (refocus (cb-superimpose p c) c))))
(slide (lt-superimpose (t "all")
(ct-superimpose
c
(scale p
(min (/ client-w (pict-width p))
(/ client-h (pict-height p))))))))

View File

@ -1,280 +0,0 @@
#lang scribble/manual
@(require (except-in "utils.rkt"
make-part make-paragraph make-table make-itemization make-compound-paragraph
make-element make-toc-element make-target-element make-toc-target-element make-toc-target2-element
make-page-target-element make-redirect-target-element make-link-element
make-index-element
make-target-url target-url struct:target-url target-url? target-url-addr
toc-element-toc-content toc-target2-element-toc-content part-title-content paragraph-content
element? element-content element-style)
(for-label scribble/manual-struct
scribble/struct
setup/main-collects))
@(define (compat) @italic{For backward compatibility.})
@(define-syntax-rule (compat/comp id)
@elem{@compat[] Compared to the normal constructor for @racket[id]})
@title[#:tag "struct"]{Compatibility Structures And Processing}
@defmodule[scribble/struct]{
The @racket[scribble/struct] compatibility library mostly re-exports
@racket[scribble/core], but using some different names (e.g.,
@racket[blockquote] instead of @racket[nested-flow]).}
The following structure types and functions are re-exported directly:
@racketblock[collect-info resolve-info tag? block?
delayed-block collected-info delayed-element ; delayed-element-content delayed-block-blocks current-serialize-resolve-info
part-relative-element collect-info-parents ; part-relative-element-content delayed-index-desc
collect-element render-element generated-tag ; generate-tag current-tag-prefixes add-current-tag-prefix
tag-key content->string element->string ; strip-aux
block-width element-width
info-key? part-collected-info collect-put!
resolve-get resolve-get/tentative resolve-get/ext?
resolve-search resolve-get-keys]
The following structure types are re-exported, but the constructors and some selectors
are replaced as documented further below:
@racketblock[part paragraph table itemization compound-paragraph
element toc-element target-element toc-target-element toc-target2-element
page-target-element redirect-target-element link-element
index-element]
Several additional compatibility functions and structure types are
also exported.
@defproc[(make-part [tag-prefix (or/c false/c string?)]
[tags (listof tag?)]
[title-content (or/c false/c list?)]
[style any/c]
[to-collect list?]
[blocks (listof block?)]
[parts (listof part?)])
part?]{
@compat/comp[part], parses @racket[style] to convert old formats to
the current one. Also, if @racket[title-content] is a list with a
single item, the item by itself is stored in the resulting
@racket[part].}
@defproc[(part-flow [p part?]) (listof block?)]{
@compat[] An alias for @racket[part-blocks].}
@defproc[(part-title-content [p part?]) list?]{
@compat[] Like the normal selector, but if the result would not be a list, it is
coerced to one.}
@deftogether[(
@defproc[(make-versioned-part [tag-prefix (or/c false/c string?)]
[tags (listof tag?)]
[title-content (or/c false/c list?)]
[style any/c]
[to-collect list?]
[blocks (listof block?)]
[parts (listof part?)]
[version string?])
part?]
@defproc[(versioned-part? [v any/c]) boolean?]
)]{
@compat[] Like @racket[make-part], but adds a the
@racket[document-version] @tech{style property} using the given
@racket[version]. The @racket[versioned-part?] predicate recognizes a
@racket[part] with a @racket[document-version] property.}
@deftogether[(
@defproc[(make-unnumbered-part [tag-prefix (or/c false/c string?)]
[tags (listof tag?)]
[title-content (or/c false/c list?)]
[style any/c]
[to-collect list?]
[blocks (listof block?)]
[parts (listof part?)])
part?]
@defproc[(unnumbered-part? [v any/c]) boolean?]
)]{
@compat[] Like @racket[make-part], but adds the @racket['unnumbered]
@tech{style property}. The @racket[unnumbered-part?] predicate
recognizes a @racket[part] with the @racket['unnumbered] property.}
@defproc[(make-paragraph [content list?]) paragraph?]{
@compat/comp[paragraph], omits a style argument. Also, if
@racket[content] is a list containing a single item, the item by
itself is stored in the resulting @racket[paragraph].}
@defproc[(paragraph-content [p paragraph?]) list?]{
@compat[] Like the normal selector, but if the result would not be a list, it is
coerced to one.
}
@deftogether[(
@defproc[(make-styled-paragraph [content list?] [style any/c]) paragraph?]
@defproc[(styled-paragraph? [v any/c]) boolean?]
@defproc[(styled-paragraph-style [p paragraph?]) style?]
)]{
@compat/comp[paragraph], parses @racket[style] to convert old formats
to the current one. The @racket[styled-paragraph?] predicate and
@racket[styled-paragraph-style] accessor are aliases for
@racket[paragraph?] and @racket[paragraph-style].}
@deftogether[(
@defproc[(make-omitable-paragraph [content list?]) paragraph?]
@defproc[(omitable-paragraph? [v any/c]) boolean?]
)]{
@compat[] Like @racket[make-paragraph], but adds the
@racket['omitable] @tech{style property}. The
@racket[omitable-paragraph?] predicate checks for a paragraph with the
property.}
@defproc[(make-table [style any/c]
[blocksss (listof (listof (or/c (listof block?) (one-of/c 'cont))))])
table?]{
@compat/comp[table], the style is converted, and each cell has a list
of blocks instead of a single block. If any such list has multiple
blocks, they are combined into a @racket[nested-flow].}
@defproc[(table-flowss [table table?])
(listof (listof (or/c (listof block?) (one-of/c 'cont))))]{
@compat[] Like @racket[table-blockss], but adds a list wrapper to be
consistent with @racket[make-table].}
@defproc[(make-itemization [blockss (listof (listof block?))]) itemization?]{
@compat/comp[itemization], omits a style argument.}
@deftogether[(
@defproc[(make-styled-itemization [style any/c]
[blockss (listof (listof block?))]) itemization?]
@defproc[(styled-itemization? [v any/c]) boolean?]
@defproc[(styled-itemization-style [i itemization?]) style?]
)]{
@compat/comp[itemization], parses @racket[style] to convert old
formats to the current one. The @racket[styled-itemization?] predicate
is an alias for @racket[itemization?], and
@racket[styled-itemization-style] is an alias for
@racket[itemization-style].}
@defproc[(make-blockquote [style any/c] [blocks (listof block?)])
nested-flow?]{
@compat[] Like @racket[make-nested-flow], but @racket[style] is
parsed to the current format.}
@deftogether[(
@defproc[(make-auxiliary-table [style any/c]
[blocksss (listof (listof (or/c (listof block?) (one-of/c 'cont))))])
table?]
@defproc[(auxiliary-table? [v any/c]) boolean?]
)]{
@compat[] Like @racket[make-table], but adds the @racket['aux]
@tech{style property}. The @racket[auxiliary-table?] predicate recognizes
tables with the @racket['aux] property.}
@defproc[(make-compound-paragraph [style any/c]
[blocks (listof block?)])
compound-paragraph?]{
@compat/comp[compound-paragraph], parses @racket[style] to convert old
formats to the current one.}
@deftogether[(
@defproc[(make-element [style any/c] [content list?]) element?]
@defproc[(make-toc-element [style any/c] [content list?] [toc-content list?]) toc-element?]
@defproc[(make-target-element [style any/c] [content list?] [tag tag?]) target-element?]
@defproc[(make-toc-target-element [style any/c] [content list?] [tag tag?]) toc-target-element?]
@defproc[(make-toc-target2-element [style any/c] [content list?] [tag tag?] [toc-content content?]) toc-target2-element?]
@defproc[(make-page-target-element [style any/c] [content list?] [tag tag?]) page-target-element?]
@defproc[(make-redirect-target-element [style any/c] [content list?] [tag tag?]
[alt-path path-string?] [alt-anchor string?]) redirect-target-element?]
@defproc[(make-link-element [style any/c] [content list?] [tag tag?]) link-element?]
@defproc[(make-index-element [style any/c] [content list?] [tag tag?]
[plain-seq (and/c pair? (listof string?))]
[entry-seq list?] [desc any/c]) index-element?]
)]{
@compat[] Compared to the normal constructors, parses @racket[style] to convert old
formats to the current one.}
@deftogether[(
@defproc[(element? [v any/c]) boolean?]
@defproc[(element-content [e element?]) list?]
@defproc[(element-style [e element?]) element-style?]
)]{
@compat[] A @tech{content} list is treated as an element by these functions,
and the result of @racket[element-content] is always a list.}
@defproc[(make-aux-element [style any/c] [content list?]) element?]{
@compat[] Like @racket[make-element], but adds the @racket['aux]
@tech{style property}.}
@defproc[(make-hover-element [style any/c] [content list?] [text string?]) element?]{
@compat[] Like @racket[make-element], but adds @racket[hover-property]
containing @racket[text] to the element's style.}
@defproc[(make-script-element [style any/c] [content list?] [type string?]
[script (or/c path-string? (listof string?))]) element?]{
@compat[] Like @racket[make-element], but adds @racket[script-property]
containing @racket[type] and @racket[script] to the element's style.}
@defstruct[with-attributes ([style any/c]
[assoc (listof (cons/c symbol? string?))])]{
@compat[] Used for an @racket[element]'s style to combine a base style with
arbitrary HTML attributes. When the @racket[style] field is itself an
instance of @racket[with-attributes], its content is automatically
flattened into the enclosing @racket[with-attributes] when it is used
(when, e.g., rendering an @racket[element] or @racket[paragraph]).}
@defstruct[target-url ([addr path-string?]
[style any/c])]{
@compat[] Used as a style for an @racket[element]. The @racket[style] at this
layer is a style for the hyperlink.}
@defstruct[image-file ([path (or/c path-string?
(cons/c 'collects (listof bytes?)))]
[scale real?])]{
@compat[] Used as a style for an @racket[element] to inline an image. The
@racket[path] field can be a result of
@racket[path->main-collects-relative].}
@defproc*[([(element->string (element content?)) string?]
[(element->string (element content?) (renderer any/c) (p part?) (info resolve-info?)) string?])]{
@compat[] An alias for @racket[content->string].
}

View File

@ -1,231 +0,0 @@
#lang scribble/doc
@(require scribble/manual scribble/eval "utils.rkt"
(for-label scribble/manual scribble/eval))
@title[#:tag "reference-style"]{Style Guide}
Consistent style---for terms, typesetting, and prose---makes
documentation clearer. As much as possible, follow the rules listed in
this section. Many of the rules are arbitrary in the sense that a
different choice of rule could work fine, but the only way to make our
documentation consistent is to pick one of the choices.
There are too many rules to absorb easily on a first reading. Re-read
this section after writing documentation for a library or two, and
revisit the section periodically to refresh your memory and check for
new rules.
@section{Prose and Terminology}
In the descriptive body of @racket[defform], @racket[defproc], etc.,
do not start with ``This ...'' Instead, start with a sentence whose
implicit subject is the form or value being described (but only start
the first sentence that way). Capitalize the first word. Thus, the
description will often start with ``Returns'' or ``Produces.'' Refer
to arguments and sub-forms by name.
Do not use the word ``argument'' to describe a sub-form in a syntactic
form; use the term ``sub-form'' instead, reserving ``argument'' for
values or expressions in a function call. Refer to libraries and
languages as such, rather than as ``modules'' (even though the form to
typeset a library or language name is called @racket[racketmodname]).
Do not call an identifier (i.e., a syntactic element) a ``variable''
or a ``symbol.'' Do not use the word ``expression'' for a form that is
a definition or might be a definition; use the word ``form,'' instead.
Prefer ``function'' to ``procedure.''
Use the word ``list'' only when you mean a run-time value consisting
of the empty list and cons cells; use the word ``sequence'' in other
cases, if you must use any word. For example, do not write that
@racket[begin] has a ``list of sub-forms;'' instead, it has a
``sequence of sub-forms.'' Similarly, do not refer to a ``list of
arguments'' in a function call; just write ``arguments'' if possible,
or write ``sequence of argument expressions.'' (Unfortunately,
``@tech[#:doc '(lib
"scribblings/reference/reference.scrbl")]{sequence}'' has acquired a
specific run-time meaning, too, but the collision is less severe than
the historical confusion between lists and other entities in Lisp.)
Avoid cut-and-paste for descriptive text. If two functions are
similar, consider documenting them together with
@racket[deftogether]. To abstract a description, consider using
explicit prose abstraction, such as ``@racket[x] is like @racket[y],
except that ...,'' instead of abstracting the source and instantiating
it multiple times; often, a prose abstraction is clearer to the reader
than a hidden abstraction in the document implementation.
Hyphenate the words ``sub-form'' and ``sub-expression.''
Use ``Windows,'' ``Mac OS X,'' and ``Unix'' for the three
``platforms'' (as opposed to ``systems'') on which Racket runs. Use
``Unix'' as a generic term for Unix-like operating systems---notably
including Linux---other than Mac OS X. Use ``Unix'' even when ``Gtk''
or ``the X11 windowing system'' would be more precisely correct, but
use ``X11'' as adjective when necessary, such as ``X11 display.''
Racket runs ``on'' a platform, as opposed to ``under'' a platform.
@section{Typesetting Code}
Use @racketidfont{id} or a name that ends @racketidfont{-id} in
@racket[defform] to mean an identifier, not @racketidfont{identifier},
@racketidfont{variable}, @racketidfont{name}, or
@racketidfont{symbol}. Similarly, use @racketidfont{expr} or something
that ends @racketidfont{-expr} for an expression position within a
syntactic form. Use @racketidfont{body} for a form (definition or
expression) in an internal-definition position---always followed by
@racket[...+] in a grammar description. Do not use
@racketidfont{expr} for something that isn't exactly an expression,
@racket[id] for something that isn't exactly an identifier, etc.;
instead, use @racket[defform/subs] to define a new non-terminal.
Beware of using @racket[deftogether] to define multiple variants of a
syntactic form or procedure, because each @racket[defform] or
@racket[defproc] creates a definition point, but each form or
procedure should have a single definition point. (Scribble issues a
warning when a binding has multiple definition points.) Instead, use
@racket[defproc*] or @racket[defform*].
For function arguments, use @racket[v] as the meta-variable for ``any
value.'' Use @racket[x] as a meta-variable only for numerical
values. Other conventions include @racket[lst] for a list and
@racket[proc] for a procedure.
Pay attention to the difference between identifiers and meta-variables
when using @racket[racket], especially outside of @racket[defproc] or
@racket[defform]. Prefix a meta-variable with @litchar{_}; for
example,
@verbatim[#:indent 2]|{@racket[(rator-expr rand-expr ...)]}|
would be the wrong way to refer to the grammar of a function call,
because it produces @racket[(rator-expr rand-expr ...)], where
@racketidfont{rator-expr} and @racketidfont{rand-expr} are
typeset as variables. The correct description is
@verbatim[#:indent 2]|{@racket[(_rator-expr _rand-expr ...)]}|
which produces @racket[(_rator-expr _rand-expr ...)], where
@racketidfont{rator-expr} and @racketidfont{rand-expr} are typeset as
meta-variables. The @racket[defproc], @racket[defform], @|etc| forms
greatly reduce this burden in descriptions, since they automatically
set up meta-variable typesetting for non-literal identifiers. In
@racket[defform], be sure to include literal identifiers (i.e., those
not meant as variables, other than the form name being defined) in a
@racket[#:literals] clause.
To typeset an identifier with no particular interpretation---syntax,
variable, meta-variable, etc.---use @racket[racketidfont] (e.g., as in
@racketidfont{rand-expr} above). Otherwise, use @racket[litchar],
not merely @racket[racketfont] or @racket[verbatim], to refer to a
specific sequence of characters.
When a syntactic form synthesizes an identifier from a given
identifier, use a combination of @racket[racketidfont] and
@racket[racket] to describe the identifiers. For example, if
@racket[_id] is combined with @racketidfont{is-} and @racketidfont{?}
to form @racketidfont{is-}@racket[_id]@racketidfont{?}, then implement
that identifier as
@code[#:lang "at-exp racket"]|{@racketidfont{is-}@racket[id]@racketidfont{?}}|.
When using @racket[defform] to describe a syntactic form, don't
confuse the @racket[#:contracts] clause with a grammar
specification. Use @racket[#:contracts] only for expressions within the
syntactic form, and the contract is a run-time constraint---not a
syntactic constraint, such as requiring a sub-form to be an identifier.
Use @racket[defform/subs] for syntactic constraints.
When showing example evaluations, use the REPL-snapshot style:
@verbatim[#:indent 2]|{
@interaction[
(+ 1 2)
]
}|
See also the @racket[scribble/eval] library and @secref["examples-style"].
Use four dots, @litchar{....}, in place of omitted code, since
@litchar{...} means repetition.
@section{Typesetting Prose}
Refrain from referring to documentation ``above'' or ``below,'' and
instead have a hyperlink point to the right place.
In prose, use @litchar{``} and @litchar{''} quotation marks instead of
@litchar{"}. Use @litchar{---} for an em dash, and do not include
spaces on either side. Use American style for quotation marks and punctuation
@; [Eli] BTW, I've asked several people about this, and the general
@; agreement that I've seen is that this is a rather arbitrary rule
@; and there's no harm in doing the more logical thing of putting
@; the punctuations outside quotations and parens. Just like you
@; did at the end of this sentence...
@; [Matthew] See intro of this section.
at the end of quotation marks (i.e., a sentence-terminating period
goes inside the quotation marks). Of course, this rule does not apply
for quotation marks that are part of code.
Do not use a citation reference (as created by @racket[cite]) as a
noun; use it as an annotation.
Do not start a sentence with a Racket variable name, since it is
normally lowercase. For example, use ``The @racket[_thing] argument
is...'' instead of ``@racket[_thing] is...''
Use @racket[etc] for ``@|etc|'' when it does not end a sentence, and
include a comma after ``@|etc|'' unless it ends a sentence of is
followed by other punctuation (such as a parenthesis).
@section{Section Titles}
Capitalize all words except articles (``the,'' ``a,'' etc.),
prepositions, and conjunctions that are not at the start of the title.
A manual title should normally start with a suitable keyword or key
phrase (such as ``Scribble'' for this manual) that is in boldface. If
the key word is primarily an executable name, use @racket[exec]
instead of @racket[bold]. Optionally add further descriptive text in
the title after a colon, where the text starting with the colon is not
in boldface.
@section{Indexing}
Document and section titles, identifiers that are documented with
@racket[defproc], @racket[defform], etc. are automatically indexed, as
are terms defined with @racket[deftech].
Symbols are not indexed automatically. Use @racket[indexed-racket]
instead of @racket[racket] for the instance of a symbol that roughly
defines the use. For an example, try searching for ``truncate'' to
find @racket['truncate] as used with @racket[open-output-file]. Do no
use something like @racket[(index "'truncate")] to index a symbol,
because it will not typeset correctly (i.e., in a fixed-width font
with the color of a literal).
Use @racket[index], @racket[as-index], and @racket[section-index] as a
last resort. Create index entries for terms that are completely
different from terms otherwise indexed. Do not try to index minor
variations of a term or phrase in an attempt to improve search
results; if search fails to find a word or phrase due to a minor
variation, then the search algorithm should be fixed, not the index
entry.
@section[#:tag "examples-style"]{Examples}
Strive to include examples (using @racket[examples]) with the
documentation of every function and syntactic form. When writing
examples, refrain from using nonsense words like ``foo'' and ``bar.''
For example, when documenting @racket[member], resist the temptation
to write
@interaction[
(member "foo" '("bar" "foo" "baz"))
]
and instead write something like
@interaction[
(member "Groucho" '("Harpo" "Groucho" "Zeppo"))
]

View File

@ -1,140 +0,0 @@
#lang scribble/doc
@(require scribble/manual "utils.rkt"
(for-label setup/main-collects))
@title[#:tag "tag"]{Tag Utilities}
@declare-exporting[scribble/tag scribble/base]
@defmodule*/no-declare[(scribble/tag)]{The @racketmodname[scribble/tag]
library provides utilities for constructing cross-reference
@tech{tags}. The library is re-exported by
@racketmodname[scribble/base].}
@; ------------------------------------------------------------------------
@defproc[(make-section-tag [name string?]
[#:doc doc-mod-path (or/c module-path? #f) #f]
[#:tag-prefixes tag-prefixes (or/c #f (listof string?)) #f])
tag?]{
Forms a @tech{tag} that refers to a section whose ``tag'' (as provided
by the @racket[#:tag] argument to @racket[section], for example) is
@racket[name]. If @racket[doc-mod-path] is provided, the @tech{tag}
references a section in the document implemented by
@racket[doc-mod-path] from outside the document. Additional tag
prefixes (for intermediate sections, typically) can be provided as
@racket[tag-prefixes].}
@defproc[(make-module-language-tag [lang symbol?]) tag?]{
Forms a @tech{tag} that refers to a section
that contains @racket[defmodulelang] for the language
@racket[lang].
}
@defproc[(taglet? [v any/c]) boolean?]{
Returns @racket[#t] if @racket[v] is a @tech{taglet}, @racket[#f]
otherwise.
A @deftech{taglet} is a value that can be combined with a symbol via
@racket[list] to form a @tech{tag}, but that is not a
@racket[generated-tag]. A @tech{taglet} is therefore useful as a piece
of a @tech{tag}, and specifically as a piece of a tag that can gain a
prefix (e.g., to refer to a section of a document from outside the
document).}
@defproc*[([(doc-prefix [mod-path (or/c #f module-path?)]
[taglet taglet?])
taglet?]
[(doc-prefix [mod-path (or/c #f module-path?)]
[extra-prefixes (or/c #f (listof taglet?))]
[taglet taglet?])
taglet?])]{
Converts part of a cross-reference @tech{tag} that would work within a
document implemented by @racket[mod-path] to one that works from
outside the document, assuming that @racket[mod-path] is not
@racket[#f]. That is, @racket[mod-path] is converted to a
@tech{taglet} and added as prefix to an existing @racket[taglet].
If @racket[extra-prefixes] is provided, then its content is added as a
extra prefix elements before the prefix for @racket[mod-path] is
added. A @racket[#f] value for @racket[extra-prefixes] is equivalent
to @racket['()].
If @racket[mod-path] is @racket[#f], then @racket[taglet] is returned
without a prefix (except adding @racket[extra-prefixes], if provided).}
@defproc[(module-path-prefix->string [mod-path module-path?]) string?]{
Converts a module path to a string by resolving it to a path, and
using @racket[path->main-collects-relative].}
@defproc[(module-path-index->taglet [mpi module-path-index?]) taglet?]{
Converts a module path index to a @tech{taglet}---a normalized
encoding of the path as an S-expression---that is interned via
@racket[intern-taglet].
The string form of the @tech{taglet} is used as prefix in a @tech{tag}
to form cross-references into the document that is implemented by the
module referenced by @racket[mpi].}
@defproc[(intern-taglet [v any/c]) any/c]{
Returns a value that is @racket[equal?] to @racket[v], where multiple
calls to @racket[intern-taglet] for @racket[equal?] @racket[v]s
produce the same (i.e., @racket[eq?]) value.}
@defproc[(definition-tag->class/interface-tag [definition-tag definition-tag?])
class/interface-tag?]{
Constructs a tag like @racket[definition-tag], except that
it matches documentation for the class. If @racket[definition-tag]
doesn't document a class or interface, this function still returns
the tag that the class or interface documentation would have had,
as if @racket[definition-tag] had documented a class or interface.
@history[#:added "1.11"]
}
@defproc[(class/interface-tag->constructor-tag [class/interface-tag class/interface-tag?])
constructor-tag?]{
Constructs a tag like @racket[definition-tag], except that
it matches documentation for the constructor of the class.
@history[#:added "1.11"]
}
@defproc[(get-class/interface-and-method [method-tag method-tag?])
(values symbol? symbol?)]{
Returns the class name and method name (respectively) for the method documented
by the docs at @racket[method-tag].
@history[#:added "1.11"]
}
@defproc[(definition-tag? [v any/c]) boolean?]{
Recognizes definition tags. If @racket[(definition-tag? _v)] is
@racket[#t], then so is @racket[(tag? _v)].
@history[#:added "1.11"]
}
@defproc[(class/interface-tag? [v any/c]) boolean?]{
Recognizes class or interface tags. If @racket[(class/interface-tag? _v)] is
@racket[#t], then so is @racket[(tag? _v)].
@history[#:added "1.11"]
}
@defproc[(method-tag? [v any/c]) boolean?]{
Recognizes method tags. If @racket[(method-tag? _v)] is
@racket[#t], then so is @racket[(tag? _v)].
@history[#:added "1.11"]
}
@defproc[(constructor-tag? [v any/c]) boolean?]{
Recognizes class constructor tags. If @racket[(constructor-tag? _v)] is
@racket[#t], then so is @racket[(tag? _v)].
@history[#:added "1.11"]
}

File diff suppressed because it is too large Load Diff

View File

@ -1,229 +0,0 @@
#lang racket/base
(require scribble/core
scribble/html-properties
scribble/manual
(prefix-in racket: scribble/racket)
(prefix-in scribble: scribble/reader))
(define-syntax bounce-for-label
(syntax-rules (all-except)
[(_ (all-except mod (id ...) (id2 ...)))
(begin (require (for-label (except-in mod id ...)))
(provide (for-label (except-out (all-from-out mod) id2 ...))))]
[(_ mod) (begin (require (for-label mod))
(provide (for-label (all-from-out mod))))]
[(_ mod ...) (begin (bounce-for-label mod) ...)]))
(bounce-for-label (all-except racket (abstract link) ())
scribble/core
scribble/base-render
scribble/decode
scribble/manual
scribble/racket
scribble/html-properties
scribble/latex-properties
scribble/bnf)
(provide scribble-examples litchar/lines doc-render-examples)
(define (as-flow e)
(if (block? e) e (make-paragraph plain (list e))))
(define (litchar/lines . strs)
(let ([strs (regexp-split #rx"\n" (apply string-append strs))])
(if (= 1 (length strs))
(litchar (car strs))
(make-table
plain
(map (lambda (s) ; the nbsp is needed for IE
(list (as-flow (if (string=? s "") 'nbsp (litchar s)))))
strs)))))
(define spacer (hspace 2))
(define ((norm-spacing base) p)
(cond [(and (syntax->list p) (not (null? (syntax-e p))))
(let loop ([e (syntax->list p)]
[line (syntax-line (car (syntax-e p)))]
[pos base]
[second #f]
[accum null])
(if (null? e)
(datum->syntax
p (reverse accum)
(list (syntax-source p) (syntax-line p) base (add1 base)
(- pos base))
p)
(let* ([v ((norm-spacing (if (= line (syntax-line (car e)))
pos
(or second pos)))
(car e))]
[next-pos (+ (syntax-column v) (syntax-span v) 1)])
(loop (cdr e)
(syntax-line v)
next-pos
(or second next-pos)
(cons v accum)))))]
[else (datum->syntax
p (syntax-e p)
(list (syntax-source p) (syntax-line p) base (add1 base) 1)
p)]))
(define (scribble-examples . lines)
(define reads-as (make-paragraph plain (list spacer "reads as" spacer)))
(let* ([lines (apply string-append lines)]
[p (open-input-string lines)])
(port-count-lines! p)
(let loop ([r '()] [newlines? #f])
(regexp-match? #px#"^[[:space:]]*" p)
(let* ([p1 (file-position p)]
[stx (scribble:read-syntax #f p)]
[p2 (file-position p)])
(if (not (eof-object? stx))
(let ([str (substring lines p1 p2)])
(loop (cons (list str stx) r)
(or newlines? (regexp-match? #rx#"\n" str))))
(let* ([r (reverse r)]
[r (if newlines?
(cdr (apply append (map (lambda (x) (list #f x)) r)))
r)])
(make-table
plain
(map (lambda (x)
(let ([@expr (if x (litchar/lines (car x)) "")]
[sexpr (if x
(racket:to-paragraph
((norm-spacing 0) (cadr x)))
"")]
[reads-as (if x reads-as "")])
(map as-flow (list spacer @expr reads-as sexpr))))
r))))))))
;; stuff for the scribble/text examples
(require racket/list (for-syntax racket/base racket/list))
(define max-textsample-width 45)
(define (textsample-verbatim-boxes line in-text out-text more)
(define (split str) (regexp-split #rx"\n" str))
(define strs1 (split in-text))
(define strs2 (split out-text))
(define strsm (map (compose split cdr) more))
(define (str->elts str)
(let ([spaces (regexp-match-positions #rx"(?:^| ) +" str)])
(if spaces
(list* (str->elts (substring str 0 (caar spaces)))
(smaller (hspace (- (cdar spaces) (caar spaces))))
(str->elts (substring str (cdar spaces))))
(list (smaller (make-element 'tt str))))))
(define (make-line str)
(list (as-flow (if (equal? str "")
(smaller (hspace 1))
(str->elts str)))))
(define (make-box strs [file #f])
(nested #:style 'code-inset
(let ([t (make-table plain (map make-line strs))])
(if file
(filebox file t)
t))))
(define filenames (map car more))
(define indent (let ([d (- max-textsample-width
(for*/fold ([m 0])
([s (in-list (cons strs1 strsm))]
[s (in-list s)])
(max m (string-length s))))])
(if (negative? d)
(error 'textsample-verbatim-boxes
"left box too wide for sample at line ~s" line)
(make-element 'tt (list (hspace d))))))
;; Note: the font-size property is reset for every table, so we need it
;; everywhere there's text, and they don't accumulate for nested tables
(values
(make-table
(make-style #f
(list (make-table-columns (list (make-style #f '(left top))))))
(cons (list (as-flow (make-box strs1)))
(map (lambda (file strs)
(list (as-flow (make-box strs file))))
filenames strsm)))
(make-box strs2)))
(define (textsample line in-text out-text more)
(define-values (box1 box2)
(textsample-verbatim-boxes line in-text out-text more))
(make-table
(make-style #f (list (make-table-columns (list (make-style #f '(left vcenter))
(make-style "Short" '(left vcenter))
(make-style #f '(left vcenter))))))
(list (map as-flow (list box1 (make-paragraph plain '(nbsp rarr nbsp)) box2)))))
(define-for-syntax tests-ids #f)
(provide initialize-tests)
(define-syntax (initialize-tests stx)
(set! tests-ids (map (lambda (x) (datum->syntax stx x stx))
'(tests add-to-tests)))
(with-syntax ([(tests add-to-tests) tests-ids])
#'(begin (provide tests)
(define-values (tests add-to-tests)
(let ([l '()])
(values (lambda () (reverse l))
(lambda (x) (set! l (cons x l)))))))))
(provide example)
(define-syntax (example stx)
(define sep-rx #px"^---[*]{3}---(?: +(.*))?$")
(define file-rx #rx"^[a-z0-9_.+-]+$")
(define-values (body hidden?)
(syntax-case stx ()
[(_ #:hidden x ...) (values #'(x ...) #t)]
[(_ x ...) (values #'(x ...) #f)]))
(let loop ([xs body] [text '(#f)] [texts '()])
(syntax-case xs ()
[("\n" sep "\n" . xs)
(and (string? (syntax-e #'sep)) (regexp-match? sep-rx (syntax-e #'sep)))
(let ([m (cond [(regexp-match sep-rx (syntax-e #'sep)) => cadr]
[else #f])])
(if (and m (not (regexp-match? file-rx m)))
(raise-syntax-error #f "bad filename specified" stx #'sep)
(loop #'xs
(list (and m (datum->syntax #'sep m #'sep #'sep)))
(cons (reverse text) texts))))]
[(x . xs) (loop #'xs (cons #'x text) texts)]
[() (let ([texts (reverse (cons (reverse text) texts))]
[line (syntax-line stx)])
(define-values (files i/o) (partition car texts))
(unless ((length i/o) . = . 2)
(raise-syntax-error
'example "need at least an input and an output block" stx))
(with-syntax ([line line]
[((in ...) (out ...)) (map cdr i/o)]
[((file text ...) ...) files]
[add-to-tests (cadr tests-ids)])
(quasisyntax/loc stx
(let* ([in-text (string-append in ...)]
[out-text (string-append out ...)]
[more (list (cons file (string-append text ...)) ...)])
(add-to-tests (list line in-text out-text more))
#,(if hidden? #'""
#'(textsample line in-text out-text more))))))]
[_ (raise-syntax-error #f "no separator found in example text")])))
(provide ltx ltxe ltxd)
(define (ltx s) (tt "\\" s)) ; command
(define (ltxe s) (tt s)) ; enviornment
(define (ltxd n s)
(make-element #f (cons (index (list s) (ltx s))
(for/list ([i (in-range n)]) (tt "{}")))))
;; Utility to render examples of scribble documentation forms
;; Note: it would be nice if this abstracted over the codeblock
;; that usually comes along with this too, but that's hard
;; because there's a read-time distinction between [...]
;; and |{...}|.
(define-syntax-rule (doc-render-examples e ...)
(nested "Renders like:\n"
(nested #:style 'inset (nested #:style 'inset e ...))))

View File

@ -1,236 +0,0 @@
#lang scribble/doc
@(require scribble/manual "utils.rkt"
(for-label scribble/xref
scribble/base-render
scribble/html-render
setup/xref))
@title[#:tag "xref"]{Cross-Reference Utilities}
@defmodule[scribble/xref]{The @racketmodname[scribble/xref] library
provides utilities for querying cross-reference information that was
collected from a document build.}
@; ------------------------------------------------------------------------
@defproc[(xref? [v any/c]) boolean?]{
Returns @racket[#t] if @racket[v] is a cross-reference record created
by @racket[load-xref], @racket[#f] otherwise.}
@defproc[(load-xref [sources (listof (-> (or/c any/c (-> list?))))]
[#:demand-source demand-source
(tag? -> (or/c (-> any/c) #f))
(lambda (_tag) #f)]
[#:render% using-render% (implementation?/c render<%>)
(render-mixin render%)]
[#:root root-path (or/c path-string? false/c) #f]
[#:doc-id doc-id-str (or/c path-string? false/c) #f])
xref?]{
Creates a cross-reference record given a list of functions,
@racket[sources].
Let @racket[_source] be a function in @racket[sources]. The
@racket[_source] function normally returns serialized information,
@racket[_info], which was formerly obtained from @xmethod[render<%>
serialize-info]. The result of @racket[_source] can optionally be
another function, which is in turn responsible for returning a list of
@racket[_info]s. Finally, each @racket[_info] can be either serialized
information, a @racket[#f] to be ignored, or a value produced by
@racket[make-data+root] or @racket[make-data+root+doc-id], from which
@racket[_data] part is used as serialized information, the
@racket[_root] part overrides @racket[root-path] for deserialization,
and the @racket[_doc-id] part (if any) overrides
@racket[doc-id-string] to identify the source document.
The @racket[demand-source] function can effectively add a new source
to @racket[sources] in response to a search for information on the
given tag. The @racket[demand-source] function returns @racket[#f]
to indicate that no new sources satisfy the given tag.
Since the format of serialized information is specific to a rendering
class, the optional @racket[using-render%] argument accepts the
relevant class. It defaults to HTML rendering, partly because
HTML-format information is usable by other formats (including
Latex/PDF and text).
If @racket[root-path] is not @racket[#f], then file paths that are
serialized as relative to an instantiation-supplied @racket[root-path]
are deserialized as relative instead to the given @racket[root-path],
but a @racket[make-data+root] result for any @racket[_info] supplies
an alternate path for deserialization of the @racket[_info]'s
@racket[_data].
If @racket[doc-id-str] is not @racket[#f], it identifies each
cross-reference entry as originating from @racket[doc-id-str]. This
identification is used when a rendering link to the cross-reference
entry as an external query; see the @racket[set-external-tag-path]
method of @racket[render-mixin].
Use @racket[load-collections-xref] from @racketmodname[setup/xref] to
get all cross-reference information for installed documentation.
@history[#:changed "1.1" @elem{Added the @racket[#:doc-id] argument.}]}
@defproc[(xref-binding->definition-tag [xref xref?]
[binding (or/c identifier?
(list/c (or/c module-path?
module-path-index?)
symbol?)
(listof module-path-index?
symbol?
module-path-index?
symbol?
(one-of/c 0 1)
(or/c exact-integer? false/c)
(or/c exact-integer? false/c)))]
[mode (or/c exact-integer? false/c)])
(or/c tag? false/c)]{
Locates a tag in @racket[xref] that documents a module export. The
binding is specified in one of several ways, as described below; all
possibilities encode an exporting module and a symbolic name. The name
must be exported from the specified module. Documentation is found
either for the specified module or, if the exported name is
re-exported from other other module, for the other module
(transitively).
The @racket[mode] argument specifies the relevant phase level for the
binding. The @racket[binding] is specified in one of four ways:
@itemize[
@item{If @racket[binding] is an identifier, then
@racket[identifier-binding] is used with @racket[mode] to
determine the binding.}
@item{If @racket[binding] is a two-element list, then the first
element provides the exporting module and the second the
exported name. The @racket[mode] argument is effectively
ignored.}
@item{If @racket[binding] is a seven-element list, then it corresponds
to a result from @racket[identifier-binding] using
@racket[mode].}
@item{If @racket[binding] is a five-element list, then the first
element is as for the two-element-list case, and the remain
elements are as in the last four elements of the seven-element
case.}
]
If a documentation point exists in @racket[xref], a tag is returned,
which might be used with @racket[xref-tag->path+anchor] or embedded in
a document rendered via @racket[xref-render]. If no definition point
is found in @racket[xref], the result is @racket[#f].}
@defproc[(xref-tag->path+anchor [xref xref?]
[tag tag?]
[#:external-root-url root-url (or/c string? #f) #f]
[#:render% using-render% (implementation?/c render<%>)
(render-mixin render%)])
(values (or/c false/c path?)
(or/c false/c string?))]{
Returns a path and anchor string designated by the key @racket[tag]
according the cross-reference @racket[xref]. The first result is
@racket[#f] if no mapping is found for the given tag. The second
result is @racket[#f] if the first result is @racket[#f], and it can
also be @racket[#f] if the tag refers to a page rather than a specific
point in a page.
If @racket[root-url] is provided, then references to documentation in
the main installation are redirected to the given URL.
The optional @racket[using-render%] argument is as for
@racket[load-xref].}
@defproc[(xref-tag->index-entry [xref xref?] [tag tag?])
(or/c false/c entry?)]{
Extract an @racket[entry] structure that provides addition information
about the definition (of any) referenced by @racket[tag]. This
function can be composed with @racket[xref-binding->definition-tag] to
obtain information about a binding, such as the library that exports
the binding and its original name.}
@defproc[(xref-render [xref xref?]
[doc part?]
[dest (or/c path-string? false/c)]
[#:render% using-render% (implemenation?/c render<%>)
(render-mixin render%)]
[#:refer-to-existing-files? use-existing? any/c (not dest)])
(or/c void? any/c)]{
Renders @racket[doc] using the cross-reference info in @racket[xref]
to the destination @racket[dest]. For example, @racket[doc] might be a
generated document of search results using link tags described in
@racket[xref].
If @racket[dest] is @racket[#f], no file is written, and the result is
an X-expression for the rendered page. Otherwise, the file
@racket[dest] is written and the result is @|void-const|.
The optional @racket[using-render%] argument is as for
@racket[load-xref]. It determines the kind of output that is
generated.
If @racket[use-existing?] is true, then files referenced during
rendering (such as image files) are referenced from their existing
locations, instead of copying to the directory of @racket[dest].}
@defproc[(xref-transfer-info [renderer (is-a?/c render<%>)]
[ci collect-info?]
[xref xref?])
void?]{
Transfers cross-reference information to @racket[ci], which is the
initially collected information from @racket[renderer].}
@defproc[(xref-index [xref xref?]) (listof entry?)]{
Converts indexing information @racket[xref] into a list of
@racket[entry] structures.}
@defstruct[entry ([words (and/c (listof string?) cons?)]
[content list?]
[tag tag?]
[desc any/c])]{
Represents a single entry in a Scribble document index.
The @racket[words] list corresponds to
@racket[index-element-plain-seq]. The @racket[content] list
corresponds to @racket[index-element-entry-seq]. The @racket[desc]
value corresponds to @racket[index-element-desc]. The @racket[tag] is
the destination for the index link into the main document.}
@deftogether[(
@defproc[(data+root? [v any/c]) boolean?]
@defproc[(make-data+root [data any/c] [root (or/c #f path-string?)]) data+root?]
)]{
A value constructed by @racket[make-data+root] can be returned by a
source procedure for @racket[load-xref] to specify a path used for
deserialization.}
@deftogether[(
@defproc[(data+root+doc-id? [v any/c]) boolean?]
@defproc[(make-data+root+doc-id [data any/c] [root (or/c #f path-string?)] [doc-id string?]) data+root+doc-id?]
)]{
Extends @racket[make-data+root+doc-id] to support an
document-identifying string (see @racket[load-xref]).
@history[#:added "1.1"]}

View File

@ -1,244 +0,0 @@
#lang scribble/manual
@(require (for-label scribble/struct
scriblib/autobib
scheme/base
scheme/contract))
@title[#:tag "autobib"]{Bibliographies}
@defmodule[scriblib/autobib]
This library provides support for bibliography management in a Scribble
document. The @racket[define-cite] form is used to bind procedures
that create in-line citations and generate the bibilography in the
document.
Individual bibliography entries are created with the @racket[make-bib]
function. See below for an example.
@codeblock|{
#lang scribble/base
@(require scriblib/autobib)
@(define-cite ~cite citet generate-bibliography)
@(define plt-tr1
(make-bib
#:title "Reference: Racket"
#:author (authors "Matthew Flatt" "PLT")
#:date "2010"
#:location (techrpt-location #:institution "PLT Inc."
#:number "PLT-TR-2010-1")
#:url "http://racket-lang.org/tr1/"))
Racket is fun@~cite[plt-tr1].
@(generate-bibliography)
}|
For citations that reference a page number or section, the @racket[in-bib]
function can be used. For example, the following snippet:
@codeblock[#:keep-lang-line? #f]|{
#lang scribble/base
Racket has a contract library.@~cite[(in-bib plt-tr1 ", §8")]
}|
includes a citation to section 8 of the Racket reference.
@defform/subs[(define-cite ~cite-id citet-id generate-bibliography-id
option ...)
([option (code:line #:style style-expr)
(code:line #:disambiguate disambiguator-expr)
(code:line #:spaces spaces-expr)
(code:line #:render-date-bib render-date-expr)
(code:line #:render-date-cite render-date-expr)
(code:line #:date<? date-compare-expr)
(code:line #:date=? date-compare-expr)])
#:contracts ([style-expr (or/c author+date-style number-style)]
[spaces-expr number]
[disambiguator-expr (or/c #f (-> exact-nonnegative-integer? element?))]
[render-date-expr (or/c #f (-> date? element?))]
[date-compare-expr (or/c #f (-> date? date? boolean?))])]{
Binds @racket[~cite-id], @racket[citet-id], and
@racket[generate-bibliography-id], which share state to accumulate and
render citations.
The function bound to @racket[~cite-id] produces a citation referring
to one or more bibliography entries with a preceding non-breaking
space, by default sorting the entries to match the bibliography order.
It has the contract
@racketblock[
(->* (bib?) (#:sort? any/c) #:rest (listof bib?) element?)
]
The function bound to @racket[citet-id] generates an element suitable
for use as a noun---referring to a document or its author---for one
or more bibliography entries which have the same authors. It has the contract
@racketblock[
(->* (bib?) () #:rest (listof bib?) element?)
]
The function bound to @racket[generate-bibliography-id] generates the
section for the bibliography. It has the contract
@racketblock[
(->* () (#:tag string? #:sec-title string?) part?)
]
The default value for the @racket[#:tag] argument is @racket["doc-bibliography"]
and for @racket[#:sec-title] is @racket["Bibliography"].
The optional @racket[spaces-expr] determines the number of blank lines that appear
between citations. The default number of lines is 1.
The optional @racket[style-expr] determines the way that citations and
the bibliography are rendered.@margin-note*{Programmer-defined styles
may be supported in the future.} Currently, two built-in style are
provided, and @racket[author+date-style] is the default.
For @racket[author+date-style],
if two citations' references would render the same (as judged by equal
authors and dates that are considered the same) but are different, the
optionally provided function from @racket[disambiguator-expr] is used
to add an extra element after the date; the default disambiguator adds
@litchar{a}, @litchar{b}, @etc until @litchar{z}, and anything more
ambiguous raises an exception. Date comparison is controlled by
@racket[date-compare-expr]s. Dates in citations and dates in the
bibliography may be rendered differently, as specified by the
optionally given @racket[render-date-expr] functions.}
@deftogether[(
@defthing[author+date-style any/c]
@defthing[number-style any/c]
)]{
Styles for use with @racket[define-cite].}
@defproc[(bib? [v any/c]) boolean?]{
Returns @racket[#t] if @racket[v] is a value produced by
@racket[make-bib] or @racket[in-bib], @racket[#f] otherwise.}
@defproc[(make-bib [#:title title any/c]
[#:author author any/c #f]
[#:is-book? is-book? any/c #f]
[#:location location any/c #f]
[#:date date (or/c #f date? exact-nonnegative-integer? string?) #f]
[#:url url string? #f]
[#:note note any/c #f])
bib?]{
Produces a value that represents a document to cite. Except for
@racket[is-book?] and @racket[url], the arguments are used as
content, except that @racket[#f] means that the information is not
supplied. Functions like @racket[proceedings-location],
@racket[author-name], and @racket[authors] help produce elements in a
standard format.
Dates are internally represented as @racket[date] values, so a @racket[date]
may be given, or a number or string that represent the year.
An element produced by a function like @racket[author-name] tracks
first, last names, and name suffixes separately, so that names can be
ordered and rendered correctly. When a string is provided as an author
name, the last non-empty sequence of alphabetic characters or
@litchar["-"] after a space is treated as the author name, and the
rest is treated as the first name.}
@defproc[(in-bib [orig bib?] [where string?]) bib?]{
Extends a bib value so that the rendered citation is suffixed with
@racket[where], which might be a page or chapter number.}
@defproc[(proceedings-location [location any/c]
[#:pages pages (or (list/c any/c any/c) #f) #f]
[#:series series any/c #f]
[#:volume volume any/c #f])
element?]{
Combines elements to generate an element that is suitable for
describing a paper's location within a conference or workshop
proceedings.}
@defproc[(journal-location [title any/c]
[#:pages pages (or (list/c any/c any/c) #f) #f]
[#:number number any/c #f]
[#:volume volume any/c #f])
element?]{
Combines elements to generate an element that is suitable for
describing a paper's location within a journal.}
@defproc[(book-location [#:edition edition any/c #f]
[#:publisher publisher any/c #f])
element?]{
Combines elements to generate an element that is suitable for
describing a book's location.}
@defproc[(techrpt-location [#:institution institution edition any/c]
[#:number number any/c])
element?]{
Combines elements to generate an element that is suitable for
describing a technical report's location.}
@defproc[(dissertation-location [#:institution institution edition any/c]
[#:degree degree any/c "PhD"])
element?]{
Combines elements to generate an element that is suitable for
describing a dissertation.}
@defproc[(author-name [first any/c]
[last any/c]
[#:suffix suffix any/c #f])
element?]{
Combines elements to generate an element that is suitable for
describing an author's name, especially where the last name is not
merely a sequence of ASCII alphabet letters or where the name has a
suffix (such as ``Jr.'').}
@defproc[(authors [name content?] [names content?] ...) element?]{
Combines multiple author elements into one, so that it is rendered and
alphabetized appropriately. Any of @racket[name] or @racket[names]
that are strings are
parsed in the same way as by @racket[make-bib].}
@defproc[(org-author-name [name any/c]) element?]{
Converts an element for an organization name to one suitable for use
as a bib-value author.}
@defproc[(other-authors) element?]{
Generates an element that is suitable for use as a ``others'' author.
When combined with another author element via @racket[authors], the
one created by @racket[other-authors] renders as ``et al.''}
@defproc[(editor [name name/c]) element?]{
Takes an author-name element and create one that represents the editor
of a collection. If a @racket[name] is a string, it is parsed in the
same way as by @racket[make-bib].}
@defparam[abbreviate-given-names abbreviate? any/c]{
Shortens given names in calls to @racket[author] and @racket[make-bib]
to just the first initial when the parameter value is not @racket[#f].
Otherwise, does not change the author names.
Defaults to @racket[#f].
@history[#:added "1.5"]
}

View File

@ -1,54 +0,0 @@
#lang scribble/manual
@(require (for-label scribble/struct
scriblib/bibtex
scriblib/autobib
racket/base
racket/contract))
@title[#:tag "bibtex"]{BibTeX Bibliographies}
@defmodule[scriblib/bibtex]
@defform[(define-bibtex-cite bib-pth ~cite-id citet-id generate-bibliography-id
option ...)]{
Expands into:
@racketblock[
(begin
(define-cite autobib-cite autobib-citet generate-bibliography-id
option ...)
(define-bibtex-cite* bib-pth
autobib-cite autobib-citet
~cite-id citet-id))]
}
@defform[(define-bibtex-cite* bib-pth autobib-cite autobib-citet
~cite-id citet-id)]{
Parses @racket[bib-pth] as a BibTeX database, and augments
@racket[autobib-cite] and @racket[autobib-citet] into
@racket[~cite-id] and @racket[citet-id] functions so that rather than
accepting @racket[bib?] structures, they accept citation key strings.
Each string is broken along spaces into citations keys that are looked up in the BibTeX database and turned into @racket[bib?] structures.
The only BibTeX entries that are supported are: @litchar{misc},
@litchar{book}, @litchar{article}, @litchar{inproceedings},
@litchar{webpage}, @litchar{mastersthesis}, and @litchar{techreport}.
}
@defstruct*[bibdb ([raw (hash/c string? (hash/c string? string?))]
[bibs (hash/c string? bib?)])]{
Represents a BibTeX database. The @racket[_raw] hash table maps the labels in the file to hash tables of the attributes and their values. The @racket[_bibs] hash table maps the same labels to Scribble data-structures representing the same information.
}
@defproc[(path->bibdb [path path-string?])
bibdb?]{
Parses a path into a BibTeX database.
}
@defproc[(bibtex-parse [ip input-port?])
bibdb?]{
Parses an input port into a BibTeX database.
}

View File

@ -1,129 +0,0 @@
#lang scribble/manual
@(require (for-label scribble/core
scribble/decode
scriblib/figure
scheme/base
scheme/contract))
@(define-syntax-rule (sn s) @racket[s])
@title[#:tag "figure"]{Figures}
@defmodule[scriblib/figure]
@deftogether[(
@defproc[(figure [tag string?] [caption content?]
[p pre-flow?] ...
[#:style style style? center-figure-style]
[#:continue? continue? any/c #f])
block?]
@defproc[(figure* [tag string?] [caption content?]
[p pre-flow?] ...
[#:style style style? center-figure-style]
[#:continue? continue? any/c #f])
block?]
@defproc[(figure** [tag string?] [caption content?]
[p pre-flow?] ...
[#:style style style? center-figure-style]
[#:continue? continue? any/c #f])
block?]
@defproc[(figure-here [tag string?] [caption content?]
[pre-flow pre-flow?] ...
[#:style style style? center-figure-style]
[#:continue? continue? any/c #f])
block?]
)]{
Creates a figure. The given @racket[tag] is for use with
@racket[figure-ref] or @racket[Figure-ref]. The @racket[caption] is an
element. The @racket[pre-flow] is decoded as a flow.
For HTML output, the @racket[figure] and @racket[figure*] functions
are the same, while @racket[figure**] allows the content to be wider
than the document body. For two-column Latex output, @racket[figure*]
and @racket[figure**] generate a figure that spans columns.
For Latex output, @racket[figure-here] generates a figure to be included at
the position in the output text where the @racket[figure-here] occurs
in the source text. For HTML output, all @racket[figure] variants
place the figure where the use appears in the source text.
By default, @racket[style] is set so that the content of the figure is
centered. Use @racket[left-figure-style], @racket[center-figure-style],
or @racket[right-figure-style] to specify the alignment.
If @racket[continue?] is a true value, then the figure counter is not
incremented.}
@deftogether[(
@defthing[left-figure-style style?]
@defthing[center-figure-style style?]
@defthing[right-figure-style style?]
@defthing[left style?]
)]{
Implements figure alignments.
The @racket[left] binding is a synonym for @racket[left-figure-style],
provided for backward compatibility.}
@defproc[(figure-ref [tag string?] ...+) element?]{
Generates a reference to one or more figures, using a lowercase word ``figure''.}
@defproc[(Figure-ref [tag string?] ...+) element?]{
Generates a reference to one or more figures, capitalizing the word ``Figure''.}
@defproc[(Figure-target [tag string?]
[#:continue? continue? any/c #f])
element?]{
Generates a new figure label. This function is normally not used
directly, since it is used by @racket[figure].}
@defproc[(suppress-floats) element?]{
Produces an empty element that renders in Latex as
@tt{\suppressfloats}, which discourages the placement of figures in
the column or page of the surrounding text.}
@section{Configuring Output}
Output uses the following style names, which can be adjusted in an
overriding @filepath{.css} or @filepath{.tex} specification:
@itemize[
@item{@sn{Figure}, @sn{FigureMulti}, @sn{FigureMultiWide}, or
@sn{HereFigure} --- used for the outer of three
@racket[nested-flow]s for a figure, depending on whether
@racket[figure], @racket[figure*], @racket[figure**], or
@racket[figure-here] is used to generate the figure.}
@item{@sn{Leftfigure}, @sn{Centerfigure}, or @sn{Rightfigure} ---
used for the middle of three @racket[nested-flow]s for a
figure, depending on the specified style.}
@item{@sn{FigureInside} --- used for the inner of three
@racket[nested-flow]s for a figure.}
@item{@sn{Legend} --- Wraps the caption for a figure.}
@item{@sn{LegendContinued} --- Wraps the caption for a figure that
does not increment the figure counter.}
@item{@sn{FigureTarget} --- Wraps the label anchor and text within a
figure's caption. For Latex output, the corresponding command
is given a second argument, which is just the generated label
(used with @tt{\label} in the command's first argument).}
@item{@sn{FigureRef} --- Wraps a reference to a figure. For Latex
output, the corresponding command is given a second argument,
which is just the target label.}
]

View File

@ -1,33 +0,0 @@
#lang scribble/manual
@(require (for-label scribble/struct
scriblib/footnote
scheme/base
scheme/contract))
@title[#:tag "footnotes"]{Footnotes}
@defmodule[scriblib/footnote]
@defproc[(note [pre-content pre-content?] ...) element?]{
Creates a margin note for HTML and a footnote for Latex/PDF output.}
@defform[(define-footnote footnote-id footnote-part-id)]{
Binds @racket[footnote-id] to a form like @racket[note] that generates
a footnote in HTML output as well as Latex/PDF output. To trigger the
HTML output of the footnotes that are registered through
@racket[footnote-id], the function bound to @racket[footnote-part-id]
must be called at a position that corresponds the bottom of the HTML
page. (The generated section will not show a title or appear in a
table of contents; it will look like a footnote area.)
Beware that any content passed to @racket[footnote-id] will occur
twice in at least an intermediate form of the document, and perhaps
also in the rendered form of the document. Consequently, the content
passed to @racket[footnote-id] should not bind link targets or include
other one-time declarations.}

View File

@ -1,81 +0,0 @@
#lang scribble/manual
@(require (for-label scribble/eval scriblib/gui-eval))
@title[#:tag "gui-eval"]{Examples Using the GUI Toolbox}
@defmodule[scriblib/gui-eval]{The
@racketmodname[scriblib/gui-eval] library support example
evaluations that use @racketmodname[racket/gui] facilities (as opposed
to just @racketmodname[racket/draw]) to generate text and image results.}
The trick is that @racketmodname[racket/gui] is not generally
available when rendering documentation, because it requires a GUI
context. Text and image output is rendered to an image file when the
@envvar{MREVAL} environment variable is set, so run the enclosing
document once with the environment varibale to generate the
images. Future runs (with the environment variable unset) use the
generated image.
@deftogether[(
@defform*[((gui-interaction datum ...)
(gui-interaction
#:eval+opts the-eval get-predicate? get-render
get-get-width get-get-height
datum ...))
]
@defform*[((gui-interaction-eval datum ...)
(gui-interaction-eval
#:eval+opts the-eval get-predicate? get-render
get-get-width get-get-height
datum ... ))]
@defform*[((gui-interaction-eval-show datum ...)
(gui-interaction-eval-show
#:eval+opts the-eval get-predicate? get-render
get-get-width get-get-height
datum ...))]
@defform*[((gui-racketblock+eval datum ...)
(gui-racketblock+eval
#:eval+opts the-eval get-predicate? get-render
get-get-width get-get-height
datum ...))]
@defform*[((gui-racketmod+eval datum ...)
(gui-racketmod+eval
#:eval+opts the-eval get-predicate? get-render
get-get-width get-get-height
datum ...))]
@defform*[((gui-def+int datum ...)
(gui-def+int
#:eval+opts the-eval get-predicate? get-render
get-get-width get-get-height
datum ...))]
@defform*[((gui-defs+int datum ...)
(gui-defs+int
#:eval+opts the-eval get-predicate? get-render
get-get-width get-get-height
datum ...))]
)]{
The first option of each of the above is
like @racket[interaction], etc., but actually evaluating the forms
only when the @envvar{MREVAL} environment variable is set, and then in
an evaluator that is initialized with @racketmodname[racket/gui/base]
and @racketmodname[slideshow].
The second option of each allows you to specify your own evaluator via
the @racket[the-eval] argument and then to specify four thunks that
return functions for finding and rendering graphical objects:
@itemize[
@item{@racket[get-predicate? : (-> (-> any/c boolean?))]
Determines if a value is a graphical object (and thus handled by the other operations)}
@item{@racket[get-render : (-> (-> any/c (is-a?/c dc<%>) number? number? void?))]
Draws a graphical object (only called if the predicate returned @racket[#t]; the first
argument will be the value for which the predicate holds).}
@item{@racket[get-get-width : (-> (-> any/c number?))]
Gets the width of a graphical object (only called if the predicate returned @racket[#t]; the first
argument will be the value for which the predicate holds).}
@item{@racket[get-get-height : (-> (-> any/c number?))]
Gets the height of a graphical object (only called if the predicate returned @racket[#t]; the first
argument will be the value for which the predicate holds).}
]
}

View File

@ -1,3 +0,0 @@
#lang info
(define scribblings '(("scriblib.scrbl" (multi-page) ("Scribble Libraries"))))

View File

@ -1,63 +0,0 @@
#lang scribble/manual
@(require (for-label scribble/core
racket/base
scriblib/render-cond))
@(define scribble-doc '(lib "scribblings/scribble/scribble.scrbl"))
@title[#:tag "render-cond"]{Conditional Content}
@defmodule[scriblib/render-cond]
As much as possible, Scribble documents should be independent of the
target format for rendering the document. To customize generated
output, use styles plus ``back end'' configurations for each target
format (see @secref[#:doc scribble-doc "config"] in
@other-manual[scribble-doc]).
As a last resort, the @racket[cond-element] and @racket[cond-block]
forms support varying the document content depending on the target
format. More precisely, they generate parts of a document where
content is delayed until the @tech[#:doc scribble-doc]{traverse pass}
of document rendering. Format detection relies on the
@racket['scribble:current-render-mode] registration that is accessible
through a @racket[traverse-element] or @racket[traverse-block].
The syntax of @racket[cond-element] and @racket[cond-block] is based
on SRFI-0.
@defform*/subs[#:literals (and or not else)
[(cond-element [feature-requirement body ...+])
(cond-element [feature-requirement body ...+] [else body ...+])]
([feature-requirement identifier
(not feature-requirement)
(and feature-requirement ...)
(or feature-requirement ...)])]{
Generates a @racket[traverse-element] whose replacement content is
produced by the @racket[body] of one of the first matching
@racket[cond-element] clause.
A @racket[feature-requirement] can be any identifier; a useful
identifier is one whose symbol form can appear in a
@racket['scribble:current-render-mode] list. The identifier matches
when its symbol form is in the @racket['scribble:current-render-mode]
list. Typically, the identifier is @racket[html], @racket[latex], or
@racket[text] to indicate the corresponding rendering target.
A @racket[(not feature-requirement)] test matches when
@racket[feature-requirement] does not match, and so on. An
@racket[else] clause always matches. If no @racket[else] clause is
present and no clause matches, then the @racket[exn:fail:contract]
exception is raised. Similarly, if the result of the selected
@racket[body] is not content according to @racket[content?], then the
@racket[exn:fail:contract] exception is raised.}
@defform*[[(cond-block [feature-requirement body ...+])
(cond-block [feature-requirement body ...+] [else body ...+])]]{
Like @racket[cond-element], but generates a @racket[traverse-block]
where the selected @racket[body] must produce a block according to
@racket[block?].}

View File

@ -1,12 +0,0 @@
#lang scribble/manual
@title{Scriblib: Extra Scribble Libraries}
@table-of-contents[]
@include-section["gui-eval.scrbl"]
@include-section["figure.scrbl"]
@include-section["autobib.scrbl"]
@include-section["bibtex.scrbl"]
@include-section["footnote.scrbl"]
@include-section["render-cond.scrbl"]

View File

@ -1,11 +0,0 @@
scribble-text-lib
Copyright (c) 2010-2014 PLT Design Inc.
This package is distributed under the GNU Lesser General Public
License (LGPL). This means that you can link this package into proprietary
applications, provided you follow the rules stated in the LGPL. You
can also modify this package; if you distribute a modified version,
you must distribute it under the terms of the LGPL, which in
particular means that you must release the source code for the
modified software. See http://www.gnu.org/copyleft/lesser.html
for more information.

View File

@ -1,11 +0,0 @@
#lang info
(define collection 'multi)
(define deps '("scheme-lib"
"base" "at-exp-lib"
"scribble-text-lib"))
(define pkg-desc "Language for HTML with embedded Racket code")
(define pkg-authors '(mflatt eli))

View File

@ -1,4 +0,0 @@
#lang racket/base
(require "html/main.rkt")
(provide (all-from-out "html/main.rkt"))

Some files were not shown because too many files have changed in this diff Show More