From a728366aab3c7258eaab780f1d02f7ad5191fed6 Mon Sep 17 00:00:00 2001
From: Asumu Takikawa <asumu@ccs.neu.edu>
Date: Fri, 8 Nov 2013 18:28:18 -0500
Subject: [PATCH] Render scribble doc examples in the page

original commit: ed4cbb8054f06ef4c92fe11cc375b0275b40f581
---
 .../scribblings/scribble/base.scrbl           |  13 +-
 .../scribblings/scribble/manual.scrbl         | 144 +++++++++++++++---
 .../scribblings/scribble/utils.rkt            |  12 +-
 3 files changed, 147 insertions(+), 22 deletions(-)

diff --git a/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/base.scrbl b/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/base.scrbl
index 4f152383..a9661e0d 100644
--- a/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/base.scrbl
+++ b/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/base.scrbl
@@ -256,7 +256,7 @@ Use @racket['cont] 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].}
+The @racket[style] argument is handled the same as @racket[para].
 
 Examples:
 @codeblock[#:keep-lang-line? #f]|{
@@ -271,6 +271,17 @@ Examples:
                (list "kinpira gobō"  "burdock")
                (list "makizushi"     'cont))]
 }|
+@doc-render-examples[
+  @tabular[#:sep @hspace[1]
+           (list (list "soup" "gazpacho")
+                 (list "soup" "tonjiru"))]
+
+  @tabular[#:style 'boxed
+           (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?]{
diff --git a/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/manual.scrbl b/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/manual.scrbl
index 3bece6f6..cd5faf74 100644
--- a/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/manual.scrbl
+++ b/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/manual.scrbl
@@ -746,6 +746,45 @@ and produces @racket[#f], the @racket[id] is indexed, and it also registered so
 that @racket[racket]-typeset uses of the identifier (with the same
 for-label binding) are hyperlinked to this documentation.
 
+Examples:
+@codeblock[#:keep-lang-line? #f]|{
+#lang scribble/manual
+@defproc[(make-sandwich [ingredients (listof ingredient?)])
+         sandwich?]{
+  Returns a sandwich given the right ingredients.
+}
+
+@defproc[#:kind "sandwich-maker"
+         (make-reuben [ingredient sauerkraut?] ...
+                      [#:veggie? veggie? any/c #f])
+         sandwich?]{
+  Produces a reuben given some number of @racket[ingredient]s.
+
+  If @racket[veggie?] is @racket[#f], produces a standard
+  reuben with corned beef. Otherwise, produces a vegetable
+  reuben.
+}
+}|
+
+@doc-render-examples[
+ @defproc[#:link-target? #f
+          (make-sandwich [ingredients (listof ingredient?)])
+          sandwich?]{
+   Returns a sandwich given the right ingredients.
+ }
+
+ @defproc[#:kind "sandwich-maker"
+          #:link-target? #f
+          (make-reuben [ingredient sauerkraut?] ...
+                       [#:veggie? veggie? any/c #f])
+          sandwich?]{
+   Produces a reuben given some number of @racket[ingredient]s.
+
+   If @racket[veggie?] is @racket[#f], produces a standard
+   reuben with corned beef. Otherwise, produces a vegetable
+   reuben.
+ }]
+
 When @racket[id] is indexed and registered, 
 a @racket[defmodule] or @racket[declare-exporting] form (or one of the
 variants) in an enclosing section determines the @racket[id] binding
@@ -809,26 +848,6 @@ If @racket[#:id [src-id dest-id-expr]] is supplied, then
 place of @racket[src-id]. This split between @racket[src-id] and
 @racket[dest-id-expr] roles is useful for functional abstraction of
 @racket[defproc].
-
-Examples:
-@codeblock[#:keep-lang-line? #f]|{
-#lang scribble/manual
-@defproc[(make-sandwich [ingredients (listof ingredient?)])
-         sandwich?]{
-  Returns a sandwich given the right ingredients.
-}
-
-@defproc[#:kind "sandwich-maker"
-         (make-reuben [ingredient sauerkraut?] ...
-                      [#:veggie? veggie? any/c #f])
-         sandwich?]{
-  Produces a reuben given some number of @racket[ingredient]s.
-
-  If @racket[veggie?] is @racket[#f], produces a standard
-  reuben with corned beef. Otherwise, produces a vegetable
-  reuben.
-}
-}|
 }
 
 @defform[(defproc* options
@@ -858,6 +877,16 @@ Examples:
   jelly.
 }
 }|
+
+@doc-render-examples[
+  @defproc[#:link-target? #f
+           ((make-pb&j)
+            (make-pb&j [jelly jelly?]))
+           sandwich?]{
+    Returns a peanut butter and jelly sandwich. If @racket[jelly]
+    is provided, then it is used instead of the standard (grape)
+    jelly.
+  }]
 }
 
 
@@ -963,6 +992,37 @@ Examples:
   clauses adds an additional ingredient to the sandwich pipeline.
 }
 }|
+@doc-render-examples[
+  @defform[#:link-target? #f
+           (sandwich-promise sandwich-expr)
+           #:contracts ([sandwich-expr sandwich?])]{
+    Returns a promise to construct a sandwich. When forced, the promise
+    will produce the result of @racket[sandwich-expr].
+  }
+
+  @defform[#:link-target? #f
+           #:literals (sandwich mixins)
+           (sandwich-promise* [sandwich sandwich-expr]
+                              [mixins ingredient-expr ...])
+           #:contracts ([sandwich-expr sandwich?]
+                        [ingreient-expr ingredient?])]{
+    Returns a promise to construct a sandwich. When forced, the promise
+    will produce the result of @racket[sandwich-expr]. Each result of
+    the @racket[ingredient-expr]s will be mixed into the resulting
+    sandwich.
+  }
+
+  @defform[#:link-target? #f
+           (sandwich-factory maybe-name factory-component ...)
+           #:grammar
+           [(maybe-name (code:line)
+                        name)
+            (factory-component (code:line #:protein protein-expr)
+                               [vegetable vegetable-expr])]]{
+    Constructs a sandwich factory. If @racket[maybe-name] is provided,
+    the factory will be named. Each of the @racket[factory-component]
+    clauses adds an additional ingredient to the sandwich pipeline.
+  }]
 }
 
 @defform[(defform* options [form-datum ...+]
@@ -982,6 +1042,14 @@ Examples:
   is invoked when the current sandwich is eaten.
 }
 }|
+@doc-render-examples[
+@defform*[#:link-target? #f
+          ((call-with-current-sandwich expr)
+           (call-with-current-sandwich expr sandwich-handler-expr))]{
+  Runs @racket[expr] and passes it the value of the current
+  sandwich. If @racket[sandwich-handler-expr] is provided, its result
+  is invoked when the current sandwich is eaten.
+}]
 }
 
 
@@ -1079,6 +1147,17 @@ Examples:
   clauses adds an additional ingredient to the sandwich pipeline.
 }
 }|
+@doc-render-examples[
+  @defform/subs[#:link-target? #f
+                (sandwich-factory maybe-name factory-component ...)
+                [(maybe-name (code:line)
+                             name)
+                 (factory-component (code:line #:protein protein-expr)
+                                    [vegetable vegetable-expr])]]{
+    Constructs a sandwich factory. If @racket[maybe-name] is provided,
+    the factory will be named. Each of the @racket[factory-component]
+    clauses adds an additional ingredient to the sandwich pipeline.
+  }]
 }
 
 
@@ -1097,6 +1176,12 @@ Examples:
   involve eating a sandwich.
 }
 }|
+@doc-render-examples[
+  @defparam[#:link-target? #f
+            current-sandwich sandwich sandwich?]{
+    A parameter that defines the current sandwich for operations that
+    involve eating a sandwich.
+  }]
 }
 
 
@@ -1143,6 +1228,11 @@ Examples:
   Don't eat this. Provided for backwards compatibility.
 }
 }|
+@doc-render-examples[
+  @defthing[#:link-target? #f
+            moldy-sandwich sandwich?]{
+    Don't eat this. Provided for backwards compatibility.
+  }]
 }
 
 
@@ -1182,6 +1272,13 @@ Examples:
   ingredients.
 }
 }|
+@doc-render-examples[
+  @defstruct[#:link-target? #f
+             sandwich ([protein ingredient?] [sauce ingredient?])]{
+    A strucure type for sandwiches. Sandwiches are a pan-human foodstuff
+    composed of a partially-enclosing bread material and various
+    ingredients.
+  }]
 }
 
 
@@ -1203,6 +1300,13 @@ Examples:
   in writing test cases
 }
 }|
+@doc-render-examples[
+  @deftogether[(@defthing[#:link-target? #f test-sandwich-1 sandwich?]
+                @defthing[#:link-target? #f test-sandwich-2 sandwich?])]{
+    Two high-quality sandwiches. These are provided for convenience
+    in writing test cases
+  }
+]
 }
 
 
diff --git a/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/utils.rkt b/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/utils.rkt
index 2041c81c..1ae1c999 100644
--- a/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/utils.rkt
+++ b/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/utils.rkt
@@ -26,7 +26,7 @@
                   scribble/eval
                   scribble/bnf)
 
-(provide scribble-examples litchar/lines)
+(provide scribble-examples litchar/lines doc-render-examples)
 
 (define (as-flow e)
   (if (block? e) e (make-paragraph plain (list e))))
@@ -227,3 +227,13 @@
 (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 ...))))
+