#lang scribble/doc
@(require scribble/manual scribble/core scribble/html-properties
          scribble/latex-properties
          racket/runtime-path
          "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/lp] are simultaneously
two things: a program and a document describing the program.

Programs in @racketmodname[scribble/lp] are viewed in two different
ways, either by running the program directly or by including it with
@racket[lp-include].  When running the program, all of the
@racket[chunk] expressions are collected and stitched together into a
program, and the rest of the module is discarded. When using
@racket[lp-include], the entire contents of the module are preserved
and 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:

@(call-with-input-file lp-ex
   (lambda (port)
     (verbatim
      #:indent 2
      (apply 
       string-append
       (let loop ()
	 (let ([line (read-line port 'any)])
	   (cond
	    [(eof-object? line) '()]
            [(equal? line "") (cons "  \n" (loop))]
            [else 
	       (list* line "\n" (loop))])))))))

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 included with @racket[lp-include], it looks
like this:

@(make-nested-flow
  (make-style "LPBoxed" null)
  (part-blocks lp-ex:doc))

@section{@racketmodname[scribble/lp] Language}

@defmodulelang[scribble/lp]{The @racketmodname[scribble/lp] language
provides core support for literate programming.}

@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 a scribble 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.

}

@defform[(CHUNK id form ...)]{

 Like @racket[chunk], but allows the use of @racket[unsyntax] in the
code part. If you want to use @racket[unsyntax] to escape to Scribble,
use @racket[UNSYNTAX].

}

@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[] scribble/base] or @racket[#, @hash-lang[]
scribble/manual], instead of @racket[#, @hash-lang[] racket].}

@defform[(lp-include filename)]{
Includes the source of @racket[filename] as the typeset version of the literate
program.
}
