c1430240aec7

adopt: Update site.
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Fri, 17 May 2019 23:12:54 -0400
parents 9918f80ae953
children f594d9d84fae
branches/tags (none)
files adopt/_dmedia/goodwolf.css adopt/_dmedia/style.less adopt/_dmedia/tango.css adopt/usage/index.html

Changes

--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/adopt/_dmedia/goodwolf.css	Fri May 17 23:12:54 2019 -0400
@@ -0,0 +1,62 @@
+/* @override http://localhost:8080/media/css/pygments-monokai-light.css */
+div.highlight .hll { background-color: #FFD7EF; display: block; }
+div.highlight .err { color: #fff; background-color: #f00 } /* Error */
+div.highlight .gi { font-weight: bold } /* Diff Insert */
+div.highlight .gd { font-weight: bold } /* Diff Delete */
+div.highlight .k { color: #111} /* Keyword */
+div.highlight .l { color: #111 } /* Literal */
+div.highlight .n { color: #111 } /* Name */
+div.highlight .o { color: #111 } /* Operator */
+div.highlight .p { color: #111 } /* Punctuation */
+div.highlight .c  { color: #714678; font-style: italic; font-weight: bold; } /* Comment */
+div.highlight .cm { color: #714678; font-style: italic; font-weight: bold; } /* Comment.Multiline */
+div.highlight .cp { color: #714678; font-style: italic; font-weight: bold; } /* Comment.Preproc */
+div.highlight .c1 { color: #714678; font-style: italic; font-weight: bold; } /* Comment.Single */
+div.highlight .cs { color: #714678; font-style: italic; font-weight: bold; } /* Comment.Special */
+div.highlight .ge { font-style: italic } /* Generic.Emph */
+div.highlight .gs { font-weight: bold } /* Generic.Strong */
+div.highlight .kc { color: #111 } /* Keyword.Constant */
+div.highlight .kd { color: #111 } /* Keyword.Declaration */
+div.highlight .kn { color: #111 } /* Keyword.Namespace */
+div.highlight .kp { color: #111 } /* Keyword.Pseudo */
+div.highlight .kr { color: #111 } /* Keyword.Reserved */
+div.highlight .kt { color: #111 } /* Keyword.Type */
+div.highlight .ld { color: #111 } /* Literal.Date */
+div.highlight .m { color: #111 } /* Literal.Number */
+div.highlight .s { color: #111; font-style: italic; } /* Literal.String */
+div.highlight .na { color: #111 } /* Name.Attribute */
+div.highlight .nb { color: #111 } /* Name.Builtin */
+div.highlight .nc { color: #111 } /* Name.Class */
+div.highlight .no { color: #111 } /* Name.Constant */
+div.highlight .nd { color: #111 } /* Name.Decorator */
+div.highlight .ni { color: #111 } /* Name.Entity */
+div.highlight .ne { color: #111 } /* Name.Exception */
+div.highlight .nf { color: #111} /* Name.Function */
+div.highlight .nl { color: #111 } /* Name.Label */
+div.highlight .nn { color: #111} /* Name.Namespace */
+div.highlight .nx { color: #111 } /* Name.Other */
+div.highlight .py { color: #111 } /* Name.Property */
+div.highlight .nt { color: #111 } /* Name.Tag */
+div.highlight .nv { color: #111 } /* Name.Variable */
+div.highlight .ow { color: #111 } /* Operator.Word */
+div.highlight .w { color: #111 } /* Text.Whitespace */
+div.highlight .mf { color: #111 } /* Literal.Number.Float */
+div.highlight .mh { color: #111 } /* Literal.Number.Hex */
+div.highlight .mi { color: #111 } /* Literal.Number.Integer */
+div.highlight .mo { color: #111 } /* Literal.Number.Oct */
+div.highlight .sb { color: #111 } /* Literal.String.Backtick */
+div.highlight .sc { color: #111 } /* Literal.String.Char */
+div.highlight .sd { color: #111 } /* Literal.String.Doc */
+div.highlight .s2 { color: #111 } /* Literal.String.Double */
+div.highlight .se { color: #111 } /* Literal.String.Escape */
+div.highlight .sh { color: #111 } /* Literal.String.Heredoc */
+div.highlight .si { color: #111 } /* Literal.String.Interpol */
+div.highlight .sx { color: #111 } /* Literal.String.Other */
+div.highlight .sr { color: #111 } /* Literal.String.Regex */
+div.highlight .s1 { color: #111 } /* Literal.String.Single */
+div.highlight .ss { color: #111 } /* Literal.String.Symbol */
+div.highlight .bp { color: #111 } /* Name.Builtin.Pseudo */
+div.highlight .vc { color: #111 } /* Name.Variable.Class */
+div.highlight .vg { color: #111 } /* Name.Variable.Global */
+div.highlight .vi { color: #111 } /* Name.Variable.Instance */
+div.highlight .il { color: #111 } /* Literal.Number.Integer.Long */
--- a/adopt/_dmedia/style.less	Wed Apr 17 10:30:37 2019 -0400
+++ b/adopt/_dmedia/style.less	Fri May 17 23:12:54 2019 -0400
@@ -2,11 +2,11 @@
     overflow-y: scroll;
 }
 .wrap {
-    width: 600px;
+    width: 640px;
     margin: 40px auto 180px;
 }
 body {
-    font-size: 18px;
+    font-size: 16px;
     line-height: 1.4;
     font-family: Georgia, Palatino, "Palatino Linotype", serif;
     color: #111111;
@@ -27,11 +27,11 @@
     }
 }
 h1 {
-    font-size: 48px;
+    font-size: 40px;
     line-height: 1;
 }
 h2 {
-    font-size: 34px;
+    font-size: 28px;
     line-height: 1;
     margin-top: 40px;
     margin-bottom: 0;
@@ -44,7 +44,7 @@
     }
 }
 h3 {
-    font-size: 26px;
+    font-size: 22px;
     line-height: 1;
     margin-top: 40px;
     margin-bottom: 0;
@@ -57,7 +57,7 @@
     }
 }
 h4 {
-    font-size: 20px;
+    font-size: 18px;
     line-height: 1;
     margin-top: 30px;
     margin-bottom: 0;
@@ -83,7 +83,7 @@
     }
 }
 pre {
-    font-size: 15px;
+    font-size: 14px;
     line-height: 1.3;
     white-space: pre;
     overflow-x: auto;
@@ -93,7 +93,7 @@
     font-family: Menlo, Monaco, Consolas, monospace;
 }
 code {
-    font-size: 15px;
+    font-size: 14px;
     border: 1px solid #fdd;
     background: #fffafa;
     padding: 1px 4px;
--- a/adopt/_dmedia/tango.css	Wed Apr 17 10:30:37 2019 -0400
+++ b/adopt/_dmedia/tango.css	Fri May 17 23:12:54 2019 -0400
@@ -1,6 +1,6 @@
 .codehilite .hll { background-color: #ffffcc }
 .codehilite .c { color: #8f5902; font-style: italic } /* Comment */
-.codehilite .err { color: #a40000; border: 1px solid #ef2929 } /* Error */
+.codehilite .err { color: #000000; } /* Error */
 .codehilite .g { color: #000000 } /* Generic */
 .codehilite .k { color: #204a87; font-weight: bold } /* Keyword */
 .codehilite .l { color: #000000 } /* Literal */
@@ -61,7 +61,7 @@
 .codehilite .sx { color: #4e9a06 } /* Literal.String.Other */
 .codehilite .sr { color: #4e9a06 } /* Literal.String.Regex */
 .codehilite .s1 { color: #4e9a06 } /* Literal.String.Single */
-.codehilite .ss { color: #4e9a06 } /* Literal.String.Symbol */
+.codehilite .ss { color: #000000 } /* Literal.String.Symbol */
 .codehilite .bp { color: #3465a4 } /* Name.Builtin.Pseudo */
 .codehilite .vc { color: #000000 } /* Name.Variable.Class */
 .codehilite .vg { color: #000000 } /* Name.Variable.Global */
--- a/adopt/usage/index.html	Wed Apr 17 10:30:37 2019 -0400
+++ b/adopt/usage/index.html	Fri May 17 23:12:54 2019 -0400
@@ -12,154 +12,215 @@
         <div class="wrap">
             <header><h1><a href="..">Adopt</a></h1></header>
                 <div class="markdown">
-<h1 id="usage"><a href="">Usage</a></h1><p>Adopt is a simple library for parsing UNIX-style command line arguments in
-Common Lisp.  It was made because none of the other libraries did what I needed.</p>
+<h1 id="usage"><a href="">Usage</a></h1><p>Adopt is a library for parsing UNIX-style command line arguments in Common Lisp.
+It was made because none of the other libraries did what I needed.</p>
 <div class="toc">
 <ul>
 <li><a href="#package">Package</a></li>
 <li><a href="#interfaces">Interfaces</a><ul>
 <li><a href="#creating-an-interface">Creating an Interface</a></li>
 <li><a href="#line-wrapping">Line Wrapping</a></li>
-<li><a href="#examples">Examples</a></li>
+<li><a href="#adding-examples">Adding Examples</a></li>
 </ul>
 </li>
 <li><a href="#exiting">Exiting</a></li>
 <li><a href="#options">Options</a></li>
 <li><a href="#parsing">Parsing</a></li>
 <li><a href="#top-level-structure">Top-Level Structure</a></li>
-<li><a href="#computing-values-with-reduce">Computing Values with Reduce</a></li>
+<li><a href="#computing-values-with-reduce">Computing Values with Reduce</a><ul>
+<li><a href="#simple-options">Simple Options</a></li>
+<li><a href="#boolean-options">Boolean Options</a></li>
+<li><a href="#counting-options">Counting Options</a></li>
+<li><a href="#single-parameter-options">Single-Parameter Options</a></li>
+<li><a href="#multiple-parameter-options">Multiple-Parameter Options</a></li>
+</ul>
+</li>
+<li><a href="#required-options">Required Options</a></li>
+<li><a href="#option-groups">Option Groups</a></li>
+<li><a href="#error-handling">Error Handling</a></li>
+<li><a href="#generating-man-pages">Generating Man Pages</a></li>
+<li><a href="#implementation-specifics">Implementation Specifics</a><ul>
+<li><a href="#sbcl">SBCL</a></li>
+<li><a href="#clozurecl">ClozureCL</a></li>
+</ul>
+</li>
 </ul></div>
 <h2 id="package">Package</h2>
 <p>All core Adopt functions are in the <code>adopt</code> package.  Several of the symbols in
 adopt shadow those in the <code>common-lisp</code> package, so you should probably use
 namespaced <code>adopt:…</code> symbols instead of <code>USE</code>ing the package.</p>
 <h2 id="interfaces">Interfaces</h2>
-<p>To get started with Adopt, you should create an interface with the
-<code>adopt:make-interface</code> function.  This returns an object representing the
-command line interface presented to your users.</p>
+<p>To get started with Adopt you can create an interface object with
+<code>adopt:make-interface</code>.  This returns an object representing the command line
+interface presented to your users.</p>
 <h3 id="creating-an-interface">Creating an Interface</h3>
 <p>Let's say you're developing a program to search the contents of files (because
 the world certainly needs <em>another</em> <code>grep</code> replacement).  You might start with
 something like:</p>
-<div class="codehilite"><pre><span/>(defparameter *ui*
-  (adopt:make-interface
-    :name "search"
-    :summary "search files for a regular expression"
-    :usage "[OPTIONS] PATTERN [FILE]..."
-    :help "Search the contents of each FILE for the regular expression PATTERN.  If no files are specified, searches standard input instead."))
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*ui*</span>
+  <span class="p">(</span><span class="nv">adopt:make-interface</span>
+    <span class="ss">:name</span> <span class="s">"search"</span>
+    <span class="ss">:summary</span> <span class="s">"search files for a regular expression"</span>
+    <span class="ss">:usage</span> <span class="s">"[OPTIONS] PATTERN [FILE]..."</span>
+    <span class="ss">:help</span> <span class="s">"Search the contents of each FILE for the regular expression PATTERN.  If no files are specified, searches standard input instead."</span><span class="p">))</span>
 </pre></div>
 
 
-<p>You can now print some help text for your CLI with <code>adopt:print-help</code>:</p>
-<div class="codehilite"><pre><span/>(adopt:print-help *ui*)
-; =&gt;
-search - search files for a regular expression
-
-USAGE: … [OPTIONS] PATTERN [FILE]...
-
-Search the contents of each FILE for the regular expression PATTERN.  If no
-files are specified, searches standard input instead.
+<p><code>make-interface</code> takes several required arguments:</p>
+<ul>
+<li><code>:name</code> is the name of the program.</li>
+<li><code>:summary</code> is a concise one-line summary of what it does.</li>
+<li><code>:usage</code> is a UNIX-style the command line usage string.</li>
+<li><code>:help</code> is a longer description of the program.</li>
+</ul>
+<p>You can now print some pretty help text for the CLI with <code>adopt:print-help</code>:</p>
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nv">adopt:print-help</span> <span class="vg">*ui*</span><span class="p">)</span>
+<span class="c1">; =&gt;</span>
+<span class="c1">; search - search files for a regular expression</span>
+<span class="c1">;</span>
+<span class="c1">; USAGE: /path/to/binary [OPTIONS] PATTERN [FILE]...</span>
+<span class="c1">;</span>
+<span class="c1">; Search the contents of each FILE for the regular expression PATTERN.  If no</span>
+<span class="c1">; files are specified, searches standard input instead.</span>
 </pre></div>
 
 
 <h3 id="line-wrapping">Line Wrapping</h3>
 <p>Adopt will handle line-wrapping your help text, so you don't need to (and
-shouldn't) add extra line breaks when creating your interface.  If you want to
-line break the text in your source code to fit nicely in your editor, remember
-that <code>adopt:make-interface</code> is just a function — you can use <code>format</code> (possibly
-with its <code>~Newline</code> directive) to preprocess the help text argument:</p>
-<div class="codehilite"><pre><span/>(defparameter *ui*
-  (adopt:make-interface
-    :name "search"
-    :summary "search files for a regular expression"
-    :usage "[OPTIONS] PATTERN [FILE]..."
-    :help (format nil "Search the contents of each FILE for ~
-                       the regular expression PATTERN.  If ~
-                       no files are specified, searches ~
-                       standard input instead.")))
+shouldn't) add extra line breaks when creating your interface.</p>
+<p>If you want to line break the text in your source code to fit nicely in your
+text editor, remember that <code>adopt:make-interface</code> is just a function — you can
+use <code>format</code> (possibly with its <a href="http://www.lispworks.com/documentation/lw71/CLHS/Body/22_cic.htm"><code>~Newline</code> directive</a>) to
+preprocess the help text argument:</p>
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*ui*</span>
+  <span class="p">(</span><span class="nv">adopt:make-interface</span>
+    <span class="ss">:name</span> <span class="s">"search"</span>
+    <span class="ss">:summary</span> <span class="s">"search files for a regular expression"</span>
+    <span class="ss">:usage</span> <span class="s">"[OPTIONS] PATTERN [FILE]..."</span>
+    <span class="ss">:help</span> <span class="p">(</span><span class="nb">format</span> <span class="no">nil</span> <span class="s">"Search the contents of each FILE for ~</span>
+<span class="s">                       the regular expression PATTERN.  If ~</span>
+<span class="s">                       no files are specified, searches ~</span>
+<span class="s">                       standard input instead."</span><span class="p">)))</span>
+</pre></div>
+
+
+<p>If you want to pull out the documentation string into its own variable to keep
+that <code>make-interface</code> call from getting too unwieldy, you can certainly do that:</p>
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*help-text*</span>
+  <span class="p">(</span><span class="nb">format</span> <span class="no">nil</span> <span class="s">"Search the contents of each FILE for the ~</span>
+<span class="s">               regular expression PATTERN.  If no files ~</span>
+<span class="s">               are specified, searches standard input ~</span>
+<span class="s">               instead."</span><span class="p">))</span>
+
+<span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*ui*</span>
+  <span class="p">(</span><span class="nv">adopt:make-interface</span>
+    <span class="ss">:name</span> <span class="s">"search"</span>
+    <span class="ss">:summary</span> <span class="s">"search files for a regular expression"</span>
+    <span class="ss">:usage</span> <span class="s">"[OPTIONS] PATTERN [FILE]..."</span>
+    <span class="ss">:help</span> <span class="vg">*help-text*</span><span class="p">))</span>
 </pre></div>
 
 
-<p>Adopt's line-wrapping library [Bobbin][] will only ever <em>add</em> line breaks, never
+<p>The <code>(defparameter … (format nil …))</code> pattern can be tedious to write, so Adopt
+provides a helper macro <code>define-string</code> that does exactly that:</p>
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nv">adopt:define-string</span> <span class="vg">*help-text*</span>
+  <span class="s">"Search the contents of each FILE for the regular ~</span>
+<span class="s">   expression PATTERN.  If no files are specified, ~</span>
+<span class="s">   searches standard input instead."</span><span class="p">)</span>
+
+<span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*ui*</span>
+  <span class="p">(</span><span class="nv">adopt:make-interface</span>
+    <span class="ss">:name</span> <span class="s">"search"</span>
+    <span class="ss">:summary</span> <span class="s">"search files for a regular expression"</span>
+    <span class="ss">:usage</span> <span class="s">"[OPTIONS] PATTERN [FILE]..."</span>
+    <span class="ss">:help</span> <span class="vg">*help-text*</span><span class="p">))</span>
+</pre></div>
+
+
+<p>Adopt's line-wrapping library <a href="https://sjl.bitbucket.io/bobbin/">Bobbin</a> will only ever <em>add</em> line breaks, never
 remove them, which means you can include breaks in the output if you want to
-have multiple paragraphs in your help text:</p>
-<div class="codehilite"><pre><span/>(defparameter *ui*
-  (adopt:make-interface
-    :name "search"
-    :summary "search files for a regular expression"
-    :usage "[OPTIONS] PATTERN [FILE]..."
-    :help (format nil
-            "Search the contents of each FILE for the regular expression PATTERN.~@
-             ~@
-             If no files are specified (or if - is given as a file name) standard input will be searched instead.")))
+have multiple paragraphs in your help text.  Once again, <code>format</code> is your
+friend:</p>
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nv">adopt:define-string</span> <span class="vg">*help-text*</span>
+  <span class="s">"Search the contents of each FILE for the regular ~</span>
+<span class="s">   expression PATTERN.~@</span>
+<span class="s">   ~@</span>
+<span class="s">   If no files are specified (or if - is given as a ~</span>
+<span class="s">   file name), standard input will be searched instead."</span><span class="p">)</span>
+
+<span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*ui*</span>
+  <span class="p">(</span><span class="nv">adopt:make-interface</span>
+    <span class="ss">:name</span> <span class="s">"search"</span>
+    <span class="ss">:summary</span> <span class="s">"search files for a regular expression"</span>
+    <span class="ss">:usage</span> <span class="s">"[OPTIONS] PATTERN [FILE]..."</span>
+    <span class="ss">:help</span> <span class="vg">*help-text*</span><span class="p">))</span>
 </pre></div>
 
 
 <p>If you want to control the width of the help text lines when they are printed,
 <code>adopt:print-help</code> takes a <code>:width</code> argument:</p>
-<div class="codehilite"><pre><span/>(adopt:print-help *ui* :width 50)
-; =&gt;
-search - search files for a regular expression
-
-USAGE: … [OPTIONS] PATTERN [FILE]...
-
-Search the contents of each FILE for the regular
-expression PATTERN.
-
-If no files are specified (or if - is given as a
-file name) standard input will be searched
-instead.
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nv">adopt:print-help</span> <span class="vg">*ui*</span> <span class="ss">:width</span> <span class="mi">50</span><span class="p">)</span>
+<span class="c1">; =&gt;</span>
+<span class="c1">; search - search files for a regular expression</span>
+<span class="c1">;</span>
+<span class="c1">; USAGE: … [OPTIONS] PATTERN [FILE]...</span>
+<span class="c1">;</span>
+<span class="c1">; Search the contents of each FILE for the regular</span>
+<span class="c1">; expression PATTERN.</span>
+<span class="c1">;</span>
+<span class="c1">; If no files are specified (or if - is given as a</span>
+<span class="c1">; file name), standard input will be searched</span>
+<span class="c1">; instead.</span>
 </pre></div>
 
 
 <p><code>adopt:print-help</code> takes a number of other options — see the API Reference for
 more information.</p>
-<h3 id="examples">Examples</h3>
+<h3 id="adding-examples">Adding Examples</h3>
 <p>Describing the CLI in detail is helpful, but users can often learn a lot more by
-seeing a few examples of its usage.  <code>adopt:make-interface</code> can take an
-<code>:examples</code> argument, which should be an alist of <code>(description . example)</code>
-conses:</p>
-<div class="codehilite"><pre><span/>(defparameter *ui*
-  (adopt:make-interface
-    :name "search"
-    :summary "search files for a regular expression"
-    :usage "[OPTIONS] PATTERN [FILE]..."
-    :help …
-    :examples
-    '(("Search foo.txt for the string 'hello':"
-       . "search hello foo.txt")
-      ("Search standard input for lines starting with x:"
-       . "search '^x' -")
-      ("Watch the file log.txt for lines containing the username steve.losh:"
-       . "tail foo/bar/baz/log.txt | search --literal steve.losh -"))))
-
-(adopt:print-help *ui* :width 50)
-; =&gt;
-search - search files for a regular expression
+seeing a few examples of its usage.  <code>make-interface</code> can take an <code>:examples</code>
+argument, which should be an alist of <code>(description . example)</code> conses:</p>
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*ui*</span>
+  <span class="p">(</span><span class="nv">adopt:make-interface</span>
+    <span class="ss">:name</span> <span class="s">"search"</span>
+    <span class="ss">:summary</span> <span class="s">"search files for a regular expression"</span>
+    <span class="ss">:usage</span> <span class="s">"[OPTIONS] PATTERN [FILE]..."</span>
+    <span class="ss">:help</span> <span class="vg">*help-text*</span>
+    <span class="ss">:examples</span>
+    <span class="o">'</span><span class="p">((</span><span class="s">"Search foo.txt for the string 'hello':"</span>
+       <span class="o">.</span> <span class="s">"search hello foo.txt"</span><span class="p">)</span>
+      <span class="p">(</span><span class="s">"Search standard input for lines starting with x:"</span>
+       <span class="o">.</span> <span class="s">"search '^x' -"</span><span class="p">)</span>
+      <span class="p">(</span><span class="s">"Watch the file log.txt for lines containing the username steve.losh:"</span>
+       <span class="o">.</span> <span class="s">"tail foo/bar/baz/log.txt | search --literal steve.losh -"</span><span class="p">))))</span>
 
-USAGE: … [OPTIONS] PATTERN [FILE]...
-
-Search the contents of each FILE for the regular
-expression PATTERN.
-
-If no files are specified (or if - is given as a
-file name) standard input will be searched
-instead.
-
-Examples:
-
-  Search foo.txt for the string 'hello':
-
-      search hello foo.txt
-
-  Search standard input for lines starting with x:
-
-      search '^x' -
-
-  Watch the file log.txt for lines containing the
-  username steve.losh:
-
-      tail foo/bar/baz/log.txt | search --literal steve.losh -
+<span class="p">(</span><span class="nv">adopt:print-help</span> <span class="vg">*ui*</span> <span class="ss">:width</span> <span class="mi">50</span><span class="p">)</span>
+<span class="c1">; =&gt;</span>
+<span class="c1">; search - search files for a regular expression</span>
+<span class="c1">;</span>
+<span class="c1">; USAGE: … [OPTIONS] PATTERN [FILE]...</span>
+<span class="c1">;</span>
+<span class="c1">; Search the contents of each FILE for the regular</span>
+<span class="c1">; expression PATTERN.</span>
+<span class="c1">;</span>
+<span class="c1">; If no files are specified (or if - is given as a</span>
+<span class="c1">; file name) standard input will be searched</span>
+<span class="c1">; instead.</span>
+<span class="c1">;</span>
+<span class="c1">; Examples:</span>
+<span class="c1">;</span>
+<span class="c1">;   Search foo.txt for the string 'hello':</span>
+<span class="c1">;</span>
+<span class="c1">;       search hello foo.txt</span>
+<span class="c1">;</span>
+<span class="c1">;   Search standard input for lines starting with x:</span>
+<span class="c1">;</span>
+<span class="c1">;       search '^x' -</span>
+<span class="c1">;</span>
+<span class="c1">;   Watch the file log.txt for lines containing the</span>
+<span class="c1">;   username steve.losh:</span>
+<span class="c1">;</span>
+<span class="c1">;       tail foo/bar/baz/log.txt | search --literal steve.losh -</span>
 </pre></div>
 
 
@@ -170,157 +231,668 @@
 <h2 id="exiting">Exiting</h2>
 <p>Adopt provides some helpful utility functions to exit out of your program with
 a UNIX exit code.  These do what you think they do:</p>
-<div class="codehilite"><pre><span/>(adopt:exit)
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nv">adopt:exit</span><span class="p">)</span>
 
-(adopt:exit 1)
+<span class="p">(</span><span class="nv">adopt:exit</span> <span class="mi">1</span><span class="p">)</span>
 
-(adopt:print-help-and-exit *ui*)
+<span class="p">(</span><span class="nv">adopt:print-help-and-exit</span> <span class="vg">*ui*</span><span class="p">)</span>
 
-(adopt:print-help-and-exit *ui*
-  :stream *error-output*
-  :exit-code 1)
+<span class="p">(</span><span class="nv">adopt:print-help-and-exit</span> <span class="vg">*ui*</span>
+  <span class="ss">:stream</span> <span class="vg">*error-output*</span>
+  <span class="ss">:exit-code</span> <span class="mi">1</span><span class="p">)</span>
 
-(handler-case (assert (= 1 0))
-  (error (err)
-    (adopt:print-error-and-exit err)))
+<span class="p">(</span><span class="nb">handler-case</span> <span class="p">(</span><span class="nb">assert</span> <span class="p">(</span><span class="nb">=</span> <span class="mi">1</span> <span class="mi">0</span><span class="p">))</span>
+  <span class="p">(</span><span class="nb">error</span> <span class="p">(</span><span class="nv">err</span><span class="p">)</span>
+    <span class="p">(</span><span class="nv">adopt:print-error-and-exit</span> <span class="nv">err</span><span class="p">)))</span>
 </pre></div>
 
 
 <p>These functions are not implemented for every Lisp implementation.  PRs are
 welcome, or you can just write the implementation-specific calls in your program
-yourself.</p>
+yourself if you prefer.</p>
 <h2 id="options">Options</h2>
 <p>Now that you know how to create an interface, you can create some options to use
 inside it with <code>adopt:make-option</code>:</p>
-<div class="codehilite"><pre><span/>(defparameter *option-version*
-  (adopt:make-option 'version
-    :long "version"
-    :help "display version information and exit"
-    :reduce (constantly t)))
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*option-version*</span>
+  <span class="p">(</span><span class="nv">adopt:make-option</span> <span class="ss">'version</span>
+    <span class="ss">:long</span> <span class="s">"version"</span>
+    <span class="ss">:help</span> <span class="s">"display version information and exit"</span>
+    <span class="ss">:reduce</span> <span class="p">(</span><span class="nb">constantly</span> <span class="no">t</span><span class="p">)))</span>
 
-(defparameter *option-help*
-  (adopt:make-option 'help
-    :long "help"
-    :short #\h
-    :help "display help information and exit"
-    :reduce (constantly t)))
+<span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*option-help*</span>
+  <span class="p">(</span><span class="nv">adopt:make-option</span> <span class="ss">'help</span>
+    <span class="ss">:long</span> <span class="s">"help"</span>
+    <span class="ss">:short</span> <span class="sc">#\h</span>
+    <span class="ss">:help</span> <span class="s">"display help information and exit"</span>
+    <span class="ss">:reduce</span> <span class="p">(</span><span class="nb">constantly</span> <span class="no">t</span><span class="p">)))</span>
 
-(defparameter *option-literal*
-  (adopt:make-option 'literal
-    :long "literal"
-    :short #\l
-    :help "treat PATTERN as a literal string instead of a regular expression"
-    :reduce (constantly t)))
+<span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*option-literal*</span>
+  <span class="p">(</span><span class="nv">adopt:make-option</span> <span class="ss">'literal</span>
+    <span class="ss">:long</span> <span class="s">"literal"</span>
+    <span class="ss">:short</span> <span class="sc">#\l</span>
+    <span class="ss">:help</span> <span class="s">"treat PATTERN as a literal string instead of a regular expression"</span>
+    <span class="ss">:reduce</span> <span class="p">(</span><span class="nb">constantly</span> <span class="no">t</span><span class="p">)))</span>
 
-(defparameter *ui*
-  (adopt:make-interface
-    :name "search"
-    :summary "search files for a regular expression"
-    :usage "[OPTIONS] PATTERN [FILE]..."
-    :help "Search the contents of …"
-    :contents (list
-                *option-version*
-                *option-help*
-                *option-literal*)))
+<span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*ui*</span>
+  <span class="p">(</span><span class="nv">adopt:make-interface</span>
+    <span class="ss">:name</span> <span class="s">"search"</span>
+    <span class="ss">:summary</span> <span class="s">"search files for a regular expression"</span>
+    <span class="ss">:usage</span> <span class="s">"[OPTIONS] PATTERN [FILE]..."</span>
+    <span class="ss">:help</span> <span class="s">"Search the contents of …"</span>
+    <span class="ss">:contents</span> <span class="p">(</span><span class="nb">list</span>
+                <span class="vg">*option-version*</span>
+                <span class="vg">*option-help*</span>
+                <span class="vg">*option-literal*</span><span class="p">)))</span>
 </pre></div>
 
 
 <p>Adopt will automatically add the options to the help text:</p>
-<div class="codehilite"><pre><span/>(adopt:print-help *ui*)
-; =&gt;
-search - search files for a regular expression
-
-USAGE: /usr/local/bin/sbcl [OPTIONS] PATTERN [FILE]...
-
-Search the contents of …
-
-Options:
-  --version             display version information and exit
-  -h, --help            display help information and exit
-  -l, --literal         treat PATTERN as a literal string instead of a regular
-                        expression
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nv">adopt:print-help</span> <span class="vg">*ui*</span><span class="p">)</span>
+<span class="c1">; =&gt;</span>
+<span class="c1">; search - search files for a regular expression</span>
+<span class="c1">;</span>
+<span class="c1">; USAGE: /usr/local/bin/sbcl [OPTIONS] PATTERN [FILE]...</span>
+<span class="c1">;</span>
+<span class="c1">; Search the contents of …</span>
+<span class="c1">;</span>
+<span class="c1">; Options:</span>
+<span class="c1">;   --version             display version information and exit</span>
+<span class="c1">;   -h, --help            display help information and exit</span>
+<span class="c1">;   -l, --literal         treat PATTERN as a literal string instead of a regular</span>
+<span class="c1">;                         expression</span>
 </pre></div>
 
 
-<p>The first argument to <code>adopt:make-option</code> is the name of the option, which we'll
-see put to use shortly.  At least one of <code>:short</code> and <code>:long</code> is required, and
-<code>:help</code> text must be specified.  We'll talk more about <code>:reduce</code> in a bit, but
-it too is required.</p>
+<p>The first argument to <code>make-option</code> is the name of the option, which we'll see
+put to use shortly.  At least one of <code>:short</code> and <code>:long</code> is required, and
+<code>:help</code> text must be specified.  We'll talk more about <code>:reduce</code> in a little
+while, but it too is required.</p>
 <p>I prefer to define each option as its own global variable to keep the call to
-<code>adopt:make-interface</code> from getting too large and unwieldy, but feel free to do
+<code>make-interface</code> from getting too large and unwieldy, but feel free to do
 something like this if you prefer to avoid cluttering your package:</p>
-<div class="codehilite"><pre><span/>(defparameter *ui*
-  (adopt:make-interface
-    …
-    :contents
-    (list (adopt:make-option 'foo …)
-          (adopt:make-option 'bar …)
-          …)))
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*ui*</span>
+  <span class="p">(</span><span class="nv">adopt:make-interface</span>
+    <span class="err">…</span>
+    <span class="ss">:contents</span>
+    <span class="p">(</span><span class="nb">list</span> <span class="p">(</span><span class="nv">adopt:make-option</span> <span class="ss">'foo</span> <span class="err">…</span><span class="p">)</span>
+          <span class="p">(</span><span class="nv">adopt:make-option</span> <span class="ss">'bar</span> <span class="err">…</span><span class="p">)</span>
+          <span class="err">…</span><span class="p">)))</span>
 </pre></div>
 
 
 <h2 id="parsing">Parsing</h2>
 <p>At this point we've got an interface with some options, so we can use it to
-parse a list of strings we've received as command line arguments:</p>
-<div class="codehilite"><pre><span/>(adopt:parse-options *ui* '("foo.*" "--literal" "a.txt" "b.txt"))
-; =&gt;
-("foo.*" "a.txt" "b.txt")
-#&lt;HASH-TABLE :TEST EQL :COUNT 3 {10103142A3}&gt;
+parse a list of strings we've received as command line arguments with
+<code>adopt:parse-options</code>:</p>
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nv">adopt:parse-options</span> <span class="vg">*ui*</span> <span class="o">'</span><span class="p">(</span><span class="s">"foo.*"</span> <span class="s">"--literal"</span> <span class="s">"a.txt"</span> <span class="s">"b.txt"</span><span class="p">))</span>
+<span class="c1">; =&gt;</span>
+<span class="c1">; ("foo.*" "a.txt" "b.txt")</span>
+<span class="c1">; #&lt;HASH-TABLE :TEST EQL :COUNT 3 {10103142A3}&gt;</span>
+</pre></div>
+
+
+<p>From now on I'll use a special pretty printer for hash tables to make it easier
+to see what's inside them:</p>
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nv">adopt:parse-options</span> <span class="vg">*ui*</span> <span class="o">'</span><span class="p">(</span><span class="s">"foo.*"</span> <span class="s">"--literal"</span> <span class="s">"a.txt"</span> <span class="s">"b.txt"</span><span class="p">))</span>
+<span class="c1">; =&gt;</span>
+<span class="c1">; ("foo.*" "a.txt" "b.txt")</span>
+<span class="c1">; {LITERAL: T, VERSION: NIL, HELP: NIL}</span>
+</pre></div>
+
+
+<p><code>parse-options</code> returns two values:</p>
+<ol>
+<li>A list of non-option arguments.</li>
+<li>An <code>eql</code> hash table of the option keys and values.</li>
+</ol>
+<p>We'll talk about how the option values are determined soon.  The keys of the
+hash table are (by default) the option names given as the first argument to
+<code>make-option</code>.  You can specify a different key for a particular option with the
+<code>:result-key</code> argument to <code>make-option</code>:</p>
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*option-literal*</span>
+  <span class="p">(</span><span class="nv">adopt:make-option</span> <span class="ss">'literal</span>
+    <span class="ss">:result-key</span> <span class="ss">'pattern-is-literal</span>
+    <span class="ss">:long</span> <span class="s">"literal"</span>
+    <span class="ss">:short</span> <span class="sc">#\l</span>
+    <span class="ss">:help</span> <span class="s">"treat PATTERN as a literal string instead of a regular expression"</span>
+    <span class="ss">:reduce</span> <span class="p">(</span><span class="nb">constantly</span> <span class="no">t</span><span class="p">)))</span>
+
+<span class="c1">;; …</span>
+
+<span class="p">(</span><span class="nv">adopt:parse-options</span> <span class="vg">*ui*</span> <span class="o">'</span><span class="p">(</span><span class="s">"foo.*"</span> <span class="s">"--literal"</span> <span class="s">"a.txt"</span> <span class="s">"b.txt"</span><span class="p">))</span>
+<span class="c1">; =&gt;</span>
+<span class="c1">; ("foo.*" "a.txt" "b.txt")</span>
+<span class="c1">; {PATTERN-IS-LITERAL: T, VERSION: NIL, HELP: NIL}</span>
+</pre></div>
+
+
+<p>This can come in useful if you want multiple options that affect the same result
+(e.g. <code>--verbose</code> and <code>--silent</code> flags that toggle extra log output on and off).</p>
+<h2 id="top-level-structure">Top-Level Structure</h2>
+<p>We'll look at how the option values are computed shortly, but first let's see
+the overall structure of the programs you'll typically create with Adopt:</p>
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nb">defun</span> <span class="nv">run</span> <span class="p">(</span><span class="nv">pattern</span> <span class="nv">files</span> <span class="k">&amp;key</span> <span class="nv">literal</span><span class="p">)</span>
+  <span class="c1">;; Actually do something here.</span>
+  <span class="p">)</span>
+
+<span class="p">(</span><span class="nb">defun</span> <span class="nv">toplevel</span> <span class="p">()</span>
+  <span class="p">(</span><span class="nb">handler-case</span>
+      <span class="p">(</span><span class="nb">multiple-value-bind</span> <span class="p">(</span><span class="nv">arguments</span> <span class="nv">options</span><span class="p">)</span> <span class="p">(</span><span class="nv">adopt:parse-options</span> <span class="vg">*ui*</span><span class="p">)</span>
+        <span class="p">(</span><span class="nb">when</span> <span class="p">(</span><span class="nb">gethash</span> <span class="ss">'help</span> <span class="nv">options</span><span class="p">)</span>
+          <span class="p">(</span><span class="nv">adopt:print-help-and-exit</span> <span class="vg">*ui*</span><span class="p">))</span>
+        <span class="p">(</span><span class="nb">when</span> <span class="p">(</span><span class="nb">gethash</span> <span class="ss">'version</span> <span class="nv">options</span><span class="p">)</span>
+          <span class="p">(</span><span class="nb">format</span> <span class="no">t</span> <span class="s">"1.0.0~%"</span><span class="p">)</span>
+          <span class="p">(</span><span class="nv">adopt:exit</span><span class="p">))</span>
+        <span class="p">(</span><span class="nb">destructuring-bind</span> <span class="p">(</span><span class="nv">pattern</span> <span class="o">.</span> <span class="nv">files</span><span class="p">)</span> <span class="nv">arguments</span>
+          <span class="p">(</span><span class="nv">run</span> <span class="nv">pattern</span>
+               <span class="nv">files</span>
+               <span class="ss">:literal</span> <span class="p">(</span><span class="nb">gethash</span> <span class="ss">'literal</span> <span class="nv">options</span><span class="p">))))</span>
+    <span class="p">(</span><span class="nb">error</span> <span class="p">(</span><span class="nv">c</span><span class="p">)</span>
+      <span class="p">(</span><span class="nv">adopt:print-error-and-exit</span> <span class="nv">c</span><span class="p">))))</span>
+
+<span class="p">(</span><span class="nb">defun</span> <span class="nv">build</span> <span class="p">()</span>
+  <span class="p">(</span><span class="nv">sb-ext:save-lisp-and-die</span> <span class="s">"search"</span> <span class="ss">:executable</span> <span class="no">t</span> <span class="ss">:toplevel</span> <span class="nf">#'</span><span class="nv">toplevel</span><span class="p">))</span>
 </pre></div>
 
 
-<p><code>adopt:parse-options</code> returns two values: a list of non-option arguments, and
-a hash table of the option values.</p>
-<p>The keys of the hash table are (by default) the option names given as the first
-argument to <code>adopt:make-option</code>.  We'll see how the option values are determined
-soon.</p>
-<p>From now on I'll use a special pretty printer for hash tables to make it easier
-to see what's inside them:</p>
-<div class="codehilite"><pre><span/>(adopt:parse-options *ui* '("foo.*" "--literal" "a.txt" "b.txt"))
-; =&gt;
-("foo.*" "a.txt" "b.txt")
-{LITERAL: T, VERSION: NIL, HELP: NIL}
+<p>This is a typical way to use Adopt.  There are three functions important
+functions here:</p>
+<ul>
+<li>The <code>toplevel</code> function takes care of parsing arguments and exiting with an
+  appropriate status code if necessary.</li>
+<li>The <code>run</code> function takes parsed, Lispy arguments and actually <em>does</em>
+  something.  When developing (in SLIME, VLIME, etc) you'll call <code>run</code>, because
+  you don't want the program to exit when you're developing interactively.</li>
+<li>The <code>build</code> function dumps an executable binary.  For more complicated
+  programs you might use something fancier, like ASDF or Shinmera's Deploy
+  library instead.</li>
+</ul>
+<p>In this example the <code>toplevel</code> function first uses a <code>handler-case</code> to trap all
+errors.  If any error occurs it will print the error message and exit, to avoid
+confusing users by dropping them into a Lisp debugger REPL (which they probably
+won't understand).  If you're developing a program just for yourself, you might
+want to omit this part and let yourself land in the debugger as usual.</p>
+<p>Next it uses <code>adopt:parse-options</code> to parse the command line arguments and
+options.  It them does some initial checks to see if the user wants <code>--help</code> or
+<code>--version</code> information.  If so, it prints the requested information and exits.</p>
+<p>Otherwise it destructures the arguments into the expected items and calls <code>run</code>
+with all the information it needs to do its job.  If the <code>destructuring-bind</code>
+fails an error will be signaled, and the <code>handler-case</code> will print it and exit.
+If you want to be a nice person you could check that the <code>arguments</code> have the
+correct shape first, and return a friendlier error message to your users if they
+don't.</p>
+<h2 id="computing-values-with-reduce">Computing Values with Reduce</h2>
+<p>So far we've talked about how to define an interface, print help text, parse
+a list of options, and the overall structure of the program you'll create with
+Adopt.  Now we need to talk about how the options the user specifies are parsed
+and turned into the resulting hash table.</p>
+<p>Not all command-line options are the same.  There are several common types of
+options in the UNIX world:</p>
+<ul>
+<li>Simple options that are either given or not, like <code>--help</code> or <code>--version</code>.</li>
+<li>Boolean options, like git's <code>-p/--paginate</code> and <code>--no-pager</code>, where both options affect a single boolean flag.</li>
+<li>Counted options, where the number of times they are given has an effect, like SSH's <code>-v</code> option (more <code>-v</code>'s means more verbosity).</li>
+<li>Options that take a single parameter, like Mercurial's <code>--repository /path/to/repo</code> option, which specifies the path to a repository to work on.</li>
+<li>Options that collect all parameters they are given, like rsync's <code>--exclude PATTERN</code>, which you can pass multiple times to add several exclusions.</li>
+</ul>
+<p>An option-parsing library needs to give you the tools to handle all of these
+cases (and more).  Python's <a href="https://docs.python.org/3/library/argparse.html#action">argparse</a> library, for example, has
+a number of different "actions" to account to handle these various use cases.
+Adopt works differently: it uses an interface similar to <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_reduce.htm">reduce</a> to let you
+do whatever you need.</p>
+<p>First: before any options are parsed, all entries in the options hash table have
+their values set to the <code>:initial-value</code> given to <code>make-option</code> (or <code>nil</code> if
+none was specified).</p>
+<p>Next: When you create an option you must specify a <code>:reduce</code> function that takes
+the current value (and, for options that take a parameter, the given parameter)
+and produces a new value each time the option is given.</p>
+<p>You may also specify a <code>:finally</code> function that will be called on the final
+value after all parsing is done.</p>
+<p>For convenience, if an option takes a parameter you may also specify a <code>:key</code>
+function, which will be called on the given string before it is passed to the
+<code>:reduce</code> function.  For example: you might use this for an option that takes
+integers as arguments with something like <code>:key #'parse-integer</code>.</p>
+<p>The combination of these four pieces will let you do just about anything you
+might want.  Let's look at how to do some common option parsing tasks using
+these as our building blocks.</p>
+<h3 id="simple-options">Simple Options</h3>
+<p>To define an option that just tracks whether it's ever been given, you can do
+something like:</p>
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*option-help*</span>
+  <span class="p">(</span><span class="nv">adopt:make-option</span> <span class="ss">'help</span>
+    <span class="ss">:long</span> <span class="s">"help"</span>
+    <span class="ss">:short</span> <span class="sc">#\h</span>
+    <span class="ss">:help</span> <span class="s">"display help information and exit"</span>
+    <span class="ss">:initial-value</span> <span class="no">nil</span>
+    <span class="ss">:reduce</span> <span class="p">(</span><span class="k">lambda</span> <span class="p">(</span><span class="nv">current-value</span><span class="p">)</span>
+              <span class="p">(</span><span class="k">declare</span> <span class="p">(</span><span class="k">ignore</span> <span class="nv">current-value</span><span class="p">))</span>
+              <span class="no">t</span><span class="p">)))</span>
+</pre></div>
+
+
+<p>But since <code>nil</code> is the default initial value and Common Lisp provides the handy
+<a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_cons_1.htm"><code>constantly</code></a>
+function, you can do this more concisely:</p>
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*option-help*</span>
+  <span class="p">(</span><span class="nv">adopt:make-option</span> <span class="ss">'help</span>
+    <span class="ss">:long</span> <span class="s">"help"</span>
+    <span class="ss">:short</span> <span class="sc">#\h</span>
+    <span class="ss">:help</span> <span class="s">"display help information and exit"</span>
+    <span class="ss">:reduce</span> <span class="p">(</span><span class="nb">constantly</span> <span class="no">t</span><span class="p">)))</span>
+</pre></div>
+
+
+<h3 id="boolean-options">Boolean Options</h3>
+<p>If you want to have multiple options that both affect the same key in the
+results, you can use <code>:result-key</code> to do this:</p>
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*option-paginate*</span>
+  <span class="p">(</span><span class="nv">adopt:make-option</span> <span class="ss">'paginate</span>
+    <span class="ss">:long</span> <span class="s">"paginate"</span>
+    <span class="ss">:short</span> <span class="sc">#\p</span>
+    <span class="ss">:help</span> <span class="s">"turn pagination on"</span>
+    <span class="ss">:reduce</span> <span class="p">(</span><span class="nb">constantly</span> <span class="no">t</span><span class="p">)))</span>
+
+<span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*option-no-paginate*</span>
+  <span class="p">(</span><span class="nv">adopt:make-option</span> <span class="ss">'no-paginate</span>
+    <span class="ss">:result-key</span> <span class="ss">'paginate</span>
+    <span class="ss">:long</span> <span class="s">"no-paginate"</span>
+    <span class="ss">:short</span> <span class="sc">#\P</span>
+    <span class="ss">:help</span> <span class="s">"turn pagination off (the default)"</span>
+    <span class="ss">:reduce</span> <span class="p">(</span><span class="nb">constantly</span> <span class="no">nil</span><span class="p">)))</span>
+</pre></div>
+
+
+<p>The way we've written this, if the user gives multiple options the last-given
+one will take precedence.  This is generally what you want, because it allows
+someone to add a shell alias with these options like this:</p>
+<div class="codehilite"><pre><span/><span class="nb">alias</span> <span class="nv">g</span><span class="o">=</span><span class="s1">'git --paginate --color=always'</span>
+</pre></div>
+
+
+<p>but still lets them override an option at runtime for a single invocation:</p>
+<div class="codehilite"><pre><span/>g --no-paginate log
+<span class="c1"># expands to: git --paginate --color=always --no-paginate log</span>
+</pre></div>
+
+
+<p>If the last-given option didn't take precedence, they'd have to fall back to the
+non-alias version of the command, and type out all the options they <em>do</em> want by
+hand.  This is annoying, so it's usually better to let the last one win.</p>
+<h3 id="counting-options">Counting Options</h3>
+<p>To define an option that counts how many times it's been given, like SSH's <code>-v</code>,
+you can use something like this:</p>
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*option-verbosity*</span>
+  <span class="p">(</span><span class="nv">adopt:make-option</span> <span class="ss">'verbosity</span>
+    <span class="ss">:short</span> <span class="sc">#\v</span>
+    <span class="ss">:help</span> <span class="s">"output more verbose logs"</span>
+    <span class="ss">:initial-value</span> <span class="mi">0</span>
+    <span class="ss">:reduce</span> <span class="nf">#'</span><span class="nb">1+</span><span class="p">))</span>
+</pre></div>
+
+
+<h3 id="single-parameter-options">Single-Parameter Options</h3>
+<p>To define an option that takes a parameter and only keeps the last one given,
+you can do something like:</p>
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*option-repository*</span>
+  <span class="p">(</span><span class="nv">adopt:make-option</span> <span class="ss">'repository</span>
+    <span class="ss">:parameter</span> <span class="s">"PATTERN"</span>
+    <span class="ss">:long</span> <span class="s">"repository"</span>
+    <span class="ss">:short</span> <span class="sc">#\R</span>
+    <span class="ss">:help</span> <span class="s">"path to the repository (default .)"</span>
+    <span class="ss">:initial-value</span> <span class="s">"."</span>
+    <span class="ss">:reduce</span> <span class="p">(</span><span class="k">lambda</span> <span class="p">(</span><span class="nv">prev</span> <span class="nv">new</span><span class="p">)</span>
+              <span class="p">(</span><span class="k">declare</span> <span class="p">(</span><span class="k">ignore</span> <span class="nv">prev</span><span class="p">))</span>
+              <span class="nv">new</span><span class="p">)))</span>
+</pre></div>
+
+
+<p>Specifying the <code>:parameter</code> argument makes this option a parameter-taking
+option, which means the <code>:reduce</code> function will be called with the current value
+and the given parameter each time.</p>
+<p>Writing that <code>lambda</code> out by hand every time would be tedious.  Adopt provides
+a function called <code>last</code> (as in "keep the <em>last</em> parameter given") that does
+exactly that:</p>
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*option-repository*</span>
+  <span class="p">(</span><span class="nv">adopt:make-option</span> <span class="ss">'repository</span>
+    <span class="ss">:long</span> <span class="s">"repository"</span>
+    <span class="ss">:short</span> <span class="sc">#\R</span>
+    <span class="ss">:help</span> <span class="s">"path to the repository (default .)"</span>
+    <span class="ss">:initial-value</span> <span class="s">"."</span>
+    <span class="ss">:reduce</span> <span class="nf">#'</span><span class="nv">adopt:last</span><span class="p">))</span>
+</pre></div>
+
+
+<h3 id="multiple-parameter-options">Multiple-Parameter Options</h3>
+<p>Collecting every parameter given can be done in a number of different ways.  One
+strategy could be:</p>
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*option-exclude*</span>
+  <span class="p">(</span><span class="nv">adopt:make-option</span> <span class="ss">'exclude</span>
+    <span class="ss">:long</span> <span class="s">"exclude"</span>
+    <span class="ss">:parameter</span> <span class="s">"PATTERN"</span>
+    <span class="ss">:help</span> <span class="s">"exclude PATTERN (may be given multiple times)"</span>
+    <span class="ss">:initial-value</span> <span class="no">nil</span>
+    <span class="ss">:reduce</span> <span class="p">(</span><span class="k">lambda</span> <span class="p">(</span><span class="nv">patterns</span> <span class="nv">new</span><span class="p">)</span>
+              <span class="p">(</span><span class="nb">cons</span> <span class="nv">new</span> <span class="nv">patterns</span><span class="p">))))</span>
+</pre></div>
+
+
+<p>You might notice that the <code>:reduce</code> function here is just <code>cons</code> with its
+arguments flipped.  Common Lisp doesn't have a function like Haskell's
+<a href="https://en.wikibooks.org/wiki/Haskell/Higher-order_functions#Flipping_arguments">flip</a>,
+so Adopt provides it:</p>
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*option-exclude*</span>
+  <span class="p">(</span><span class="nv">adopt:make-option</span> <span class="ss">'exclude</span>
+    <span class="ss">:long</span> <span class="s">"exclude"</span>
+    <span class="ss">:parameter</span> <span class="s">"PATTERN"</span>
+    <span class="ss">:help</span> <span class="s">"exclude PATTERN (may be given multiple times)"</span>
+    <span class="ss">:initial-value</span> <span class="no">nil</span>
+    <span class="ss">:reduce</span> <span class="p">(</span><span class="nv">adopt:flip</span> <span class="nf">#'</span><span class="nb">cons</span><span class="p">)))</span>
+</pre></div>
+
+
+<p>Note that the result of this will be a fresh list of all the given parameters,
+but their order will be reversed because <code>cons</code> adds each new parameter to the
+front of the list.  If the order doesn't matter for what you're going to do with
+it, you're all set.  Otherwise, there are several ways to get around this
+problem.  The first is to add the parameter to the end of the list in the
+<code>:reduce</code> function:</p>
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*option-exclude*</span>
+  <span class="p">(</span><span class="nv">adopt:make-option</span> <span class="ss">'exclude</span>
+    <span class="ss">:long</span> <span class="s">"exclude"</span>
+    <span class="ss">:parameter</span> <span class="s">"PATTERN"</span>
+    <span class="ss">:help</span> <span class="s">"exclude PATTERN (may be given multiple times)"</span>
+    <span class="ss">:initial-value</span> <span class="no">nil</span>
+    <span class="ss">:reduce</span> <span class="p">(</span><span class="k">lambda</span> <span class="p">(</span><span class="nv">patterns</span> <span class="nv">new</span><span class="p">)</span>
+              <span class="p">(</span><span class="nb">append</span> <span class="nv">patterns</span> <span class="p">(</span><span class="nb">list</span> <span class="nv">new</span><span class="p">)))))</span>
 </pre></div>
 
 
-<h2 id="top-level-structure">Top-Level Structure</h2>
-<p>We'll look at how the option values are computed shortly, but first let's see
-the overall structure of the programs you create with Adopt:</p>
-<div class="codehilite"><pre><span/>(defun toplevel ()
-  (handler-case
-      (multiple-value-bind (arguments options)
-          (adopt:parse-options *ui*)
-        (when (gethash 'help options)
-          (adopt:print-help-and-exit *ui*))
-        (when (gethash 'version options)
-          (format t "1.0.0~%")
-          (adopt:exit))
-        (destructuring-bind (pattern . files) arguments
-          (run pattern
-               files
-               :literal (gethash 'literal options))))
-    (error (c)
-      (adopt:print-error-and-exit c))))
+<p>This is tedious and inefficient if you have a lot of arguments.  If you don't
+care much about argument parsing speed, Adopt provides a function called
+<code>collect</code> that does exactly this, so you don't have to type out that <code>lambda</code>
+yourself (and <code>nil</code> is the default initial value, so you don't need that
+either):</p>
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*option-exclude*</span>
+  <span class="p">(</span><span class="nv">adopt:make-option</span> <span class="ss">'exclude</span>
+    <span class="ss">:long</span> <span class="s">"exclude"</span>
+    <span class="ss">:parameter</span> <span class="s">"PATTERN"</span>
+    <span class="ss">:help</span> <span class="s">"exclude PATTERN (may be given multiple times)"</span>
+    <span class="ss">:reduce</span> <span class="nf">#'</span><span class="nv">adopt:collect</span><span class="p">))</span>
+</pre></div>
+
 
-(sb-ext:save-lisp-and-die "search" :toplevel #'toplevel)
+<p>A more efficient (though slightly uglier) solution would be to use <code>nreverse</code> at
+the end:</p>
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*option-exclude*</span>
+  <span class="p">(</span><span class="nv">adopt:make-option</span> <span class="ss">'exclude</span>
+    <span class="ss">:long</span> <span class="s">"exclude"</span>
+    <span class="ss">:parameter</span> <span class="s">"PATTERN"</span>
+    <span class="ss">:help</span> <span class="s">"exclude PATTERN (may be given multiple times)"</span>
+    <span class="ss">:reduce</span> <span class="p">(</span><span class="nv">adopt:flip</span> <span class="nf">#'</span><span class="nb">cons</span><span class="p">)</span>
+    <span class="ss">:finally</span> <span class="nf">#'</span><span class="nb">nreverse</span><span class="p">))</span>
+</pre></div>
+
+
+<p>If you really need maximum efficiency when parsing command line options (you
+probably don't) you could use a queue library, or use a vector and
+<code>vector-push-extend</code>, or anything else you might dream up.  The combination of
+<code>:reduce</code>, <code>:initial-value</code>, and <code>:finally</code> will let you do just about anything.</p>
+<h2 id="required-options">Required Options</h2>
+<p>Adopt doesn't have a concept of a required option.  Not only is "required
+option" an oxymoron, but it's almost never what you want — if a user types
+<code>foo --help</code> they shouldn't get an error about a missing required option.</p>
+<p>In cases where you really do need to require an option (perhaps only if some
+other one is also given) you can check it yourself:</p>
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nb">defun</span> <span class="nv">toplevel</span> <span class="p">()</span>
+  <span class="p">(</span><span class="nb">handler-case</span>
+      <span class="p">(</span><span class="nb">multiple-value-bind</span> <span class="p">(</span><span class="nv">arguments</span> <span class="nv">options</span><span class="p">)</span> <span class="p">(</span><span class="nv">adopt:parse-options</span> <span class="vg">*ui*</span><span class="p">)</span>
+        <span class="p">(</span><span class="nb">when</span> <span class="p">(</span><span class="nb">gethash</span> <span class="ss">'help</span> <span class="nv">options</span><span class="p">)</span>
+          <span class="p">(</span><span class="nv">adopt:print-help-and-exit</span> <span class="vg">*ui*</span><span class="p">))</span>
+        <span class="p">(</span><span class="nb">unless</span> <span class="p">(</span><span class="nb">gethash</span> <span class="ss">'some-required-option</span> <span class="nv">options</span><span class="p">)</span>
+          <span class="p">(</span><span class="nb">error</span> <span class="s">"Required option foo is missing."</span><span class="p">))</span>
+        <span class="p">(</span><span class="nv">run</span> <span class="err">…</span><span class="p">))</span>
+    <span class="p">(</span><span class="nb">error</span> <span class="p">(</span><span class="nv">c</span><span class="p">)</span>
+      <span class="p">(</span><span class="nv">adopt:print-error-and-exit</span> <span class="nv">c</span><span class="p">))))</span>
 </pre></div>
 
 
-<p>The <code>toplevel</code> function first uses a <code>handler-case</code> to trap all <code>error</code>s.  If
-any error occurs it will print the error message and exit, to avoid confusing
-users by dropping them into a Lisp debugger REPL (which they probably won't
-understand).  When you're developing your program yourself you'll want to omit
-this part and let yourself land in the debugger as usual.</p>
-<p>Next we use <code>adopt:parse-options</code> to parse the command line arguments and
-options.  We do some initial checks to see if the user wants <code>--help</code> or
-<code>--version</code> information.  If not, we destructure the arguments into the items we
-expect and call a <code>run</code> function with all the information it needs to do its
-job.</p>
-<p>If the <code>destructuring-bind</code> fails an error will be signaled, and the
-<code>handler-case</code> will print it and exit.  If you want to be a nice person you
-could check that the <code>arguments</code> have the correct shape first, and return
-a friendlier error message to your users if they don't.</p>
-<h2 id="computing-values-with-reduce">Computing Values with Reduce</h2>
+<h2 id="option-groups">Option Groups</h2>
+<p>Related options can be grouped together in the help text to make them easier for
+users to understand.  Groups can have their own name, title, and help text.</p>
+<p>Here's a example of how this works.  It's fairly long, but shows how Adopt can
+help you make a command line interface with all the fixins:</p>
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*option-help*</span>
+  <span class="p">(</span><span class="nv">adopt:make-option</span> <span class="ss">'help</span>
+    <span class="ss">:help</span> <span class="s">"display help and exit"</span>
+    <span class="ss">:long</span> <span class="s">"help"</span>
+    <span class="ss">:short</span> <span class="sc">#\h</span>
+    <span class="ss">:reduce</span> <span class="p">(</span><span class="nb">constantly</span> <span class="no">t</span><span class="p">)))</span>
+
+<span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*option-literal*</span>
+  <span class="p">(</span><span class="nv">adopt:make-option</span> <span class="ss">'literal</span>
+    <span class="ss">:help</span> <span class="s">"treat PATTERN as a literal string instead of a regex"</span>
+    <span class="ss">:long</span> <span class="s">"literal"</span>
+    <span class="ss">:short</span> <span class="sc">#\l</span>
+    <span class="ss">:reduce</span> <span class="p">(</span><span class="nb">constantly</span> <span class="no">t</span><span class="p">)))</span>
+
+<span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*option-no-literal*</span>
+  <span class="p">(</span><span class="nv">adopt:make-option</span> <span class="ss">'no-literal</span>
+    <span class="ss">:help</span> <span class="s">"treat PATTERN as a regex (the default)"</span>
+    <span class="ss">:long</span> <span class="s">"no-literal"</span>
+    <span class="ss">:short</span> <span class="sc">#\L</span>
+    <span class="ss">:result-key</span> <span class="ss">'literal</span>
+    <span class="ss">:reduce</span> <span class="p">(</span><span class="nb">constantly</span> <span class="no">nil</span><span class="p">)))</span>
+
+<span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*option-case-sensitive*</span>
+  <span class="p">(</span><span class="nv">adopt:make-option</span> <span class="ss">'case-sensitive</span>
+    <span class="ss">:help</span> <span class="s">"match case-sensitively (the default)"</span>
+    <span class="ss">:long</span> <span class="s">"case-sensitive"</span>
+    <span class="ss">:short</span> <span class="sc">#\c</span>
+    <span class="ss">:initial-value</span> <span class="no">t</span>
+    <span class="ss">:reduce</span> <span class="p">(</span><span class="nb">constantly</span> <span class="no">t</span><span class="p">)))</span>
+
+<span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*option-case-insensitive*</span>
+  <span class="p">(</span><span class="nv">adopt:make-option</span> <span class="ss">'case-insensitive</span>
+    <span class="ss">:help</span> <span class="s">"ignore case when matching"</span>
+    <span class="ss">:long</span> <span class="s">"case-insensitive"</span>
+    <span class="ss">:short</span> <span class="sc">#\C</span>
+    <span class="ss">:result-key</span> <span class="ss">'case-sensitive</span>
+    <span class="ss">:reduce</span> <span class="p">(</span><span class="nb">constantly</span> <span class="no">nil</span><span class="p">)))</span>
+
+<span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*option-color*</span>
+  <span class="p">(</span><span class="nv">adopt:make-option</span> <span class="ss">'color</span>
+    <span class="ss">:help</span> <span class="s">"highlight matches with color"</span>
+    <span class="ss">:long</span> <span class="s">"color"</span>
+    <span class="ss">:reduce</span> <span class="p">(</span><span class="nb">constantly</span> <span class="no">t</span><span class="p">)))</span>
+
+<span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*option-no-color*</span>
+  <span class="p">(</span><span class="nv">adopt:make-option</span> <span class="ss">'no-color</span>
+    <span class="ss">:help</span> <span class="s">"don't highlight matches (the default)"</span>
+    <span class="ss">:long</span> <span class="s">"no-color"</span>
+    <span class="ss">:result-key</span> <span class="ss">'color</span>
+    <span class="ss">:reduce</span> <span class="p">(</span><span class="nb">constantly</span> <span class="no">nil</span><span class="p">)))</span>
+
+<span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*option-context*</span>
+  <span class="p">(</span><span class="nv">adopt:make-option</span> <span class="ss">'context</span>
+    <span class="ss">:parameter</span> <span class="s">"N"</span>
+    <span class="ss">:help</span> <span class="s">"show N lines of context (default 0)"</span>
+    <span class="ss">:long</span> <span class="s">"context"</span>
+    <span class="ss">:short</span> <span class="sc">#\U</span>
+    <span class="ss">:initial-value</span> <span class="mi">0</span>
+    <span class="ss">:reduce</span> <span class="nf">#'</span><span class="nv">adopt:last</span>
+    <span class="ss">:key</span> <span class="nf">#'</span><span class="nb">parse-integer</span><span class="p">))</span>
+
+<span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*group-matching*</span>
+  <span class="p">(</span><span class="nv">adopt:make-group</span> <span class="ss">'matching-options</span>
+    <span class="ss">:title</span> <span class="s">"Matching Options"</span>
+    <span class="ss">:help</span> <span class="s">"These options affect how lines are matched."</span>
+    <span class="ss">:options</span> <span class="p">(</span><span class="nb">list</span> <span class="vg">*option-literal*</span>
+                   <span class="vg">*option-no-literal*</span>
+                   <span class="vg">*option-case-sensitive*</span>
+                   <span class="vg">*option-case-insensitive*</span><span class="p">)))</span>
+
+<span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*group-output*</span>
+  <span class="p">(</span><span class="nv">adopt:make-group</span> <span class="ss">'output-options</span>
+    <span class="ss">:title</span> <span class="s">"Output Options"</span>
+    <span class="ss">:help</span> <span class="s">"These options affect how matching lines are printed."</span>
+    <span class="ss">:options</span> <span class="p">(</span><span class="nb">list</span> <span class="vg">*option-color*</span>
+                   <span class="vg">*option-no-color*</span>
+                   <span class="vg">*option-context*</span><span class="p">)))</span>
+
+<span class="p">(</span><span class="nv">adopt:define-string</span> <span class="vg">*help-text*</span>
+  <span class="s">"Search FILEs for lines that match the regular expression ~</span>
+<span class="s">   PATTERN and print them to standard out.  Several options ~</span>
+<span class="s">   are available to control how the matching lines are printed.~@</span>
+<span class="s">   ~@</span>
+<span class="s">   If no files are given (or if - is given as a filename) ~</span>
+<span class="s">   standard input will be searched."</span><span class="p">)</span>
+
+<span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*ui*</span>
+  <span class="p">(</span><span class="nv">adopt:make-interface</span>
+    <span class="ss">:name</span> <span class="s">"search"</span>
+    <span class="ss">:usage</span> <span class="s">"PATTERN [FILE...]"</span>
+    <span class="ss">:summary</span> <span class="s">"print lines that match a regular expression"</span>
+    <span class="ss">:help</span> <span class="vg">*help-text*</span>
+    <span class="ss">:contents</span> <span class="p">(</span><span class="nb">list</span> <span class="vg">*option-help*</span>
+                    <span class="vg">*group-matching*</span>
+                    <span class="vg">*group-output*</span><span class="p">)))</span>
+</pre></div>
+
+
+<p>And with all that out of the way, you've got some nicely-organized help text
+for your users:</p>
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nv">adopt:print-help</span> <span class="vg">*ui*</span> <span class="ss">:width</span> <span class="mi">60</span> <span class="ss">:option-width</span> <span class="mi">16</span><span class="p">)</span>
+<span class="c1">; =&gt;</span>
+<span class="c1">; search - print lines that match a regular expression</span>
+<span class="c1">;</span>
+<span class="c1">; USAGE: /usr/local/bin/sbcl PATTERN [FILE...]</span>
+<span class="c1">;</span>
+<span class="c1">; Search FILEs for lines that match the regular expression</span>
+<span class="c1">; PATTERN and print them to standard out.  Several options are</span>
+<span class="c1">; available to control how the matching lines are printed.</span>
+<span class="c1">;</span>
+<span class="c1">; If no files are given (or if - is given as a filename)</span>
+<span class="c1">; standard input will be searched.</span>
+<span class="c1">;</span>
+<span class="c1">; Options:</span>
+<span class="c1">;   -h, --help        display help and exit</span>
+<span class="c1">;</span>
+<span class="c1">; Matching Options:</span>
+<span class="c1">;   -l, --literal     treat PATTERN as a literal string</span>
+<span class="c1">;                     instead of a regex</span>
+<span class="c1">;   -L, --no-literal  treat PATTERN as a regex (the default)</span>
+<span class="c1">;   -c, --case-sensitive</span>
+<span class="c1">;                     match case-sensitively (the default)</span>
+<span class="c1">;   -C, --case-insensitive</span>
+<span class="c1">;                     ignore case when matching</span>
+<span class="c1">;</span>
+<span class="c1">; Output Options:</span>
+<span class="c1">;   --color           highlight matches with color</span>
+<span class="c1">;   --no-color        don't highlight matches (the default)</span>
+<span class="c1">;   -U N, --context N show N lines of context (default 0)</span>
+</pre></div>
+
+
+<h2 id="error-handling">Error Handling</h2>
+<p>For the most part Adopt doesn't try to be too smart about error handling and
+leaves it up to you.</p>
+<p>However, when Adopt is parsing the command line options it <em>will</em> signal an
+error of type <code>adopt:unrecognized-option</code> if the user passes a command line
+option that wasn't defined in the interface:</p>
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*ui*</span>
+  <span class="p">(</span><span class="nv">adopt:make-interface</span>
+    <span class="ss">:name</span> <span class="s">"meow"</span>
+    <span class="ss">:summary</span> <span class="s">"say meow"</span>
+    <span class="ss">:usage</span> <span class="s">"[OPTIONS]"</span>
+    <span class="ss">:help</span> <span class="s">"Say meow.  Like a cat."</span>
+    <span class="ss">:contents</span> <span class="p">(</span><span class="nb">list</span> <span class="p">(</span><span class="nv">make-option</span> <span class="ss">'times</span>
+                      <span class="ss">:parameter</span> <span class="s">"N"</span>
+                      <span class="ss">:long</span> <span class="s">"times"</span>
+                      <span class="ss">:initial-value</span> <span class="mi">1</span>
+                      <span class="ss">:help</span> <span class="s">"say meow N times (default 1)"</span>
+                      <span class="ss">:reduce</span> <span class="nf">#'</span><span class="nv">adopt:last</span>
+                      <span class="ss">:key</span> <span class="nf">#'</span><span class="nb">parse-integer</span><span class="p">))))</span>
+
+<span class="p">(</span><span class="nv">adopt:parse-options</span> <span class="vg">*ui*</span> <span class="o">'</span><span class="p">(</span><span class="s">"--times"</span> <span class="s">"5"</span><span class="p">))</span>
+<span class="c1">; =&gt;</span>
+<span class="c1">; NIL</span>
+<span class="c1">; {TIMES: 5}</span>
+
+<span class="p">(</span><span class="nv">adopt:parse-options</span> <span class="vg">*ui*</span> <span class="o">'</span><span class="p">(</span><span class="s">"--bark"</span><span class="p">))</span>
+<span class="c1">; =&gt;</span>
+<span class="c1">; No such option "--bark".</span>
+<span class="c1">;    [Condition of type UNRECOGNIZED-OPTION]</span>
+<span class="c1">;</span>
+<span class="c1">; Restarts:</span>
+<span class="c1">;   R 0.  DISCARD-OPTION    - Discard the unrecognized option.</span>
+<span class="c1">;   R 1.  TREAT-AS-ARGUMENT - Treat the unrecognized option as a plain argument.</span>
+<span class="c1">;   R 2.  SUPPLY-NEW-VALUE  - Supply a new value to parse.</span>
+<span class="c1">;   R 3.  RETRY             - Retry SLIME REPL evaluation request.</span>
+<span class="c1">;   R 4. *ABORT             - Return to SLIME's top level.</span>
+<span class="c1">;   R 5.  ABORT             - abort thread (#&lt;THREAD "repl-thread" RUNNING {100AF48413}&gt;)</span>
+</pre></div>
+
+
+<p>Adopt provides three possible restarts for this condition as seen above.  Adopt
+also provides functions with the same names that invoke the restarts properly,
+to make it easier to use them programatically with <code>handler-bind</code>.  For example:</p>
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nb">handler-bind</span>
+    <span class="p">((</span><span class="nv">adopt:unrecognized-option</span> <span class="ss">'adopt:discard-option</span><span class="p">))</span>
+  <span class="p">(</span><span class="nv">adopt:parse-options</span> <span class="vg">*ui*</span> <span class="o">'</span><span class="p">(</span><span class="s">"--bark"</span><span class="p">)))</span>
+<span class="c1">; =&gt;</span>
+<span class="c1">; NIL</span>
+<span class="c1">; {TIMES: 1}</span>
+
+<span class="p">(</span><span class="nb">handler-bind</span>
+    <span class="p">((</span><span class="nv">adopt:unrecognized-option</span> <span class="ss">'adopt:treat-as-argument</span><span class="p">))</span>
+  <span class="p">(</span><span class="nv">adopt:parse-options</span> <span class="vg">*ui*</span> <span class="o">'</span><span class="p">(</span><span class="s">"--bark"</span><span class="p">)))</span>
+<span class="c1">; =&gt;</span>
+<span class="c1">; ("--bark")</span>
+<span class="c1">; {TIMES: 1}</span>
+
+<span class="p">(</span><span class="nb">handler-bind</span>
+    <span class="p">((</span><span class="nv">adopt:unrecognized-option</span>
+       <span class="p">(</span><span class="nv">alexandria:rcurry</span> <span class="ss">'adopt:supply-new-value</span> <span class="s">"--times"</span><span class="p">)))</span>
+  <span class="p">(</span><span class="nv">adopt:parse-options</span> <span class="vg">*ui*</span> <span class="o">'</span><span class="p">(</span><span class="s">"--bark"</span> <span class="s">"5"</span><span class="p">)))</span>
+<span class="c1">; =&gt;</span>
+<span class="c1">; NIL</span>
+<span class="c1">; {TIMES: 5}</span>
+</pre></div>
+
+
+<h2 id="generating-man-pages">Generating Man Pages</h2>
+<p>We've already seen that Adopt can print a pretty help document, but it can also
+render <code>man</code> pages for you:</p>
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nb">with-open-file</span> <span class="p">(</span><span class="nv">out</span> <span class="s">"man/man1/search.1"</span>
+                  <span class="ss">:direction</span> <span class="ss">:output</span>
+                  <span class="ss">:if-exists</span> <span class="ss">:supersede</span><span class="p">)</span>
+  <span class="p">(</span><span class="nv">adopt:print-manual</span> <span class="vg">*ui*</span> <span class="ss">:stream</span> <span class="nv">out</span><span class="p">))</span>
+</pre></div>
+
+
+<p>The generated <code>man</code> page will contain the same information as the help text by
+default.  If you want to override this (e.g. to provide a short summary of an
+option in the help text, but elaborate more in the manual), you can use the
+<code>:manual</code> argument to <code>make-interface</code> and <code>make-option</code>:</p>
+<div class="codehilite"><pre><span/><span class="p">(</span><span class="nb">defparameter</span> <span class="vg">*option-exclude*</span>
+  <span class="p">(</span><span class="nv">adopt:make-option</span> <span class="ss">'exclude</span>
+    <span class="ss">:long</span> <span class="s">"exclude"</span>
+    <span class="ss">:parameter</span> <span class="s">"PATTERN"</span>
+    <span class="ss">:help</span> <span class="s">"exclude PATTERN"</span>
+    <span class="ss">:manual</span> <span class="s">"Exclude lines that match PATTERN (a PERL-compatible regular expression) from the search results.  Multiple PATTERNs can be specified by giving this option multiple times."</span>
+    <span class="ss">:reduce</span> <span class="p">(</span><span class="nv">adopt:flip</span> <span class="nf">#'</span><span class="nb">cons</span><span class="p">)))</span>
+</pre></div>
+
+
+<p>In order for <code>man</code> to find the pages, they need to be in the correct place.  By
+default <code>man</code> is usually smart enough to look next to every directory in your
+<code>$PATH</code> to find a directory called <code>man</code>.  So if you put your binaries in
+<code>/home/me/bin/</code> you can put your man pages in <code>/home/me/man/</code> under the
+appropriate subdirectories and it should all Just Work™.  Consult the <code>man</code>
+documentation for more information.</p>
+<h2 id="implementation-specifics">Implementation Specifics</h2>
+<h3 id="sbcl">SBCL</h3>
+<h3 id="clozurecl">ClozureCL</h3>
                 </div>
             <footer><p><i>Made with Lisp and love by <a href="http://stevelosh.com/">Steve Losh</a>.</i></p>
 <p><a href="http://rochestermade.com" title="Rochester Made"><img src="http://rochestermade.com/media/images/rochester-made-dark-on-light.png" alt="Rochester Made" title="Rochester Made"/></a></p>