lp.scrbl (5520B)
1 #lang scribble/doc 2 @(require scribble/manual scribble/core scribble/html-properties 3 scribble/latex-properties 4 racket/runtime-path 5 racket/file 6 "utils.rkt" 7 (prefix-in lp-ex: "lp-ex-doc.scrbl") 8 (for-label scribble/lp-include scribble/lp)) 9 10 @title[#:tag "lp" 11 #:style (make-style #f 12 (list (make-css-addition "lp.css") 13 (make-tex-addition "lp.tex"))) 14 ]{Literate Programming} 15 16 Programs written using @racketmodname[scribble/lp2] are simultaneously 17 two things: a program and a document describing the program: 18 19 @itemlist[ 20 21 @item{When the program is run, all of the @racket[chunk] expressions 22 are collected and stitched together into a program, and the 23 rest of the module is discarded.} 24 25 @item{When the program is provided to Scribble---or used through 26 @racket[include-section] in another Scribble document with a 27 @racket[(submod ... doc)] module path---the entire contents of 28 the module are treated like an ordinary Scribble document, 29 where @racket[chunk]s are typeset in a manner similar to 30 @racket[codeblock].} 31 32 ] 33 34 @(define-runtime-path lp-ex "lp-ex.rkt") 35 36 For example, consider this program: 37 38 @(codeblock (file->string lp-ex)) 39 40 When this file is @racket[require]d in the normal manner, it defines a 41 function @racket[f] that squares its argument, and the documentation 42 is ignored. When it is rendered as a Scribble document, the output 43 looks like this: 44 45 @(make-nested-flow 46 (make-style "LPBoxed" null) 47 (part-blocks lp-ex:doc)) 48 49 @; ------------------------------------------------------------ 50 51 @section{@racketmodname[scribble/lp2] Language} 52 53 @defmodulelang[scribble/lp2 #:use-sources (scribble/lp)]{The 54 @racketmodname[scribble/lp] language provides core support for 55 literate programming. It is read like a @racketmodname[scribble/base] 56 program, but its bindings extend @racketmodname[racket/base] with two 57 forms: @racket[chunk] and @racket[CHUNK].} 58 59 More precisely, a module in @racketmodname[scribble/lp2] has its 60 @racketmodname[racket/base]-like content in a @racketidfont{doc} 61 submodule, which is recognized by tools such as @exec{raco scribble}. 62 The content of the @racket[chunk] and @racket[CHUNK] forms is 63 stitched together as the immediate content of the module. 64 65 The @racket[chunk] and @racket[CHUNK] content is discovered by first 66 @racket[expand]ing the module as written. The content is collected 67 into a new module, and then the original module content is placed into 68 a @racket[doc] submodule that is expanded (so that the content is 69 effectively re-expanded). The @racketidfont{doc} submodule is declared 70 with @racket[module*]. 71 72 To include a @racketmodname[scribble/lp2] document named 73 @filepath{file.scrbl} into another Scribble document, 74 import the @racketidfont{doc} submodule: 75 76 @codeblock[#:keep-lang-line? #false]|{ 77 #lang scribble/manual 78 @include-section[(submod "file.scrbl" doc)] 79 }| 80 81 @history[#:added "1.8" 82 #:changed "1.17" @elem{Declared the @racketidfont{doc} submodule with 83 @racket[module*] instead of @racket[module].}] 84 85 @defform[(chunk id form ...)]{ 86 87 Introduces a chunk, binding @racket[id] for use in other 88 chunks. Normally, @racket[id] starts with @litchar{<} and ends with 89 @litchar{>}. 90 91 When running the enclosing program, only the code inside the 92 chunks is run; the rest is ignored. 93 94 If @racket[id] is @racketidfont{<*>}, then this chunk is 95 used as the main chunk in the file. If @racketidfont{<*>} 96 is never used, then the first chunk in the file is treated 97 as the main chunk. If some chunk is not referenced from 98 the main chunk (possibly indirectly via other chunks that 99 the main chunk references), then it is not included in the 100 program and thus is not run. 101 102 The @racket[form]s are typeset using @racket[racketblock], so 103 @racket[code:comment], etc., can be used to adjust the output. 104 Those output-adjusting forms are stripped from each @racket[form] 105 for running the program. 106 107 @history[#:changed "1.17" @elem{Strip @racket[code:comment], etc., for running.}]} 108 109 @defform[(CHUNK id form ...)]{ 110 111 Like @racket[chunk], but typesets with @racket[RACKETBLOCK], so @racket[unsyntax] 112 can be used normally in each @racket[form]. To escape, 113 use @racket[UNSYNTAX]. 114 115 } 116 117 @; ------------------------------------------------------------ 118 119 @section{@racketmodname[scribble/lp] Language} 120 121 @defmodulelang[scribble/lp]{Programs written using the older 122 @racketmodname[scribble/lp] language are similar to 123 @racketmodname[scribble/lp2] programs, except that the module cannot 124 be provided directly to Scribble. Instead, the document content must be 125 extracted using @racket[lp-include].} 126 127 The @racketmodname[scribble/lp] language effectively binds only 128 @racket[chunk] and @racket[CHUNK], while all other bindings for 129 documentation are taken from the context where @racket[lp-include] is 130 used. 131 132 @; ------------------------------------------------------------ 133 134 @section{@racketmodname[scribble/lp-include] Module} 135 136 @defmodule[scribble/lp-include]{The 137 @racketmodname[scribble/lp-include] library is normally used within a 138 Scribble document---that is, a module that starts with something like 139 @hash-lang[] @racketmodname[scribble/base] or @hash-lang[] @racketmodname[scribble/manual], 140 instead of @hash-lang[] @racketmodname[racket].} 141 142 @defform[(lp-include filename)]{ 143 Includes the source of @racket[filename] as the typeset version of the literate 144 program. 145 }