152830fa3f85

Start the docs
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Thu, 22 Nov 2018 00:03:53 -0500
parents 845fc8785d54
children 9f211ca82604
branches/tags (none)
files Makefile README.markdown docs/01-installation.markdown docs/02-usage.markdown docs/03-reference.markdown docs/04-changelog.markdown docs/api.lisp docs/footer.markdown docs/index.markdown docs/title package.lisp src/main.lisp

Changes

--- a/Makefile	Wed Nov 21 23:22:18 2018 -0500
+++ b/Makefile	Thu Nov 22 00:03:53 2018 -0500
@@ -1,6 +1,9 @@
-.PHONY: test test-sbcl test-ccl test-ecl test-abcl
+.PHONY: test test-sbcl test-ccl test-ecl test-abcl pubdocs
 
 heading_printer = $(shell which heading || echo 'true')
+sourcefiles = $(shell ffind --full-path --literal .lisp)
+docfiles = $(shell ls docs/*.markdown)
+apidocs = $(shell ls docs/*reference*.markdown)
 
 # Testing ---------------------------------------------------------------------
 test: test-sbcl test-ccl test-ecl test-abcl
@@ -20,3 +23,18 @@
 test-abcl:
 	$(heading_printer) broadway 'ABCL'
 	abcl --load test/run.lisp
+
+# Documentation ---------------------------------------------------------------
+$(apidocs): $(sourcefiles)
+	sbcl --noinform --load docs/api.lisp  --eval '(quit)'
+
+docs/build/index.html: $(docfiles) $(apidocs) docs/title
+	cd docs && ~/.virtualenvs/d/bin/d
+
+docs: docs/build/index.html
+
+pubdocs: docs
+	hg -R ~/src/sjl.bitbucket.org pull -u
+	rsync --delete -a ./docs/build/ ~/src/sjl.bitbucket.org/adopt
+	hg -R ~/src/sjl.bitbucket.org commit -Am 'adopt: Update site.'
+	hg -R ~/src/sjl.bitbucket.org push
--- a/README.markdown	Wed Nov 21 23:22:18 2018 -0500
+++ b/README.markdown	Thu Nov 22 00:03:53 2018 -0500
@@ -1,15 +1,18 @@
 Adopt
 =====
 
-I need **A** **D**amn **OPT**ion parsing library.
-
+I needed **A** **D**amn **OPT**ion parsing library.
 
-Adopt is a simple (~200 LOC) UNIX-style option parser in Common Lisp.
-It depends on `bobbin` and `split-sequence`.
+Adopt is a simple (~150 LOC) UNIX-style option parser in Common Lisp.
+It depends on [Bobbin][] and [split-sequence][].
 
-It aims to be simple and powerful enough for the majority of use cases.
+The test suite currently passes in SBCL, CCL, ECL, and ABCL on Debian.  Further
+testing is welcome.
 
 * **License:** MIT
 * **Documentation:** <https://sjl.bitbucket.io/adopt/>
 * **Mercurial:** <https://bitbucket.org/sjl/adopt/>
 * **Git:** <https://github.com/sjl/adopt/>
+
+[Bobbin]: https://github.com/sjl/bobbin
+[split-sequence]: https://www.cliki.net/split-sequence
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/01-installation.markdown	Thu Nov 22 00:03:53 2018 -0500
@@ -0,0 +1,17 @@
+Installation
+============
+
+Adopt is compatible with Quicklisp, but not *in* Quicklisp (yet?).  You can
+clone the repository into your [Quicklisp local-projects directory][local] for
+now.
+
+The `adopt` system contains the core API and depends on [Bobbin][] and
+[split-sequence][].
+
+The `adopt.test` system contains the test suite, which uses depends on some
+other systems.  You don't need to load this unless you want to run the unit
+tests.
+
+[local]: https://www.quicklisp.org/beta/faq.html#local-project
+[Bobbin]: https://github.com/sjl/bobbin
+[split-sequence]: https://www.cliki.net/split-sequence
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/02-usage.markdown	Thu Nov 22 00:03:53 2018 -0500
@@ -0,0 +1,56 @@
+Usage
+=====
+
+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.
+
+[TOC]
+
+Package
+-------
+
+All core Adopt functions are in the `adopt` package.  You can `:use` that if you
+really want to, but it's probably clearer to use namespaced `adopt:…` symbols.
+
+Example
+-------
+
+    (define-interface *my-program* "[options] FILES"
+      (verbosity
+        "Output extra information."
+        :short #\v
+        :long "verbose"
+        :initial-value 0
+        :reduce (constantly 1))
+      (verbosity
+        "Shut up."
+        :short #\q
+        :long "quiet"
+        :reduce (constantly -1))
+      (ignore
+        "Ignore FILE.  May be specified multiple times."
+        :long "ignore"
+        :parameter "FILE"
+        :reduce #'append1)
+      (name
+        "Your name.  May be specified many times, last one wins."
+        :short #\n
+        :long "name"
+        :parameter "NAME"
+        :reduce #'latest)
+      (meows
+        "Meow."
+        :short #\m
+        :long "meow"
+        :initial-value 0
+        :reduce #'1+))
+    
+    (pprint
+      (multiple-value-list
+        (parse-options *my-program*
+                       '("-vqn" "steve"
+                         "--meow"
+                         "-m" "--meow" "foo"
+                         "--name=sjl" "more"
+                         "--" "--ignore" "bar"
+                         ))))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/03-reference.markdown	Thu Nov 22 00:03:53 2018 -0500
@@ -0,0 +1,108 @@
+# API Reference
+
+The following is a list of all user-facing parts of adopt.
+
+If there are backwards-incompatible changes to anything listed here, they will
+be noted in the changelog and the author will feel bad.
+
+Anything not listed here is subject to change at any time with no warning, so
+don't touch it.
+
+[TOC]
+
+## Package `ADOPT`
+
+### `APPEND1` (function)
+
+    (APPEND1 LIST EL)
+
+Append element `el` to the end of `list`.
+
+  This is implemented as `(append list (list el))`.  It is not particularly
+  fast.
+
+  It is useful as a `:reduce` function when you want to collect all values given
+  for an option.
+
+  
+
+### `ARGV` (function)
+
+    (ARGV)
+
+Return a list of the program name and command line arguments.
+
+  This is not implemented for every Common Lisp implementation.  You can always
+  pass your own values to `parse-options` and `print-usage` if it's not
+  implemented for your particular Lisp.
+
+  
+
+### `DEFINE-INTERFACE` (macro)
+
+    (DEFINE-INTERFACE NAME USAGE &REST OPTIONS)
+
+### `LATEST` (function)
+
+    (LATEST OLD NEW)
+
+Return `new`.
+
+  It is useful as a `:reduce` function when you want to just keep the last-given
+  value for an option.
+
+  
+
+### `PARSE-OPTIONS` (function)
+
+    (PARSE-OPTIONS INTERFACE &OPTIONAL (ARGUMENTS (REST (ARGV))))
+
+Parse `arguments` according to `interface`.
+
+  Two values are returned:
+
+  1. A fresh list of top-level, unaccounted-for arguments that don't correspond
+     to any options defined in `interface`.
+  2. An `EQL` hash map of option `name`s to values.
+
+  See the full usage documentation for more information.
+
+  
+
+### `PRINT-USAGE` (function)
+
+    (PRINT-USAGE INTERFACE &KEY (STREAM *STANDARD-OUTPUT*) (PROGRAM-NAME (FIRST (ARGV))) (WIDTH 80) (OPTION-WIDTH 20))
+
+Print a pretty usage document for `interface` to `stream`.
+
+  `width` should be the total width (in characters) for line-wrapping purposes.
+  Care will be taken to ensure lines are no longer than this, though some edge
+  cases (extremely long short/long option names and parameters) may slip
+  through.
+
+  `option-width` should be the width of the column of short/long options (in
+  characters).  If the short/long option documentation is shorter than this, the
+  option's documentation string will start on the same line.  Otherwise the
+  option's documentation string will start on the next line.
+
+  The result will look something like (assuming a usage string of
+  `"[options] FILES"`):
+
+    (print-usage *program-interface* :width 60 :option-width 15)
+    ; =>
+    ; USAGE: /bin/foo [options] FILES
+    ;
+    ; Options:
+    ;   -v, --verbose    Output extra information.
+    ;   -q, --quiet      Shut up.
+    ;   --ignore FILE    Ignore FILE.  May be specified multiple
+    ;                    times.
+    ;   -n NAME, --name NAME
+    ;                    Your name.  May be specified many times,
+    ;                    last one wins.
+    ;   -m, --meow       Meow.
+    ;   0.........1.... option-width
+    ; 0........1.........2.........3.........4.........5.........6
+
+  
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/04-changelog.markdown	Thu Nov 22 00:03:53 2018 -0500
@@ -0,0 +1,11 @@
+Changelog
+=========
+
+Here's the list of changes in each released version.
+
+[TOC]
+
+Current Development Version
+---------------------------
+
+Adopt is still in active development.  No promises yet.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/api.lisp	Thu Nov 22 00:03:53 2018 -0500
@@ -0,0 +1,20 @@
+(ql:quickload "cl-d-api")
+
+(defparameter *header*
+  "The following is a list of all user-facing parts of adopt.
+
+If there are backwards-incompatible changes to anything listed here, they will
+be noted in the changelog and the author will feel bad.
+
+Anything not listed here is subject to change at any time with no warning, so
+don't touch it.
+
+")
+
+(d-api:generate-documentation
+  :adopt
+  #p"docs/03-reference.markdown"
+  (list "ADOPT")
+  *header*
+  :title "API Reference")
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/footer.markdown	Thu Nov 22 00:03:53 2018 -0500
@@ -0,0 +1,14 @@
+<i>Made with Lisp and love by [Steve Losh][] in Rochester, New York.</i>
+
+[Steve Losh]: http://stevelosh.com/
+
+<script>
+  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+  ga('create', 'UA-15328874-3', 'auto');
+  ga('send', 'pageview');
+
+</script>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/index.markdown	Thu Nov 22 00:03:53 2018 -0500
@@ -0,0 +1,17 @@
+I needed **A** **D**amn **OPT**ion parsing library.
+
+Adopt is a simple (~150 LOC) UNIX-style option parser in Common Lisp.
+It depends on [Bobbin][] and [split-sequence][].
+
+It aims to be simple and powerful enough for the majority of use cases.
+
+* **License:** MIT
+* **Documentation:** <https://sjl.bitbucket.io/adopt/>
+* **Mercurial:** <https://bitbucket.org/sjl/adopt/>
+* **Git:** <https://github.com/sjl/adopt/>
+
+The test suite currently passes in SBCL, CCL, ECL, and ABCL on Debian.  Further
+testing is welcome.
+
+[Bobbin]: https://github.com/sjl/bobbin
+[split-sequence]: https://www.cliki.net/split-sequence
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/title	Thu Nov 22 00:03:53 2018 -0500
@@ -0,0 +1,1 @@
+Adopt
--- a/package.lisp	Wed Nov 21 23:22:18 2018 -0500
+++ b/package.lisp	Thu Nov 22 00:03:53 2018 -0500
@@ -1,3 +1,12 @@
 (defpackage :adopt
   (:use :cl)
-  (:export :parse-options :print-usage :define-interface))
+  (:export
+    :parse-options
+    :print-usage
+    :define-interface
+
+    :argv
+
+    :latest
+    :append1
+    ))
--- a/src/main.lisp	Wed Nov 21 23:22:18 2018 -0500
+++ b/src/main.lisp	Thu Nov 22 00:03:53 2018 -0500
@@ -2,13 +2,36 @@
 
 ;;;; Utils --------------------------------------------------------------------
 (defun append1 (list el)
+  "Append element `el` to the end of `list`.
+
+  This is implemented as `(append list (list el))`.  It is not particularly
+  fast.
+
+  It is useful as a `:reduce` function when you want to collect all values given
+  for an option.
+
+  "
   (append list (list el)))
 
 (defun latest (old new)
+  "Return `new`.
+
+  It is useful as a `:reduce` function when you want to just keep the last-given
+  value for an option.
+
+  "
   (declare (ignore old))
   new)
 
+
 (defun argv ()
+  "Return a list of the program name and command line arguments.
+
+  This is not implemented for every Common Lisp implementation.  You can always
+  pass your own values to `parse-options` and `print-usage` if it's not
+  implemented for your particular Lisp.
+
+  "
   #+sbcl sb-ext:*posix-argv*
   #+ccl ccl:*unprocessed-command-line-arguments*
   #-(or sbcl ccl) (error "ARGV is not supported on this implementation."))
@@ -126,6 +149,17 @@
 
 
 (defun parse-options (interface &optional (arguments (rest (argv))))
+  "Parse `arguments` according to `interface`.
+
+  Two values are returned:
+
+  1. A fresh list of top-level, unaccounted-for arguments that don't correspond
+     to any options defined in `interface`.
+  2. An `EQL` hash map of option `name`s to values.
+
+  See the full usage documentation for more information.
+
+  "
   (let ((toplevel nil)
         (results (make-hash-table)))
     (dolist (option (options interface))
@@ -212,20 +246,19 @@
 
     (print-usage *program-interface* :width 60 :option-width 15)
     ; =>
-    USAGE: /bin/foo [options] FILES
-
-    Options:
-      -v, --verbose    Output extra information.
-      -q, --quiet      Shut up.
-      --ignore FILE    Ignore FILE.  May be specified multiple
-                       times.
-      -n NAME, --name NAME
-                       Your name.  May be specified many times,
-                       last one wins.
-      -m, --meow       Meow.
-
-      0.........10... option-width
-    0........10........20........30........40........50........60 width
+    ; USAGE: /bin/foo [options] FILES
+    ;
+    ; Options:
+    ;   -v, --verbose    Output extra information.
+    ;   -q, --quiet      Shut up.
+    ;   --ignore FILE    Ignore FILE.  May be specified multiple
+    ;                    times.
+    ;   -n NAME, --name NAME
+    ;                    Your name.  May be specified many times,
+    ;                    last one wins.
+    ;   -m, --meow       Meow.
+    ;   0.........1.... option-width
+    ; 0........1.........2.........3.........4.........5.........6
 
   "
   (assert (> width (+ 2 option-width 2)) (width option-width)
@@ -238,45 +271,3 @@
          (doc-width (- width doc-column)))
     (dolist (option (options interface))
       (print-option-usage stream option option-column doc-column doc-width))))
-
-
-;;;; Scratch ------------------------------------------------------------------
-(define-interface *my-program* "[options] FILES"
-  (verbosity
-    "Output extra information."
-    :short #\v
-    :long "verbose"
-    :initial-value 0
-    :reduce (constantly 1))
-  (verbosity
-    "Shut up."
-    :short #\q
-    :long "quiet"
-    :reduce (constantly -1))
-  (ignore
-    "Ignore FILE.  May be specified multiple times."
-    :long "ignore"
-    :parameter "FILE"
-    :reduce #'append1)
-  (name
-    "Your name.  May be specified many times, last one wins."
-    :short #\n
-    :long "name"
-    :parameter "NAME"
-    :reduce #'latest)
-  (meows
-    "Meow."
-    :short #\m
-    :long "meow"
-    :initial-value 0
-    :reduce #'1+))
-
-(pprint
-  (multiple-value-list
-    (parse-options *my-program*
-                   '("-vqn" "steve"
-                     "--meow"
-                     "-m" "--meow" "foo"
-                     "--name=sjl" "more"
-                     "--" "--ignore" "bar"
-                     ))))