Changing scribble notation to use TeX-style \ instead of @.

Documentation looks much nicer now (or at least more familiar).
Test cases become ugly because we need to double the escape in
strings.  Also escaping requires \"\\" which in a Scheme string
gets written \\"\\\\".  Consider \\ as a shortcut (which is still
\\\\ in a string).
This commit is contained in:
Alex Shinn 2013-07-14 12:52:28 +09:00
parent 4a7f1867d5
commit dddc6d1806
20 changed files with 997 additions and 981 deletions

File diff suppressed because it is too large Load diff

View file

@ -6,16 +6,16 @@
;;> the compiler, and other core types less commonly
;;> needed in user code, plus related utilities.
;;> @subsubsection{Analysis and Expansion}
;;> \subsubsection{Analysis and Expansion}
;;> @subsubsubsection{@scheme{(analyze x [env])}}
;;> \subsubsubsection{\scheme{(analyze x [env])}}
;;> Expands and analyzes the expression @var{x} and returns the
;;> Expands and analyzes the expression \var{x} and returns the
;;> resulting AST.
;;> @subsubsubsection{@scheme{(optimize ast)}}
;;> \subsubsubsection{\scheme{(optimize ast)}}
;;> Runs an optimization pass on @var{ast} and returns the
;;> Runs an optimization pass on \var{ast} and returns the
;;> resulting simplified expression.
(define (ast-renames ast)
@ -78,13 +78,13 @@
((null? ls) '())
(else (f ls))))
;;> Performs a full syntax expansion of the form @var{x} and
;;> Performs a full syntax expansion of the form \var{x} and
;;> returns the resulting s-expression.
(define (macroexpand x)
(ast->sexp (analyze x)))
;;> Convert @var{ast} to a s-expression, renaming variables if
;;> Convert \var{ast} to a s-expression, renaming variables if
;;> necessary.
(define (ast->sexp ast)
@ -109,78 +109,78 @@
((opcode? x) (cond ((opcode-name x) => string->symbol) (else x)))
(else x)))))
;;> @subsubsection{Types}
;;> \subsubsection{Types}
;;> All objects have an associated type, and types may have parent
;;> types. When using
;;> @hyperlink["http://srfi.schemers.org/srfi-9/srfi-9/html"]{SRFI-9}
;;> @scheme{define-record-type}, the name is bound to a first class
;;> \hyperlink["http://srfi.schemers.org/srfi-9/srfi-9/html"]{SRFI-9}
;;> \scheme{define-record-type}, the name is bound to a first class
;;> type object.
;;> The following core types are also available by name, and may be
;;> used in the @scheme{match} @scheme{($ ...)} syntax.
;;> used in the \scheme{match} \scheme{($ ...)} syntax.
;;> @itemlist[
;;> @item{@scheme{<object>} - the parent of all types}
;;> @item{@scheme{<number>} - abstract numeric type}
;;> @item{@scheme{<bignum>} - arbitrary precision exact integers}
;;> @item{@scheme{<flonum>} - inexact real numbers}
;;> @item{@scheme{<integer>} - abstract integer type}
;;> @item{@scheme{<symbol>} - symbols}
;;> @item{@scheme{<char>} - character}
;;> @item{@scheme{<boolean>} - @scheme{#t} or @scheme{#f}}
;;> @item{@scheme{<string>} - strings of characters}
;;> @item{@scheme{<byte-vector>} - uniform vector of octets}
;;> @item{@scheme{<pair>} - a @var{car} and @var{cdr}, the basis for lists}
;;> @item{@scheme{<vector>} - vectors}
;;> @item{@scheme{<opcode>} - a primitive opcode or C function}
;;> @item{@scheme{<procedure>} - a closure}
;;> @item{@scheme{<bytecode>} - the compiled code for a closure}
;;> @item{@scheme{<env>} - an environment structure}
;;> @item{@scheme{<macro>} - a macro object, usually not first-class}
;;> @item{@scheme{<lam>} - a lambda AST type}
;;> @item{@scheme{<cnd>} - an conditional AST type (i.e. @scheme{if})}
;;> @item{@scheme{<ref>} - a reference AST type}
;;> @item{@scheme{<set>} - a mutation AST type (i.e. @scheme{set!})}
;;> @item{@scheme{<seq>} - a sequence AST type}
;;> @item{@scheme{<lit>} - a literal AST type}
;;> @item{@scheme{<sc>} - a syntactic closure}
;;> @item{@scheme{<context>} - a context object (including threads)}
;;> @item{@scheme{<exception>} - an exception object}
;;> \itemlist[
;;> \item{\scheme{<object>} - the parent of all types}
;;> \item{\scheme{<number>} - abstract numeric type}
;;> \item{\scheme{<bignum>} - arbitrary precision exact integers}
;;> \item{\scheme{<flonum>} - inexact real numbers}
;;> \item{\scheme{<integer>} - abstract integer type}
;;> \item{\scheme{<symbol>} - symbols}
;;> \item{\scheme{<char>} - character}
;;> \item{\scheme{<boolean>} - \scheme{#t} or \scheme{#f}}
;;> \item{\scheme{<string>} - strings of characters}
;;> \item{\scheme{<byte-vector>} - uniform vector of octets}
;;> \item{\scheme{<pair>} - a \var{car} and \var{cdr}, the basis for lists}
;;> \item{\scheme{<vector>} - vectors}
;;> \item{\scheme{<opcode>} - a primitive opcode or C function}
;;> \item{\scheme{<procedure>} - a closure}
;;> \item{\scheme{<bytecode>} - the compiled code for a closure}
;;> \item{\scheme{<env>} - an environment structure}
;;> \item{\scheme{<macro>} - a macro object, usually not first-class}
;;> \item{\scheme{<lam>} - a lambda AST type}
;;> \item{\scheme{<cnd>} - an conditional AST type (i.e. \scheme{if})}
;;> \item{\scheme{<ref>} - a reference AST type}
;;> \item{\scheme{<set>} - a mutation AST type (i.e. \scheme{set!})}
;;> \item{\scheme{<seq>} - a sequence AST type}
;;> \item{\scheme{<lit>} - a literal AST type}
;;> \item{\scheme{<sc>} - a syntactic closure}
;;> \item{\scheme{<context>} - a context object (including threads)}
;;> \item{\scheme{<exception>} - an exception object}
;;> ]
;;> The following extended type predicates may also be used to test
;;> individual objects for their type:
;;> @itemlist[
;;> @item{@scheme{environment?}}
;;> @item{@scheme{bytecode?}}
;;> @item{@scheme{macro?}}
;;> @item{@scheme{syntactic-closure?}}
;;> @item{@scheme{lambda?}}
;;> @item{@scheme{cnd?}}
;;> @item{@scheme{ref?}}
;;> @item{@scheme{set?}}
;;> @item{@scheme{seq?}}
;;> @item{@scheme{lit?}}
;;> @item{@scheme{opcode?}}
;;> @item{@scheme{type?}}
;;> @item{@scheme{context?}}
;;> @item{@scheme{exception?}}
;;> \itemlist[
;;> \item{\scheme{environment?}}
;;> \item{\scheme{bytecode?}}
;;> \item{\scheme{macro?}}
;;> \item{\scheme{syntactic-closure?}}
;;> \item{\scheme{lambda?}}
;;> \item{\scheme{cnd?}}
;;> \item{\scheme{ref?}}
;;> \item{\scheme{set?}}
;;> \item{\scheme{seq?}}
;;> \item{\scheme{lit?}}
;;> \item{\scheme{opcode?}}
;;> \item{\scheme{type?}}
;;> \item{\scheme{context?}}
;;> \item{\scheme{exception?}}
;;> ]
;;> @subsubsubsection{@scheme{(type-of x)}}
;;> \subsubsubsection{\scheme{(type-of x)}}
;;> Returns the type of any object @var{x}.
;;> Returns the type of any object \var{x}.
;;> @subsubsubsection{@scheme{(type-name type)}}
;;> \subsubsubsection{\scheme{(type-name type)}}
;;> Returns the name of type @var{type}.
;;> Returns the name of type \var{type}.
;;> @subsubsubsection{@scheme{(type-parent type)}}
;;> \subsubsubsection{\scheme{(type-parent type)}}
;;> Returns the immediate parent of type @var{type},
;;> or @scheme{#f} for a type with no parent.
;;> Returns the immediate parent of type \var{type},
;;> or \scheme{#f} for a type with no parent.
(define (type-parent type)
(let ((v (type-cpl type)))
@ -188,26 +188,26 @@
(> (vector-length v) 1)
(vector-ref v (- (vector-length v) 2)))))
;;> @subsubsubsection{@scheme{(type-cpl type)}}
;;> \subsubsubsection{\scheme{(type-cpl type)}}
;;> Returns the class precedence list of type @var{type} as a
;;> vector, or @scheme{#f} for a type with no parent.
;;> Returns the class precedence list of type \var{type} as a
;;> vector, or \scheme{#f} for a type with no parent.
;;> @subsubsubsection{@scheme{(type-slots type)}}
;;> \subsubsubsection{\scheme{(type-slots type)}}
;;> Returns the slot list of type @var{type}.
;;> Returns the slot list of type \var{type}.
;;> @subsubsection{Accessors}
;;> \subsubsection{Accessors}
;;> This section describes additional accessors on AST and other core
;;> types.
;;> @subsubsubsection{Procedures}
;;> \subsubsubsection{Procedures}
;;> @itemlist[
;;> @item{@scheme{(procedure-code f)} - the compiled bytecode object}
;;> @item{@scheme{(procedure-vars f)} - the variables closed over by @var{f}}
;;> @item{@scheme{(procedure-name f)} - the name of @var{f} if known, else @scheme{#f}}
;;> \itemlist[
;;> \item{\scheme{(procedure-code f)} - the compiled bytecode object}
;;> \item{\scheme{(procedure-vars f)} - the variables closed over by \var{f}}
;;> \item{\scheme{(procedure-name f)} - the name of \var{f} if known, else \scheme{#f}}
;;> ]
(define (procedure-name x)
@ -216,149 +216,149 @@
(define (procedure-name-set! x name)
(bytecode-name-set! (procedure-code x) name))
;;> @subsubsubsection{Macros}
;;> \subsubsubsection{Macros}
;;> @itemlist[
;;> @item{@scheme{(macro-procedure f)} - the macro procedure}
;;> @item{@scheme{(macro-env f)} - the environment the macro was defined in}
;;> @item{@scheme{(macro-source f)} - the source location the macro was defined in}
;;> \itemlist[
;;> \item{\scheme{(macro-procedure f)} - the macro procedure}
;;> \item{\scheme{(macro-env f)} - the environment the macro was defined in}
;;> \item{\scheme{(macro-source f)} - the source location the macro was defined in}
;;> ]
;;> @subsubsubsection{Bytecode Objects}
;;> \subsubsubsection{Bytecode Objects}
;;> @itemlist[
;;> @item{@scheme{(bytecode-name bc)} - the macro procedure}
;;> @item{@scheme{(bytecode-literals bc)} - literals the bytecode references}
;;> @item{@scheme{(bytecode-source bc)} - the source location the procedure was defined in}
;;> \itemlist[
;;> \item{\scheme{(bytecode-name bc)} - the macro procedure}
;;> \item{\scheme{(bytecode-literals bc)} - literals the bytecode references}
;;> \item{\scheme{(bytecode-source bc)} - the source location the procedure was defined in}
;;> ]
;;> @subsubsubsection{Syntactic Closures}
;;> \subsubsubsection{Syntactic Closures}
;;> @itemlist[
;;> @item{@scheme{(syntactic-closure-env sc)}}
;;> @item{@scheme{(syntactic-closure-vars sc)}}
;;> @item{@scheme{(syntactic-closure-expr sc)}}
;;> \itemlist[
;;> \item{\scheme{(syntactic-closure-env sc)}}
;;> \item{\scheme{(syntactic-closure-vars sc)}}
;;> \item{\scheme{(syntactic-closure-expr sc)}}
;;> ]
;;> Return the environment, free variables, and expression
;;> associated with @var{sc} respectively.
;;> associated with \var{sc} respectively.
;;> @subsubsubsection{Exceptions}
;;> \subsubsubsection{Exceptions}
;;> @itemlist[
;;> @item{@scheme{(exception-kind exn)}}
;;> @item{@scheme{(exception-message exn)}}
;;> @item{@scheme{(exception-irritants exn)}}
;;> \itemlist[
;;> \item{\scheme{(exception-kind exn)}}
;;> \item{\scheme{(exception-message exn)}}
;;> \item{\scheme{(exception-irritants exn)}}
;;> ]
;;> Return the kind, message, and irritants
;;> associated with @var{exn} respectively.
;;> associated with \var{exn} respectively.
;;> @subsubsubsection{Lambdas}
;;> \subsubsubsection{Lambdas}
;;> @itemlist[
;;> @item{@scheme{(lambda-name lam)} - the name of the lambda, if known}
;;> @item{@scheme{(lambda-name-set! lam x)}}
;;> @item{@scheme{(lambda-params lam)} - the lambda parameter list}
;;> @item{@scheme{(lambda-params-set! lam x)}}
;;> @item{@scheme{(lambda-body lam)} - the body of the lambda}
;;> @item{@scheme{(lambda-body-set! lam x)}}
;;> @item{@scheme{(lambda-defs lam)} - internal definitions of the lambda}
;;> @item{@scheme{(lambda-defs-set! lam x)}}
;;> @item{@scheme{(lambda-locals lam)} - local variables as a list of identifiers}
;;> @item{@scheme{(lambda-locals-set! lam x)}}
;;> @item{@scheme{(lambda-flags lam)} - various flags describing the lambda}
;;> @item{@scheme{(lambda-flags-set! lam x)}}
;;> @item{@scheme{(lambda-free-vars lam)} - free variables the lambda will need to close over}
;;> @item{@scheme{(lambda-free-vars-set! lam x)}}
;;> @item{@scheme{(lambda-set-vars lam)} - variables the lambda mutates}
;;> @item{@scheme{(lambda-set-vars-set! lam x)}}
;;> @item{@scheme{(lambda-return-type lam)} - the return type of the lambda}
;;> @item{@scheme{(lambda-return-type-set! lam x)}}
;;> @item{@scheme{(lambda-param-types lam)} - the types of the input parameters}
;;> @item{@scheme{(lambda-param-types-set! lam x)}}
;;> @item{@scheme{(lambda-source lam)} - the source code of the lambda}
;;> @item{@scheme{(lambda-source-set! lam x)}}
;;> \itemlist[
;;> \item{\scheme{(lambda-name lam)} - the name of the lambda, if known}
;;> \item{\scheme{(lambda-name-set! lam x)}}
;;> \item{\scheme{(lambda-params lam)} - the lambda parameter list}
;;> \item{\scheme{(lambda-params-set! lam x)}}
;;> \item{\scheme{(lambda-body lam)} - the body of the lambda}
;;> \item{\scheme{(lambda-body-set! lam x)}}
;;> \item{\scheme{(lambda-defs lam)} - internal definitions of the lambda}
;;> \item{\scheme{(lambda-defs-set! lam x)}}
;;> \item{\scheme{(lambda-locals lam)} - local variables as a list of identifiers}
;;> \item{\scheme{(lambda-locals-set! lam x)}}
;;> \item{\scheme{(lambda-flags lam)} - various flags describing the lambda}
;;> \item{\scheme{(lambda-flags-set! lam x)}}
;;> \item{\scheme{(lambda-free-vars lam)} - free variables the lambda will need to close over}
;;> \item{\scheme{(lambda-free-vars-set! lam x)}}
;;> \item{\scheme{(lambda-set-vars lam)} - variables the lambda mutates}
;;> \item{\scheme{(lambda-set-vars-set! lam x)}}
;;> \item{\scheme{(lambda-return-type lam)} - the return type of the lambda}
;;> \item{\scheme{(lambda-return-type-set! lam x)}}
;;> \item{\scheme{(lambda-param-types lam)} - the types of the input parameters}
;;> \item{\scheme{(lambda-param-types-set! lam x)}}
;;> \item{\scheme{(lambda-source lam)} - the source code of the lambda}
;;> \item{\scheme{(lambda-source-set! lam x)}}
;;> ]
;;> @subsubsubsection{Conditionals}
;;> \subsubsubsection{Conditionals}
;;> @itemlist[
;;> @item{@scheme{(cnd-test cnd)} - the test for the conditional}
;;> @item{@scheme{(cnd-test-set! cnd x)}}
;;> @item{@scheme{(cnd-pass cnd)} - the success branch}
;;> @item{@scheme{(cnd-pass-set! cnd x)}}
;;> @item{@scheme{(cnd-fail cnd)} - the failure branch}
;;> @item{@scheme{(cnd-fail-set! cnd x)}}
;;> \itemlist[
;;> \item{\scheme{(cnd-test cnd)} - the test for the conditional}
;;> \item{\scheme{(cnd-test-set! cnd x)}}
;;> \item{\scheme{(cnd-pass cnd)} - the success branch}
;;> \item{\scheme{(cnd-pass-set! cnd x)}}
;;> \item{\scheme{(cnd-fail cnd)} - the failure branch}
;;> \item{\scheme{(cnd-fail-set! cnd x)}}
;;> ]
;;> @subsubsubsection{Sequences}
;;> \subsubsubsection{Sequences}
;;> @itemlist[
;;> @item{@scheme{(seq-ls seq)} - the list of sequence expressions}
;;> @item{@scheme{(seq-ls-set! seq x)}}
;;> \itemlist[
;;> \item{\scheme{(seq-ls seq)} - the list of sequence expressions}
;;> \item{\scheme{(seq-ls-set! seq x)}}
;;> ]
;;> @subsubsubsection{References}
;;> \subsubsubsection{References}
;;> @itemlist[
;;> @item{@scheme{(ref-name ref)} - the name of the referenced variable}
;;> @item{@scheme{(ref-name-set! ref x)}}
;;> @item{@scheme{(ref-cell ref)} - the environment cell the reference resolves to}
;;> @item{@scheme{(ref-cell-set! ref x)}}
;;> \itemlist[
;;> \item{\scheme{(ref-name ref)} - the name of the referenced variable}
;;> \item{\scheme{(ref-name-set! ref x)}}
;;> \item{\scheme{(ref-cell ref)} - the environment cell the reference resolves to}
;;> \item{\scheme{(ref-cell-set! ref x)}}
;;> ]
;;> @subsubsubsection{Mutations}
;;> \subsubsubsection{Mutations}
;;> @itemlist[
;;> @item{@scheme{(set-var set)} - a reference to the mutated variable}
;;> @item{@scheme{(set-var-set! set x)}}
;;> @item{@scheme{(set-value set)} - the value to set the variable to}
;;> @item{@scheme{(set-value-set! set x)}}
;;> \itemlist[
;;> \item{\scheme{(set-var set)} - a reference to the mutated variable}
;;> \item{\scheme{(set-var-set! set x)}}
;;> \item{\scheme{(set-value set)} - the value to set the variable to}
;;> \item{\scheme{(set-value-set! set x)}}
;;> ]
;;> @subsubsubsection{Literals}
;;> \subsubsubsection{Literals}
;;> @itemlist[
;;> @item{@scheme{(lit-value lit)} - the literal value}
;;> @item{@scheme{(lit-value-set! lit x)}}
;;> \itemlist[
;;> \item{\scheme{(lit-value lit)} - the literal value}
;;> \item{\scheme{(lit-value-set! lit x)}}
;;> ]
;;> @subsubsubsection{Pairs}
;;> \subsubsubsection{Pairs}
;;> @itemlist[
;;> @item{@scheme{(pair-source x)}}
;;> @item{@scheme{(pair-source-set! x source)}}
;;> \itemlist[
;;> \item{\scheme{(pair-source x)}}
;;> \item{\scheme{(pair-source-set! x source)}}
;;> ]
;;> Set or return the source code info associated with a pair x.
;;> Source info is represented as another pair whose @var{car} is
;;> the source file name and whose @var{cdr} is the line number.
;;> Source info is represented as another pair whose \var{car} is
;;> the source file name and whose \var{cdr} is the line number.
;;> @subsubsection{Miscellaneous Utilities}
;;> \subsubsection{Miscellaneous Utilities}
;;> @subsubsubsection{@scheme{(gc)}}
;;> \subsubsubsection{\scheme{(gc)}}
;;> Force a garbage collection.
;;> @subsubsubsection{@scheme{(object-size x)}}
;;> \subsubsubsection{\scheme{(object-size x)}}
;;> Returns the heap space directly used by @var{x}, not
;;> counting any elements of @var{x}.
;;> Returns the heap space directly used by \var{x}, not
;;> counting any elements of \var{x}.
;;> @subsubsubsection{@scheme{(integer->immediate n)}}
;;> \subsubsubsection{\scheme{(integer->immediate n)}}
;;> Returns the interpretation of the integer @var{n} as
;;> Returns the interpretation of the integer \var{n} as
;;> an immediate object, useful for debugging.
;;> @subsubsubsection{@scheme{(string-contains str pat)}}
;;> \subsubsubsection{\scheme{(string-contains str pat)}}
;;> Returns the first string cursor of @var{pat} in @var{str},
;;> of @scheme{#f} if it's not found.
;;> Returns the first string cursor of \var{pat} in \var{str},
;;> of \scheme{#f} if it's not found.
;;> @subsubsubsection{@scheme{(atomically expr)}}
;;> \subsubsubsection{\scheme{(atomically expr)}}
;;> Run @var{expr} atomically, disabling yields. Ideally should only be
;;> Run \var{expr} atomically, disabling yields. Ideally should only be
;;> used for brief, deterministic expressions. If used incorrectly (e.g.
;;> running an infinite loop) can render the system unusable.
;;> Never expose to a sandbox.

View file

@ -11,7 +11,7 @@
;;> loading these collections from files while allowing extensions
;;> such as configurations from command-line options.
;;> @subsubsection{Background}
;;> \subsubsection{Background}
;;>
;;> As any application grows to sufficient complexity, it acquires
;;> options and behaviors that one may want to modify at startup or
@ -19,17 +19,17 @@
;;> command-line options, config files, environment variables, and/or
;;> other specialized settings. These all have various pros and cons:
;;>
;;> @table[(@|@| (border 1) (style border-collapse:collapse) (width "100%"))]{
;;> @tr{@th{name} @th{pros} @th{cons}}
;;> @tr{@td{environment variables}
;;> @td{implicit - no need to retype; can share between applications}
;;> @td{unclear when set; unexpected differences between users; limited size}}
;;> @tr{@td{command-line options}
;;> @td{explicit - visible each time a command is run; }
;;> @td{verbose; limited size}}
;;> @tr{@td{config files}
;;> @td{implicit; preserved - can be shared and version controlled}
;;> @td{requires a parser}}
;;> \table[(@ (border 1) (style border-collapse:collapse) (width "100%"))]{
;;> \tr{\th{name} \th{pros} \th{cons}}
;;> \tr{\td{environment variables}
;;> \td{implicit - no need to retype; can share between applications}
;;> \td{unclear when set; unexpected differences between users; limited size}}
;;> \tr{\td{command-line options}
;;> \td{explicit - visible each time a command is run; }
;;> \td{verbose; limited size}}
;;> \tr{\td{config files}
;;> \td{implicit; preserved - can be shared and version controlled}
;;> \td{requires a parser}}
;;> }
;;>
;;> Environment variables are convenient for broad preferences, used
@ -40,7 +40,7 @@
;;> users of a group or whole system are likely to want to share, then
;;> it makes sense to cascade multiple config files.
;;> @subsubsection{Syntax}
;;> \subsubsection{Syntax}
;;>
;;> With any other language there is a question of config file syntax,
;;> and a few popular choices exist such as .ini syntax. With Scheme
@ -49,31 +49,31 @@
;;> arbitrary sexps for values. The alists are intended primarily for
;;> editing by hand and need not be dotted, but the interface allows
;;> dotted values. Disambiguation is handled as with two separate
;;> functions, @scheme{(conf-get config key)} and
;;> @scheme{(conf-get-list config key)}, which both retrieve the value
;;> associated with @var{key} from @var{config}, in the latter case
;;> functions, \scheme{(conf-get config key)} and
;;> \scheme{(conf-get-list config key)}, which both retrieve the value
;;> associated with \var{key} from \var{config}, in the latter case
;;> coercing to a list. The result is determined according to the
;;> structure of the alist cell as follows:
;;>
;;> @table[(@|@| (border 1) (style border-collapse:collapse) (width "100%"))]{
;;> @tr{@th{Cell} @th{@scheme{conf-get} result} @th{@scheme{conf-get-list} result}}
;;> @tr{@td{@scheme{(key)}} @td{@scheme{()}} @td{@scheme{()}}}
;;> @tr{@td{@scheme{(key . non-list-value)}} @td{@scheme{non-list-value}} @td{@scheme{(non-list-value)}}}
;;> @tr{@td{@scheme{(key non-list-value)}} @td{@scheme{non-list-value}} @td{@scheme{(non-list-value)}}}
;;> @tr{@td{@scheme{(key (value1 value2 ...))}} @td{@scheme{(value1 value2 ...)}} @td{@scheme{(value1 value2 ...)}}}
;;> @tr{@td{@scheme{(key value1 value2 ...)}} @td{@scheme{(value1 value2 ...)}} @td{@scheme{(value1 value2 ...)}}}
;;> \table[(@ (border 1) (style border-collapse:collapse) (width "100%"))]{
;;> \tr{\th{Cell} \th{\scheme{conf-get} result} \th{\scheme{conf-get-list} result}}
;;> \tr{\td{\scheme{(key)}} \td{\scheme{()}} \td{\scheme{()}}}
;;> \tr{\td{\scheme{(key . non-list-value)}} \td{\scheme{non-list-value}} \td{\scheme{(non-list-value)}}}
;;> \tr{\td{\scheme{(key non-list-value)}} \td{\scheme{non-list-value}} \td{\scheme{(non-list-value)}}}
;;> \tr{\td{\scheme{(key (value1 value2 ...))}} \td{\scheme{(value1 value2 ...)}} \td{\scheme{(value1 value2 ...)}}}
;;> \tr{\td{\scheme{(key value1 value2 ...)}} \td{\scheme{(value1 value2 ...)}} \td{\scheme{(value1 value2 ...)}}}
;;> }
;;>
;;> Thus writing the non-dotted value will always do what you want.
;;> Specifically, the only thing to be careful of is if you want a
;;> single-element list value, even with @scheme{conf-get}, you should
;;> write @scheme{(key (value))}.
;;> single-element list value, even with \scheme{conf-get}, you should
;;> write \scheme{(key (value))}.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;> @subsubsection{Interface}
;;> \subsubsection{Interface}
;;> Returns true iff @var{x} is a config object.
;;> Returns true iff \var{x} is a config object.
(define-record-type Config
(make-conf alist parent source timestamp)
@ -112,7 +112,7 @@
(define (alist? x)
(and (list? x) (every pair? x)))
;;> Returns just the base of @var{config} without any parent.
;;> Returns just the base of \var{config} without any parent.
(define (conf-head config)
(make-conf
@ -121,9 +121,9 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Loading from files.
;;> @subsubsubsection{@rawcode{(conf-load file [conf])}}
;;> \subsubsubsection{\rawcode{(conf-load file [conf])}}
;;> Loads the config file @var{file}, prepending to @var{conf} if
;;> Loads the config file \var{file}, prepending to \var{conf} if
;;> provided.
(define (conf-load file . o)
@ -133,8 +133,8 @@
file
(current-second)))
;;> Search for and load any files named @var{file} in the
;;> @var{config-path}, which should be a list of strings.
;;> Search for and load any files named \var{file} in the
;;> \var{config-path}, which should be a list of strings.
(define (conf-load-in-path config-path file)
(cond
@ -151,11 +151,11 @@
(lp (cdr ls) (conf-load path res))
(lp (cdr ls) res))))))))
;;> @subsubsubsection{@rawcode{(conf-load-cascaded config-path file [include-keyword])}}
;;> \subsubsubsection{\rawcode{(conf-load-cascaded config-path file [include-keyword])}}
;;> Similar to conf-load-in-path, but also recursively loads any
;;> "include" config files, indicated by a top-level
;;> @var{include-keyword} with either a string or symbol value.
;;> \var{include-keyword} with either a string or symbol value.
;;> Includes are loaded relative to the current file, and cycles
;;> automatically ignored.
@ -213,11 +213,11 @@
(or (assq key (conf-alist config))
(search (conf-parent config))))))))
;;> @subsubsubsection{@rawcode{(conf-get config key [default])}}
;;> \subsubsubsection{\rawcode{(conf-get config key [default])}}
;;> Basic config lookup - retrieves the value from @var{config}
;;> associated with @var{key}. If not present, return @var{default}.
;;> In @scheme{conf-get} and related accessors @var{key} can be either
;;> Basic config lookup - retrieves the value from \var{config}
;;> associated with \var{key}. If not present, return \var{default}.
;;> In \scheme{conf-get} and related accessors \var{key} can be either
;;> a symbol, or a list of symbols. In the latter case, each symbol
;;> is used as a key in turn, with the value taken as an alist to
;;> further lookup values in.
@ -230,9 +230,9 @@
(cadr cell)
(cdr cell)))))
;;> @subsubsubsection{@rawcode{(conf-get-list config key [default])}}
;;> \subsubsubsection{\rawcode{(conf-get-list config key [default])}}
;;> Equivalent to @scheme{conf-get} but coerces its result to a list
;;> Equivalent to \scheme{conf-get} but coerces its result to a list
;;> as described in the syntax section.
(define (conf-get-list config key . opt)
@ -241,7 +241,7 @@
(if (or (pair? res) (null? res)) res (list res))
(if (pair? opt) (car opt) '()))))
;;> Equivalent to @scheme{conf-get-list} but returns a list of all
;;> Equivalent to \scheme{conf-get-list} but returns a list of all
(define (conf-get-multi config key)
(if (not config)
@ -263,7 +263,7 @@
(make-conf (conf-alist a) parent (conf-source a) (conf-timestamp a))))
;;> Utility to create an alist cell representing the chained key
;;> @var{key} mapped to @var{value}.
;;> \var{key} mapped to \var{value}.
(define (conf-unfold-key key value)
(if (null? (cdr key))
@ -310,7 +310,7 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;> @subsubsection{Config Verification}
;;> \subsubsection{Config Verification}
(define (conf-default-warn . args)
(for-each

View file

@ -1,7 +1,7 @@
;;> Cycle-aware equality. Returns @scheme{#t} iff @scheme{a} and
;;> @scheme{b} are @scheme{equal?}, including cycles. Another way
;;> to think of it is they are @scheme{equiv} if they print the
;;> Cycle-aware equality. Returns \scheme{#t} iff \scheme{a} and
;;> \scheme{b} are \scheme{equal?}, including cycles. Another way
;;> to think of it is they are \scheme{equiv} if they print the
;;> same, assuming all elements can be printed.
(define (equiv? a b)

View file

@ -2,11 +2,11 @@
;; Copyright (c) 2009-2012 Alex Shinn. All rights reserved.
;; BSD-style license: http://synthcode.com/license.txt
;;> The fundamental directory iterator. Applies @var{kons} to
;;> each filename in directory @var{dir} and the result of the
;;> previous application, beginning with @var{knil}. With
;;> @var{kons} as @scheme{cons} and @var{knil} as @scheme{'()},
;;> equivalent to @scheme{directory-files}.
;;> The fundamental directory iterator. Applies \var{kons} to
;;> each filename in directory \var{dir} and the result of the
;;> previous application, beginning with \var{knil}. With
;;> \var{kons} as \scheme{cons} and \var{knil} as \scheme{'()},
;;> equivalent to \scheme{directory-files}.
(define (directory-fold dir kons knil)
(let ((dir (opendir dir)))
@ -14,7 +14,7 @@
(let ((file (readdir dir)))
(if file (lp (kons (dirent-name file) res)) res)))))
;;> Returns a list of the files in @var{dir} in an unspecified
;;> Returns a list of the files in \var{dir} in an unspecified
;;> order.
(define (directory-files dir)
@ -47,16 +47,16 @@
(else
(here file acc))))))
;;> Unlinks the file named @var{string} from the filesystem.
;;> Returns @scheme{#t} on success and @scheme{#f} on failure.
;;> Unlinks the file named \var{string} from the filesystem.
;;> Returns \scheme{#t} on success and \scheme{#f} on failure.
(define (delete-file file)
(if (not (%delete-file file))
(raise-continuable
(make-exception 'file "couldn't delete file" file delete-file #f))))
;;> Recursively delete all files and directories under @var{dir}.
;;> Unless optional arg @var{ignore-errors?} is true, raises an error
;;> Recursively delete all files and directories under \var{dir}.
;;> Unless optional arg \var{ignore-errors?} is true, raises an error
;;> if any file can't be deleted.
(define (delete-file-hierarchy dir . o)
@ -73,8 +73,8 @@
(if (and (not (delete-file f)) (not ignore-errors?))
(error "couldn't delete file" f))))))
;;> Runs @var{thunk} with the current directory of the process temporarily
;;> set to @var{dir}.
;;> Runs \var{thunk} with the current directory of the process temporarily
;;> set to \var{dir}.
(define (with-directory dir thunk)
(let ((pwd (current-directory)))
@ -83,7 +83,7 @@
thunk
(lambda () (change-directory pwd)))))
;;> Returns the @scheme{status} object for the given @var{file},
;;> Returns the \scheme{status} object for the given \var{file},
;;> which should be a string indicating the path or a file
;;> descriptor.
@ -104,7 +104,7 @@
(define (file-modification-time x) (stat-mtime (if (stat? x) x (file-status x))))
(define (file-change-time x) (stat-ctime (if (stat? x) x (file-status x))))
;;> File status accessors. @var{x} should be a string indicating
;;> File status accessors. \var{x} should be a string indicating
;;> the file to lookup the status for, or an existing status object.
;;/
@ -117,14 +117,14 @@
(define (file-socket? x) (S_ISSOCK (file-mode x)))
(define (file-exists? x) (and (file-status x) #t))
;;> File type tests. @var{x} should be a string indicating the
;;> File type tests. \var{x} should be a string indicating the
;;> file to lookup the status for, or an existing status object.
;;> Returns @scheme{#t} if the file exists and the given type
;;> is satisfied, and @scheme{#f} otherwise.
;;> Returns \scheme{#t} if the file exists and the given type
;;> is satisfied, and \scheme{#f} otherwise.
;;/
;;> Equivalent to duplicating the file descriptor @var{old} to
;;> @var{new} and closing @var{old}.
;;> Equivalent to duplicating the file descriptor \var{old} to
;;> \var{new} and closing \var{old}.
(define (renumber-file-descriptor old new)
(and (duplicate-file-descriptor-to old new)

View file

@ -1,5 +1,5 @@
;;> Define a new generic function named @var{name}.
;;> Define a new generic function named \var{name}.
(define-syntax define-generic
(syntax-rules ()
@ -16,9 +16,9 @@
(let-syntax ((call))
. body))))))
;;> @subsubsubsection{(define-method (name (param type) ...) body ...)}
;;> \subsubsubsection{(define-method (name (param type) ...) body ...)}
;;> Extends the generic function @var{name} with a new method that
;;> Extends the generic function \var{name} with a new method that
;;> applies when the given param types all match.
(define-syntax define-method
@ -46,7 +46,7 @@
(define add-method-tag (list 'add-method-tag))
;;> Create a new first-class generic function named @var{name}.
;;> Create a new first-class generic function named \var{name}.
(define (make-generic name)
(let ((name name)
@ -85,9 +85,9 @@
(vector-set! res plen (cons (cons preds f) (vector-ref res plen)))
res)))
;;> Extend the generic @var{g} with a new method @var{f}
;;> Extend the generic \var{g} with a new method \var{f}
;;> that applies when all parameters match the given list
;;> of predicates @var{preds}.
;;> of predicates \var{preds}.
(define (generic-add! g preds f)
(g add-method-tag preds f))

View file

@ -15,14 +15,14 @@
;;> Returns an sxml structure representing the code from source
;;> with various language constructs wrapped in highlighting
;;> forms. @var{source} should be a string or port. The
;;> forms. \var{source} should be a string or port. The
;;> language to highlight for is auto-detected.
(define (highlight source)
(let ((str (if (string? source) source (port->string source))))
((highlighter-for (highlight-detect-language str)) str)))
;;> Attempst to auto-detect which language @var{str} is code
;;> Attempst to auto-detect which language \var{str} is code
;;> for, and returns a symbol representing that language.
(define (highlight-detect-language str)
@ -68,8 +68,8 @@
'("#AAAAAA" "#888888" "#666666" "#444444" "#222222" "#000000"))
;;> Returns a string representing the CSS needed for the output
;;> of @var{highlight}. This should be included in a referenced
;;> CSS file, or in a @var{<script>} section in the generated in
;;> of \var{highlight}. This should be included in a referenced
;;> CSS file, or in a \var{<script>} section in the generated in
;;> the generated HTML output.
(define (highlight-style . theme)

View file

@ -11,9 +11,9 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; association lists
;;> @subsubsubsection{@scheme{(assq-ref ls key [default])}}
;;> Returns the @scheme{cdr} of the cell in @var{ls} whose
;;> @scheme{car} is @scheme{eq?} to @var{key}, or @var{default}
;;> \subsubsubsection{\scheme{(assq-ref ls key [default])}}
;;> Returns the \scheme{cdr} of the cell in \var{ls} whose
;;> \scheme{car} is \scheme{eq?} to \var{key}, or \var{default}
;;> if not found. Useful for retrieving values associated with
;;> MIME headers.
@ -81,24 +81,24 @@
(string-for-each (lambda (ch) (write-char (char-downcase ch) out)) s))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;> @subsubsection{RFC2822 Headers}
;;> \subsubsection{RFC2822 Headers}
;;> @subsubsubsection{@scheme{(mime-header-fold kons knil [source [limit [kons-from]]])}}
;;> \subsubsubsection{\scheme{(mime-header-fold kons knil [source [limit [kons-from]]])}}
;;>
;;> Performs a fold operation on the MIME headers of source which can be
;;> either a string or port, and defaults to current-input-port. @var{kons}
;;> either a string or port, and defaults to current-input-port. \var{kons}
;;> is called on the three values:
;;> @scheme{(kons header value accumulator)}
;;> where accumulator begins with @var{knil}. Neither the header nor the
;;> \scheme{(kons header value accumulator)}
;;> where accumulator begins with \var{knil}. Neither the header nor the
;;> value are modified, except wrapped lines are handled for the value.
;;>
;;> The optional procedure @var{kons-from} is a procedure to be called when
;;> The optional procedure \var{kons-from} is a procedure to be called when
;;> the first line of the headers is an "From <address> <date>" line, to
;;> enable this procedure to be used as-is on mbox files and the like.
;;> It defaults to @var{kons}, and if such a line is found the fold will begin
;;> with @scheme{(kons-from "%from" <address> (kons-from "%date" <date> knil))}.
;;> It defaults to \var{kons}, and if such a line is found the fold will begin
;;> with \scheme{(kons-from '%from <address> (kons-from '%date <date> knil))}.
;;>
;;> The optional @var{limit} gives a limit on the number of headers to read.
;;> The optional \var{limit} gives a limit on the number of headers to read.
(define (mime-header-fold kons knil . o)
(let ((src (and (pair? o) (car o)))
@ -147,7 +147,7 @@
(else
(out first-line knil 0)))))
;;> @subsubsubsection{@scheme{(mime-headers->list [source])}}
;;> \subsubsubsection{\scheme{(mime-headers->list [source])}}
;;> Return an alist of the MIME headers from source with headers all
;;> downcased.
@ -170,11 +170,11 @@
(substring s (+ i 1) (string-length s)))))
(cons (string->symbol (string-downcase (string-trim s))) ""))))
;;> @subsubsubsection{@scheme{(mime-parse-content-type str)}}
;;> Parses @var{str} as a Content-Type style-value returning the list
;;> @scheme{(type (attr . val) ...)}.
;;> \subsubsubsection{\scheme{(mime-parse-content-type str)}}
;;> Parses \var{str} as a Content-Type style-value returning the list
;;> \scheme{(type (attr . val) ...)}.
;;> @example{
;;> \example{
;;> (mime-parse-content-type "text/html; CHARSET=UTF-8; filename=index.html")
;;> }
@ -184,8 +184,8 @@
(cons (caar res) (cdr res))
res)))
;;> @subsubsubsection{@scheme{(mime-decode-header str)}}
;;> Replace all occurrences of RFC1522 =?ENC?...?= escapes in @var{str} with
;;> \subsubsubsection{\scheme{(mime-decode-header str)}}
;;> Replace all occurrences of RFC1522 =?ENC?...?= escapes in \var{str} with
;;> the appropriate decoded and charset converted value.
(define (mime-decode-header str)
@ -246,19 +246,19 @@
(lambda (x) (next (mime-convert-part x cte enc)))
(lambda (x) (final (mime-convert-part x cte enc)))))
;;> @subsubsection{RFC2045 MIME Encoding}
;;> \subsubsection{RFC2045 MIME Encoding}
;;> @subsubsubsection{@scheme{(mime-message-fold src kons knil [start end headers])}}
;;> Performs a fold operation on the given string or port @var{src} as a
;;> MIME body corresponding to the headers give in @var{headers}. @var{kons}
;;> \subsubsubsection{\scheme{(mime-message-fold src kons knil [start end headers])}}
;;> Performs a fold operation on the given string or port \var{src} as a
;;> MIME body corresponding to the headers give in \var{headers}. \var{kons}
;;> is called on the successive values:
;;>
;;> @schemeblock{(kons parent-headers part-headers part-body accumulator)}
;;> \schemeblock{(kons parent-headers part-headers part-body accumulator)}
;;>
;;> where @var{part-headers} are the headers for the given MIME part (the
;;> original headers for single-part MIME), @var{part-body} is the
;;> where \var{part-headers} are the headers for the given MIME part (the
;;> original headers for single-part MIME), \var{part-body} is the
;;> appropriately decoded and charset-converted body of the message,
;;> and the @var{accumulator} begins with @var{knil}.
;;> and the \var{accumulator} begins with \var{knil}.
(define (mime-message-fold src kons init-seed . o)
(let ((port (if (string? src) (open-input-string src) src)))
@ -314,11 +314,11 @@
(lambda (x) (next (kons parent-headers headers x seed)))
(lambda (x) (final (kons parent-headers headers x seed)))))))))))
;;> @subsubsubsection{@scheme{(mime-message->sxml [src])}}
;;> \subsubsubsection{\scheme{(mime-message->sxml [src])}}
;;>
;;> Parse the given source as a MIME message and return
;;> the result as an SXML object of the form:
;;> @scheme{(mime (@ (header . value) ...) parts ...)}.
;;> \scheme{(mime (@ (header . value) ...) parts ...)}.
(define (mime-message->sxml . o)
(car

View file

@ -1,11 +1,11 @@
;; Copyright (c) 2010-2012 Alex Shinn. All rights reserved.
;; BSD-style license: http://synthcode.com/license.txt
;;> @subsubsubsection{@scheme{(get-address-info host service [addrinfo])}}
;;> \subsubsubsection{\scheme{(get-address-info host service [addrinfo])}}
;;> Create and return a new addrinfo structure for the given host
;;> and service. @var{host} should be a string and @var{service} a
;;> string or integer. The optional @var{addrinfo} defaults to
;;> and service. \var{host} should be a string and \var{service} a
;;> string or integer. The optional \var{addrinfo} defaults to
;;> a TCP/IP stream setting.
(define (get-address-info host service . o)
@ -17,11 +17,11 @@
socket-type/stream
ip-proto/tcp))))
;;> Opens a client net connection to @var{host}, a string,
;;> on port @var{service}, which can be a string such as
;;> @scheme{"http"} or an integer. Returns a list of three
;;> Opens a client net connection to \var{host}, a string,
;;> on port \var{service}, which can be a string such as
;;> \scheme{"http"} or an integer. Returns a list of three
;;> values on success - the socket, an input port, and an
;;> output port - or @scheme{#f} on failure.
;;> output port - or \scheme{#f} on failure.
(define (open-net-io host service)
(let lp ((addr (get-address-info host service)))
@ -46,11 +46,11 @@
(open-input-file-descriptor sock #t)
(open-output-file-descriptor sock #t)))))))))
;;> Convenience wrapper around @scheme{open-net-io}, opens
;;> the connection then calls @var{proc} with two arguments,
;;> Convenience wrapper around \scheme{open-net-io}, opens
;;> the connection then calls \var{proc} with two arguments,
;;> the input port and the output port connected to the
;;> service, then closes the connection. Returns the result
;;> of @var{proc}. Raises an error if a connection can't
;;> of \var{proc}. Raises an error if a connection can't
;;> be made.
(define (with-net-io host service proc)
@ -63,13 +63,13 @@
(close-file-descriptor (car io))
res))))
;;> @subsubsubsection{@scheme{(make-listener-socket addrinfo [max-conn])}}
;;> \subsubsubsection{\scheme{(make-listener-socket addrinfo [max-conn])}}
;;> Convenience wrapper to call socket, bind and listen to return
;;> a socket suitable for accepting connections on the given
;;> @var{addrinfo}. @var{max-conn} is the maximum number of pending
;;> \var{addrinfo}. \var{max-conn} is the maximum number of pending
;;> connections, and defaults to 128. Automatically specifies
;;> @scheme{socket-opt/reuseaddr}.
;;> \scheme{socket-opt/reuseaddr}.
(define (make-listener-socket addrinfo . o)
(let* ((max-connections (if (pair? o) (car o) 128))
@ -92,9 +92,9 @@
(else
sock))))
;;> Returns the socket option of the given @var{name} for @var{socket}.
;;> @var{socket} should be a file descriptor, level the constant
;;> @scheme{level/socket}, and name one of the constants beginning with
;;> Returns the socket option of the given \var{name} for \var{socket}.
;;> \var{socket} should be a file descriptor, level the constant
;;> \scheme{level/socket}, and name one of the constants beginning with
;;> "socket-opt/".
(define (get-socket-option socket level name)

View file

@ -31,6 +31,11 @@
(define (symbol->keyword sym)
(string->symbol (string-append (symbol->string sym) ":")))
(define-syntax symbol->keyword*
(syntax-rules ()
((symbol->keyword* sym)
(string->symbol (string-append (symbol->string sym) ":")))))
(define-syntax let-keywords*
(syntax-rules ()
((let-keywords* opt-ls () . body)
@ -38,8 +43,10 @@
((let-keywords* (op . args) vars . body)
(let ((tmp (op . args)))
(let-keywords* tmp vars . body)))
((let-keywords* opt-ls ((var) . rest) . body)
(let-keywords* opt-ls ((var #f) . rest) . body))
((let-keywords* opt-ls ((var default) . rest) . body)
(let ((var (keyword-ref* opt-ls (symbol->keyword 'var) default)))
(let ((var (keyword-ref* opt-ls (symbol->keyword* 'var) default)))
(let-keywords* opt-ls rest . body)))
((let-keywords* opt-ls ((var key default) . rest) . body)
(let ((var (keyword-ref* opt-ls 'key default)))

View file

@ -39,9 +39,9 @@
;; (let ((start (string-scan-right #\/ path (- end 1))))
;; (substring path (if start (+ start 1) 0) (+ end 1)))))))
;;> Returns just the basename of @var{path}, with any directory
;;> removed. If @var{path} does not contain a directory separator,
;;> return the whole @var{path}. If @var{path} ends in a directory
;;> Returns just the basename of \var{path}, with any directory
;;> removed. If \var{path} does not contain a directory separator,
;;> return the whole \var{path}. If \var{path} ends in a directory
;;> separator (i.e. path is a directory) return the empty string.
;; GNU basename
@ -56,8 +56,8 @@
path
(substring path (+ slash 1) len)))))))
;;> Returns just the directory of @var{path}.
;;> If @var{path} is relative, return @scheme{"."}.
;;> Returns just the directory of \var{path}.
;;> If \var{path} is relative, return \scheme{"."}.
(define (path-directory path)
(if (string=? path "")
@ -73,8 +73,8 @@
(define (path-extension-pos path) (string-scan-right #\. path))
;;> Returns the rightmost extension of @var{path}, not including
;;> the @scheme{"."}. If there is no extension, returns @scheme{#f}.
;;> Returns the rightmost extension of \var{path}, not including
;;> the \scheme{"."}. If there is no extension, returns \scheme{#f}.
(define (path-extension path)
(let ((i (path-extension-pos path)))
@ -82,8 +82,8 @@
(let ((start (+ i 1)) (end (string-length path)))
(and (< start end) (substring path start end))))))
;;> Returns @var{path} with the extension, if any, removed,
;;> along with the @scheme{"."}.
;;> Returns \var{path} with the extension, if any, removed,
;;> along with the \scheme{"."}.
(define (path-strip-extension path)
(let ((i (path-extension-pos path)))
@ -91,18 +91,18 @@
(substring path 0 i)
path)))
;;> Returns @var{path} with the extension, if any, replaced
;;> with @var{ext}.
;;> Returns \var{path} with the extension, if any, replaced
;;> with \var{ext}.
(define (path-replace-extension path ext)
(string-append (path-strip-extension path) "." ext))
;;> Returns @scheme{#t} iff @var{path} is an absolute path.
;;> Returns \scheme{#t} iff \var{path} is an absolute path.
(define (path-absolute? path)
(and (not (string=? "" path)) (eqv? #\/ (string-ref path 0))))
;;> Returns @scheme{#t} iff @var{path} is a relative path.
;;> Returns \scheme{#t} iff \var{path} is a relative path.
(define (path-relative? path) (not (path-absolute? path)))
@ -114,7 +114,7 @@
;;> separators removed and "/./" and "x/../" references removed.
;;> Does not take symbolic links into account - this is meant to
;;> be abstract and applicable to paths on remote systems and in
;;> URIs. Returns @var{path} itself if @var{path} is already
;;> URIs. Returns \var{path} itself if \var{path} is already
;;> normalized.
(define (path-normalize path)
@ -184,7 +184,7 @@
path
((if (eqv? #\/ (string-ref path 0)) boundary inside) 0 1 '()))))
;;> Return a new string representing the path where each of @var{args}
;;> Return a new string representing the path where each of \var{args}
;;> is a path component, separated with the directory separator.
(define (make-path . args)

View file

@ -9,7 +9,7 @@
;;> editing and signal handling, so that C-c will interrupt a
;;> computation and bring you back to the REPL prompt. To use
;;> this repl, run
;;> @command{chibi-scheme -mchibi.repl -e'(repl)'}
;;> \command{chibi-scheme -mchibi.repl -e'(repl)'}
;;> from the command line or within Emacs.
(define (with-signal-handler sig handler thunk)
@ -130,39 +130,39 @@
;;> Runs an interactive REPL. Repeatedly displays a prompt,
;;> then Reads an expression, Evaluates the expression, Prints
;;> the result then Loops. Terminates when the end of input is
;;> reached or the @scheme|{@exit}| command is given.
;;> reached or the \scheme|{\exit}| command is given.
;;>
;;> Basic Emacs-style line editing with persistent history
;;> completion is provided. C-c can be used to interrupt the
;;> current computation and drop back to the prompt. The
;;> following keyword arguments customize the REPL:
;;>
;;> @itemlist[
;;> @item{@scheme{in:} - the input port (default @scheme{(current-input-port)})}
;;> @item{@scheme{out:} - the output port (default @scheme{(current-output-port)})}
;;> @item{@scheme{module:} - the initial module}
;;> @item{@scheme{environment:} - the initial environment (default @scheme{(interaction-environment)})}
;;> @item{@scheme{escape:} - the command escape character (default @scheme|{#\@}|)}
;;> @item{@scheme{make-prompt:} - a procedure taking one argument (the current module name as a list) and returning a string to be used as the prompt}
;;> @item{@scheme{history:} - the initial command history}
;;> @item{@scheme{history-file:} - the file to save history to (default ~/.chibi-repl-history)}
;;> \itemlist[
;;> \item{\scheme{in:} - the input port (default \scheme{(current-input-port)})}
;;> \item{\scheme{out:} - the output port (default \scheme{(current-output-port)})}
;;> \item{\scheme{module:} - the initial module}
;;> \item{\scheme{environment:} - the initial environment (default \scheme{(interaction-environment)})}
;;> \item{\scheme{escape:} - the command escape character (default \scheme|{#\\}|)}
;;> \item{\scheme{make-prompt:} - a procedure taking one argument (the current module name as a list) and returning a string to be used as the prompt}
;;> \item{\scheme{history:} - the initial command history}
;;> \item{\scheme{history-file:} - the file to save history to (default ~/.chibi-repl-history)}
;;> ]
;;>
;;> The module: and environment: keyword arguments should not both be given.
;;>
;;> REPL commands in the style of @hyperlink["http://s48.org/"]{Scheme48}
;;> are available to control out-of-band properties. By default a command
;;> is written as an identifier beginning with an "@"@"" character (which
;;> would not be a portable identifier), but this can be customized with
;;> the @scheme{escape:} keyword. The following commands are available:
;;> REPL commands in the style of \hyperlink["http://s48.org/"]{Scheme48}
;;> are available to control out-of-band properties. By default a
;;> command is written as an identifier beginning with an "@"
;;> character, but this can be customized with the \scheme{escape:}
;;> keyword. The following commands are available:
;;>
;;> @itemlist[
;;> @item{@scheme|{@import <import-spec>}| - import the @var{<import-spec>} in the @scheme{interaction-environment}, useful if the @scheme{import} binding is not available}
;;> @item{@scheme|{@import-only <import-spec>}| - replace the @scheme{interaction-environment} with the given @var{<import-spec>}}
;;> @item{@scheme|{@in [<module>]}| - switch to @var{<module>}, or the @scheme{interaction-environment} if @var{<module>} is not specified}
;;> @item{@scheme|{@meta <expr>}| - evaluate @var{<expr>} in the @scheme{(meta)} module}
;;> @item{@scheme|{@meta-module-is <module>}| - switch the meta module to @var{<module>}}
;;> @item{@scheme|{@exit}| - exit the REPL}
;;> \itemlist[
;;> \item{\scheme|{\import <import-spec>}| - import the \var{<import-spec>} in the \scheme{interaction-environment}, useful if the \scheme{import} binding is not available}
;;> \item{\scheme|{\import-only <import-spec>}| - replace the \scheme{interaction-environment} with the given \var{<import-spec>}}
;;> \item{\scheme|{\in [<module>]}| - switch to \var{<module>}, or the \scheme{interaction-environment} if \var{<module>} is not specified}
;;> \item{\scheme|{\meta <expr>}| - evaluate \var{<expr>} in the \scheme{(meta)} module}
;;> \item{\scheme|{\meta-module-is <module>}| - switch the meta module to \var{<module>}}
;;> \item{\scheme|{\exit}| - exit the REPL}
;;> ]
(define-record-type Repl
@ -236,7 +236,7 @@
(define (repl/meta-module-is rp args meta continue)
(cond
((null? (cdr args))
(warn "usage: @meta <module>"))
(warn "usage: @meta-module-is <module>"))
((eval `(load-module ',(cadr args)) (repl-meta-env rp))
=> (lambda (m) (repl-meta-env-set! rp (module-env m))))
(else

View file

@ -2,9 +2,11 @@
;; Copyright (c) 2011 Alex Shinn. All rights reserved.
;; BSD-style license: http://synthcode.com/license.txt
;;> A library used for parsing "scribble" format, introduced
;;> by @hyperlink["http://www.racket-lang.org/"]{Racket} and
;;> the format used to write this manual.
;;> A library used for parsing "scribble" format, introduced by
;;> \hyperlink["http://www.racket-lang.org/"]{Racket} and the format
;;> used to write this manual. The default escape character is
;;> backslash as in TeX instead of @ as in Racket, though this can be
;;> overridden.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; general character utils
@ -21,6 +23,8 @@
(define (char-digit ch) (- (char->integer ch) (char->integer #\0)))
(define default-ecape-char #\\)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; list utils
@ -80,11 +84,14 @@
((char-delimiter? c) (string->symbol (list->string (reverse ls))))
(read-char in)))
(define (scrib-read in)
(define (scrib-read in . o)
(define ch (read-char in))
(define ec (if (pair? o) (car o) default-ecape-char))
(cond
((eof-object? ch) ch)
((char-whitespace? ch) (scrib-read in))
((eqv? ch ec)
(scribble-parse-escape in ec))
(else
(case ch
((#\( #\[ #\{)
@ -106,7 +113,6 @@
((#\') (list 'quote (scrib-read in)))
((#\`) (list 'quasiquote (scrib-read in)))
((#\,) (list (if-peek-char #\@ in 'unquote-splicing 'unquote) (scrib-read in)))
((#\@) (scribble-parse-escape in #\@))
((#\;) (skip-line in) (scrib-read in))
((#\|) (string->symbol (read-escaped in #\|)))
((#\") (read-escaped in #\"))
@ -132,8 +138,8 @@
(read-number in (char-digit ch) 10)
(read-symbol in (list ch))))))))
(define (scribble-read in)
(let ((res (scrib-read in)))
(define (scribble-read in . o)
(let ((res (scrib-read in (if (pair? o) (car o) default-ecape-char))))
(cond ((eq? res scribble-dot) (error "invalid . in source"))
((eq? res scribble-close) (error "too many )'s"))
(else res))))
@ -167,9 +173,9 @@
(define brace-char #\{)
(let* ((wrap (read-prefix-wrapper in))
(c (peek-char in))
(cmd (if (or (eqv? c bracket-char) (eqv? c brace-char)) '() (list (scribble-read in))))
(cmd (if (or (eqv? c bracket-char) (eqv? c brace-char)) '() (list (scribble-read in ec))))
(data? (eqv? (peek-char in) bracket-char))
(data (if data? (scribble-read in) '()))
(data (if data? (scribble-read in ec) '()))
(punc (read-punctuation in))
(body? (eqv? (peek-char in) brace-char))
(body (cond (body? (read-char in) (scribble-parse in punc ec)) (else '()))))
@ -177,7 +183,8 @@
(define (scribble-parse in . o)
(define init-punc (if (pair? o) (car o) '()))
(define escape-char (if (and (pair? o) (pair? (cdr o))) (cadr o) #\@))
(define escape-char
(if (and (pair? o) (pair? (cdr o))) (cadr o) default-ecape-char))
(define comment-char #\;)
(define bracket-char #\[)
(define brace-char #\{)

View file

@ -164,12 +164,12 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; high-level interface
;;> @subsubsubsection{@scheme{(stty [port] args ...)}}
;;> \subsubsubsection{\scheme{(stty [port] args ...)}}
;;> Set the terminal attributes for @var{port} (default
;;> @scheme{(current-output-port)}) to @var{attrs}.
;;> Set the terminal attributes for \var{port} (default
;;> \scheme{(current-output-port)}) to \var{attrs}.
;;> Attributes are specified symbolically using the
;;> names from the @rawcode{stty(1)} command. In addition,
;;> names from the \rawcode{stty(1)} command. In addition,
;;> (not args ...) may be used to negate the listed symbols.
(define (stty . args)
@ -225,7 +225,7 @@
(else
(return iflag oflag cflag lflag))))))
;;> Run @var{thunk} with the @scheme{stty} @var{setting}s in effect
;;> Run \var{thunk} with the \scheme{stty} \var{setting}s in effect
;;> during its dynamic extent, resetting the original settings
;;> when it returns.
@ -242,13 +242,13 @@
;; No terminal attributes means this isn't a tty.
(thunk)))))
;;> Run @var{thunk} with the "raw" (no canonical or echo) options
;;> Run \var{thunk} with the "raw" (no canonical or echo) options
;;> needed for a terminal application.
(define (with-raw-io port thunk)
(with-stty '(not icanon isig echo) thunk port))
;;> Returns the current terminal width in characters of @var{x},
;;> Returns the current terminal width in characters of \var{x},
;;> which must be a port or a file descriptor.
(define (get-terminal-width x)
@ -256,7 +256,7 @@
(and ws (winsize-col ws))))
;;> Returns the current terminal dimensions, as a list of character width
;;> and height, of @var{x}, which must be a port or a file descriptor.
;;> and height, of \var{x}, which must be a port or a file descriptor.
(define (get-terminal-dimensions x)
(let ((ws (ioctl x TIOCGWINSZ)))

View file

@ -1,7 +1,7 @@
;; Copyright (c) 2010-2013 Alex Shinn. All rights reserved.
;; BSD-style license: http://synthcode.com/license.txt
;;> Simple testing framework adapted from the Chicken @scheme{test}
;;> Simple testing framework adapted from the Chicken \scheme{test}
;;> module.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -44,11 +44,11 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; test interface
;;> @subsubsubsection{@scheme{(test [name] expect expr)}}
;;> \subsubsubsection{\scheme{(test [name] expect expr)}}
;;> Evaluate @var{expr} and check that it is @scheme{equal?}
;;> to @var{expect}. @var{name} is used in reporting, and
;;> defaults to a printed summary of @var{expr}.
;;> Evaluate \var{expr} and check that it is \scheme{equal?}
;;> to \var{expect}. \var{name} is used in reporting, and
;;> defaults to a printed summary of \var{expr}.
(define-syntax test
(syntax-rules ()
@ -66,10 +66,10 @@
((test a ...)
(test-syntax-error 'test "test requires 2 or 3 arguments" (test a ...)))))
;;> @subsubsubsection{@scheme{(test-equal equal [name] expect expr)}}
;;> \subsubsubsection{\scheme{(test-equal equal [name] expect expr)}}
;;> Equivalent to test, using @var{equal} for comparison instead of
;;> @scheme{equal?}.
;;> Equivalent to test, using \var{equal} for comparison instead of
;;> \scheme{equal?}.
(define-syntax test-equal
(syntax-rules ()
@ -77,9 +77,9 @@
(parameterize ((current-test-comparator equal))
(test . args)))))
;;> @subsubsubsection{@scheme{(test-assert [name] expr)}}
;;> \subsubsubsection{\scheme{(test-assert [name] expr)}}
;;> Like @scheme{test} but evaluates @var{expr} and checks that it's true.
;;> Like \scheme{test} but evaluates \var{expr} and checks that it's true.
(define-syntax test-assert
(syntax-rules ()
@ -91,18 +91,18 @@
(test-syntax-error 'test-assert "1 or 2 arguments required"
(test a ...)))))
;;> @subsubsubsection{@scheme{(test-not [name] expr)}}
;;> \subsubsubsection{\scheme{(test-not [name] expr)}}
;;> Like @scheme{test} but evaluates @var{expr} and checks that it's false.
;;> Like \scheme{test} but evaluates \var{expr} and checks that it's false.
(define-syntax test-not
(syntax-rules ()
((_ expr) (test-assert (not expr)))
((_ name expr) (test-assert name (not expr)))))
;;> @subsubsubsection{@scheme{(test-values [name] expect expr)}}
;;> \subsubsubsection{\scheme{(test-values [name] expect expr)}}
;;> Like @scheme{test} but @var{expect} and @var{expr} can both
;;> Like \scheme{test} but \var{expect} and \var{expr} can both
;;> return multiple values.
(define-syntax test-values
@ -113,9 +113,9 @@
(test name (call-with-values (lambda () expect) (lambda results results))
(call-with-values (lambda () expr) (lambda results results))))))
;;> @subsubsubsection{@scheme{(test-error [name] expr)}}
;;> \subsubsubsection{\scheme{(test-error [name] expr)}}
;;> Like @scheme{test} but evaluates @var{expr} and checks that it
;;> Like \scheme{test} but evaluates \var{expr} and checks that it
;;> raises an error.
(define-syntax test-error
@ -146,7 +146,7 @@
(var-values . ,(list vars ...))
(key . val) ...)))))
;;> @subsubsubsection{@scheme{(test-exit)}}
;;> \subsubsubsection{\scheme{(test-exit)}}
;;> Exits with a failure status if any tests have failed,
;;> and a successful status otherwise.
@ -157,7 +157,7 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; group interface
;;> Wraps @var{body} as a single test group, which can be filtered
;;> Wraps \var{body} as a single test group, which can be filtered
;;> and summarized separately.
(define-syntax test-group
@ -683,7 +683,7 @@
(test-equal? (real-part expect) (real-part res))
(test-equal? (imag-part expect) (imag-part res))))))
;;> Begin testing a new group until the closing @scheme{(test-end)}.
;;> Begin testing a new group until the closing \scheme{(test-end)}.
(define (test-begin . o)
(let* ((name (if (pair? o) (car o) ""))
@ -706,7 +706,7 @@
(display (bold (string-append name ": ")))))
(current-test-group group)))
;;> Ends testing group introduced with @scheme{(test-begin)}, and
;;> Ends testing group introduced with \scheme{(test-begin)}, and
;;> summarizes the results.
(define (test-end . o)

View file

@ -266,7 +266,7 @@
(for-each type-analyze-expr ls)
(for-each type-resolve-circularities ls))
;;> Analyze the types of all bindings in the module @var{name}.
;;> Analyze the types of all bindings in the module \var{name}.
(define (type-analyze-module name)
(let* ((mod (analyze-module name))
@ -300,7 +300,7 @@
(define (lambda-type x)
(cons 'lambda (cons (lambda-return-type x) (lambda-param-types x))))
;;> Return the type signature for the procedure @var{x} as
;;> Return the type signature for the procedure \var{x} as
;;> a list whose first element is the return type and whose
;;> remaining arguments are the parameter types.

View file

@ -20,7 +20,7 @@
;;> Accessors for the URI type.
;;/
;;> @subsubsubsection{@scheme{(make-uri scheme [user host port path query fragment])}}
;;> \subsubsubsection{\scheme{(make-uri scheme [user host port path query fragment])}}
(define (make-uri scheme . o)
(let* ((user (if (pair? o) (car o) #f))
@ -115,7 +115,7 @@
(%make-uri (uri-scheme u) (uri-user u) (uri-host u) (uri-port u)
(uri-path u) (uri-query u) fragment))
;;> Functional updaters - returns a new uri identical to @var{u}
;;> Functional updaters - returns a new uri identical to \var{u}
;;> with only the specified field changed.
;;/
@ -233,11 +233,11 @@
res
(cons (substring str from to) res)))
;;> @subsubsubsection{@scheme{(uri-encode str [plus?])}}
;;> \subsubsubsection{\scheme{(uri-encode str [plus?])}}
;;> Return the URI encoded version of the string @var{str},
;;> Return the URI encoded version of the string \var{str},
;;> using hex escapes as needed and replacing spaces with "+"
;;> iff the optional argument @var{plus?} is true.
;;> iff the optional argument \var{plus?} is true.
(define (uri-encode str . o)
(define (encode-1-space ch)
@ -267,11 +267,11 @@
(lp next next (cons (encode-1 ch)
(collect str from to res)))))))))
;;> @subsubsubsection{@scheme{(uri-decode str [plus?])}}
;;> \subsubsubsection{\scheme{(uri-decode str [plus?])}}
;;> Decodes any URI hex escapes in the given string, and
;;> translates any pluses ("+") to space iff the optional
;;> argument @var{plus?} is true.
;;> argument \var{plus?} is true.
(define (uri-decode str . o)
(let ((space-as-plus? (and (pair? o) (car o)))
@ -301,10 +301,10 @@
(else
(lp from next res))))))))
;;> @subsubsubsection{@scheme{(uri-query->alist str [plus?])}}
;;> \subsubsubsection{\scheme{(uri-query->alist str [plus?])}}
;;> Parses the query part of a URI as a delimited list of
;;> URI encoded @rawcode{VAR=VALUE} pairs, decodes them and
;;> URI encoded \rawcode{VAR=VALUE} pairs, decodes them and
;;> returns the result as an alist.
(define (uri-query->alist str . o)
@ -322,7 +322,7 @@
(cons (uri-decode (substring str i j) plus?) #f))))
(lp (+ j 1) (cons cell res)))))))
;;> @subsubsubsection{@scheme{(uri-alist->query ls [plus?])}}
;;> \subsubsubsection{\scheme{(uri-alist->query ls [plus?])}}
;;> The reverse of the above, formats the alist as a URI
;;> query string.

View file

@ -1,4 +1,4 @@
(define-library (scheme eval)
(import (chibi) (meta))
(import (chibi) (meta)) ; (chibi compiler analyze)
(export eval environment))

View file

@ -25,7 +25,7 @@
(load "tests/hash-tests.scm")
(load "tests/sort-tests.scm")
(load "tests/parse-tests.scm")
(load "tests/weak-tests.scm")
;; (load "tests/weak-tests.scm")
(load "tests/io-tests.scm")
(load "tests/process-tests.scm")
(load "tests/system-tests.scm")

View file

@ -12,198 +12,200 @@
expect
(call-with-input-string str scribble-parse)))
(test-scribble '((foo "blah blah blah")) "@foo{blah blah blah}")
(test-scribble '((foo "blah \"blah\" (`blah'?)")) "@foo{blah \"blah\" (`blah'?)}")
(test-scribble '((foo 1 2 "3 4")) "@foo[1 2]{3 4}")
(test-scribble '((foo 1 2 3 4)) "@foo[1 2 3 4]")
(test-scribble '((foo width: 2 "blah blah")) "@foo[width: 2]{blah blah}")
(test-scribble '((foo "blah blah" "\n" " yada yada")) "@foo{blah blah
(test-scribble '((foo "blah blah blah")) "\\foo{blah blah blah}")
(test-scribble '((foo "blah \"blah\" (`blah'?)")) "\\foo{blah \"blah\" (`blah'?)}")
(test-scribble '((foo 1 2 "3 4")) "\\foo[1 2]{3 4}")
(test-scribble '((foo 1 2 3 4)) "\\foo[1 2 3 4]")
(test-scribble '((foo width: 2 "blah blah")) "\\foo[width: 2]{blah blah}")
(test-scribble '((foo "blah blah" "\n" " yada yada")) "\\foo{blah blah
yada yada}")
(test-scribble '((foo " blah blah" "\n" " yada yada" "\n")) "@foo{
(test-scribble '((foo " blah blah" "\n" " yada yada" "\n")) "\\foo{
blah blah
yada yada
}")
(test-scribble '((foo "bar " (baz "3") "\n" " blah")) "@foo{bar @baz{3}
(test-scribble '((foo "bar " (baz "3") "\n" " blah")) "\\foo{bar \\baz{3}
blah}")
(test-scribble '((foo (b (u 3) " " (u "4")) "\n" " blah")) "@foo{@b{@u[3] @u{4}}
(test-scribble '((foo (b (u 3) " " (u "4")) "\n" " blah")) "\\foo{\\b{\\u[3] \\u{4}}
blah}")
(test-scribble '((C "while (*(p++))" "\n" " *p = '\\n';")) "@C{while (*(p++))
*p = '\\n';}")
(test-scribble '(("blah blah")) "@{blah blah}")
(test-scribble '(("blah " (3))) "@{blah @[3]}")
(test-scribble '(("foo" "\n" " bar" "\n" " baz")) "@{foo
(test-scribble '((C "while (*(p++))" "\n" " *p = '\\n';")) "\\C{while (*(p++))
*p = '\\\"\\\\\"n';}")
(test-scribble '(("blah blah")) "\\{blah blah}")
(test-scribble '(("blah " (3))) "\\{blah \\[3]}")
(test-scribble '(("foo" "\n" " bar" "\n" " baz")) "\\{foo
bar
baz}")
(test-scribble '(foo) "@foo")
(test-scribble '(("blah " foo " blah")) "@{blah @foo blah}")
(test-scribble '(("blah " foo: " blah")) "@{blah @foo: blah}")
(test-scribble '(("blah " foo ": blah")) "@{blah @|foo|: blah}")
(test-scribble '((foo "(+ 1 2) -> " (+ 1 2) "!")) "@foo{(+ 1 2) -> @(+ 1 2)!}")
(test-scribble '((foo "A string escape")) "@foo{A @\"string\" escape}")
(test-scribble '((foo "eli@barzilay.org")) "@foo{eli@\"@\"barzilay.org}")
(test-scribble '((foo "A { begins a block")) "@foo{A @\"{\" begins a block}")
(test-scribble '(foo) "\\foo")
(test-scribble '(("blah " foo " blah")) "\\{blah \\foo blah}")
(test-scribble '(("blah " foo: " blah")) "\\{blah \\foo: blah}")
(test-scribble '(("blah " foo ": blah")) "\\{blah \\|foo|: blah}")
(test-scribble '((foo "(+ 1 2) -> " (+ 1 2) "!")) "\\foo{(+ 1 2) -> \\(+ 1 2)!}")
(test-scribble '((foo "A string escape")) "\\foo{A \\\"string\" escape}")
(test-scribble '((foo "eli@barzilay.org")) "\\foo{eli@barzilay.org}")
(test-scribble '((foo "eli\\barzilay.org")) "\\foo{eli\\\"\\\\\"barzilay.org}")
(test-scribble '((foo "A { begins a block")) "\\foo{A \\\"{\" begins a block}")
(test-scribble '((C "while (*(p++)) {" "\n" " *p = '\\n';" "\n" " }"))
"@C{while (*(p++)) {
*p = '\\n';
"\\C{while (*(p++)) {
*p = '\\\"\\\\\"n';
}}")
(test-scribble '((foo "bar}@{baz")) "@foo|{bar}@{baz}|")
(test-scribble '((foo "bar " (x "X") " baz")) "@foo|{bar |@x{X} baz}|")
(test-scribble '((foo "bar " (x "@") " baz")) "@foo|{bar |@x|{@}| baz}|")
(test-scribble '((foo "bar}\\{baz")) "\\foo|{bar}\\{baz}|")
(test-scribble '((foo "bar " (x "X") " baz")) "\\foo|{bar |\\x{X} baz}|")
(test-scribble '((foo "bar " (x "\\") " baz")) "\\foo|{bar |\\x|{\\}| baz}|")
(test-scribble '((foo "bar}@|{baz")) "@foo|--{bar}@|{baz}--|")
(test-scribble '((foo "bar}@|{baz")) "@foo|<<{bar}@|{baz}>>|")
(test-scribble '((foo "bar}\\|{baz")) "\\foo|--{bar}\\|{baz}--|")
(test-scribble '((foo "bar}\\|{baz")) "\\foo|<<{bar}\\|{baz}>>|")
(test-scribble '((foo "bar " (baz 2 3) " {4 5}")) "@foo{bar @baz[2 3] {4 5}}")
(test-scribble '((foo "bar " (baz 2 3) " {4 5}")) "\\foo{bar \\baz[2 3] {4 5}}")
(test-scribble '(`',@(foo "blah")) "@`',@foo{blah}")
;;(test-scribble '(#`#'#,@(foo "blah")) "@#`#'#,@foo{blah}")
(test-scribble '(((lambda (x) x) "blah")) "@(lambda (x) x){blah}")
(test-scribble '(`(,foo "blah")) "@`(unquote foo){blah}")
(test-scribble '(`',@(foo "blah")) "\\`',@foo{blah}")
;;(test-scribble '(#`#'#,@(foo "blah")) "\\#`#'#,@foo{blah}")
(test-scribble '(((lambda (x) x) "blah")) "\\(lambda (x) x){blah}")
(test-scribble '(`(,foo "blah")) "\\`(unquote foo){blah}")
(test-scribble '(("foo bar" "\n" " baz")) "@{foo bar
(test-scribble '(("foo bar" "\n" " baz")) "\\{foo bar
baz}")
(test-scribble '('("foo bar" "\n" " baz")) "@'{foo bar
(test-scribble '('("foo bar" "\n" " baz")) "\\'{foo bar
baz}")
(test-scribble '((foo "bar baz blah")) "@foo{bar @; comment
baz@;
(test-scribble '((foo "bar baz blah")) "\\foo{bar \\; comment
baz\\;
blah}")
(test-scribble '((foo "x " y " z")) "@foo{x @y z}")
(test-scribble '((foo "x " (* y 2) " z")) "@foo{x @(* y 2) z}")
(test-scribble '((foo " bar")) "@{@foo bar}")
(test-scribble '(((foo "bar") "baz")) "@@foo{bar}{baz}")
(test-scribble '((foo "x " y " z")) "\\foo{x \\y z}")
(test-scribble '((foo "x " (* y 2) " z")) "\\foo{x \\(* y 2) z}")
(test-scribble '((foo " bar")) "\\{\\foo bar}")
(test-scribble '(((foo "bar") "baz")) "\\\\foo{bar}{baz}")
(test-scribble '((foo 1 (* 2 3) "bar")) "@foo[1 (* 2 3)]{bar}")
(test-scribble '((foo (bar "...") "blah")) "@foo[@bar{...}]{blah}")
(test-scribble '((foo bar)) "@foo[bar]")
(test-scribble '((foo "bar " (f x) " baz")) "@foo{bar @f[x] baz}")
(test-scribble '((foo "bar")) "@foo[]{bar}")
(test-scribble '((foo)) "@foo[]")
(test-scribble '(foo) "@foo")
(test-scribble '((foo)) "@foo{}")
(test-scribble '((foo 1 (* 2 3) "bar")) "\\foo[1 (* 2 3)]{bar}")
(test-scribble '((foo (bar "...") "blah")) "\\foo[\\bar{...}]{blah}")
(test-scribble '((foo bar)) "\\foo[bar]")
(test-scribble '((foo "bar " (f x) " baz")) "\\foo{bar \\f[x] baz}")
(test-scribble '((foo "bar")) "\\foo[]{bar}")
(test-scribble '((foo)) "\\foo[]")
(test-scribble '(foo) "\\foo")
(test-scribble '((foo)) "\\foo{}")
(test-scribble '((foo 'style: 'big "bar")) "@foo['style: 'big]{bar}")
(test-scribble '((foo 'style: 'big "bar")) "\\foo['style: 'big]{bar}")
(test-scribble '((foo "f{o}o")) "@foo{f{o}o}")
(test-scribble '((foo "{{}}{}")) "@foo{{{}}{}}")
(test-scribble '((foo "bar")) "@foo{bar}")
(test-scribble '((foo " bar ")) "@foo{ bar }")
(test-scribble '((foo 1 " bar ")) "@foo[1]{ bar }")
(test-scribble '((foo "f{o}o")) "\\foo{f{o}o}")
(test-scribble '((foo "{{}}{}")) "\\foo{{{}}{}}")
(test-scribble '((foo "bar")) "\\foo{bar}")
(test-scribble '((foo " bar ")) "\\foo{ bar }")
(test-scribble '((foo 1 " bar ")) "\\foo[1]{ bar }")
(test-scribble '((foo "a " (bar "b") " c")) "@foo{a @bar{b} c}")
(test-scribble '((foo "a " bar " c")) "@foo{a @bar c}")
(test-scribble '((foo "a " (bar 2) " c")) "@foo{a @(bar 2) c}")
(test-scribble '((foo "A } marks the end")) "@foo{A @\"}\" marks the end}")
(test-scribble '((foo "The prefix: @.")) "@foo{The prefix: @\"@\".}")
(test-scribble '((foo "@x{y} --> (x \"y\")")) "@foo{@\"@x{y}\" --> (x \"y\")}")
(test-scribble '((foo "a " (bar "b") " c")) "\\foo{a \\bar{b} c}")
(test-scribble '((foo "a " bar " c")) "\\foo{a \\bar c}")
(test-scribble '((foo "a " (bar 2) " c")) "\\foo{a \\(bar 2) c}")
(test-scribble '((foo "A } marks the end")) "\\foo{A \\\"}\" marks the end}")
(test-scribble '((foo "The prefix: @.")) "\\foo{The prefix: \\\"@\".}")
(test-scribble '((foo "The prefix: \\.")) "\\foo{The prefix: \\\"\\\\\".}")
(test-scribble '((foo "\\x{y} --> (x \"y\")")) "\\foo{\\\"\\\\x{y}\" --> (x \"y\")}")
(test-scribble '((foo "...")) "@foo|{...}|")
(test-scribble '((foo "\"}\" follows \"{\"")) "@foo|{\"}\" follows \"{\"}|")
(test-scribble '((foo "Nesting |{is}| ok")) "@foo|{Nesting |{is}| ok}|")
(test-scribble '((foo "...")) "\\foo|{...}|")
(test-scribble '((foo "\"}\" follows \"{\"")) "\\foo|{\"}\" follows \"{\"}|")
(test-scribble '((foo "Nesting |{is}| ok")) "\\foo|{Nesting |{is}| ok}|")
(test-scribble '((foo "Maze" "\n" " " (bar "is") "\n" " Life!"))
"@foo|{Maze
|@bar{is}
"\\foo|{Maze
|\\bar{is}
Life!}|")
(test-scribble '((t "In " (i "sub@s") " too")) "@t|{In |@i|{sub|@\"@\"s}| too}|")
(test-scribble '((foo "@x{foo} |@{bar}|.")) "@foo|<<<{@x{foo} |@{bar}|.}>>>|")
(test-scribble '((foo "X " (b "Y") "...")) "@foo|!!{X |!!@b{Y}...}!!|")
(test-scribble '((t "In " (i "sub\\s") " too")) "\\t|{In |\\i|{sub|\\\"\\\\\"s}| too}|")
(test-scribble '((foo "\\x{foo} |\\{bar}|.")) "\\foo|<<<{\\x{foo} |\\{bar}|.}>>>|")
(test-scribble '((foo "X " (b "Y") "...")) "\\foo|!!{X |!!\\b{Y}...}!!|")
(test-scribble '((foo "foo" bar.)) "@foo{foo@bar.}")
(test-scribble '((foo "foo" bar ".")) "@foo{foo@|bar|.}")
(test-scribble '((foo "foo" 3.0)) "@foo{foo@3.}")
(test-scribble '((foo "foo" 3 ".")) "@foo{foo@|3|.}")
(test-scribble '((foo "foo" (f 1) "{bar}")) "@foo{foo@|(f 1)|{bar}}")
(test-scribble '((foo "foo" bar "[1]{baz}")) "@foo{foo@|bar|[1]{baz}}")
(test-scribble '((foo "xyz")) "@foo{x@\"y\"z}")
(test-scribble '((foo "x" "y" "z")) "@foo{x@|\"y\"|z}")
(test-scribble '((foo "x" 1 (+ 2 3) 4 "y")) "@foo{x@|1 (+ 2 3) 4|y}")
(test-scribble '((foo "x" * * "y")) "@foo{x@|*
(test-scribble '((foo "foo" bar.)) "\\foo{foo\\bar.}")
(test-scribble '((foo "foo" bar ".")) "\\foo{foo\\|bar|.}")
(test-scribble '((foo "foo" 3.0)) "\\foo{foo\\3.}")
(test-scribble '((foo "foo" 3 ".")) "\\foo{foo\\|3|.}")
(test-scribble '((foo "foo" (f 1) "{bar}")) "\\foo{foo\\|(f 1)|{bar}}")
(test-scribble '((foo "foo" bar "[1]{baz}")) "\\foo{foo\\|bar|[1]{baz}}")
(test-scribble '((foo "xyz")) "\\foo{x\\\"y\"z}")
(test-scribble '((foo "x" "y" "z")) "\\foo{x\\|\"y\"|z}")
(test-scribble '((foo "x" 1 (+ 2 3) 4 "y")) "\\foo{x\\|1 (+ 2 3) 4|y}")
(test-scribble '((foo "x" * * "y")) "\\foo{x\\|*
*|y}")
(test-scribble '((foo "Alice" "Bob" "Carol")) "@foo{Alice@||Bob@|
(test-scribble '((foo "Alice" "Bob" "Carol")) "\\foo{Alice\\||Bob\\|
|Carol}")
(test-scribble '((blah)) "@|{blah}|")
(test-scribble '((blah blah)) "@|{blah blah}|")
(test-scribble '((blah)) "\\|{blah}|")
(test-scribble '((blah blah)) "\\|{blah blah}|")
(test-scribble '((foo "First line" "\n" " Second line")) "@foo{First line@;{there is still a
(test-scribble '((foo "First line" "\n" " Second line")) "\\foo{First line\\;{there is still a
newline here;}
Second line}")
(test-scribble '((foo "A long single- string arg.")) "@foo{A long @;
single-@;
(test-scribble '((foo "A long single- string arg.")) "\\foo{A long \\;
single-\\;
string arg.}")
(test-scribble '((foo "bar")) "@foo{bar}")
(test-scribble '((foo " bar ")) "@foo{ bar }")
(test-scribble '((foo " bar" "\n" " baz ")) "@foo{ bar
(test-scribble '((foo "bar")) "\\foo{bar}")
(test-scribble '((foo " bar ")) "\\foo{ bar }")
(test-scribble '((foo " bar" "\n" " baz ")) "\\foo{ bar
baz }")
(test-scribble '((foo "bar" "\n")) "@foo{bar
(test-scribble '((foo "bar" "\n")) "\\foo{bar
}")
(test-scribble '((foo " bar" "\n") "\n") "@foo{
(test-scribble '((foo " bar" "\n") "\n") "\\foo{
bar
}
")
(test-scribble '((foo " bar" "\n" "\n")) "@foo{
(test-scribble '((foo " bar" "\n" "\n")) "\\foo{
bar
}")
(test-scribble '((foo " bar" "\n" "\n" " baz" "\n")) "@foo{
(test-scribble '((foo " bar" "\n" "\n" " baz" "\n")) "\\foo{
bar
baz
}")
(test-scribble '((foo)) "@foo{
(test-scribble '((foo)) "\\foo{
}")
(test-scribble '((foo)) "@foo{
(test-scribble '((foo)) "\\foo{
}")
(test-scribble '((foo " bar" "\n" " baz ")) "@foo{ bar
(test-scribble '((foo " bar" "\n" " baz ")) "\\foo{ bar
baz }")
(test-scribble '((foo " bar" "\n" " baz" "\n" " blah" "\n")) "@foo{
(test-scribble '((foo " bar" "\n" " baz" "\n" " blah" "\n")) "\\foo{
bar
baz
blah
}")
(test-scribble '((foo " begin" "\n" " x++;" "\n" " end")) "@foo{
(test-scribble '((foo " begin" "\n" " x++;" "\n" " end")) "\\foo{
begin
x++;
end}")
(test-scribble '((foo " a" "\n" " b" "\n" " c")) "@foo{
(test-scribble '((foo " a" "\n" " b" "\n" " c")) "\\foo{
a
b
c}")
(test-scribble '((foo "bar" "\n" " baz" "\n" " bbb")) "@foo{bar
(test-scribble '((foo "bar" "\n" " baz" "\n" " bbb")) "\\foo{bar
baz
bbb}")
(test-scribble '((foo " bar" "\n" " baz" "\n" " bbb")) "@foo{ bar
(test-scribble '((foo " bar" "\n" " baz" "\n" " bbb")) "\\foo{ bar
baz
bbb}")
(test-scribble '((foo "bar" "\n" " baz" "\n" " bbb")) "@foo{bar
(test-scribble '((foo "bar" "\n" " baz" "\n" " bbb")) "\\foo{bar
baz
bbb}")
(test-scribble '((foo " bar" "\n" " baz" "\n" " bbb")) "@foo{ bar
(test-scribble '((foo " bar" "\n" " baz" "\n" " bbb")) "\\foo{ bar
baz
bbb}")
(test-scribble
'((foo " bar" "\n" " baz" "\n" " bbb"))
"@foo{ bar
"\\foo{ bar
baz
bbb}")
(test-scribble
'((text "Some " (b "bold" "\n" "\n" " text")", and" "\n" "\n" " more text."))
"@text{Some @b{bold
"\\text{Some \\b{bold
text}, and
more text.}")
(test-scribble '((foo " " " bar " "\n" " " " baz")) "@foo{
@|| bar @||
@|| baz}")
(test-scribble '((foo " " " bar " "\n" " " " baz")) "\\foo{
\\|| bar \\||
\\|| baz}")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;