emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/taxy-magit-section f9c37e3: Meta: Package taxy-magit-se


From: ELPA Syncer
Subject: [elpa] externals/taxy-magit-section f9c37e3: Meta: Package taxy-magit-section separately
Date: Wed, 6 Oct 2021 16:58:47 -0400 (EDT)

branch: externals/taxy-magit-section
commit f9c37e34277137ce95c4a86949e8f1479583a7f5
Author: Adam Porter <adam@alphapapa.net>
Commit: Adam Porter <adam@alphapapa.net>

    Meta: Package taxy-magit-section separately
---
 .elpaignore                      |    3 -
 README.org                       | 1010 +-------------------------
 examples/README.org              |   50 --
 examples/bookmarky.el            |  189 -----
 examples/deffy.el                |  409 -----------
 examples/diredy.el               |  114 ---
 examples/magit-loggy.el          |   81 ---
 examples/musicy.el               |  123 ----
 examples/taxy-package-report.el  |   53 --
 images/bookmarky.png             |  Bin 12878 -> 0 bytes
 images/deffy.png                 |  Bin 156622 -> 0 bytes
 images/diredy.png                |  Bin 36255 -> 0 bytes
 images/magit-section-numbery.png |  Bin 18985 -> 0 bytes
 images/mascot.png                |  Bin 114906 -> 0 bytes
 images/musicy.png                |  Bin 28010 -> 0 bytes
 taxy-magit-section.info          |  122 ++++
 taxy.el                          |  438 -----------
 taxy.info                        | 1479 --------------------------------------
 18 files changed, 133 insertions(+), 3938 deletions(-)

diff --git a/.elpaignore b/.elpaignore
index a8ea314..e69de29 100644
--- a/.elpaignore
+++ b/.elpaignore
@@ -1,3 +0,0 @@
-examples/musicy.el
-examples/magit-loggy.el
-examples/taxy-org-ql-view.el
\ No newline at end of file
diff --git a/README.org b/README.org
index 0440ef2..9a69f00 100644
--- a/README.org
+++ b/README.org
@@ -1,932 +1,31 @@
-#+TITLE: taxy.el
+#+TITLE: taxy-magit-section.el
 
 #+PROPERTY: LOGGING nil
 
 # Note: This readme works with the org-make-toc 
<https://github.com/alphapapa/org-make-toc> package, which automatically 
updates the table of contents.
 
-#+HTML: <img src="images/mascot.png" align="right">
+[[https://elpa.gnu.org/packages/taxy-magit-section.html][https://elpa.gnu.org/packages/taxy-magit-section.svg]]
 
-[[https://elpa.gnu.org/packages/taxy.html][https://elpa.gnu.org/packages/taxy.svg]]
-
-/Now, where did I put that.../
-
-This library provides a programmable way to classify arbitrary objects into a 
hierarchical taxonomy.  (That's a lot of fancy words to say that this lets you 
automatically put things in nested groups.)
-
-Helpful features include:
-
-+  Dynamic taxonomies :: Objects may be classified into hierarchies 
automatically defined at runtime based on their attributes.
-+  Reusable taxonomies :: Taxonomy definitions may be stored in variables and 
reused in other taxonomies' descendant groups.
-+  Classification domain-specific language :: Easily define a custom DSL used 
to classify items dynamically (which can be extended by users).
-+  Flexible table view :: Based on =magit-section=, with easily defined 
columns (also extendable by users).
+This library renders [[https://github.com/alphapapa/taxy.el][Taxy]] structs 
with [[https://melpa.org/#/magit-section][magit-section]].
 
 * Contents                                                         :noexport:
 :PROPERTIES:
 :TOC:      :include siblings
 :END:
 :CONTENTS:
-- [[#examples][Examples]]
 - [[#installation][Installation]]
-- [[#usage][Usage]]
 - [[#changelog][Changelog]]
 - [[#development][Development]]
 - [[#credits][Credits]]
 :END:
 
-* Examples
-:PROPERTIES:
-:TOC:      :include descendants :depth 1 :ignore (descendants)
-:END:
-:CONTENTS:
-- [[#numbery-starting-basically][Numbery (starting basically)]]
-- [[#lettery-filling-incrementally][Lettery (filling incrementally)]]
-- [[#sporty-understanding-completely][Sporty (understanding completely)]]
-- [[#applications][Applications]]
-:END:
-
-May these examples help you classify your understanding.
-
-** Numbery (starting basically)
-
-Let's imagine a silly taxonomy of numbers below 100:
-
-#+BEGIN_SRC elisp
-  ("Numbery" "A silly taxonomy of numbers."
-   (("< 10" "Numbers below 10"
-     ;; These numbers are leftovers from the sub-taxys below.
-     (0 2 4 6 8)
-     ;; These sub-taxys further classify the numbers below 10 into odd
-     ;; and even.  The odd taxy "consumes" numbers, while the even one
-     ;; doesn't, leaving them to reappear in the parent taxy's items.
-     (("Odd" "(consuming)"
-       (1 3 5 7 9))
-      ("Even" "(non-consuming)"
-       (0 2 4 6 8))))
-    (">= 10" "Numbers above 9"
-     ;; Like in the "< 10" taxy, these numbers are leftovers from this
-     ;; taxy's sub-taxys, three of which are non-consuming.
-     (10 11 13 14 17 19 22 23 25 26 29 31 34 35 37 38 41 43 46 47 49 50 53 55 
58
-         59 61 62 65 67 70 71 73 74 77 79 82 83 85 86 89 91 94 95 97 98)
-     (("Divisible by 3" "(non-consuming)"
-       (12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 
81 84
-           87 90 93 96 99))
-      ("Divisible by 4" "(non-consuming)"
-       (12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96))
-      ("Divisible by 3 or 4" "(consuming)"
-       ;; This taxy consumes numbers it takes in, but since these
-       ;; numbers have already been taken in (without being consumed) by
-       ;; the previous two sibling taxys, they may also appear in them.
-       (12 15 16 18 20 21 24 27 28 30 32 33 36 39 40 42 44 45 48 51 52 54 56 
57 60
-           63 64 66 68 69 72 75 76 78 80 81 84 87 88 90 92 93 96 99))
-      ("Divisible by 5" "(non-consuming)"
-       (10 25 35 50 55 65 70 85 95))))))
-#+END_SRC
-
-You might think about how to produce that by writing some imperative code, but 
=taxy= allows you to do so in a more declarative and functional manner:
-
-#+BEGIN_SRC elisp :exports code
-  (require 'taxy)
-
-  (defvar numbery
-    (make-taxy
-     :name "Numbery"
-     :description "A silly taxonomy of numbers."
-     :taxys (list (make-taxy
-                   :name "< 10"
-                   :description "Numbers below 10 (consuming)"
-                   :predicate (lambda (n) (< n 10))
-                   :taxys (list
-                           ;; These sub-taxys further classify the numbers 
below 10 into odd
-                           ;; and even.  The odd taxy "consumes" numbers, 
while the even one
-                           ;; doesn't, leaving them to reappear in the parent 
taxy's items.
-                           (make-taxy :name "Odd"
-                                      :description "(consuming)"
-                                      :predicate #'oddp)
-                           (make-taxy :name "Even"
-                                      :description "(non-consuming)"
-                                      :predicate #'evenp
-                                      :then #'identity)))
-                  (make-taxy
-                   :name ">= 10"
-                   :description "Numbers above 9 (consuming)"
-                   :predicate (lambda (n) (>= n 10))
-                   :taxys (list
-                           ;; Like in the "< 10" taxy, these sub-taxys further 
classify
-                           ;; the numbers, but only one of them consumes 
numbers it
-                           ;; takes in, leaving the rest to reappear in the 
parent taxy.
-                           (make-taxy :name "Divisible by 3"
-                                      :description "(non-consuming)"
-                                      :predicate (lambda (n) (zerop (mod n 3)))
-                                      :then #'identity)
-                           (make-taxy :name "Divisible by 4"
-                                      :description "(non-consuming)"
-                                      :predicate (lambda (n) (zerop (mod n 4)))
-                                      :then #'identity)
-                           (make-taxy :name "Divisible by 3 or 4"
-                                      :description "(consuming)"
-                                      ;; Since this taxy's `:then' function is 
unset,
-                                      ;; it defaults to `ignore', which causes 
it to
-                                      ;; consume numbers it takes in.  Since 
these
-                                      ;; numbers have already been taken in 
(without
-                                      ;; being consumed) by the previous two 
sibling
-                                      ;; taxys, they also appear in them.
-                                      :predicate (lambda (n) (or (zerop (mod n 
3))
-                                                                 (zerop (mod n 
4)))))
-                           (make-taxy :name "Divisible by 5"
-                                      :description "(non-consuming)"
-                                      :predicate (lambda (n) (zerop (mod n 5)))
-                                      :then #'identity))))))
-
-  (let ((numbers (cl-loop for i below 100 collect i))
-        ;; Since `numbery' is stored in a variable, we use an emptied
-        ;; copy of it to avoid mutating the original taxy.
-        (taxy (taxy-emptied numbery)))
-    (taxy-plain (taxy-fill (reverse numbers) taxy)))
-#+END_SRC
-
-The ~taxy-fill~ function applies the numbers in a "cascade" down the hierarchy 
of "taxys", and the ~taxy-plain~ function returns a meaningful subset of the 
taxys' slots, suitable for display.
-
-** Lettery (filling incrementally)
-
-You can also add more items after the hierarchy has been filled.  In this 
example we'll make a comprehensive taxonomy of letters.  The first sub-taxy 
collects vowels, and the second, by leaving its predicate at the default value, 
~identity~, collects all letters not collected by the first taxy, i.e. 
non-vowels.
-
-#+BEGIN_SRC elisp
-  (defvar lettery
-    (make-taxy
-     :name "Lettery"
-     :description "A comprehensive taxonomy of letters."
-     :taxys (list (make-taxy
-                   :name "Vowels"
-                   :description "You know what those are."
-                   :predicate (lambda (l)
-                                (member-ignore-case l '("a" "e" "i" "o" "u"))))
-                  (make-taxy
-                   :name "Consonants"
-                   :description "Well, if they aren't vowels..."))))
-
-  (taxy-plain
-   (taxy-fill (reverse
-               (cl-loop for l from ?a to ?n
-                        collect (upcase (char-to-string l))))
-              lettery))
-#+END_SRC
-
-That produces:
-
-#+BEGIN_SRC elisp
-  ("Lettery" "A comprehensive taxonomy of letters."
-   (("Vowels" "You know what those are."
-     ("A" "E" "I"))
-    ("Consonants" "Well, if they aren't vowels..."
-     ("B" "C" "D" "F" "G" "H" "J" "K" "L" "M" "N"))))
-#+END_SRC
-
-Oops, we forgot the letters after N!  Let's add them, too:
-
-#+BEGIN_SRC elisp
-  (taxy-plain
-   (taxy-fill (reverse
-               (cl-loop for l from ?n to ?z
-                        collect (upcase (char-to-string l))))
-              lettery))
-#+END_SRC
-
-Which gives us:
-
-#+BEGIN_SRC elisp
-  ("Lettery" "A comprehensive taxonomy of letters."
-   (("Vowels" "You know what those are."
-     ("O" "U" "A" "E" "I"))
-    ("Consonants" "Well, if they aren't vowels..."
-     ("N" "P" "Q" "R" "S" "T" "V" "W" "X" "Y" "Z" "B" "C" "D" "F" "G" "H" "J" 
"K" "L" "M" "N"))))
-#+END_SRC
-
-Oh, they're out of order, now.  That won't do.  Let's fix that:
-
-#+BEGIN_SRC elisp :exports code :results code
-  (taxy-plain
-   (taxy-sort #'string< #'identity lettery))
-#+END_SRC
-
-That's better:
-
-#+BEGIN_SRC elisp
-  ("Lettery" "A comprehensive taxonomy of letters."
-   (("Vowels" "You know what those are."
-     ("A" "E" "I" "O" "U"))
-    ("Consonants" "Well, if they aren't vowels..."
-     ("B" "C" "D" "F" "G" "H" "J" "K" "L" "M" "N" "N" "P" "Q" "R" "S" "T" "V" 
"W" "X" "Y" "Z"))))
-#+END_SRC
-
-** Sporty (understanding completely)
-
-Let's try to understand a few things about sports.  First we'll define a 
struct to make them easier to grasp:
-
-#+BEGIN_SRC elisp :exports code :results silent
-  (cl-defstruct sport
-    name uses venue fun)
-#+END_SRC
-
-Now we'll make a list of sports:
-
-#+BEGIN_SRC elisp :exports code :results silent
-  (defvar sports
-    (list (make-sport :name "Baseball"
-                      :uses '(bat ball glove)
-                      :venue 'outdoor
-                      :fun t)
-          (make-sport :name "Football"
-                      :uses '(ball)
-                      :venue 'outdoor
-                      :fun t)
-          (make-sport :name "Basketball"
-                      :uses '(ball hoop)
-                      :venue 'indoor
-                      :fun t)
-          (make-sport :name "Tennis"
-                      :uses '(ball racket)
-                      :venue 'outdoor
-                      :fun t)
-          (make-sport :name "Racquetball"
-                      :uses '(ball racket)
-                      :venue 'indoor
-                      :fun t)
-          (make-sport :name "Handball"
-                      :uses '(ball glove)
-                      :venue 'indoor
-                      :fun t)
-          (make-sport :name "Soccer"
-                      :uses '(ball)
-                      :venue 'outdoor
-                      :fun nil)
-          (make-sport :name "Disc golf"
-                      :uses '(disc basket)
-                      :venue 'outdoor
-                      :fun t)
-          (make-sport :name "Ultimate"
-                      :uses '(disc)
-                      :venue 'outdoor
-                      :fun t)
-          (make-sport :name "Volleyball"
-                      :uses '(ball)
-                      :venue 'indoor
-                      :fun t)))
-#+END_SRC
-
-And finally we'll define a taxy to organize them.  In this, we use a helper 
macro to make the ~member~ function easier to use in the list of key functions:
-
-#+BEGIN_SRC elisp :exports code :results silent :lexical t
-  (defvar sporty
-    (cl-macrolet ((in (needle haystack)
-                      `(lambda (item)
-                         (when (member ,needle (funcall ,haystack item))
-                           ,needle))))
-      (make-taxy
-       :name "Sporty"
-       :take (lambda (item taxy)
-               (taxy-take-keyed
-                 (list #'sport-venue
-                       (in 'ball 'sport-uses)
-                       (in 'disc 'sport-uses)
-                       (in 'glove 'sport-uses)
-                       (in 'racket 'sport-uses))
-                 item taxy
-                 ;; We set the `:then' function of the taxys
-                 ;; created by `taxy-take-keyed' to `identity'
-                 ;; so they will not consume their items.
-                 :then #'identity)))))
-#+END_SRC
-
-Now let's fill the taxy with the sports and format it:
-
-#+BEGIN_SRC elisp :exports code
-  (thread-last sporty
-    taxy-emptied
-    (taxy-fill sports)
-    (taxy-mapcar #'sport-name)
-    taxy-plain)
-#+END_SRC
-
-#+BEGIN_SRC elisp :exports code
-  ((("Sporty"
-     ((indoor
-       ((ball
-         ("Volleyball" "Basketball")
-         ((glove
-           ("Handball"))
-          (racket
-           ("Racquetball"))))))
-      (outdoor
-       ((disc
-         ("Ultimate" "Disc golf"))
-        (ball
-         ("Soccer" "Football")
-         ((racket
-           ("Tennis"))
-          (glove
-           ("Baseball"))))))))))
-#+END_SRC
-
-That's pretty sporty.  But classifying them by venue first makes the racket 
and glove sports not be listed together.  Let's swap the key functions around 
so the venue is classified at the deepest level of the hierarchy:
-
-#+BEGIN_SRC elisp :exports code :results silent
-  (defvar sporty
-    (cl-macrolet ((in (needle haystack)
-                      `(lambda (item)
-                         (when (member ,needle (funcall ,haystack item))
-                           ,needle))))
-      (make-taxy
-       :name "Sporty"
-       :take (lambda (item taxy)
-               (taxy-take-keyed
-                 (list (in 'ball 'sport-uses)
-                       (in 'disc 'sport-uses)
-                       (in 'glove 'sport-uses)
-                       (in 'racket 'sport-uses)
-                       #'sport-venue)
-                 item taxy
-                 :then #'identity)))))
-
-  (thread-last sporty
-    taxy-emptied
-    (taxy-fill sports)
-    (taxy-mapcar #'sport-name)
-    taxy-plain)
-#+END_SRC
-
-#+BEGIN_SRC elisp :exports code
-  ((("Sporty"
-     ((disc
-       ((outdoor
-         ("Ultimate" "Disc golf"))))
-      (ball
-       ((racket
-         ((indoor
-           ("Racquetball"))
-          (outdoor
-           ("Tennis"))))
-        (indoor
-         ("Volleyball" "Basketball"))
-        (outdoor
-         ("Soccer" "Football"))
-        (glove
-         ((indoor
-           ("Handball"))
-          (outdoor
-           ("Baseball"))))))))))
-#+END_SRC
-
-That's better.  But I'd also like to see a very simple classification to help 
me decide what to play:
-
-#+BEGIN_SRC elisp :exports code
-  (thread-last
-      (make-taxy
-       :name "Funny"
-       :take (lambda (item taxy)
-               (taxy-take-keyed
-                 (list (lambda (sport)
-                         (if (sport-fun sport)
-                             'fun 'boring))
-                       #'sport-venue)
-                 item taxy)))
-    taxy-emptied
-    (taxy-fill sports)
-    (taxy-mapcar #'sport-name)
-    taxy-plain)
-#+END_SRC
-
-#+BEGIN_SRC elisp :exports code
-((("Funny"
-   ((boring
-     ((outdoor
-       ("Soccer"))))
-    (fun
-     ((indoor
-       ("Volleyball" "Handball" "Racquetball" "Basketball"))
-      (outdoor
-       ("Ultimate" "Disc golf" "Tennis" "Football" "Baseball"))))))))
-#+END_SRC
-
-Ah, now I understand.
-
-** Applications
-
-Some example applications may be found in the [[file:examples/][examples 
directory]]:
-
-+  Deffy shows top-level definitions and forms in an Elisp project or file:
-   [[images/deffy.png]]
-+  Diredy rearranges a Dired buffer into groups by file size and type:
-   [[images/diredy.png]]
-+  Musicy shows a music library with tracks categorized by genre, artist, 
year, album, etc:
-   [[images/musicy.png]]
+* COMMENT Examples
 
 * Installation
 
-=taxy= is distributed in [[https://elpa.gnu.org/][GNU ELPA]], which is 
available in Emacs by default.  Use =M-x package-install RET taxy RET=, then 
~(require 'taxy)~ in your Elisp project.
-
-* Usage
-:PROPERTIES:
-:TOC:      :include descendants :depth 1 :ignore (descendants)
-:END:
-:CONTENTS:
-- [[#reusable-taxys][Reusable taxys]]
-- [[#threading-macros][Threading macros]]
-- [[#modifying-filled-taxys][Modifying filled taxys]]
-- [[#dynamic-taxys][Dynamic taxys]]
-- [[#magit-section][Magit section]]
-- [[#reference][Reference]]
-:END:
-
-A taxy is defined with the ~make-taxy~ constructor, like:
-
-#+BEGIN_SRC elisp
-  (make-taxy :name "Numbery"
-             :description "A silly taxonomy of numbers."
-             :predicate #'numberp
-             :then #'ignore
-             :taxys (list ...))
-#+END_SRC
-
-The ~:predicate~ function determines whether an object fits into that taxy.  
If it does, ~taxy-fill~ adds the object to that taxy's descendant ~:taxys~, if 
present, or to its own ~:items~.  The function defaults to ~identity~, so a 
taxy "takes in" any object by default (i.e. if you only apply objects you want 
to classify, there's no need to test them at the top-level taxy).
-
-The ~:then~ function determines what happens to an object after being taken in 
to the taxy's ~:items~: if the function, called with the object, returns a 
non-nil value, that value is applied to other taxys at the same level until one 
of their ~:then~ functions returns nil or no more taxys remain.  The function 
defaults to ~ignore~, which makes a taxy "consume" its items by default.  
Setting the function to, e.g. ~identity~, makes it not consume them, leaving 
them eligible to also be take [...]
-
-After defining a taxy, call ~taxy-fill~ with it and a list of objects to fill 
the taxy's hierarchy.  *Note:* ~taxy-fill~ modifies the taxy given to it 
(filling its ~:items~ and those of its ~:taxys~), so when using a statically 
defined taxy (e.g. one defined with ~defvar~), you should pass ~taxy-fill~ a 
taxy copied with ~taxy-emptied~, which recursively copies a taxy without 
~:items~.
-
-To return a taxy in a more human-readable format (with only relevant fields 
included), use ~taxy-plain~.  You may also use ~taxy-mapcar~ to replace items 
in a taxy with, e.g. a more useful representation.
-
-** Reusable taxys
-
-Since taxys are structs, they may be stored in variables and used in other 
structs (being sure to copy the root taxy with ~taxy-emptied~ before filling).  
For example, this shows using =taxy= to classify Matrix rooms in 
[[https://github.com/alphapapa/ement.el][Ement.el]]:
-
-#+BEGIN_SRC elisp
-  (defun ement-roomy-buffer (room)
-    (alist-get 'buffer (ement-room-local room)))
-
-  (defvar ement-roomy-unread
-    (make-taxy :name "Unread"
-               :predicate (lambda (room)
-                            (buffer-modified-p (ement-roomy-buffer room)))))
-
-  (defvar ement-roomy-opened
-    (make-taxy :name "Opened"
-               :description "Rooms with buffers"
-               :predicate #'ement-roomy-buffer
-               :taxys (list ement-roomy-unread
-                            (make-taxy))))
-
-  (defvar ement-roomy-closed
-    (make-taxy :name "Closed"
-               :description "Rooms without buffers"
-               :predicate (lambda (room)
-                            (not (ement-roomy-buffer room)))))
-
-  (defvar ement-roomy
-    (make-taxy
-     :name "Ement Rooms"
-     :taxys (list (make-taxy
-                   :name "Direct"
-                   :description "Direct messaging rooms"
-                   :predicate (lambda (room)
-                                (ement-room--direct-p room ement-session))
-                   :taxys (list ement-roomy-opened
-                                ement-roomy-closed))
-                  (make-taxy
-                   :name "Non-direct"
-                   :description "Group chat rooms"
-                   :taxys (list ement-roomy-opened
-                                ement-roomy-closed)))))
-#+END_SRC
-
-Note how the taxys defined in the first three variables are used in subsequent 
taxys.  As well, the ~ement-roomy-opened~ taxy has an "anonymous" taxy, which 
collects any rooms that aren't collected by its sibling taxy (otherwise those 
objects would be collected into the parent, "Opened" taxy, which may not always 
be the most useful way to present the objects).
-
-Using those defined taxys, we then fill the ~ement-roomy~ taxy with all of the 
rooms in the user's session, and then use ~taxy-mapcar~ to replace the room 
structs with useful representations for display:
-
-#+BEGIN_SRC elisp
-  (taxy-plain
-   (taxy-mapcar (lambda (room)
-                  (list (ement-room--room-display-name room)
-                        (ement-room-id room)))
-     (taxy-fill (ement-session-rooms ement-session)
-                (taxy-emptied ement-roomy))))
-#+END_SRC
-
-This produces:
-
-#+BEGIN_SRC elisp
-  ("Ement Rooms"
-   (("Direct" "Direct messaging rooms"
-     (("Opened" "Rooms with buffers"
-       (("Unread"
-         (("Lars Ingebrigtsen" "!nope:gnus.org")))))
-      ("Closed" "Rooms without buffers"
-       (("John Wiegley" "!not-really:newartisans.com")
-        ("Eli Zaretskii" "!im-afraid-not:gnu.org")))))
-    ("Non-direct" "Group chat rooms"
-     (("Opened" "Rooms with buffers"
-       (("Unread"
-         (("Emacs" "!WfZsmtnxbxTdoYPkaT:greyface.org")
-          ("#emacs" "!KuaCUVGoCiunYyKEpm:libera.chat")))
-        ;; The non-unread buffers in the "anonymous" taxy.
-        ((("magit/magit" "!HZYimOcmEAsAxOcgpE:gitter.im")
-          ("Ement.el" "!NicAJNwJawmHrEhqZs:matrix.org")
-          ("#emacsconf" "!UjTTDnYmSAslLTtMCF:libera.chat")
-          ("Emacs Matrix Client" "!ZrZoyXEyFrzcBZKNis:matrix.org")
-          ("org-mode" "!rUhEinythPhVTdddsb:matrix.org")
-          ("This Week in Matrix (TWIM)" "!xYvNcQPhnkrdUmYczI:matrix.org")))))
-      ("Closed" "Rooms without buffers"
-       (("#matrix-spec" "!NasysSDfxKxZBzJJoE:matrix.org")
-        ("#commonlisp" "!IiGsrmKRHzpupHRaKS:libera.chat")
-        ("Matrix HQ" "!OGEhHVWSdvArJzumhm:matrix.org")
-        ("#lisp" "!czLxhhEegTEGNKUBgo:libera.chat")
-        ("Emacs" "!gLamGIXTWBaDFfhEeO:matrix.org")
-        ("#matrix-dev:matrix.org" "!jxlRxnrZCsjpjDubDX:matrix.org")))))))
-#+END_SRC
-
-** Threading macros
-
-If you happen to like macros, ~taxy~ works well with threading (i.e. 
~thread-last~ or ~->>~):
-
-#+BEGIN_SRC elisp
-  (thread-last ement-roomy
-    taxy-emptied
-    (taxy-fill (ement-session-rooms ement-session))
-    (taxy-mapcar (lambda (room)
-                   (list (ement-room--room-display-name room)
-                         (ement-room-id room))))
-    taxy-plain)
-#+END_SRC
-
-** Modifying filled taxys
-
-Sometimes it's necessary to modify a taxy after filling it with objects, e.g. 
to sort the items and/or the sub-taxys.  For this, use the function 
~taxy-mapc-taxys~ (a.k.a. ~taxy-mapc*~).  For example, in the sample 
application [[file:examples/musicy.el][musicy.el]], the taxys and their items 
are sorted after filling, like so:
-
-#+BEGIN_SRC elisp
-  (defun musicy-files (files)
-    (thread-last musicy-taxy
-      taxy-emptied
-      (taxy-fill files)
-      ;; Sort sub-taxys by their name.
-      (taxy-sort* #'string< #'taxy-name)
-      ;; Sort sub-taxys' items by name.
-      (taxy-sort #'string< #'identity)
-      taxy-magit-section-pp))
-#+END_SRC
-
-** Dynamic taxys
-:PROPERTIES:
-:TOC:      :include descendants
-:END:
-:CONTENTS:
-- [[#multi-level-dynamic-taxys][Multi-level dynamic taxys]]
-- [[#chains-of-independent-multi-level-dynamic-taxys]["Chains" of independent, 
multi-level dynamic taxys]]
-- [[#defining-a-classification-domain-specific-language][Defining a 
classification domain-specific language]]
-:END:
-
-You may not always know in advance what taxonomy a set of objects fits into, 
so =taxy= lets you add taxys dynamically by using the ~:take~ function to add a 
taxy when an object is "taken into" a parent taxy's items.  For example, you 
could dynamically classify buffers by their major mode like so:
-
-#+BEGIN_SRC elisp :exports code
-  (defun buffery-major-mode (buffer)
-    (buffer-local-value 'major-mode buffer))
-
-  (defvar buffery
-    (make-taxy
-     :name "Buffers"
-     :taxys (list
-             (make-taxy
-              :name "Modes"
-              :take (apply-partially #'taxy-take-keyed (list 
#'buffery-major-mode))))))
-
-  ;; Note the use of `taxy-emptied' to avoid mutating the original taxy 
definition.
-  (taxy-plain
-   (taxy-fill (buffer-list)
-              (taxy-emptied buffery)))
-#+END_SRC
-
-The taxy's ~:take~ function is set to the ~taxy-take-keyed~ function, 
partially applied with the ~buffery-major-mode~ function as its list of 
~key-fns~ (~taxy-fill~ supplies the buffer and the taxy as arguments), and it 
produces this taxonomy of buffers:
-
-#+BEGIN_SRC elisp
-  ("Buffers"
-   (("Modes"
-     ((magit-process-mode
-       (#<buffer magit-process: taxy.el> #<buffer magit-process: > #<buffer 
magit-process: notes>))
-      (messages-buffer-mode
-       (#<buffer *Messages*>))
-      (special-mode
-       (#<buffer *Warnings*> #<buffer *elfeed-log*>))
-      (dired-mode
-       (#<buffer ement.el<emacs>>))
-      (Custom-mode
-       (#<buffer *Customize Apropos*>))
-      (fundamental-mode
-       (#<buffer  *helm candidates:Bookmarks*> #<buffer *Backtrace*>))
-      (magit-diff-mode
-       (#<buffer magit-diff: taxy.el> #<buffer magit-diff: notes> #<buffer 
magit-diff: ement.el>))
-      (compilation-mode
-       (#<buffer *compilation*> #<buffer *Compile-Log*>))
-      (Info-mode
-       (#<buffer  *helm info temp buffer*> #<buffer *info*>))
-      (help-mode
-       (#<buffer *Help*>))
-      (emacs-lisp-mode
-       (#<buffer ement.el<ement.el>> #<buffer ement-room-list.el> #<buffer 
*scratch*>
-                 #<buffer ement-room.el> #<buffer init.el> #<buffer bufler.el>
-                 #<buffer dash.el> #<buffer *Pp Eval Output*> #<buffer 
taxy.el> #<buffer scratch.el>))))))
-#+END_SRC
-
-*** Multi-level dynamic taxys
-
-Of course, the point of taxonomies is that they aren't restricted to a single 
level of depth, so you may also use the function ~taxy-take-keyed~ to 
dynamically make multi-level taxys.
-
-Expanding on the previous example, we use ~cl-labels~ to define functions 
which are used in the taxy's definition, which are used in the ~:take~ 
function, which calls ~taxy-take-keyed~ (rather than using ~apply-partially~ 
like in the previous example, we use a lambda function, which performs better 
than partially applied functions).  Then when the taxy is filled, a multi-level 
hierarchy is created dynamically, organizing buffers first by their directory, 
and then by mode in each directory.
+=taxy-magit-section= is distributed in [[https://elpa.gnu.org/][GNU ELPA]], 
which is available in Emacs by default.  Use =M-x package-install RET 
taxy-magit-section RET=, then ~(require 'taxy-magit-section)~ in your Elisp 
project.
 
-# MAYBE: A macro to define :take functions more concisely.
-
-#+BEGIN_SRC elisp :exports code
-  (defvar buffery
-    (cl-labels ((buffer-mode (buffer) (buffer-local-value 'major-mode buffer))
-                (buffer-directory (buffer) (buffer-local-value 
'default-directory buffer)))
-      (make-taxy
-       :name "Buffers"
-       :taxys (list
-               (make-taxy
-                :name "Directories"
-                :take (lambda (item taxy)
-                        (taxy-take-keyed (list #'buffer-directory 
#'buffer-mode) item taxy)))))))
-
-  (taxy-plain
-   (taxy-fill (buffer-list)
-              (taxy-emptied buffery)))
-#+END_SRC
-
-That produces a list like:
-
-#+BEGIN_SRC elisp
-  ("Buffers"
-   (("Directories"
-     (("~/src/emacs/ement.el/"
-       ((dired-mode
-         (#<buffer ement.el<emacs>))
-        (emacs-lisp-mode
-         (#<buffer ement.el<ement.el> #<buffer ement-room-list.el> #<buffer 
ement-room.el>))
-        (magit-diff-mode
-         (#<buffer magit-diff: ement.el>))))
-      ("~/src/emacs/taxy.el/"
-       ((dired-mode
-         (#<buffer taxy.el<emacs>))
-        (Info-mode
-         (#<buffer *info*>))
-        (magit-status-mode
-         (#<buffer magit: taxy.el>))
-        (emacs-lisp-mode
-         (#<buffer taxy-magit-section.el> #<buffer taxy.el<taxy.el> #<buffer 
scratch.el>))))))))
-#+END_SRC
-
-*** "Chains" of independent, multi-level dynamic taxys
-:PROPERTIES:
-:ID:       8aec3671-ee22-44a0-968c-81443f4dcd74
-:END:
-
-/Naming things is hard./
-
-Going a step further, each element in the ~taxy-take-keyed~ function's 
~KEY-FNS~ argument may be a list of functions (or a list of lists of functions, 
etc.), which creates a "chain" of "independent" dynamic taxys.  Each such chain 
may be said to "short-circuit" the filling process in that, when an object is 
"taken" by the first key function in a chain, the object is not "offered" to 
other functions outside that chain.  This allows each dynamic sub-taxy to have 
its own set of sub-taxys, r [...]
-
-Building on the ~sporty~ example, let's define a taxy in which outdoor sports 
are classified only by whether they involve a disc, but indoor sports are 
additionally classified by whatever equipment they may use:
-
-#+BEGIN_SRC elisp :exports code :results silent :lexical t
-  (defvar sporty-dynamic
-    (cl-macrolet ((in (needle haystack)
-                      `(lambda (item)
-                         (when (member ,needle (funcall ,haystack item))
-                           ,needle))))
-      (cl-labels ((outdoor-p
-                   (sport) (when (eq 'outdoor (sport-venue sport))
-                             "Outdoor"))
-                  (indoor-p
-                   (sport) (when (eq 'indoor (sport-venue sport))
-                             "Indoor"))
-                  (disc-p
-                   (sport) (if (funcall (in 'disc 'sport-uses) sport)
-                               'disc
-                             'non-disc)))
-        (make-taxy
-         :name "Sporty (dynamic)"
-         :take (lambda (item taxy)
-                 (taxy-take-keyed
-                   (list (list #'outdoor-p #'disc-p)
-                         (list #'indoor-p
-                               (in 'ball 'sport-uses)
-                               (in 'disc 'sport-uses)
-                               (in 'glove 'sport-uses)
-                               (in 'racket 'sport-uses)))
-                   item taxy))))))
-#+END_SRC
-
-Now let's fill the taxy with the sports and format it:
-
-#+BEGIN_SRC elisp :exports code :results code
-  (thread-last sporty-dynamic
-    taxy-emptied
-    (taxy-fill sports)
-    (taxy-mapcar #'sport-name)
-    taxy-plain)
-#+END_SRC
-
-#+BEGIN_SRC elisp :exports code
-  ("Sporty (dynamic)"
-   (("Indoor"
-     ((ball
-       ("Volleyball" "Basketball")
-       ((glove
-         ("Handball"))
-        (racket
-         ("Racquetball"))))))
-    ("Outdoor"
-     ((disc
-       ("Ultimate" "Disc golf"))
-      (non-disc
-       ("Soccer" "Tennis" "Football" "Baseball"))))))
-#+END_SRC
-
-*** Defining a classification domain-specific language
-
-When writing a larger Taxy-based application, it may be necessary to define a 
number of key functions that would be unwieldy to manage in a ~cl-labels~ form. 
 For this case, Taxy provides the macro ~taxy-define-key-definer~ to easily 
define Taxy key functions in an application library.  Those functions are then 
passed to the function ~taxy-make-take-function~ at runtime, along with a list 
of keys being used to classify items.  Using these allows key functions to be 
defined in top-level f [...]
-
-Extending the previous ~sporty~ example, let's redefine its key functions 
using ~taxy-define-key-definer~:
-
-#+begin_src elisp :exports code :results silent :lexical t
-  (taxy-define-key-definer sporty-define-key
-    sporty-keys "sporty"
-    "Define a `sporty' key function.")
-
-  (sporty-define-key disc-based ()
-    (if (member 'disc (sport-uses item))
-        "Disc-based"
-      "Non-disc-based"))
-
-  (sporty-define-key uses (&optional thing)
-    (pcase thing
-      (`nil (sport-uses item))
-      (_ (when (cl-typecase (sport-uses item)
-                 (symbol (equal thing (sport-uses item)))
-                 (list (member thing (sport-uses item))))
-           thing))))
-
-  (sporty-define-key venue (&optional place)
-    (pcase place
-      (`nil (sport-venue item))
-      (_ (when (equal place (sport-venue item))
-           (sport-venue item)))))
-#+end_src
-
-Now we'll define the default keys to use when classifying items.  This list is 
equivalent to the one passed to ~taxy-take-keyed~ in the previous, "Chains" 
example.
-
-#+begin_src elisp :exports code :results silent :lexical t
-  (defvar sporty-default-keys
-    '(
-      ((venue 'outdoor)
-       disc-based)
-
-      ((venue 'indoor)
-       (uses 'ball)
-       (uses 'disc)
-       (uses 'glove)
-       (uses 'racket))))
-#+end_src
-
-Finally, rather than using a pre-made taxy struct, we make one at runtime, 
making the ~:take~ function with ~taxy-make-take-function~.
-
-#+begin_src elisp :exports code :results code :lexical t
-  (let ((taxy (make-taxy
-               :name "Sporty (DSL)"
-               :take (taxy-make-take-function sporty-default-keys
-                                              sporty-keys))))
-    (thread-last taxy
-      (taxy-fill sports)
-      (taxy-mapcar #'sport-name)
-      taxy-plain))
-#+end_src
-
-Which gives us:
-
-#+RESULTS:
-#+begin_src elisp
-  ("Sporty (DSL)"
-   ((indoor
-     ((ball
-       ("Volleyball" "Basketball")
-       ((glove
-         ("Handball"))
-        (racket
-         ("Racquetball"))))))
-    (outdoor
-     (("Disc-based"
-       ("Ultimate" "Disc golf"))
-      ("Non-disc-based"
-       ("Soccer" "Tennis" "Football" "Baseball"))))))
-#+end_src
-
-As you can see, the result is the same as that in the previous example, but 
we've defined a kind of DSL for grouping sports in a modular, extendable way.
-
-This also allows the grouping keys to be easily changed at runtime, producing 
a different result.  For example, we could group sports by, first, whether they 
use a ball, and then by venue.  Let's do this in a function so that users can 
pass their own list of keys:
-
-#+begin_src elisp :exports code :results code :lexical t
-  (cl-defun sporty-classify (sports &key (keys sporty-default-keys))
-    (declare (indent defun))
-    (let* ((taxy (make-taxy
-                  :name "Sporty (DSL)"
-                  :take (taxy-make-take-function keys
-                                                 sporty-keys))))
-      (thread-last taxy
-        (taxy-fill sports)
-        (taxy-mapcar #'sport-name)
-        taxy-plain)))
-
-  (sporty-classify sports
-    :keys '((uses 'ball) venue))
-#+end_src
-
-And this produces:
-
-#+RESULTS:
-#+begin_src elisp :exports code
-  ("Sporty (DSL)"
-   ((outdoor
-     ("Ultimate" "Disc golf"))
-    (ball
-     ((indoor
-       ("Volleyball" "Handball" "Racquetball" "Basketball"))
-      (outdoor
-       ("Soccer" "Tennis" "Football" "Baseball"))))))
-#+end_src
-
-** Magit section
-
-Showing a =taxy= with =magit-section= is very easy:
-
-#+BEGIN_SRC elisp :exports code
-  (require 'taxy-magit-section)
-
-  ;; Using the `numbery' taxy defined in earlier examples:
-  (thread-last numbery
-    taxy-emptied ;; Get an empty copy of the taxy, since it's defined in a 
variable.
-    (taxy-fill (reverse (cl-loop for i below 30 collect i)))
-    taxy-magit-section-pp)
-#+END_SRC
-
-That shows a buffer like this:
-
-[[images/magit-section-numbery.png]]
-
-Note that while =taxy-magit-section.el= is installed with the =taxy= package, 
the =magit-section= package is not automatically installed with it.
-
-** Reference
-
-In Emacs 28+, see also =M-x shortdoc-display-group RET taxy RET=.
-
-*** Functions
-
-- taxy-flatten (taxy) ::
-  Return a list of items in =taxy= and its sub-taxys.
-
-- taxy-emptied (taxy) ::
-  Return a copy of =taxy= without items.  Omits =taxy=’s items and those of 
its descendant taxys.  Useful when reusing taxy definitions.
-
-- taxy-fill (items taxy) ::
-  Fill =taxy= with =items= according to its definition.
-
-- taxy-make-take-function (keys aliases) ::
-  Return a taxy "take" function for =keys=.  Each of =keys= should be a 
function alias defined in =aliases=, or a list of such =key-fns= (recursively, 
ad infinitum, approximately).  =aliases= should be an alist mapping aliases to 
functions (such as defined with a definer defined by ~taxy-define-key-definer~).
-
-- taxy-mapc-taxys (fn taxy) ::
-  *Alias:* ~taxy-mapc*~
-
-  Return =taxy= having applied =fn= to it and its descendants.  Does not copy 
=taxy=.  Destructively modifies =taxy=, if =fn= does.
-
-- taxy-mapcar-items (fn taxy) ::
-  *Alias:* ~taxy-mapcar~
-
-  Return copy of =taxy=, having replaced its items with the value of =fn= on 
each.  Replaces every item in =taxy= and its descendants.  Useful to replace 
items with a more useful form after classification.
-
-- taxy-plain (taxy) ::
-  Return a list of the human-readable parts of =taxy=.
-
-- taxy-size (taxy) ::
-  Return the number of items =taxy= holds.  Includes items in =taxy= ’s 
sub-taxys.
-
-- taxy-sort-items (pred key taxy) ::
-  *Alias:* ~taxy-sort~
-
-  Sort =taxy= ’s items by =pred= and =key=.  Sorts items in =taxy= and its 
sub-taxys.  =key= is passed to ~cl-sort~, which see.
-
-- taxy-sort-taxys (pred key taxy) ::
-  *Alias:* ~taxy-sort*~
-
-  Sort =taxy= ’s sub-taxys by =pred= and =key=.  =key= is passed to ~cl-sort~, 
which see.
-
-*** Macros
-
-- taxy-define-key-definer (name variable prefix docstring) ::
-  Define a macro =name= that defines a key-function-defining macro.  The 
defined macro, having string =docstring=, associates the defined key functions 
with their aliases in an alist stored in symbol =variable=.  The defined key 
functions are named having string =prefix=, which will have a hyphen appended 
to it.  The key functions take one or more arguments, the first of which is the 
item being tested, bound within the function to ~item~.
+* COMMENT Usage
 
 * Changelog
 :PROPERTIES:
@@ -935,101 +34,14 @@ In Emacs 28+, see also =M-x shortdoc-display-group RET 
taxy RET=.
 
 ** 0.9-pre
 
-Nothing new yet.
-
-** 0.8
-
-*** Additions
-
-+  Short documentation group for Emacs 28+.
-
-*** Fixes
-
-+  Require =map= for ~pcase~ pattern.
-
-** 0.7
-
-*** Additions
-
-+  Function ~taxy-flatten~ returns a list of the items in a taxy and its 
sub-taxys.
-+  Function/macro reference documentation.
-+  Example application =bookmarky= lists Emacs bookmarks grouped with Taxy.
-
-** 0.6
-
-*** Additions
-
-+ Sorting functions:
-  + ~taxy-sort-items~ (alias: ~taxy-sort~) sorts the items in a taxy and its 
sub-taxys.
-  + ~taxy-sort-taxys~ (alias: ~taxy-sort*~) sorts a taxy's sub-taxys.
-+ Defining classification domain-specific languages:
-  + Macro ~taxy-define-key-definer~ defines a key-function-defining macro.
-  + Function ~taxy-make-take-function~ makes a ~:take~ function using a list 
of key functions and a set of classification keys.
-+ Table-like, column-based formatting system for ~taxy-magit-section~:
-  + Function ~taxy-magit-section-format-items~, which formats items by columns.
-  + Variable ~taxy-magit-section-insert-indent-items~, which controls whether 
~taxy-magit-section-insert~ applies indentation to each item.  (Used to disable 
that behavior when items are pre-indented strings, e.g. as formatted by 
~taxy-magit-section-format-items~.)
-+ Example application =deffy=, which shows an overview of top-level 
definitions and forms in an Elisp project or file.  (Likely to be published as 
a separate package later.)
-
-** 0.5
-
-*** Additions
-
-+  Function ~taxy-magit-section-insert~ takes new arguments:
-     -  ~:initial-depth~ sets the level at which the first level of hierarchy 
is considered to be at, for purposes of indentation.  Setting it to a negative 
number prevents indentation of so many levels (i.e. setting it to -1 causes the 
first two levels to be unindented, since the first level will be considered to 
be at depth -1, and the second at depth 0).
-     -  ~:blank-between-depth~ sets the level up to which blank lines are 
inserted between sections (i.e. setting it to 1 causes blank lines to be 
inserted between sections up to depth 1, but not between sections deeper than 
that).
-+  Struct ~taxy-magit-section~ has a new ~heading-face~ slot, a function which 
takes a depth level argument and returns the face with which to propertize that 
section's heading.
-+  New example ~taxy-package-report~.
-
-*** Fixes
-
-+  Example ~diredy~ referred to an old function name.
-
-** 0.4
-
-+  Incremented version to cause a new ELPA release (since removing a file that 
wasn't intended to be distributed on ELPA).
-
-** 0.3
-
-*** Changes
-
-+  Within the ~taxy~ struct and related functions, the term =objects= is 
renamed to =items=, which is shorter and has the same meaning.  This makes code 
a bit more concise (e.g. ~(taxy-objects taxy)~ becomes ~(taxy-items taxy)~).
-
-*** Fixes
-
-+  Function ~taxy-fill~ always calls a taxy's ~:take~ function if defined.  
(Fixing "chains" of dynamic taxys.)
-+  Function ~taxy-magit-section-insert~ applies text properties from the 
inserted string to the indentation string (so commands that rely on text 
properties at the beginning of a line will work).
-
-** 0.2
-
-*** Changes
-
-+  Function ~taxy-take-keyed*~ is renamed to ~taxy-take-keyed~, replacing the 
old function: it's more powerful, and there's little reason to maintain two 
versions.
-
-*** Additions
-
-+  Struct ~taxy~ now has a ~:make~ slot, a function called to make new 
sub-taxys by ~take-take-keyed~ (defaulting to ~make-taxy~).  This is useful 
when defining structs specialized on ~taxy~.
-+  Struct ~taxy-magit-section~ now has an ~:indent~ slot, a number of 
characters by which to indent each level of sub-taxy, applied automatically by 
function ~taxy-magit-section-insert~.
-+  Each element of the new ~taxy-take-keyed~'s ~KEY-FNS~ argument may now be a 
function or a list of functions (or a list of a list of functions, etc.).  
Lists of functions create "chains" of independent, dynamic taxys descending 
from a single root taxy.  See 
[[id:8aec3671-ee22-44a0-968c-81443f4dcd74][example]].
-
-*** Fixes
-
-+  ~taxy-magit-section~'s ~insert-object~ function.
-+  ~taxy-fill~ now applies objects to the root taxy if no sub-taxys take them.
-
-** 0.1
-
-First tagged version.
++  =taxy-magit-section= moved to separate package.
 
 * Development
 :PROPERTIES:
 :TOC:      :ignore (descendants)
 :END:
 
-Bug reports, feature requests, suggestions — /oh my/!
-
-** Copyright assignment
-
-This package is part of [[https://www.gnu.org/software/emacs/][GNU Emacs]], 
being distributed in [[https://elpa.gnu.org/][GNU ELPA]].  Contributions to 
this project must follow GNU guidelines, which means that, as with other parts 
of Emacs, patches of more than a few lines must be accompanied by having 
assigned copyright for the contribution to the FSF.  Contributors who wish to 
do so may contact [[mailto:emacs-devel@gnu.org][emacs-devel@gnu.org]] to 
request the assignment form.
+=taxy-magit-section= is developed in a branch of the 
[[https://github.com/alphapapa/taxy.el][main Taxy repo]].
 
 * Credits
 
@@ -1054,8 +66,8 @@ GPLv3
 ** Info export options
 
 #+TEXINFO_DIR_CATEGORY: Emacs
-#+TEXINFO_DIR_TITLE: Taxy: (taxy)
-#+TEXINFO_DIR_DESC: Programmable taxonomical grouping for arbitrary objects
+#+TEXINFO_DIR_TITLE: Taxy Magit Section: (taxy-magit-section)
+#+TEXINFO_DIR_DESC: Render Taxy structs with Magit Section
 
 # NOTE: We could use these, but that causes a pointless error, 
"org-compile-file: File "..README.info" wasn't produced...", so we just rename 
the files in the after-save-hook instead.
 # #+TEXINFO_FILENAME: taxy.info
@@ -1067,7 +79,7 @@ GPLv3
 
 # Local Variables:
 # before-save-hook: org-make-toc
-# after-save-hook: (lambda nil (when (and (require 'ox-texinfo nil t) 
(org-texinfo-export-to-info)) (delete-file "README.texi") (rename-file 
"README.info" "taxy.info" t)))
+# after-save-hook: (lambda nil (when (and (require 'ox-texinfo nil t) 
(org-texinfo-export-to-info)) (delete-file "README.texi") (rename-file 
"README.info" "taxy-magit-section.info" t)))
 # org-export-initial-scope: buffer
 # org-comment-string: "NOTCOMMENT"
 # End:
diff --git a/examples/README.org b/examples/README.org
deleted file mode 100644
index 478f35a..0000000
--- a/examples/README.org
+++ /dev/null
@@ -1,50 +0,0 @@
-#+TITLE: Taxy Examples
-
-Some example applcations using ~taxy~.
-
-* Bookmarky
-
-=bookmarky= shows Emacs bookmarks grouped in a customizeable way:
-
-[[../images/bookmarky.png]]
-
-* Deffy
-
-=deffy= shows definitions and top-level forms in an Elisp project or file.
-
-[[../images/deffy.png]]
-
-* Diredy
-
-[[file:diredy.el][Diredy]] rearranges a Dired buffer, grouping files and 
directories by their size and MIME type.  Use it like:
-
-#+BEGIN_SRC elisp
-  (require 'diredy)
-#+END_SRC
-
-Then open a Dired buffer and =M-x diredy RET=, and it will be rearranged like 
so:
-
-[[../images/diredy.png]]
-
-* Musicy
-
-[[file:musicy.el][Musicy]] displays a music library in a ~magit-section~ 
buffer.  Use it like:
-
-#+BEGIN_SRC elisp
-  (require 'musicy)
-
-  (musicy "~/Music")
-#+END_SRC
-
-Since it calls the =mediainfo= program on every file, it can be slow on large 
music libraries, so you might want to test it on only a subset of them, like:
-
-#+BEGIN_SRC elisp
-  (musicy-files
-   (seq-take (directory-files-recursively
-              "~/Music" (rx "." (or "mp3" "ogg") eos))
-             100))
-#+END_SRC
-
-The resulting buffer shows tracks organized by genre, then artist, then year, 
then album, then track name:
-
-[[../images/musicy.png]]
diff --git a/examples/bookmarky.el b/examples/bookmarky.el
deleted file mode 100644
index 9fa5e53..0000000
--- a/examples/bookmarky.el
+++ /dev/null
@@ -1,189 +0,0 @@
-;;; bookmarky.el --- List bookmarks organized with Taxy  -*- lexical-binding: 
t; -*-
-
-;; Copyright (C) 2021  Free Software Foundation, Inc.
-
-;; Author: Adam Porter <adam@alphapapa.net>
-;; Keywords: convenience, lisp
-;; Package-Requires: ((emacs "27.2") (taxy "0.7"))
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This library provides commands that show bookmarks organized in a
-;; flexible, customizeable hierarchy and table.
-
-;;; Code:
-
-(require 'bookmark)
-(require 'cl-lib)
-(require 'subr-x)
-
-(require 'taxy)
-(require 'taxy-magit-section)
-
-(defgroup bookmarky nil
-  "List bookmarks grouped with Taxy."
-  :group 'bookmark)
-
-;;;; Keys
-
-(cl-eval-when (compile load eval)
-  ;; I don't understand why using `cl-eval-when' is necessary, but it
-  ;; seems to be.
-  (taxy-define-key-definer bookmarky-define-key bookmarky-keys "bookmarky-key"
-    ;; FIXME: Docstring.
-    ""))
-
-(bookmarky-define-key directory (&optional directory &key descendant-p name)
-  "Return key string for ITEM's directory, or nil.
-If DIRECTORY is specified, return key string if ITEM's `filename'
-is in DIRECTORY.  If DESCENDANT-P, return key string if ITEM's
-`filename' is a descendant of DIRECTORY.  DIRECTORY should end in
-a slash."
-  ;; It seems like undesirable overhead to `file-truename' every
-  ;; time this function is called, but avoiding that wouldn't be easy.
-  (when-let (filename (bookmark-prop-get item 'filename))
-    (setf filename (expand-file-name filename))
-    (pcase directory
-      ('nil (concat "Directory: " (file-name-directory filename)))
-      (_
-       (cl-assert (directory-name-p directory) t
-                  "DIRECTORY should end in a directory separator character 
(i.e. a slash)")
-       (setf directory (file-truename directory))
-       (pcase descendant-p
-         ('nil (when (equal directory (file-truename filename))
-                 (or name (concat "Directory: " directory))))
-         (_ (when (string-prefix-p directory filename)
-              (or name (concat "Directory: " directory)))))))))
-
-(bookmarky-define-key filename (&key name regexp)
-  "Return NAME if bookmark ITEM's filename matches REGEXP, or without REGEXP, 
the filename."
-  (when-let (filename (bookmark-prop-get item 'filename))
-    (pcase regexp
-      (`nil filename)
-      (_ (when (string-match-p regexp filename)
-           name)))))
-
-(bookmarky-define-key handler (handlers &key name)
-  "Return NAME if bookmark ITEM's handler is in HANDLERS."
-  (when-let (handler (bookmark-prop-get item 'handler))
-    (when (member handler handlers)
-      name)))
-
-(bookmarky-define-key name (&key name regexp)
-  "Return NAME if bookmark ITEM's name matches REGEXP."
-  (when (string-match-p regexp (car item))
-    name))
-
-(defvar bookmarky-default-keys
-  '(
-    ((handler '(burly-bookmark-handler) :name "Burly"))
-    ((directory "~/src/emacs/" :name "Emacs" :descendant-p t)))
-  "Default keys.")
-
-;;;; Columns
-
-(cl-eval-when (compile load eval)
-  ;; I don't understand why using `cl-eval-when' is necessary, but it
-  ;; seems to be.
-  (taxy-magit-section-define-column-definer "bookmarky"))
-
-(bookmarky-define-column "Name" (:max-width 45 :face bookmark-menu-bookmark)
-  (car item))
-
-(bookmarky-define-column "File" (:max-width nil :face font-lock-doc-face)
-  (bookmark-prop-get item 'filename))
-
-(unless bookmarky-columns
-  ;; TODO: Automate this or document it
-  (setq-default bookmarky-columns
-               (get 'bookmarky-columns 'standard-value)))
-
-;;;; Variables
-
-(defvar bookmarky-mode-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map (kbd "RET") #'bookmarky-RET)
-    (define-key map [mouse-1] #'bookmarky-mouse-1)
-    map))
-
-;;;; Commands
-
-;;;###autoload
-(cl-defun bookmarky (&key (keys bookmarky-default-keys)
-                         (buffer-name "*Bookmarky*")
-                         visibility-fn display-buffer-action)
-  "Show bookmarks grouped with Taxy."
-  (interactive)
-  (let (format-table column-sizes)
-    (cl-labels ((format-item (item) (gethash item format-table))
-               (make-fn (&rest args)
-                        (apply #'make-taxy-magit-section
-                               :make #'make-fn
-                               :format-fn #'format-item
-                               :level-indent bookmarky-level-indent
-                               :visibility-fn visibility-fn
-                               args)))
-      (with-current-buffer (get-buffer-create buffer-name)
-       (bookmarky-mode)
-       (let* ((taxy (thread-last
-                        (make-fn
-                         :name "Bookmarky"
-                         :take (taxy-make-take-function keys bookmarky-keys))
-                      (taxy-fill bookmark-alist)
-                      (taxy-sort* #'string< #'taxy-name)
-                      (taxy-sort #'string< #'car)))
-              (taxy-magit-section-insert-indent-items nil)
-              (inhibit-read-only t)
-              (format-cons (taxy-magit-section-format-items
-                            bookmarky-columns bookmarky-column-formatters 
taxy)))
-         (setf format-table (car format-cons)
-               column-sizes (cdr format-cons)
-               header-line-format (taxy-magit-section-format-header
-                                   column-sizes bookmarky-column-formatters))
-          (delete-all-overlays)
-          (erase-buffer)
-         (save-excursion
-           (taxy-magit-section-insert taxy :items 'last
-             ;; :blank-between-depth bufler-taxy-blank-between-depth
-             :initial-depth 0))))
-      (pop-to-buffer buffer-name display-buffer-action))))
-
-(defun bookmarky-revert (_ignore-auto _noconfirm)
-  "Revert current Bookmarky buffer."
-  (interactive)
-  (bookmarky))
-
-(defun bookmarky-mouse-1 (event)
-  "Call `bookmarky-RET' with point at EVENT's position."
-  (interactive "e")
-  (mouse-set-point event)
-  (call-interactively #'bookmarky-RET))
-
-(defun bookmarky-RET ()
-  "Go to bookmark at point, or expand section at point."
-  (interactive)
-  (cl-etypecase (oref (magit-current-section) value)
-    (taxy-magit-section (call-interactively #'magit-section-cycle))
-    (null nil)
-    (list (bookmark-jump (oref (magit-current-section) value)))))
-
-(define-derived-mode bookmarky-mode magit-section-mode "Bookmarky"
-  :global nil
-  (setq-local revert-buffer-function #'bookmarky-revert))
-
-(provide 'bookmarky)
-
-;;; bookmarky.el ends here
diff --git a/examples/deffy.el b/examples/deffy.el
deleted file mode 100644
index 62f8170..0000000
--- a/examples/deffy.el
+++ /dev/null
@@ -1,409 +0,0 @@
-;;; deffy.el --- Show definitions in an Elisp project/buffer  -*- 
lexical-binding: t; -*-
-
-;; Copyright (C) 2021  Free Software Foundation, Inc.
-
-;; Author: Adam Porter <adam@alphapapa.net>
-;; Keywords: convenience, lisp
-;; Package-Requires: ((emacs "27.2") (taxy "0.7"))
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This library provides commands that show top-level forms and
-;; definitions found in an Emacs Lisp project or buffer, organized by
-;; file and type.
-
-;;; Code:
-
-(require 'map)
-(require 'project)
-
-(require 'taxy)
-(require 'taxy-magit-section)
-
-(cl-defstruct deffy-def
-  ;; Okay, the name of this struct is silly, but at least it's concise.
-  file pos form name type docstring)
-
-(defgroup deffy nil
-  "Show an overview of definitions in an Emacs Lisp project or buffer."
-  :group 'emacs-lisp-mode)
-
-;;;; Variables
-
-(defvar deffy-mode-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map (kbd "RET") #'deffy-RET)
-    (define-key map [mouse-1] #'deffy-mouse-1)
-    map))
-
-(defvar-local deffy-directory nil
-  "Directory relative to which filenames should be expanded.")
-
-(defvar-local deffy-files nil
-  "Files shown in the current Deffy buffer.")
-
-(defvar-local deffy-display-buffer-action nil
-  "Last-used display-buffer-action in the current Deffy buffer.")
-
-;;;; Keys
-
-(cl-eval-when (compile load eval)
-  ;; I don't understand why using `cl-eval-when' is necessary, but it
-  ;; seems to be.
-  (taxy-define-key-definer deffy-define-key deffy-keys "deffy-key"
-    ;; FIXME: Docstring.
-    "")
-
-  (deffy-define-key file ()
-    (file-relative-name (deffy-def-file item) deffy-directory))
-
-  (deffy-define-key type ()
-    (pcase-let* (((cl-struct deffy-def form) item)
-                (type (pcase form
-                        (`(,(or 'defun 'cl-defun) . ,_)
-                         (if (cl-find-if (lambda (form)
-                                           (pcase form
-                                             (`(interactive . ,_) t)))
-                                         form)
-                             'command
-                           'function))
-                        (`(,(or 'defmacro 'cl-defmacro) . ,_)
-                         'macro)
-                        (`(,car . ,_) car))))
-      (when type
-        (format "%s" type)))))
-
-(defvar deffy-taxy-default-keys
-  '(type file))
-
-;;;; Columns
-
-(cl-eval-when (compile load eval)
-  ;; I don't understand why using `cl-eval-when' is necessary, but it
-  ;; seems to be.
-  (taxy-magit-section-define-column-definer "deffy"))
-
-(deffy-define-column "Definition" (:max-width 45 :face 
font-lock-function-name-face)
-  (format "%s" (deffy-def-name item)))
-
-(deffy-define-column "Type" (:max-width 25 :face font-lock-type-face)
-  (format "%s" (deffy-def-type item)))
-
-(deffy-define-column "Docstring" (:max-width nil :face font-lock-doc-face)
-  (deffy-def-docstring item))
-
-(unless deffy-columns
-  ;; TODO: Automate this or document it
-  (setq-default deffy-columns
-               (get 'deffy-columns 'standard-value)))
-
-;;;; Options
-
-(defcustom deffy-side-window-action
-  '(display-buffer-in-side-window
-    (side . right)
-    (window-parameters
-     (dedicated . t)
-     (window-side . right)
-     (no-delete-other-windows . t)))
-  "`display-buffer' action used when displaying Deffy buffer in a side window.
-See Info node `(elisp)Displaying Buffers in Side Windows'."
-  :type 'sexp)
-
-;;;; Commands
-
-;;;###autoload
-(cl-defun deffy
-    (&key (project (or (project-current)
-                      (cons 'transient default-directory)))
-         (keys deffy-taxy-default-keys)
-         (files deffy-files)
-         (buffer-name (format "*Deffy: %s*"
-                              (if files
-                                  (string-join (mapcar #'file-relative-name 
files) ", ")
-                                (file-name-nondirectory
-                                 (directory-file-name (project-root 
project))))))
-         visibility-fn display-buffer-action)
-  "Show definitions defined in PROJECT or FILES.
-Interactively, with PREFIX, show only definitions in current
-buffer."
-  (interactive (list :files (when current-prefix-arg
-                             (list (buffer-file-name)))
-                    :keys (if current-prefix-arg
-                              (remove 'file deffy-taxy-default-keys)
-                            deffy-taxy-default-keys)))
-  (let (format-table column-sizes)
-    (cl-labels (;; (heading-face
-               ;;  (depth) (list :inherit (list 'bufler-group 
(bufler-level-face depth))))
-               (elisp-file-p (file) (string-match-p (rx ".el" (optional ".gz") 
eos) file))
-               (file-visible-p
-                (file) (not (string-match-p (rx bos ".") 
(file-name-nondirectory file))))
-               (format-item (item) (gethash item format-table))
-               (make-fn (&rest args)
-                        (apply #'make-taxy-magit-section
-                               :make #'make-fn
-                               :format-fn #'format-item
-                               :level-indent deffy-level-indent
-                               :visibility-fn visibility-fn
-                               ;; :heading-face-fn #'heading-face
-                               args))
-               (def-name (def) (format "%s" (cl-second (deffy-def-form def)))))
-      ;; (when (get-buffer buffer-name)
-      ;;   (kill-buffer buffer-name))
-      (setf files (cl-reduce #'cl-remove-if-not (list #'elisp-file-p 
#'file-visible-p)
-                            :initial-value (or files (project-files project))
-                            :from-end t))
-      (unless files
-        (user-error "No files to show"))
-      (with-current-buffer (get-buffer-create buffer-name)
-       (deffy-mode)
-       (setq-local deffy-taxy-default-keys keys
-                   deffy-directory (project-root project)
-                   deffy-files files
-                   deffy-display-buffer-action display-buffer-action
-                   default-directory deffy-directory)
-       (let* ((forms (apply #'append (mapcar #'deffy--file-forms files)))
-              (taxy (thread-last
-                        (make-fn
-                         :name "Deffy"
-                         :description
-                          (format "Definitions in %s:"
-                                 (if files
-                                     (string-join (mapcar #'file-relative-name 
files) ", ")
-                                   (file-name-nondirectory
-                                    (directory-file-name (project-root 
project)))))
-                         :take (taxy-make-take-function keys deffy-keys))
-                      (taxy-fill forms)
-                      (taxy-sort* #'string< #'taxy-name)
-                      (taxy-sort #'string< #'def-name)))
-              (taxy-magit-section-insert-indent-items nil)
-              (inhibit-read-only t)
-              (format-cons (taxy-magit-section-format-items
-                            deffy-columns deffy-column-formatters taxy)))
-         (setf format-table (car format-cons)
-               column-sizes (cdr format-cons)
-               header-line-format (taxy-magit-section-format-header
-                                   column-sizes deffy-column-formatters))
-          (delete-all-overlays)
-          (erase-buffer)
-         (save-excursion
-           (taxy-magit-section-insert taxy :items 'last
-             ;; :blank-between-depth bufler-taxy-blank-between-depth
-             :initial-depth 0))))
-      (pop-to-buffer buffer-name display-buffer-action))))
-
-;;;###autoload
-(cl-defun deffy-buffer
-    (&optional (buffer (current-buffer))
-              &key display-buffer-action)
-  "Show an Deffy view for BUFFER.
-Interactively, with prefix, display in dedicated side window."
-  (interactive
-   (list (current-buffer)
-        :display-buffer-action (when current-prefix-arg
-                                 deffy-side-window-action)))
-  (unless (buffer-file-name buffer)
-    (user-error "Buffer is not file-backed: %S.  See command `deffy-project'"
-               buffer))
-  (deffy :files (list (buffer-file-name buffer))
-    :keys (remove 'file deffy-taxy-default-keys)
-    :display-buffer-action display-buffer-action))
-
-(cl-defun deffy-project (&optional project &key display-buffer-action)
-  "Show an Deffy view for PROJECT.
-Interactively, with prefix, display in dedicated side window."
-  (interactive
-   (list nil :display-buffer-action (when current-prefix-arg
-                                     deffy-side-window-action)))
-  (deffy :project (or project
-                     (project-current)
-                     (cons 'transient default-directory))
-    :display-buffer-action display-buffer-action))
-
-(defun deffy-revert (_ignore-auto _noconfirm)
-  "Revert current Deffy buffer."
-  (interactive)
-  (deffy :display-buffer-action (or deffy-display-buffer-action
-                                   '((display-buffer-same-window)))))
-
-(defun deffy-jump (def)
-  "Jump to definition DEF.
-Interactively, read DEF from current buffer with completion; with
-prefix, from all `deffy-mode' buffers."
-  (interactive
-   (list (deffy--read-def
-          (if current-prefix-arg
-              (cl-loop for buffer in (buffer-list)
-                       when (eq 'deffy-mode (buffer-local-value 'major-mode 
buffer))
-                       collect buffer)
-            (or (cl-loop for buffer in (buffer-list)
-                         when (and (eq 'deffy-mode (buffer-local-value 
'major-mode buffer))
-                                   (member (buffer-file-name)
-                                            (buffer-local-value 'deffy-files 
buffer)))
-                         return (list buffer))
-                (condition-case nil
-                    (save-window-excursion
-                      (deffy-buffer)
-                      (list (current-buffer)))
-                  (error (cl-loop for window in (window-list)
-                                   when (eq 'deffy-mode
-                                            (buffer-local-value 'major-mode 
(window-buffer window)))
-                                   return (list (window-buffer window))))))))))
-  (pcase-let (((cl-struct deffy-def file pos) def)
-              (action (if (eq 'deffy-mode major-mode)
-                          `(display-buffer-in-previous-window
-                            (previous-window . ,(get-mru-window nil nil 
'not-selected)))
-                        '(display-buffer-same-window))))
-    (pop-to-buffer
-     (or (find-buffer-visiting file)
-        (find-file-noselect file))
-     action)
-    (goto-char pos)
-    (backward-sexp 1)))
-
-(defun deffy-mouse-1 (event)
-  "Call `deffy-RET' with point at EVENT's position."
-  (interactive "e")
-  (mouse-set-point event)
-  (call-interactively #'deffy-RET))
-
-(defun deffy-RET ()
-  "Go to form at point, or expand section at point."
-  (interactive)
-  (cl-etypecase (oref (magit-current-section) value)
-    (deffy-def (deffy-jump (oref (magit-current-section) value)))
-    (taxy-magit-section (call-interactively #'magit-section-cycle))
-    (null nil)))
-
-(define-derived-mode deffy-mode magit-section-mode "Deffy"
-  :global nil
-  (setq-local bookmark-make-record-function #'deffy-bookmark-make-record
-             revert-buffer-function #'deffy-revert))
-
-;;;; Functions
-
-(cl-defun deffy--read-def
-    (deffy-buffers &key
-      affixation-fn
-      (annotate-fn (lambda (def)
-                    (concat (deffy-def-type def) " " (deffy-def-docstring 
def))))
-      (group-fn #'deffy-def-file))
-  "Read form selected from Deffy BUFFERS with completion."
-  (unless deffy-buffers
-    (user-error "No Deffy buffers to find in"))
-  (cl-labels ((def-cons
-               (def) (cons (propertize
-                            (format "%s" (deffy-def-name def))
-                            :annotation (funcall annotate-fn def)
-                            :group (funcall group-fn def)
-                            :def def)
-                           def))
-             (buffer-taxy
-              (buffer) (with-current-buffer buffer
-                         (save-excursion
-                           (goto-char (point-min))
-                           (oref (magit-current-section) value))))
-             (annotate
-              (candidate)
-              (concat (propertize " " 'display '(space :align-to center))
-                      (get-text-property 0 :annotation candidate)))
-             (group
-              (candidate transform)
-              (pcase transform
-                (`nil (get-text-property 0 :group candidate))
-                (_ candidate)))
-             (affix (candidates)
-                    (cl-loop for candidate in candidates collect
-                             (list (propertize candidate
-                                               'face 
'font-lock-function-name-face)
-                                   (concat (propertize
-                                             (symbol-name
-                                              (deffy-def-type
-                                               (get-text-property 0 :def 
candidate)))
-                                            'face 'font-lock-type-face)
-                                           "  ")
-                                   (concat (propertize " "
-                                                        'display '(space 
:align-to center))
-                                           (get-text-property 0 :annotation 
candidate))))))
-    (pcase (length deffy-buffers)
-      (1 (setf annotate-fn #'deffy-def-docstring
-              group-fn #'deffy-key-type))
-      (_ (setf annotate-fn #'deffy-def-docstring
-               affixation-fn #'affix)))
-    (let* ((taxys (mapcar #'buffer-taxy deffy-buffers))
-          (items (mapcan #'taxy-flatten taxys))
-          (alist (setf items (mapcar #'def-cons items)))
-          (metadata (list 'metadata (cons 'group-function #'group)))
-          (dynamic-fn (lambda (str pred flag)
-                        (pcase flag
-                          ('metadata metadata)
-                          (_ (complete-with-action flag alist str pred)))))
-          (completion-extra-properties (list :annotation-function #'annotate
-                                             :affixation-function 
affixation-fn))
-          (selected (completing-read "Definition: " dynamic-fn nil t)))
-      (alist-get selected alist nil nil #'equal))))
-
-(cl-defun deffy--file-forms (file)
-  "Return forms defined in FILE."
-  (with-temp-buffer
-    (save-excursion
-      (insert-file-contents file))
-    (cl-loop for form = (ignore-errors
-                         (read (current-buffer)))
-            while form
-            when (listp form)
-            collect (make-deffy-def
-                      :file file :pos (point) :form form
-                      :name (pcase-exhaustive (cadr form)
-                             ((and (pred atom) it) it)
-                             (`(quote ,it) it)
-                             (`(,it . ,_) it))
-                      :type (car form)
-                      :docstring
-                      (replace-regexp-in-string
-                       "\n" "  "
-                       (pcase form
-                        (`(,(or 'defun 'cl-defun 'defmacro 'cl-defmacro) 
,_name ,_args
-                           ,(and (pred stringp) docstring) . ,_)
-                         docstring)
-                        (`(,(or 'defvar 'defvar-local 'defcustom) ,_name 
,_value
-                           ,(and (pred stringp) docstring) . ,_)
-                         docstring)
-                        (_ ;; Use the first string found, if any.
-                         (or (cl-find-if #'stringp form)
-                              ""))))))))
-
-;;;;; Bookmark support
-
-(defvar bookmark-make-record-function)
-
-(defun deffy-bookmark-make-record ()
-  "Return a bookmark record for current Deffy buffer."
-  (list (concat "Deffy: %s" deffy-directory)
-       (cons 'directory deffy-directory)
-       (cons 'files deffy-files)
-       (cons 'handler #'deffy-bookmark-handler)))
-
-;;;###autoload
-(defun deffy-bookmark-handler (record)
-  "Show Deffy buffer for bookmark RECORD."
-  (pcase-let* ((`(,_ . ,(map directory files)) record))
-    (deffy :files files :project (project-current nil directory))
-    (current-buffer)))
-
-(provide 'deffy)
-
-;;; deffy.el ends here
diff --git a/examples/diredy.el b/examples/diredy.el
deleted file mode 100644
index 8e79e8b..0000000
--- a/examples/diredy.el
+++ /dev/null
@@ -1,114 +0,0 @@
-;;; diredy.el --- Flexible grouping for files in Dired buffers  -*- 
lexical-binding: t; -*-
-
-;; Copyright (C) 2021  Free Software Foundation, Inc.
-
-;; Author: Adam Porter <adam@alphapapa.net>
-;; Maintainer: Adam Porter <adam@alphapapa.net>
-;; Keywords: convenience
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This library provides a command, `diredy', that rearranges a Dired
-;; buffer into a hierarchy by file size and MIME type.
-
-;;; Code:
-
-;;;; Requirements
-
-(require 'taxy)
-(require 'taxy-magit-section)
-
-(require 'dired)
-(require 'mailcap)
-
-;;;; Variables
-
-(defvar diredy-taxy
-  (cl-labels ((file-name
-               (string) (let* ((start (text-property-not-all 0 (length string) 
'dired-filename nil string))
-                               (end (text-property-any start (length string) 
'dired-filename nil string)))
-                          (substring string start end)))
-              (file-extension
-               (filename) (file-name-extension filename))
-              (file-type (string)
-                         (when-let ((extension (file-extension (file-name 
string))))
-                           (mailcap-extension-to-mime extension)))
-              (file-size
-               (filename) (file-attribute-size (file-attributes filename)))
-              (file-size-group
-               (string) (pcase (file-size (file-name string))
-                          ('nil "No size")
-                          ((pred (> 1024))
-                           "< 1K")
-                          ((pred (> 102400))
-                           "< 100K")
-                          ((pred (> 1048576))
-                           "< 1M")
-                          ((pred (> 10485760))
-                           "< 10M")
-                          (_ ">= 10M")))
-              (file-dir? (string) (if (file-directory-p (file-name string))
-                                      "Directory" "File"))
-             (make-fn (&rest args)
-                      (apply #'make-taxy-magit-section
-                             :make #'make-fn
-                             :level-indent 1
-                             :item-indent 2
-                             args)))
-    (make-fn
-     :name "Diredy"
-     :make #'make-fn
-     :take (apply-partially #'taxy-take-keyed (list #'file-dir? 
#'file-size-group #'file-type)))))
-
-(defvar dired-mode)
-
-;;;; Customization
-
-
-;;;; Commands
-
-(defun diredy ()
-  "Apply grouping to current Dired buffer."
-  (interactive)
-  (cl-assert (eq 'dired-mode major-mode))
-  (use-local-map (make-composed-keymap (list dired-mode-map 
magit-section-mode-map)))
-  (save-excursion
-    (goto-char (point-min))
-    (forward-line 2)
-    (let* ((lines (save-excursion
-                   (cl-loop until (eobp)
-                            collect (string-trim (buffer-substring 
(point-at-bol) (point-at-eol)))
-                            do (forward-line 1))))
-          (filled-taxy (thread-last diredy-taxy
-                         taxy-emptied
-                         (taxy-fill lines)
-                         (taxy-mapc* (lambda (taxy)
-                                       (setf (taxy-taxys taxy)
-                                             (cl-sort (taxy-taxys taxy) 
#'string<
-                                                      :key #'taxy-name))))))
-          (inhibit-read-only t))
-      (delete-region (point) (point-max))
-      (taxy-magit-section-insert filled-taxy :items 'last
-       :initial-depth 0 :blank-between-depth 1))))
-
-;;;; Functions
-
-
-;;;; Footer
-
-(provide 'diredy)
-
-;;; diredy.el ends here
diff --git a/examples/magit-loggy.el b/examples/magit-loggy.el
deleted file mode 100644
index e15f914..0000000
--- a/examples/magit-loggy.el
+++ /dev/null
@@ -1,81 +0,0 @@
-;;; magit-loggy.el --- Group Magit log commits by date  -*- lexical-binding: 
t; -*-
-
-;; Copyright (C) 2021  Free Software Foundation, Inc.
-
-;; Author: Adam Porter <adam@alphapapa.net>
-;; Maintainer: Adam Porter <adam@alphapapa.net>
-;; Keywords: convenience
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This works, but since magit-log uses overlays for the committer and
-;; date on each line, those are lost when we erase the buffer.  Fixing
-;; that would require copying the properties of those overlays into
-;; the text properties of each line.  Probably not worth it, since
-;; this is just a demo, anyway.
-
-;;; Code:
-
-;;;; Requirements
-
-(require 'magit-log)
-(require 'ov)
-
-;;;; Variables
-
-(defvar magit-loggy-taxy
-  (make-taxy :name "Commits"
-             :taxys (list
-                     (make-taxy :name "By date"
-                                :take (apply-partially #'taxy-take-keyed 
#'cdr)))))
-
-;;;; Customization
-
-
-;;;; Commands
-
-(defun magit-loggy ()
-  (interactive)
-  (cl-assert (derived-mode-p 'magit-log-mode))
-  (save-excursion
-    (goto-char (point-min))
-    (cl-labels ((line-date
-                 () (when-let ((ov (car (ov-in 'before-string 'any 
(line-beginning-position) (line-end-position))))
-                               (string (cadr (get-text-property 0 'display 
(overlay-get ov 'before-string))))
-                               (_ (string-match (rx (group (1+ digit) ; number
-                                                           " "
-                                                           (1+ (not blank))) ; 
unit
-                                                    (1+ blank) eos)
-                                                string)))
-                      (match-string 1 string))))
-      (let* ((lines (cl-loop until (eobp)
-                             collect (cons (buffer-substring (point-at-bol) 
(point-at-eol))
-                                           (line-date))
-                             do (forward-line 1)))
-             (taxy (taxy-fill lines (taxy-emptied magit-loggy-taxy)))
-             (inhibit-read-only t))
-        (erase-buffer)
-        (taxy-magit-section-insert taxy)))))
-
-
-;;;; Functions
-
-
-;;;; Footer
-
-(provide 'magit-loggy)
-
-;;; magit-loggy.el ends here
diff --git a/examples/musicy.el b/examples/musicy.el
deleted file mode 100644
index 6d496d2..0000000
--- a/examples/musicy.el
+++ /dev/null
@@ -1,123 +0,0 @@
-;;; musicy.el --- View a music library in a useful taxonomy  -*- 
lexical-binding: t; -*-
-
-;; Copyright (C) 2021  Free Software Foundation, Inc.
-
-;; Author: Adam Porter <adam@alphapapa.net>
-;; Maintainer: Adam Porter <adam@alphapapa.net>
-;; Keywords: convenience
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This is a sample application using `taxy'.  It uses the "mediainfo"
-;; program to get metadata of about audio files, but any function
-;; could be swapped into its place (e.g. one that retrieved data from
-;; MPD).
-
-;;; Code:
-
-;;;; Requirements
-
-(require 'cl-lib)
-
-(require 'taxy)
-(require 'taxy-magit-section)
-
-;; Used to avoid repeated calls to "mediainfo" for the same file.
-(require 'memoize)
-
-;;;; Variables
-
-(defvar musicy-taxy
-  (cl-labels ((call-proc (process &rest args)
-                         "Return results of running PROCESS with ARGS."
-                         (declare (indent defun))
-                         (with-temp-buffer
-                           (if (zerop (apply #'call-process process nil t nil
-                                             args))
-                               (buffer-substring-no-properties (point-min) 
(point-max))
-                             (warn "mediainfo failed for: %S" args))))
-              (mediainfo (file)
-                         (call-proc "mediainfo" file))
-              (mediainfo-attr (attr file)
-                              (if-let ((info (musicy-mediainfo file)))
-                                  (when (string-match
-                                         (rx-to-string `(seq (eval ,attr) (1+ 
blank) ":" (1+ blank) (group (1+ nonl))))
-                                         info)
-                                    (match-string 1 info))
-                                (format "No info for file: %S" file)))
-              (genre (file)
-                     (or (mediainfo-attr "Genre" file)
-                         "[unknown genre]"))
-              (year (file)
-                    (or (when-let (date (or (mediainfo-attr "Recorded date" 
file)
-                                            (mediainfo-attr "Original/Released 
date" file)
-                                            (mediainfo-attr "Year" file)))
-                          (when (string-match (rx (group (1+ digit))) date)
-                            (match-string 1 date)))
-                        "[unknown year]"))
-              (artist (file)
-                      (mediainfo-attr "Performer" file))
-              (album (file)
-                     (mediainfo-attr "Album" file))
-              (track-name (file)
-                          (mediainfo-attr "Track name" file))
-              (track-number (file)
-                            (mediainfo-attr "Track name/Position" file))
-              (track-string (file)
-                            (concat
-                             (pcase (track-number file)
-                               ((or "-1" 'nil) nil)
-                               (number (format "%s: " number)))
-                             (track-name file))))
-    (make-taxy
-     :name "Musicy"
-     :taxys (list (make-taxy
-                   :name "Genres"
-                   :take (apply-partially #'taxy-take-keyed
-                                          (list #'genre #'artist #'year 
#'album #'track-string)))))))
-
-;;;; Customization
-
-
-;;;; Commands
-
-(defun musicy (directory)
-  (interactive (list (read-directory-name "Directory of music files: ")))
-  (let ((files (directory-files-recursively
-                directory (rx "." (or "mp3" "ogg") eos))))
-    (musicy-files files)))
-
-(defun musicy-files (files)
-  (thread-last musicy-taxy
-    taxy-emptied
-    (taxy-fill files)
-    (taxy-sort #'string< #'taxy-name)
-    (taxy-sort* #'string< #'taxy-name)    
-    taxy-magit-section-pp))
-
-;;;; Functions
-
-(defmemoize musicy-mediainfo (file)
-  (with-temp-buffer
-    (if (zerop (call-process "mediainfo" nil t nil file))
-        (buffer-substring-no-properties (point-min) (point-max))
-      (warn "mediainfo failed for: %S" file))))
-
-;;;; Footer
-
-(provide 'musicy)
-
-;;; musicy.el ends here
diff --git a/examples/taxy-package-report.el b/examples/taxy-package-report.el
deleted file mode 100644
index 5c251ce..0000000
--- a/examples/taxy-package-report.el
+++ /dev/null
@@ -1,53 +0,0 @@
-;; taxy-package-report.el  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2021  Free Software Foundation, Inc.
-
-;; Author: Adam Porter <adam@alphapapa.net>
-;; Maintainer: Adam Porter <adam@alphapapa.net>n
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Inspired by Manuel Uberti's blog post:
-;; <https://www.manueluberti.eu//emacs/2021/09/01/package-report/>.
-
-;;; Code:
-
-(require 'cl-lib)
-(require 'package)
-
-(require 'taxy-magit-section)
-
-(defun taxy-package-report ()
-  "List installed packages by archive in a `magit-section' buffer."
-  (interactive)
-  (cl-labels ((package-archive
-               (package) (if-let* ((package-struct (car (alist-get (car 
package) package-archive-contents)))
-                                   (archive (package-desc-archive 
package-struct)))
-                             archive
-                           "no archive"))
-              (format-package
-               (package) (symbol-name (car package))))
-    (let ((taxy (make-taxy-magit-section
-                 :name "Packages by archive"
-                 :take (lambda (item taxy)
-                         (taxy-take-keyed (list #'package-archive) item taxy))
-                 :make (lambda (&rest args)
-                         (apply #'make-taxy-magit-section :format-fn 
#'format-package :indent 0 args))
-                 :format-fn #'format-package
-                 :indent 0)))
-      (taxy-magit-section-pp (taxy-fill package-alist taxy)))))
-
-;;; taxy-package-report.el ends here
diff --git a/images/bookmarky.png b/images/bookmarky.png
deleted file mode 100644
index 024395c..0000000
Binary files a/images/bookmarky.png and /dev/null differ
diff --git a/images/deffy.png b/images/deffy.png
deleted file mode 100644
index 3c80012..0000000
Binary files a/images/deffy.png and /dev/null differ
diff --git a/images/diredy.png b/images/diredy.png
deleted file mode 100644
index 7e84fb4..0000000
Binary files a/images/diredy.png and /dev/null differ
diff --git a/images/magit-section-numbery.png b/images/magit-section-numbery.png
deleted file mode 100644
index 72255669..0000000
Binary files a/images/magit-section-numbery.png and /dev/null differ
diff --git a/images/mascot.png b/images/mascot.png
deleted file mode 100644
index 919e45e..0000000
Binary files a/images/mascot.png and /dev/null differ
diff --git a/images/musicy.png b/images/musicy.png
deleted file mode 100644
index 8b2af29..0000000
Binary files a/images/musicy.png and /dev/null differ
diff --git a/taxy-magit-section.info b/taxy-magit-section.info
new file mode 100644
index 0000000..5930152
--- /dev/null
+++ b/taxy-magit-section.info
@@ -0,0 +1,122 @@
+This is README.info, produced by makeinfo version 5.2 from README.texi.
+
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* Taxy Magit Section: (taxy-magit-section). Render Taxy structs with Magit 
Section.
+END-INFO-DIR-ENTRY
+
+
+File: README.info,  Node: Top,  Next: COMMENT Examples,  Up: (dir)
+
+taxy-magit-section.el
+*********************
+
+https://elpa.gnu.org/packages/taxy-magit-section.svg
+(https://elpa.gnu.org/packages/taxy-magit-section.html)
+
+   This library renders Taxy (https://github.com/alphapapa/taxy.el)
+structs with magit-section (https://melpa.org/#/magit-section).
+
+* Menu:
+
+* COMMENT Examples::
+* Installation::
+* COMMENT Usage::
+* Changelog::
+* Development::
+* Credits::
+* License::
+
+— The Detailed Node Listing —
+
+Changelog
+
+* 0.9-pre: 09-pre. 
+
+
+
+File: README.info,  Node: COMMENT Examples,  Next: Installation,  Prev: Top,  
Up: Top
+
+1 COMMENT Examples
+******************
+
+
+File: README.info,  Node: Installation,  Next: COMMENT Usage,  Prev: COMMENT 
Examples,  Up: Top
+
+2 Installation
+**************
+
+‘taxy-magit-section’ is distributed in GNU ELPA (https://elpa.gnu.org/),
+which is available in Emacs by default.  Use ‘M-x package-install RET
+taxy-magit-section RET’, then ‘(require 'taxy-magit-section)’ in your
+Elisp project.
+
+
+File: README.info,  Node: COMMENT Usage,  Next: Changelog,  Prev: 
Installation,  Up: Top
+
+3 COMMENT Usage
+***************
+
+
+File: README.info,  Node: Changelog,  Next: Development,  Prev: COMMENT Usage, 
 Up: Top
+
+4 Changelog
+***********
+
+* Menu:
+
+* 0.9-pre: 09-pre. 
+
+
+File: README.info,  Node: 09-pre,  Up: Changelog
+
+4.1 0.9-pre
+===========
+
+   • ‘taxy-magit-section’ moved to separate package.
+
+
+File: README.info,  Node: Development,  Next: Credits,  Prev: Changelog,  Up: 
Top
+
+5 Development
+*************
+
+‘taxy-magit-section’ is developed in a branch of the main Taxy repo
+(https://github.com/alphapapa/taxy.el).
+
+
+File: README.info,  Node: Credits,  Next: License,  Prev: Development,  Up: Top
+
+6 Credits
+*********
+
+   • Thanks to Stefan Monnier for his feedback, and for maintaining GNU
+     ELPA.
+
+
+File: README.info,  Node: License,  Prev: Credits,  Up: Top
+
+7 License
+*********
+
+GPLv3
+
+
+
+Tag Table:
+Node: Top221
+Node: COMMENT Examples767
+Node: Installation895
+Node: COMMENT Usage1266
+Node: Changelog1391
+Node: 09-pre1537
+Node: Development1674
+Node: Credits1901
+Node: License2091
+
+End Tag Table
+
+
+Local Variables:
+coding: utf-8
+End:
diff --git a/taxy.el b/taxy.el
deleted file mode 100644
index db54a14..0000000
--- a/taxy.el
+++ /dev/null
@@ -1,438 +0,0 @@
-;;; taxy.el --- Programmable taxonomical grouping for arbitrary objects  -*- 
lexical-binding: t; -*-
-
-;; Copyright (C) 2021  Free Software Foundation, Inc.
-
-;; Author: Adam Porter <adam@alphapapa.net>
-;; Maintainer: Adam Porter <adam@alphapapa.net>
-;; URL: https://github.com/alphapapa/taxy.el
-;; Version: 0.9-pre
-;; Package-Requires: ((emacs "26.3"))
-;; Keywords: lisp
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This library provides a programmable way to classify arbitrary
-;; objects into a hierarchical taxonomy.  (That's a lot of fancy words
-;; to say that this lets you put things in nested groups.)
-
-;; Helpful features include:
-
-;; + Dynamic taxonomies: Objects may be classified into hierarchies
-;; automatically defined at runtime based on their attributes.
-
-;; + Reusable taxonomies: Taxonomy definitions may be stored in
-;; variables and reused in other taxonomies' descendant groups.
-
-;; Basic usage:
-
-;; 1.  Make a taxy with `make-taxy'.
-;; 2.  Fill the taxy with items using `taxy-fill'.
-;; 3.  For a simple display of a taxy's items, use `taxy-plain'.
-
-;; For more details, please see the README.org file.
-
-;;; Code:
-
-;;;; Requirements
-
-(require 'cl-lib)
-(require 'map)
-(require 'subr-x)
-
-;;;; Structs
-
-(cl-defstruct taxy
-  name description key items taxys
-  (predicate #'identity) (then #'ignore)
-  (make #'make-taxy)
-  take)
-
-;;;; Variables
-
-
-;;;; Customization
-
-
-;;;; Commands
-
-
-;;;; Functions
-
-(defun taxy-fill (items taxy)
-  "Fill TAXY with ITEMS according to its definition."
-  (cl-labels ((apply-item (item taxy)
-                          (or (if (taxy-take taxy)
-                                  (funcall (taxy-take taxy) item taxy)
-                                (cl-loop for taxy in (taxy-taxys taxy)
-                                         when (funcall (taxy-predicate taxy) 
item)
-                                         do (progn
-                                              (if (taxy-take taxy)
-                                                  (funcall (taxy-take taxy) 
item taxy)
-                                                (if (taxy-taxys taxy)
-                                                    (or (apply-item item taxy)
-                                                        (push item (taxy-items 
taxy)))
-                                                  (push item (taxy-items 
taxy))))
-                                              (setf item (funcall (taxy-then 
taxy) item)))
-                                         unless item return t
-                                         finally return nil))
-                              ;; No sub-taxys took the item: add it to this 
taxy.
-                              (when (funcall (taxy-predicate taxy) item)
-                                (if (taxy-take taxy)
-                                    (funcall (taxy-take taxy) item taxy)
-                                  (push item (taxy-items taxy)))))))
-    (dolist (item items taxy)
-      (apply-item item taxy))))
-
-(defun taxy-plain (taxy)
-  "Return a list of the human-readable parts of TAXY."
-  (delq nil
-        (list (taxy-name taxy)
-              (taxy-description taxy)
-              (taxy-items taxy)
-              (mapcar #'taxy-plain (taxy-taxys taxy)))))
-
-(defun taxy-emptied (taxy)
-  "Return a copy of TAXY without items.
-Omits TAXY's items and those of its descendant taxys.  Useful
-when reusing taxy definitions."
-  (setf taxy (copy-taxy taxy)
-        (taxy-items taxy) nil
-        (taxy-taxys taxy) (mapcar #'taxy-emptied (taxy-taxys taxy)))
-  taxy)
-
-(defun taxy-flatten (taxy)
-  "Return a list of items in TAXY and its sub-taxys."
-  (append (taxy-items taxy)
-          (cl-loop for taxy in (taxy-taxys taxy)
-                   append (taxy-flatten taxy))))
-
-(defun taxy-mapcar-items (fn taxy)
-  "Return copy of TAXY, having replaced its items with the value of FN on each.
-Replaces every item in TAXY and its descendants.  Useful to
-replace items with a more useful form after classification."
-  (declare (indent defun))
-  ;; It might be preferable to destructively replace items rather
-  ;; than consing new lists, but I haven't found a way that works
-  ;; (even `cl-loop' with `in-ref' hasn't worked).
-  (setf (taxy-items taxy) (mapcar fn (taxy-items taxy))
-        (taxy-taxys taxy) (cl-loop for taxy in (taxy-taxys taxy)
-                                   collect (taxy-mapcar-items fn taxy)))
-  taxy)
-
-(defalias 'taxy-mapcar #'taxy-mapcar-items)
-
-(defun taxy-mapc-taxys (fn taxy)
-  "Return TAXY having applied FN to it and its descendants.
-Does not copy TAXY.  Destructively modifies TAXY, if FN does."
-  (declare (indent defun))
-  (funcall fn taxy)
-  (cl-loop for sub-taxy in-ref (taxy-taxys taxy)
-           do (setf sub-taxy (taxy-mapc-taxys fn sub-taxy)))
-  taxy)
-
-(defalias 'taxy-mapc* #'taxy-mapc-taxys)
-
-(cl-defun taxy-take-keyed
-    (key-fns item taxy
-             &key (key-name-fn #'identity) (then #'ignore))
-  "Take ITEM into TAXY, adding new taxys dynamically and recursively.
-Places ITEM into a taxy in TAXY for the value returned by
-KEY-FNS called with ITEM.  The new taxys are added to TAXY
-recursively as necessary.  Each new taxy's name is that returned
-by KEY-NAME-FN called with ITEM.
-
-Each element of KEY-FNS may be a function or a list of functions.
-A list of functions creates a \"chain\" of functions: when an
-item is matched by the first function in a chain, it is placed
-in that chain's taxonomy, and is not \"offered\" to functions
-outside of that chain.
-
-For example, if KEY-FNS were:
-
-  '(((lambda (n) (< n 10)) oddp)
-    ((lambda (n) (>= n 10)) evenp))
-
-Then a list of numbers from 0-19 would be classified
-like (listing numbers on a single line for the sake of example):
-
-  - <10:
-    - 0, 2, 4, 6, 8
-    - oddp:
-      - 1, 3, 5, 7, 9
-  - >=10:
-    - 11, 13, 15, 17, 19
-    - evenp:
-      - 10, 12, 14, 16, 18
-
-So only numbers below 10 are tested against `oddp', and only
-numbers greater-than-or-equal-to 10 are tested against
-`evenp'.  (A contrived example, of course, since testing against
-`evenp' or `oddp' is just the inverse.)"
-  (declare (indent defun))
-  (cl-macrolet ((offer-or-push
-                 () `(if (cdr key-fns)
-                         (taxy-take-keyed (cdr key-fns) item taxy
-                           :key-name-fn key-name-fn :then then)
-                       (push item (taxy-items taxy)))))
-    (cl-typecase (car key-fns)
-      (function
-       ;; A single key function.
-       (let ((key-fn (car key-fns)))
-         (if-let ((key (funcall key-fn item)))
-             ;; This key function returned non-nil for the item:
-             ;; apply it to the appropriate sub-taxy.
-             (let ((key-taxy
-                    (or (cl-find-if (lambda (taxy-key)
-                                      (equal key taxy-key))
-                                    (taxy-taxys taxy)
-                                    :key #'taxy-key)
-                        ;; No existing, matching sub-taxy found: make
-                        ;; a new one and add it to TAXY's sub-taxys.
-                        (car
-                         (push (funcall
-                                ;; NOTE: Calling `make-taxy' directly might 
offer the
-                                ;; compiler a chance to optimize compared to 
using `funcall',
-                                ;; but allowing taxy structs to specify their 
own MAKE
-                                ;; functions is very helpful when using 
specialized structs.
-                                (taxy-make taxy)
-                                :name (funcall key-name-fn key)
-                                :key key
-                                :predicate (lambda (item)
-                                             (equal key (funcall key-fn item)))
-                                :take (when (cdr key-fns)
-                                        (lambda (item taxy)
-                                          (taxy-take-keyed (cdr key-fns) item 
taxy
-                                            :key-name-fn key-name-fn :then 
then)))
-                                :then then)
-                               (taxy-taxys taxy))))))
-               (if (cdr key-fns)
-                   ;; Other key-fns remain: offer item to them, allowing
-                   ;; them to create more sub-taxys beneath this key-taxy.
-                   (taxy-take-keyed (cdr key-fns) item key-taxy
-                     :key-name-fn key-name-fn :then then)
-                 ;; No more key-fns remain: add item to this taxy.
-                 (push item (taxy-items key-taxy))))
-           ;; No key value: offer to other KEY-FNS or push to this taxy.
-           (offer-or-push))))
-      (list
-       ;; A "chain" of key functions.
-       (or (when (funcall (caar key-fns) item)
-             ;; The first function in this chain returns non-nil for
-             ;; the item: apply the item to the chain.
-             (taxy-take-keyed (car key-fns) item taxy
-               :key-name-fn key-name-fn :then then))
-           ;; This "chain" of key-fns didn't take the item: offer it to
-           ;; other chains, or push to this taxy if they don't take it.
-           (offer-or-push))))))
-
-(defun taxy-size (taxy)
-  "Return the number of items TAXY holds.
-Includes items in TAXY's sub-taxys."
-  (cl-loop for sub-taxy in (taxy-taxys taxy)
-           sum (taxy-size sub-taxy) into total
-           finally return (+ total (length (taxy-items taxy)))))
-
-(defun taxy-sort-items (pred key taxy)
-  "Sort TAXY's items by PRED and KEY.
-Sorts items in TAXY and its sub-taxys.  KEY is passed to
-`cl-sort', which see."
-  (declare (indent defun))
-  (taxy-mapc* (lambda (taxy)
-                (setf (taxy-items taxy)
-                      (cl-sort (taxy-items taxy)
-                               pred :key key)))
-    taxy))
-
-(defalias 'taxy-sort #'taxy-sort-items)
-
-(defun taxy-sort-taxys (pred key taxy)
-  "Sort TAXY's sub-taxys by PRED and KEY.
-KEY is passed to `cl-sort', which see."
-  (declare (indent defun))
-  (taxy-mapc* (lambda (taxy)
-                (setf (taxy-taxys taxy)
-                      (cl-sort (taxy-taxys taxy)
-                               pred :key key)))
-    taxy))
-
-(defalias 'taxy-sort* #'taxy-sort-taxys)
-
-;;;; Key functions
-
-;; Utilities to define key and take functions in a standard way.
-
-(defmacro taxy-define-key-definer (name variable prefix docstring)
-  "Define a macro NAME that defines a key-function-defining macro.
-The defined macro, having string DOCSTRING, associates the
-defined key functions with their aliases in an alist stored in
-symbol VARIABLE.  The defined key functions are named having
-string PREFIX, which will have a hyphen appended to it.  The key
-functions take one or more arguments, the first of which is the
-item being tested, bound within the function to `item'."
-  ;; Example docstring:
-
-  ;;   "Define a `taxy-org-ql-view' key function by NAME having BODY taking 
ARGS.
-  ;; Within BODY, `element' is bound to the `org-element' element
-  ;; being tested.
-
-  ;; Defines a function named `taxy-org-ql--predicate-NAME', and adds
-  ;; an entry to `taxy-org-ql-view-keys' mapping NAME to the new
-  ;; function symbol."
-  (declare (indent defun))
-  ;; I'm not sure why it's necessary to bind the variable in the first
-  ;; level of the expansion here, but double-unquoting the variable in
-  ;; the defined macro's form leaves the second comma in place, which
-  ;; breaks the second expansion, and this works around that.
-  `(let ((variable ',variable))
-     (defvar ,variable nil
-       ,(format "Alist mapping key aliases to key functions defined with `%s'."
-                name))
-     (defmacro ,name (name args &rest body)
-       ,docstring
-       (declare (indent defun)
-                (debug (&define symbolp listp &rest def-form)))
-       (let* ((fn-symbol (intern (format "%s-%s" ,prefix name)))
-              (fn `(cl-function
-                    (lambda (item ,@args)
-                      ,@body))))
-         `(progn
-            (fset ',fn-symbol ,fn)
-            (setf (map-elt ,variable ',name) ',fn-symbol))))))
-
-(defun taxy-make-take-function (keys aliases)
-  "Return a `taxy' \"take\" function for KEYS.
-Each of KEYS should be a function alias defined in ALIASES, or a
-list of such KEY-FNS (recursively, ad infinitum, approximately).
-ALIASES should be an alist mapping aliases to functions (such as
-defined with a definer defined by `taxy-define-key-definer')."
-  (let ((macrolets (cl-loop for (name . fn) in aliases
-                            collect `(,name ',fn))))
-    (cl-labels ((expand-form
-                 ;; Is using (cadr (macroexpand-all ...)) really better than 
`eval'?
-                 (form) (cadr (macroexpand-all
-                               `(cl-symbol-macrolet (,@macrolets)
-                                  ,form))))
-                (quote-fn
-                 (fn) (pcase fn
-                        ((pred symbolp) (expand-form fn))
-                        (`(,(and (or 'and 'or 'not) boolean)
-                           . ,(and args (map (:name name) (:keys keys))))
-                         ;; Well, that pcase expression isn't confusing at 
all...  ;)
-                         ;;  (cl-assert name t "Boolean key functions require 
a NAME")
-                         ;;  (cl-assert keys t "Boolean key functions require 
KEYS")
-                         `(lambda (buffer)
-                            (when (cl-loop for fn in ',(mapcar #'quote-fn (or 
keys args))
-                                           ,(pcase boolean
-                                              ('and 'always)
-                                              ('or 'thereis)
-                                              ('not 'never))
-                                           (funcall fn buffer))
-                              (or ,name ""))))
-                        (`(,(and (pred symbolp) fn)
-                           . ,(and args (guard (pcase (car args)
-                                                 ((or (pred keywordp)
-                                                      (and (pred atom)
-                                                           ;; SOMEDAY: Use 
(not symbolp) when depending on Emacs 28.1.
-                                                           (pred (lambda (it) 
(not (symbolp it)))))
-                                                      `(quote ,_))
-                                                  t)))))
-                         ;; Key with args: replace with a lambda that
-                         ;; calls that key's function with given args.
-                         `(lambda (element)
-                            (,(expand-form fn) element ,@args)))
-                        ((pred listp) (mapcar #'quote-fn fn)))))
-      (setf keys (mapcar #'quote-fn keys))
-      `(lambda (item taxy)
-         (taxy-take-keyed ',keys item taxy)))))
-
-;;;; Documentation group
-
-;; Available in Emacs 28.  NOTE: In earlier Emacs versions,
-;; byte-compiling this section will produce warnings due to the
-;; shortdoc forms that appear to be function calls.
-
-(with-eval-after-load 'shortdoc
-  (declare-function shortdoc-add-function "shortdoc" (group section elem))
-  (mapc (lambda (elem)
-         (shortdoc-add-function 'taxy nil elem))
-        '((taxy-flatten
-           :eval (taxy-flatten
-                  (make-taxy
-                   :items '(a b c)
-                   :taxys (list (make-taxy
-                                 :items '(d e f))))))
-          (taxy-emptied
-           :eval (taxy-emptied
-                  (make-taxy
-                   :items '(a b c)
-                   :taxys (list (make-taxy
-                                 :items '(d e f))))))
-          (taxy-fill
-           :eval (taxy-fill '(0 1 2 3)
-                            (make-taxy
-                             :name "Numbers"
-                             :taxys (list (make-taxy
-                                           :name "Odd"
-                                           :predicate #'cl-oddp)
-                                          (make-taxy
-                                           :name "Even"
-                                           :predicate #'cl-evenp)))))
-          (taxy-make-take-function
-           :eval (taxy-make-take-function
-                  '(first-char second-char)
-                  '((first-char (lambda (s) (substring s nil 1)))
-                    (second-char (lambda (s) (substring s 1 2))))))
-          (taxy-mapc-taxys
-            :eval (taxy-mapc-taxys
-                    (lambda (taxy)
-                      (setf (taxy-name taxy) (upcase (taxy-name taxy))))
-                    (make-taxy :name "a" :taxys (list (make-taxy :name "b")))))
-          (taxy-mapcar-items
-            :eval (taxy-mapcar-items #'upcase
-                    (make-taxy :items (list "a" "b" "c")
-                               :taxys (list (make-taxy :items (list "d" "e" 
"f"))))))
-          (taxy-plain
-           :eval (taxy-plain
-                  (taxy-fill '(0 1 2 3)
-                             (make-taxy
-                              :name "Numbers"
-                              :taxys (list (make-taxy
-                                            :name "Odd"
-                                            :predicate #'cl-oddp)
-                                           (make-taxy
-                                            :name "Even"
-                                            :predicate #'cl-evenp))))))
-          (taxy-size
-           :eval (taxy-size
-                  (make-taxy
-                   :items '(a b c)
-                   :taxys (list (make-taxy
-                                 :items '(d e f))))))
-          (taxy-sort-items
-            :eval (taxy-sort-items #'string< #'identity
-                    (make-taxy :items (list "c" "b" "a")
-                               :taxys (list (make-taxy :items (list "f" "e" 
"d"))))))
-          (taxy-sort-taxys
-            :eval (taxy-sort-taxys #'string< #'taxy-name
-                    (make-taxy :name "Taxy"
-                               :taxys (list (make-taxy :name "Beta")
-                                            (make-taxy :name "Alpha"))))))))
-
-;;;; Footer
-
-(provide 'taxy)
-
-;;; taxy.el ends here
diff --git a/taxy.info b/taxy.info
deleted file mode 100644
index 187e915..0000000
--- a/taxy.info
+++ /dev/null
@@ -1,1479 +0,0 @@
-This is README.info, produced by makeinfo version 6.5 from README.texi.
-
-INFO-DIR-SECTION Emacs
-START-INFO-DIR-ENTRY
-* Taxy: (taxy).         Programmable taxonomical grouping for arbitrary 
objects.
-END-INFO-DIR-ENTRY
-
-
-File: README.info,  Node: Top,  Next: Examples,  Up: (dir)
-
-taxy.el
-*******
-
-https://elpa.gnu.org/packages/taxy.svg
-(https://elpa.gnu.org/packages/taxy.html)
-
-   _Now, where did I put that..._
-
-   This library provides a programmable way to classify arbitrary
-objects into a hierarchical taxonomy.  (That’s a lot of fancy words to
-say that this lets you automatically put things in nested groups.)
-
-   Helpful features include:
-
-Dynamic taxonomies
-     Objects may be classified into hierarchies automatically defined at
-     runtime based on their attributes.
-Reusable taxonomies
-     Taxonomy definitions may be stored in variables and reused in other
-     taxonomies’ descendant groups.
-Classification domain-specific language
-     Easily define a custom DSL used to classify items dynamically
-     (which can be extended by users).
-Flexible table view
-     Based on ‘magit-section’, with easily defined columns (also
-     extendable by users).
-
-* Menu:
-
-* Examples::
-* Installation::
-* Usage::
-* Changelog::
-* Development::
-* Credits::
-* License::
-
-— The Detailed Node Listing —
-
-Examples
-
-* Numbery (starting basically)::
-* Lettery (filling incrementally)::
-* Sporty (understanding completely)::
-* Applications::
-
-Usage
-
-* Reusable taxys::
-* Threading macros::
-* Modifying filled taxys::
-* Dynamic taxys::
-* Magit section::
-* Reference::
-
-Dynamic taxys
-
-* Multi-level dynamic taxys::
-* "Chains" of independent, multi-level dynamic taxys: "Chains" of independent 
multi-level dynamic taxys.
-* Defining a classification domain-specific language::
-
-Reference
-
-* Functions::
-* Macros::
-
-Changelog
-
-* 0.9-pre: 09-pre.
-* 0.8: 08.
-* 0.7: 07.
-* 0.6: 06.
-* 0.5: 05.
-* 0.4: 04.
-* 0.3: 03.
-* 0.2: 02.
-* 0.1: 01.
-
-0.8
-
-* Additions::
-* Fixes::
-
-0.7
-
-* Additions: Additions (1).
-
-0.6
-
-* Additions: Additions (2).
-
-0.5
-
-* Additions: Additions (3).
-* Fixes: Fixes (1).
-
-0.3
-
-* Changes::
-* Fixes: Fixes (2).
-
-0.2
-
-* Changes: Changes (1).
-* Additions: Additions (4).
-* Fixes: Fixes (3).
-
-Development
-
-* Copyright assignment::
-
-
-
-File: README.info,  Node: Examples,  Next: Installation,  Prev: Top,  Up: Top
-
-1 Examples
-**********
-
-   • • • • 
-   May these examples help you classify your understanding.
-
-* Menu:
-
-* Numbery (starting basically)::
-* Lettery (filling incrementally)::
-* Sporty (understanding completely)::
-* Applications::
-
-
-File: README.info,  Node: Numbery (starting basically),  Next: Lettery 
(filling incrementally),  Up: Examples
-
-1.1 Numbery (starting basically)
-================================
-
-Let’s imagine a silly taxonomy of numbers below 100:
-
-     ("Numbery" "A silly taxonomy of numbers."
-      (("< 10" "Numbers below 10"
-        ;; These numbers are leftovers from the sub-taxys below.
-        (0 2 4 6 8)
-        ;; These sub-taxys further classify the numbers below 10 into odd
-        ;; and even.  The odd taxy "consumes" numbers, while the even one
-        ;; doesn't, leaving them to reappear in the parent taxy's items.
-        (("Odd" "(consuming)"
-          (1 3 5 7 9))
-         ("Even" "(non-consuming)"
-          (0 2 4 6 8))))
-       (">= 10" "Numbers above 9"
-        ;; Like in the "< 10" taxy, these numbers are leftovers from this
-        ;; taxy's sub-taxys, three of which are non-consuming.
-        (10 11 13 14 17 19 22 23 25 26 29 31 34 35 37 38 41 43 46 47 49 50 53 
55 58
-            59 61 62 65 67 70 71 73 74 77 79 82 83 85 86 89 91 94 95 97 98)
-        (("Divisible by 3" "(non-consuming)"
-          (12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 
78 81 84
-              87 90 93 96 99))
-         ("Divisible by 4" "(non-consuming)"
-          (12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96))
-         ("Divisible by 3 or 4" "(consuming)"
-          ;; This taxy consumes numbers it takes in, but since these
-          ;; numbers have already been taken in (without being consumed) by
-          ;; the previous two sibling taxys, they may also appear in them.
-          (12 15 16 18 20 21 24 27 28 30 32 33 36 39 40 42 44 45 48 51 52 54 
56 57 60
-              63 64 66 68 69 72 75 76 78 80 81 84 87 88 90 92 93 96 99))
-         ("Divisible by 5" "(non-consuming)"
-          (10 25 35 50 55 65 70 85 95))))))
-
-   You might think about how to produce that by writing some imperative
-code, but ‘taxy’ allows you to do so in a more declarative and
-functional manner:
-
-     (require 'taxy)
-
-     (defvar numbery
-       (make-taxy
-        :name "Numbery"
-        :description "A silly taxonomy of numbers."
-        :taxys (list (make-taxy
-                      :name "< 10"
-                      :description "Numbers below 10 (consuming)"
-                      :predicate (lambda (n) (< n 10))
-                      :taxys (list
-                              ;; These sub-taxys further classify the numbers 
below 10 into odd
-                              ;; and even.  The odd taxy "consumes" numbers, 
while the even one
-                              ;; doesn't, leaving them to reappear in the 
parent taxy's items.
-                              (make-taxy :name "Odd"
-                                         :description "(consuming)"
-                                         :predicate #'oddp)
-                              (make-taxy :name "Even"
-                                         :description "(non-consuming)"
-                                         :predicate #'evenp
-                                         :then #'identity)))
-                     (make-taxy
-                      :name ">= 10"
-                      :description "Numbers above 9 (consuming)"
-                      :predicate (lambda (n) (>= n 10))
-                      :taxys (list
-                              ;; Like in the "< 10" taxy, these sub-taxys 
further classify
-                              ;; the numbers, but only one of them consumes 
numbers it
-                              ;; takes in, leaving the rest to reappear in the 
parent taxy.
-                              (make-taxy :name "Divisible by 3"
-                                         :description "(non-consuming)"
-                                         :predicate (lambda (n) (zerop (mod n 
3)))
-                                         :then #'identity)
-                              (make-taxy :name "Divisible by 4"
-                                         :description "(non-consuming)"
-                                         :predicate (lambda (n) (zerop (mod n 
4)))
-                                         :then #'identity)
-                              (make-taxy :name "Divisible by 3 or 4"
-                                         :description "(consuming)"
-                                         ;; Since this taxy's `:then' function 
is unset,
-                                         ;; it defaults to `ignore', which 
causes it to
-                                         ;; consume numbers it takes in.  
Since these
-                                         ;; numbers have already been taken in 
(without
-                                         ;; being consumed) by the previous 
two sibling
-                                         ;; taxys, they also appear in them.
-                                         :predicate (lambda (n) (or (zerop 
(mod n 3))
-                                                                    (zerop 
(mod n 4)))))
-                              (make-taxy :name "Divisible by 5"
-                                         :description "(non-consuming)"
-                                         :predicate (lambda (n) (zerop (mod n 
5)))
-                                         :then #'identity))))))
-
-     (let ((numbers (cl-loop for i below 100 collect i))
-           ;; Since `numbery' is stored in a variable, we use an emptied
-           ;; copy of it to avoid mutating the original taxy.
-           (taxy (taxy-emptied numbery)))
-       (taxy-plain (taxy-fill (reverse numbers) taxy)))
-
-   The ‘taxy-fill’ function applies the numbers in a "cascade" down the
-hierarchy of "taxys", and the ‘taxy-plain’ function returns a meaningful
-subset of the taxys’ slots, suitable for display.
-
-
-File: README.info,  Node: Lettery (filling incrementally),  Next: Sporty 
(understanding completely),  Prev: Numbery (starting basically),  Up: Examples
-
-1.2 Lettery (filling incrementally)
-===================================
-
-You can also add more items after the hierarchy has been filled.  In
-this example we’ll make a comprehensive taxonomy of letters.  The first
-sub-taxy collects vowels, and the second, by leaving its predicate at
-the default value, ‘identity’, collects all letters not collected by the
-first taxy, i.e.  non-vowels.
-
-     (defvar lettery
-       (make-taxy
-        :name "Lettery"
-        :description "A comprehensive taxonomy of letters."
-        :taxys (list (make-taxy
-                      :name "Vowels"
-                      :description "You know what those are."
-                      :predicate (lambda (l)
-                                   (member-ignore-case l '("a" "e" "i" "o" 
"u"))))
-                     (make-taxy
-                      :name "Consonants"
-                      :description "Well, if they aren't vowels..."))))
-
-     (taxy-plain
-      (taxy-fill (reverse
-                  (cl-loop for l from ?a to ?n
-                           collect (upcase (char-to-string l))))
-                 lettery))
-
-   That produces:
-
-     ("Lettery" "A comprehensive taxonomy of letters."
-      (("Vowels" "You know what those are."
-        ("A" "E" "I"))
-       ("Consonants" "Well, if they aren't vowels..."
-        ("B" "C" "D" "F" "G" "H" "J" "K" "L" "M" "N"))))
-
-   Oops, we forgot the letters after N!  Let’s add them, too:
-
-     (taxy-plain
-      (taxy-fill (reverse
-                  (cl-loop for l from ?n to ?z
-                           collect (upcase (char-to-string l))))
-                 lettery))
-
-   Which gives us:
-
-     ("Lettery" "A comprehensive taxonomy of letters."
-      (("Vowels" "You know what those are."
-        ("O" "U" "A" "E" "I"))
-       ("Consonants" "Well, if they aren't vowels..."
-        ("N" "P" "Q" "R" "S" "T" "V" "W" "X" "Y" "Z" "B" "C" "D" "F" "G" "H" 
"J" "K" "L" "M" "N"))))
-
-   Oh, they’re out of order, now.  That won’t do.  Let’s fix that:
-
-     (taxy-plain
-      (taxy-sort #'string< #'identity lettery))
-
-   That’s better:
-
-     ("Lettery" "A comprehensive taxonomy of letters."
-      (("Vowels" "You know what those are."
-        ("A" "E" "I" "O" "U"))
-       ("Consonants" "Well, if they aren't vowels..."
-        ("B" "C" "D" "F" "G" "H" "J" "K" "L" "M" "N" "N" "P" "Q" "R" "S" "T" 
"V" "W" "X" "Y" "Z"))))
-
-
-File: README.info,  Node: Sporty (understanding completely),  Next: 
Applications,  Prev: Lettery (filling incrementally),  Up: Examples
-
-1.3 Sporty (understanding completely)
-=====================================
-
-Let’s try to understand a few things about sports.  First we’ll define a
-struct to make them easier to grasp:
-
-     (cl-defstruct sport
-       name uses venue fun)
-
-   Now we’ll make a list of sports:
-
-     (defvar sports
-       (list (make-sport :name "Baseball"
-                         :uses '(bat ball glove)
-                         :venue 'outdoor
-                         :fun t)
-             (make-sport :name "Football"
-                         :uses '(ball)
-                         :venue 'outdoor
-                         :fun t)
-             (make-sport :name "Basketball"
-                         :uses '(ball hoop)
-                         :venue 'indoor
-                         :fun t)
-             (make-sport :name "Tennis"
-                         :uses '(ball racket)
-                         :venue 'outdoor
-                         :fun t)
-             (make-sport :name "Racquetball"
-                         :uses '(ball racket)
-                         :venue 'indoor
-                         :fun t)
-             (make-sport :name "Handball"
-                         :uses '(ball glove)
-                         :venue 'indoor
-                         :fun t)
-             (make-sport :name "Soccer"
-                         :uses '(ball)
-                         :venue 'outdoor
-                         :fun nil)
-             (make-sport :name "Disc golf"
-                         :uses '(disc basket)
-                         :venue 'outdoor
-                         :fun t)
-             (make-sport :name "Ultimate"
-                         :uses '(disc)
-                         :venue 'outdoor
-                         :fun t)
-             (make-sport :name "Volleyball"
-                         :uses '(ball)
-                         :venue 'indoor
-                         :fun t)))
-
-   And finally we’ll define a taxy to organize them.  In this, we use a
-helper macro to make the ‘member’ function easier to use in the list of
-key functions:
-
-     (defvar sporty
-       (cl-macrolet ((in (needle haystack)
-                         `(lambda (item)
-                            (when (member ,needle (funcall ,haystack item))
-                              ,needle))))
-         (make-taxy
-          :name "Sporty"
-          :take (lambda (item taxy)
-                  (taxy-take-keyed
-                    (list #'sport-venue
-                          (in 'ball 'sport-uses)
-                          (in 'disc 'sport-uses)
-                          (in 'glove 'sport-uses)
-                          (in 'racket 'sport-uses))
-                    item taxy
-                    ;; We set the `:then' function of the taxys
-                    ;; created by `taxy-take-keyed' to `identity'
-                    ;; so they will not consume their items.
-                    :then #'identity)))))
-
-   Now let’s fill the taxy with the sports and format it:
-
-     (thread-last sporty
-       taxy-emptied
-       (taxy-fill sports)
-       (taxy-mapcar #'sport-name)
-       taxy-plain)
-
-     ((("Sporty"
-        ((indoor
-          ((ball
-            ("Volleyball" "Basketball")
-            ((glove
-              ("Handball"))
-             (racket
-              ("Racquetball"))))))
-         (outdoor
-          ((disc
-            ("Ultimate" "Disc golf"))
-           (ball
-            ("Soccer" "Football")
-            ((racket
-              ("Tennis"))
-             (glove
-              ("Baseball"))))))))))
-
-   That’s pretty sporty.  But classifying them by venue first makes the
-racket and glove sports not be listed together.  Let’s swap the key
-functions around so the venue is classified at the deepest level of the
-hierarchy:
-
-     (defvar sporty
-       (cl-macrolet ((in (needle haystack)
-                         `(lambda (item)
-                            (when (member ,needle (funcall ,haystack item))
-                              ,needle))))
-         (make-taxy
-          :name "Sporty"
-          :take (lambda (item taxy)
-                  (taxy-take-keyed
-                    (list (in 'ball 'sport-uses)
-                          (in 'disc 'sport-uses)
-                          (in 'glove 'sport-uses)
-                          (in 'racket 'sport-uses)
-                          #'sport-venue)
-                    item taxy
-                    :then #'identity)))))
-
-     (thread-last sporty
-       taxy-emptied
-       (taxy-fill sports)
-       (taxy-mapcar #'sport-name)
-       taxy-plain)
-
-     ((("Sporty"
-        ((disc
-          ((outdoor
-            ("Ultimate" "Disc golf"))))
-         (ball
-          ((racket
-            ((indoor
-              ("Racquetball"))
-             (outdoor
-              ("Tennis"))))
-           (indoor
-            ("Volleyball" "Basketball"))
-           (outdoor
-            ("Soccer" "Football"))
-           (glove
-            ((indoor
-              ("Handball"))
-             (outdoor
-              ("Baseball"))))))))))
-
-   That’s better.  But I’d also like to see a very simple classification
-to help me decide what to play:
-
-     (thread-last
-         (make-taxy
-          :name "Funny"
-          :take (lambda (item taxy)
-                  (taxy-take-keyed
-                    (list (lambda (sport)
-                            (if (sport-fun sport)
-                                'fun 'boring))
-                          #'sport-venue)
-                    item taxy)))
-       taxy-emptied
-       (taxy-fill sports)
-       (taxy-mapcar #'sport-name)
-       taxy-plain)
-
-     ((("Funny"
-        ((boring
-          ((outdoor
-            ("Soccer"))))
-         (fun
-          ((indoor
-            ("Volleyball" "Handball" "Racquetball" "Basketball"))
-           (outdoor
-            ("Ultimate" "Disc golf" "Tennis" "Football" "Baseball"))))))))
-
-   Ah, now I understand.
-
-
-File: README.info,  Node: Applications,  Prev: Sporty (understanding 
completely),  Up: Examples
-
-1.4 Applications
-================
-
-Some example applications may be found in the examples directory
-(examples/):
-
-   • Deffy shows top-level definitions and forms in an Elisp project or
-     file:
-   • Diredy rearranges a Dired buffer into groups by file size and type:
-   • Musicy shows a music library with tracks categorized by genre,
-     artist, year, album, etc:
-
-
-File: README.info,  Node: Installation,  Next: Usage,  Prev: Examples,  Up: Top
-
-2 Installation
-**************
-
-‘taxy’ is distributed in GNU ELPA (https://elpa.gnu.org/), which is
-available in Emacs by default.  Use ‘M-x package-install RET taxy RET’,
-then ‘(require 'taxy)’ in your Elisp project.
-
-
-File: README.info,  Node: Usage,  Next: Changelog,  Prev: Installation,  Up: 
Top
-
-3 Usage
-*******
-
-   • • • • • • 
-   A taxy is defined with the ‘make-taxy’ constructor, like:
-
-     (make-taxy :name "Numbery"
-                :description "A silly taxonomy of numbers."
-                :predicate #'numberp
-                :then #'ignore
-                :taxys (list ...))
-
-   The ‘:predicate’ function determines whether an object fits into that
-taxy.  If it does, ‘taxy-fill’ adds the object to that taxy’s descendant
-‘:taxys’, if present, or to its own ‘:items’.  The function defaults to
-‘identity’, so a taxy "takes in" any object by default (i.e.  if you
-only apply objects you want to classify, there’s no need to test them at
-the top-level taxy).
-
-   The ‘:then’ function determines what happens to an object after being
-taken in to the taxy’s ‘:items’: if the function, called with the
-object, returns a non-nil value, that value is applied to other taxys at
-the same level until one of their ‘:then’ functions returns nil or no
-more taxys remain.  The function defaults to ‘ignore’, which makes a
-taxy "consume" its items by default.  Setting the function to, e.g.
-‘identity’, makes it not consume them, leaving them eligible to also be
-taken into subsequent taxys, or to appear in the parent taxy’s items.
-
-   After defining a taxy, call ‘taxy-fill’ with it and a list of objects
-to fill the taxy’s hierarchy.  *Note:* ‘taxy-fill’ modifies the taxy
-given to it (filling its ‘:items’ and those of its ‘:taxys’), so when
-using a statically defined taxy (e.g.  one defined with ‘defvar’), you
-should pass ‘taxy-fill’ a taxy copied with ‘taxy-emptied’, which
-recursively copies a taxy without ‘:items’.
-
-   To return a taxy in a more human-readable format (with only relevant
-fields included), use ‘taxy-plain’.  You may also use ‘taxy-mapcar’ to
-replace items in a taxy with, e.g.  a more useful representation.
-
-* Menu:
-
-* Reusable taxys::
-* Threading macros::
-* Modifying filled taxys::
-* Dynamic taxys::
-* Magit section::
-* Reference::
-
-
-File: README.info,  Node: Reusable taxys,  Next: Threading macros,  Up: Usage
-
-3.1 Reusable taxys
-==================
-
-Since taxys are structs, they may be stored in variables and used in
-other structs (being sure to copy the root taxy with ‘taxy-emptied’
-before filling).  For example, this shows using ‘taxy’ to classify
-Matrix rooms in Ement.el (https://github.com/alphapapa/ement.el):
-
-     (defun ement-roomy-buffer (room)
-       (alist-get 'buffer (ement-room-local room)))
-
-     (defvar ement-roomy-unread
-       (make-taxy :name "Unread"
-                  :predicate (lambda (room)
-                               (buffer-modified-p (ement-roomy-buffer room)))))
-
-     (defvar ement-roomy-opened
-       (make-taxy :name "Opened"
-                  :description "Rooms with buffers"
-                  :predicate #'ement-roomy-buffer
-                  :taxys (list ement-roomy-unread
-                               (make-taxy))))
-
-     (defvar ement-roomy-closed
-       (make-taxy :name "Closed"
-                  :description "Rooms without buffers"
-                  :predicate (lambda (room)
-                               (not (ement-roomy-buffer room)))))
-
-     (defvar ement-roomy
-       (make-taxy
-        :name "Ement Rooms"
-        :taxys (list (make-taxy
-                      :name "Direct"
-                      :description "Direct messaging rooms"
-                      :predicate (lambda (room)
-                                   (ement-room--direct-p room ement-session))
-                      :taxys (list ement-roomy-opened
-                                   ement-roomy-closed))
-                     (make-taxy
-                      :name "Non-direct"
-                      :description "Group chat rooms"
-                      :taxys (list ement-roomy-opened
-                                   ement-roomy-closed)))))
-
-   Note how the taxys defined in the first three variables are used in
-subsequent taxys.  As well, the ‘ement-roomy-opened’ taxy has an
-"anonymous" taxy, which collects any rooms that aren’t collected by its
-sibling taxy (otherwise those objects would be collected into the
-parent, "Opened" taxy, which may not always be the most useful way to
-present the objects).
-
-   Using those defined taxys, we then fill the ‘ement-roomy’ taxy with
-all of the rooms in the user’s session, and then use ‘taxy-mapcar’ to
-replace the room structs with useful representations for display:
-
-     (taxy-plain
-      (taxy-mapcar (lambda (room)
-                     (list (ement-room--room-display-name room)
-                           (ement-room-id room)))
-        (taxy-fill (ement-session-rooms ement-session)
-                   (taxy-emptied ement-roomy))))
-
-   This produces:
-
-     ("Ement Rooms"
-      (("Direct" "Direct messaging rooms"
-        (("Opened" "Rooms with buffers"
-          (("Unread"
-            (("Lars Ingebrigtsen" "!nope:gnus.org")))))
-         ("Closed" "Rooms without buffers"
-          (("John Wiegley" "!not-really:newartisans.com")
-           ("Eli Zaretskii" "!im-afraid-not:gnu.org")))))
-       ("Non-direct" "Group chat rooms"
-        (("Opened" "Rooms with buffers"
-          (("Unread"
-            (("Emacs" "!WfZsmtnxbxTdoYPkaT:greyface.org")
-             ("#emacs" "!KuaCUVGoCiunYyKEpm:libera.chat")))
-           ;; The non-unread buffers in the "anonymous" taxy.
-           ((("magit/magit" "!HZYimOcmEAsAxOcgpE:gitter.im")
-             ("Ement.el" "!NicAJNwJawmHrEhqZs:matrix.org")
-             ("#emacsconf" "!UjTTDnYmSAslLTtMCF:libera.chat")
-             ("Emacs Matrix Client" "!ZrZoyXEyFrzcBZKNis:matrix.org")
-             ("org-mode" "!rUhEinythPhVTdddsb:matrix.org")
-             ("This Week in Matrix (TWIM)" 
"!xYvNcQPhnkrdUmYczI:matrix.org")))))
-         ("Closed" "Rooms without buffers"
-          (("#matrix-spec" "!NasysSDfxKxZBzJJoE:matrix.org")
-           ("#commonlisp" "!IiGsrmKRHzpupHRaKS:libera.chat")
-           ("Matrix HQ" "!OGEhHVWSdvArJzumhm:matrix.org")
-           ("#lisp" "!czLxhhEegTEGNKUBgo:libera.chat")
-           ("Emacs" "!gLamGIXTWBaDFfhEeO:matrix.org")
-           ("#matrix-dev:matrix.org" "!jxlRxnrZCsjpjDubDX:matrix.org")))))))
-
-
-File: README.info,  Node: Threading macros,  Next: Modifying filled taxys,  
Prev: Reusable taxys,  Up: Usage
-
-3.2 Threading macros
-====================
-
-If you happen to like macros, ‘taxy’ works well with threading (i.e.
-‘thread-last’ or ‘->>’):
-
-     (thread-last ement-roomy
-       taxy-emptied
-       (taxy-fill (ement-session-rooms ement-session))
-       (taxy-mapcar (lambda (room)
-                      (list (ement-room--room-display-name room)
-                            (ement-room-id room))))
-       taxy-plain)
-
-
-File: README.info,  Node: Modifying filled taxys,  Next: Dynamic taxys,  Prev: 
Threading macros,  Up: Usage
-
-3.3 Modifying filled taxys
-==========================
-
-Sometimes it’s necessary to modify a taxy after filling it with objects,
-e.g.  to sort the items and/or the sub-taxys.  For this, use the
-function ‘taxy-mapc-taxys’ (a.k.a.  ‘taxy-mapc*’).  For example, in the
-sample application musicy.el (examples/musicy.el), the taxys and their
-items are sorted after filling, like so:
-
-     (defun musicy-files (files)
-       (thread-last musicy-taxy
-         taxy-emptied
-         (taxy-fill files)
-         ;; Sort sub-taxys by their name.
-         (taxy-sort* #'string< #'taxy-name)
-         ;; Sort sub-taxys' items by name.
-         (taxy-sort #'string< #'identity)
-         taxy-magit-section-pp))
-
-
-File: README.info,  Node: Dynamic taxys,  Next: Magit section,  Prev: 
Modifying filled taxys,  Up: Usage
-
-3.4 Dynamic taxys
-=================
-
-   • • • 
-   You may not always know in advance what taxonomy a set of objects
-fits into, so ‘taxy’ lets you add taxys dynamically by using the ‘:take’
-function to add a taxy when an object is "taken into" a parent taxy’s
-items.  For example, you could dynamically classify buffers by their
-major mode like so:
-
-     (defun buffery-major-mode (buffer)
-       (buffer-local-value 'major-mode buffer))
-
-     (defvar buffery
-       (make-taxy
-        :name "Buffers"
-        :taxys (list
-                (make-taxy
-                 :name "Modes"
-                 :take (apply-partially #'taxy-take-keyed (list 
#'buffery-major-mode))))))
-
-     ;; Note the use of `taxy-emptied' to avoid mutating the original taxy 
definition.
-     (taxy-plain
-      (taxy-fill (buffer-list)
-                 (taxy-emptied buffery)))
-
-   The taxy’s ‘:take’ function is set to the ‘taxy-take-keyed’ function,
-partially applied with the ‘buffery-major-mode’ function as its list of
-‘key-fns’ (‘taxy-fill’ supplies the buffer and the taxy as arguments),
-and it produces this taxonomy of buffers:
-
-     ("Buffers"
-      (("Modes"
-        ((magit-process-mode
-          (#<buffer magit-process: taxy.el> #<buffer magit-process: > #<buffer 
magit-process: notes>))
-         (messages-buffer-mode
-          (#<buffer *Messages*>))
-         (special-mode
-          (#<buffer *Warnings*> #<buffer *elfeed-log*>))
-         (dired-mode
-          (#<buffer ement.el<emacs>>))
-         (Custom-mode
-          (#<buffer *Customize Apropos*>))
-         (fundamental-mode
-          (#<buffer  *helm candidates:Bookmarks*> #<buffer *Backtrace*>))
-         (magit-diff-mode
-          (#<buffer magit-diff: taxy.el> #<buffer magit-diff: notes> #<buffer 
magit-diff: ement.el>))
-         (compilation-mode
-          (#<buffer *compilation*> #<buffer *Compile-Log*>))
-         (Info-mode
-          (#<buffer  *helm info temp buffer*> #<buffer *info*>))
-         (help-mode
-          (#<buffer *Help*>))
-         (emacs-lisp-mode
-          (#<buffer ement.el<ement.el>> #<buffer ement-room-list.el> #<buffer 
*scratch*>
-                    #<buffer ement-room.el> #<buffer init.el> #<buffer 
bufler.el>
-                    #<buffer dash.el> #<buffer *Pp Eval Output*> #<buffer 
taxy.el> #<buffer scratch.el>))))))
-
-* Menu:
-
-* Multi-level dynamic taxys::
-* "Chains" of independent, multi-level dynamic taxys: "Chains" of independent 
multi-level dynamic taxys.
-* Defining a classification domain-specific language::
-
-
-File: README.info,  Node: Multi-level dynamic taxys,  Next: "Chains" of 
independent multi-level dynamic taxys,  Up: Dynamic taxys
-
-3.4.1 Multi-level dynamic taxys
--------------------------------
-
-Of course, the point of taxonomies is that they aren’t restricted to a
-single level of depth, so you may also use the function
-‘taxy-take-keyed’ to dynamically make multi-level taxys.
-
-   Expanding on the previous example, we use ‘cl-labels’ to define
-functions which are used in the taxy’s definition, which are used in the
-‘:take’ function, which calls ‘taxy-take-keyed’ (rather than using
-‘apply-partially’ like in the previous example, we use a lambda
-function, which performs better than partially applied functions).  Then
-when the taxy is filled, a multi-level hierarchy is created dynamically,
-organizing buffers first by their directory, and then by mode in each
-directory.
-
-     (defvar buffery
-       (cl-labels ((buffer-mode (buffer) (buffer-local-value 'major-mode 
buffer))
-                   (buffer-directory (buffer) (buffer-local-value 
'default-directory buffer)))
-         (make-taxy
-          :name "Buffers"
-          :taxys (list
-                  (make-taxy
-                   :name "Directories"
-                   :take (lambda (item taxy)
-                           (taxy-take-keyed (list #'buffer-directory 
#'buffer-mode) item taxy)))))))
-
-     (taxy-plain
-      (taxy-fill (buffer-list)
-                 (taxy-emptied buffery)))
-
-   That produces a list like:
-
-     ("Buffers"
-      (("Directories"
-        (("~/src/emacs/ement.el/"
-          ((dired-mode
-            (#<buffer ement.el<emacs>))
-           (emacs-lisp-mode
-            (#<buffer ement.el<ement.el> #<buffer ement-room-list.el> #<buffer 
ement-room.el>))
-           (magit-diff-mode
-            (#<buffer magit-diff: ement.el>))))
-         ("~/src/emacs/taxy.el/"
-          ((dired-mode
-            (#<buffer taxy.el<emacs>))
-           (Info-mode
-            (#<buffer *info*>))
-           (magit-status-mode
-            (#<buffer magit: taxy.el>))
-           (emacs-lisp-mode
-            (#<buffer taxy-magit-section.el> #<buffer taxy.el<taxy.el> 
#<buffer scratch.el>))))))))
-
-
-File: README.info,  Node: "Chains" of independent multi-level dynamic taxys,  
Next: Defining a classification domain-specific language,  Prev: Multi-level 
dynamic taxys,  Up: Dynamic taxys
-
-3.4.2 "Chains" of independent, multi-level dynamic taxys
---------------------------------------------------------
-
-_Naming things is hard._
-
-   Going a step further, each element in the ‘taxy-take-keyed’
-function’s ‘KEY-FNS’ argument may be a list of functions (or a list of
-lists of functions, etc.), which creates a "chain" of "independent"
-dynamic taxys.  Each such chain may be said to "short-circuit" the
-filling process in that, when an object is "taken" by the first key
-function in a chain, the object is not "offered" to other functions
-outside that chain.  This allows each dynamic sub-taxy to have its own
-set of sub-taxys, rather than sharing the same "global" set.  In effect,
-this creates multiple, unique taxonomies that share a single root taxy.
-
-   Building on the ‘sporty’ example, let’s define a taxy in which
-outdoor sports are classified only by whether they involve a disc, but
-indoor sports are additionally classified by whatever equipment they may
-use:
-
-     (defvar sporty-dynamic
-       (cl-macrolet ((in (needle haystack)
-                         `(lambda (item)
-                            (when (member ,needle (funcall ,haystack item))
-                              ,needle))))
-         (cl-labels ((outdoor-p
-                      (sport) (when (eq 'outdoor (sport-venue sport))
-                                "Outdoor"))
-                     (indoor-p
-                      (sport) (when (eq 'indoor (sport-venue sport))
-                                "Indoor"))
-                     (disc-p
-                      (sport) (if (funcall (in 'disc 'sport-uses) sport)
-                                  'disc
-                                'non-disc)))
-           (make-taxy
-            :name "Sporty (dynamic)"
-            :take (lambda (item taxy)
-                    (taxy-take-keyed
-                      (list (list #'outdoor-p #'disc-p)
-                            (list #'indoor-p
-                                  (in 'ball 'sport-uses)
-                                  (in 'disc 'sport-uses)
-                                  (in 'glove 'sport-uses)
-                                  (in 'racket 'sport-uses)))
-                      item taxy))))))
-
-   Now let’s fill the taxy with the sports and format it:
-
-     (thread-last sporty-dynamic
-       taxy-emptied
-       (taxy-fill sports)
-       (taxy-mapcar #'sport-name)
-       taxy-plain)
-
-     ("Sporty (dynamic)"
-      (("Indoor"
-        ((ball
-          ("Volleyball" "Basketball")
-          ((glove
-            ("Handball"))
-           (racket
-            ("Racquetball"))))))
-       ("Outdoor"
-        ((disc
-          ("Ultimate" "Disc golf"))
-         (non-disc
-          ("Soccer" "Tennis" "Football" "Baseball"))))))
-
-
-File: README.info,  Node: Defining a classification domain-specific language,  
Prev: "Chains" of independent multi-level dynamic taxys,  Up: Dynamic taxys
-
-3.4.3 Defining a classification domain-specific language
---------------------------------------------------------
-
-When writing a larger Taxy-based application, it may be necessary to
-define a number of key functions that would be unwieldy to manage in a
-‘cl-labels’ form.  For this case, Taxy provides the macro
-‘taxy-define-key-definer’ to easily define Taxy key functions in an
-application library.  Those functions are then passed to the function
-‘taxy-make-take-function’ at runtime, along with a list of keys being
-used to classify items.  Using these allows key functions to be defined
-in top-level forms, and it allows an application to be extended by users
-by defining additional key functions in their configurations.
-
-   Extending the previous ‘sporty’ example, let’s redefine its key
-functions using ‘taxy-define-key-definer’:
-
-     (taxy-define-key-definer sporty-define-key
-       sporty-keys "sporty"
-       "Define a `sporty' key function.")
-
-     (sporty-define-key disc-based ()
-       (if (member 'disc (sport-uses item))
-           "Disc-based"
-         "Non-disc-based"))
-
-     (sporty-define-key uses (&optional thing)
-       (pcase thing
-         (`nil (sport-uses item))
-         (_ (when (cl-typecase (sport-uses item)
-                    (symbol (equal thing (sport-uses item)))
-                    (list (member thing (sport-uses item))))
-              thing))))
-
-     (sporty-define-key venue (&optional place)
-       (pcase place
-         (`nil (sport-venue item))
-         (_ (when (equal place (sport-venue item))
-              (sport-venue item)))))
-
-   Now we’ll define the default keys to use when classifying items.
-This list is equivalent to the one passed to ‘taxy-take-keyed’ in the
-previous, "Chains" example.
-
-     (defvar sporty-default-keys
-       '(
-         ((venue 'outdoor)
-          disc-based)
-
-         ((venue 'indoor)
-          (uses 'ball)
-          (uses 'disc)
-          (uses 'glove)
-          (uses 'racket))))
-
-   Finally, rather than using a pre-made taxy struct, we make one at
-runtime, making the ‘:take’ function with ‘taxy-make-take-function’.
-
-     (let ((taxy (make-taxy
-                  :name "Sporty (DSL)"
-                  :take (taxy-make-take-function sporty-default-keys
-                                                 sporty-keys))))
-       (thread-last taxy
-         (taxy-fill sports)
-         (taxy-mapcar #'sport-name)
-         taxy-plain))
-
-   Which gives us:
-
-     ("Sporty (DSL)"
-      ((indoor
-        ((ball
-          ("Volleyball" "Basketball")
-          ((glove
-            ("Handball"))
-           (racket
-            ("Racquetball"))))))
-       (outdoor
-        (("Disc-based"
-          ("Ultimate" "Disc golf"))
-         ("Non-disc-based"
-          ("Soccer" "Tennis" "Football" "Baseball"))))))
-
-   As you can see, the result is the same as that in the previous
-example, but we’ve defined a kind of DSL for grouping sports in a
-modular, extendable way.
-
-   This also allows the grouping keys to be easily changed at runtime,
-producing a different result.  For example, we could group sports by,
-first, whether they use a ball, and then by venue.  Let’s do this in a
-function so that users can pass their own list of keys:
-
-     (cl-defun sporty-classify (sports &key (keys sporty-default-keys))
-       (declare (indent defun))
-       (let* ((taxy (make-taxy
-                     :name "Sporty (DSL)"
-                     :take (taxy-make-take-function keys
-                                                    sporty-keys))))
-         (thread-last taxy
-           (taxy-fill sports)
-           (taxy-mapcar #'sport-name)
-           taxy-plain)))
-
-     (sporty-classify sports
-       :keys '((uses 'ball) venue))
-
-   And this produces:
-
-     ("Sporty (DSL)"
-      ((outdoor
-        ("Ultimate" "Disc golf"))
-       (ball
-        ((indoor
-          ("Volleyball" "Handball" "Racquetball" "Basketball"))
-         (outdoor
-          ("Soccer" "Tennis" "Football" "Baseball"))))))
-
-
-File: README.info,  Node: Magit section,  Next: Reference,  Prev: Dynamic 
taxys,  Up: Usage
-
-3.5 Magit section
-=================
-
-Showing a ‘taxy’ with ‘magit-section’ is very easy:
-
-     (require 'taxy-magit-section)
-
-     ;; Using the `numbery' taxy defined in earlier examples:
-     (thread-last numbery
-       taxy-emptied ;; Get an empty copy of the taxy, since it's defined in a 
variable.
-       (taxy-fill (reverse (cl-loop for i below 30 collect i)))
-       taxy-magit-section-pp)
-
-   That shows a buffer like this:
-
-   Note that while ‘taxy-magit-section.el’ is installed with the ‘taxy’
-package, the ‘magit-section’ package is not automatically installed with
-it.
-
-
-File: README.info,  Node: Reference,  Prev: Magit section,  Up: Usage
-
-3.6 Reference
-=============
-
-In Emacs 28+, see also ‘M-x shortdoc-display-group RET taxy RET’.
-
-* Menu:
-
-* Functions::
-* Macros::
-
-
-File: README.info,  Node: Functions,  Next: Macros,  Up: Reference
-
-3.6.1 Functions
----------------
-
-taxy-flatten (taxy)
-     Return a list of items in ‘taxy’ and its sub-taxys.
-
-taxy-emptied (taxy)
-     Return a copy of ‘taxy’ without items.  Omits =taxy=’s items and
-     those of its descendant taxys.  Useful when reusing taxy
-     definitions.
-
-taxy-fill (items taxy)
-     Fill ‘taxy’ with ‘items’ according to its definition.
-
-taxy-make-take-function (keys aliases)
-     Return a taxy "take" function for ‘keys’.  Each of ‘keys’ should be
-     a function alias defined in ‘aliases’, or a list of such ‘key-fns’
-     (recursively, ad infinitum, approximately).  ‘aliases’ should be an
-     alist mapping aliases to functions (such as defined with a definer
-     defined by ‘taxy-define-key-definer’).
-
-taxy-mapc-taxys (fn taxy)
-     *Alias:* ‘taxy-mapc*’
-
-     Return ‘taxy’ having applied ‘fn’ to it and its descendants.  Does
-     not copy ‘taxy’.  Destructively modifies ‘taxy’, if ‘fn’ does.
-
-taxy-mapcar-items (fn taxy)
-     *Alias:* ‘taxy-mapcar’
-
-     Return copy of ‘taxy’, having replaced its items with the value of
-     ‘fn’ on each.  Replaces every item in ‘taxy’ and its descendants.
-     Useful to replace items with a more useful form after
-     classification.
-
-taxy-plain (taxy)
-     Return a list of the human-readable parts of ‘taxy’.
-
-taxy-size (taxy)
-     Return the number of items ‘taxy’ holds.  Includes items in ‘taxy’
-     ’s sub-taxys.
-
-taxy-sort-items (pred key taxy)
-     *Alias:* ‘taxy-sort’
-
-     Sort ‘taxy’ ’s items by ‘pred’ and ‘key’.  Sorts items in ‘taxy’
-     and its sub-taxys.  ‘key’ is passed to ‘cl-sort’, which see.
-
-taxy-sort-taxys (pred key taxy)
-     *Alias:* ‘taxy-sort*’
-
-     Sort ‘taxy’ ’s sub-taxys by ‘pred’ and ‘key’.  ‘key’ is passed to
-     ‘cl-sort’, which see.
-
-
-File: README.info,  Node: Macros,  Prev: Functions,  Up: Reference
-
-3.6.2 Macros
-------------
-
-taxy-define-key-definer (name variable prefix docstring)
-     Define a macro ‘name’ that defines a key-function-defining macro.
-     The defined macro, having string ‘docstring’, associates the
-     defined key functions with their aliases in an alist stored in
-     symbol ‘variable’.  The defined key functions are named having
-     string ‘prefix’, which will have a hyphen appended to it.  The key
-     functions take one or more arguments, the first of which is the
-     item being tested, bound within the function to ‘item’.
-
-
-File: README.info,  Node: Changelog,  Next: Development,  Prev: Usage,  Up: Top
-
-4 Changelog
-***********
-
-* Menu:
-
-* 0.9-pre: 09-pre.
-* 0.8: 08.
-* 0.7: 07.
-* 0.6: 06.
-* 0.5: 05.
-* 0.4: 04.
-* 0.3: 03.
-* 0.2: 02.
-* 0.1: 01.
-
-
-File: README.info,  Node: 09-pre,  Next: 08,  Up: Changelog
-
-4.1 0.9-pre
-===========
-
-Nothing new yet.
-
-
-File: README.info,  Node: 08,  Next: 07,  Prev: 09-pre,  Up: Changelog
-
-4.2 0.8
-=======
-
-* Menu:
-
-* Additions::
-* Fixes::
-
-
-File: README.info,  Node: Additions,  Next: Fixes,  Up: 08
-
-4.2.1 Additions
----------------
-
-   • Short documentation group for Emacs 28+.
-
-
-File: README.info,  Node: Fixes,  Prev: Additions,  Up: 08
-
-4.2.2 Fixes
------------
-
-   • Require ‘map’ for ‘pcase’ pattern.
-
-
-File: README.info,  Node: 07,  Next: 06,  Prev: 08,  Up: Changelog
-
-4.3 0.7
-=======
-
-* Menu:
-
-* Additions: Additions (1).
-
-
-File: README.info,  Node: Additions (1),  Up: 07
-
-4.3.1 Additions
----------------
-
-   • Function ‘taxy-flatten’ returns a list of the items in a taxy and
-     its sub-taxys.
-   • Function/macro reference documentation.
-   • Example application ‘bookmarky’ lists Emacs bookmarks grouped with
-     Taxy.
-
-
-File: README.info,  Node: 06,  Next: 05,  Prev: 07,  Up: Changelog
-
-4.4 0.6
-=======
-
-* Menu:
-
-* Additions: Additions (2).
-
-
-File: README.info,  Node: Additions (2),  Up: 06
-
-4.4.1 Additions
----------------
-
-   • Sorting functions:
-        • ‘taxy-sort-items’ (alias: ‘taxy-sort’) sorts the items in a
-          taxy and its sub-taxys.
-        • ‘taxy-sort-taxys’ (alias: ‘taxy-sort*’) sorts a taxy’s
-          sub-taxys.
-   • Defining classification domain-specific languages:
-        • Macro ‘taxy-define-key-definer’ defines a
-          key-function-defining macro.
-        • Function ‘taxy-make-take-function’ makes a ‘:take’ function
-          using a list of key functions and a set of classification
-          keys.
-   • Table-like, column-based formatting system for
-     ‘taxy-magit-section’:
-        • Function ‘taxy-magit-section-format-items’, which formats
-          items by columns.
-        • Variable ‘taxy-magit-section-insert-indent-items’, which
-          controls whether ‘taxy-magit-section-insert’ applies
-          indentation to each item.  (Used to disable that behavior when
-          items are pre-indented strings, e.g.  as formatted by
-          ‘taxy-magit-section-format-items’.)
-   • Example application ‘deffy’, which shows an overview of top-level
-     definitions and forms in an Elisp project or file.  (Likely to be
-     published as a separate package later.)
-
-
-File: README.info,  Node: 05,  Next: 04,  Prev: 06,  Up: Changelog
-
-4.5 0.5
-=======
-
-* Menu:
-
-* Additions: Additions (3).
-* Fixes: Fixes (1).
-
-
-File: README.info,  Node: Additions (3),  Next: Fixes (1),  Up: 05
-
-4.5.1 Additions
----------------
-
-   • Function ‘taxy-magit-section-insert’ takes new arguments:
-        • ‘:initial-depth’ sets the level at which the first level of
-          hierarchy is considered to be at, for purposes of indentation.
-          Setting it to a negative number prevents indentation of so
-          many levels (i.e.  setting it to -1 causes the first two
-          levels to be unindented, since the first level will be
-          considered to be at depth -1, and the second at depth 0).
-        • ‘:blank-between-depth’ sets the level up to which blank lines
-          are inserted between sections (i.e.  setting it to 1 causes
-          blank lines to be inserted between sections up to depth 1, but
-          not between sections deeper than that).
-   • Struct ‘taxy-magit-section’ has a new ‘heading-face’ slot, a
-     function which takes a depth level argument and returns the face
-     with which to propertize that section’s heading.
-   • New example ‘taxy-package-report’.
-
-
-File: README.info,  Node: Fixes (1),  Prev: Additions (3),  Up: 05
-
-4.5.2 Fixes
------------
-
-   • Example ‘diredy’ referred to an old function name.
-
-
-File: README.info,  Node: 04,  Next: 03,  Prev: 05,  Up: Changelog
-
-4.6 0.4
-=======
-
-   • Incremented version to cause a new ELPA release (since removing a
-     file that wasn’t intended to be distributed on ELPA).
-
-
-File: README.info,  Node: 03,  Next: 02,  Prev: 04,  Up: Changelog
-
-4.7 0.3
-=======
-
-* Menu:
-
-* Changes::
-* Fixes: Fixes (2).
-
-
-File: README.info,  Node: Changes,  Next: Fixes (2),  Up: 03
-
-4.7.1 Changes
--------------
-
-   • Within the ‘taxy’ struct and related functions, the term ‘objects’
-     is renamed to ‘items’, which is shorter and has the same meaning.
-     This makes code a bit more concise (e.g.  ‘(taxy-objects taxy)’
-     becomes ‘(taxy-items taxy)’).
-
-
-File: README.info,  Node: Fixes (2),  Prev: Changes,  Up: 03
-
-4.7.2 Fixes
------------
-
-   • Function ‘taxy-fill’ always calls a taxy’s ‘:take’ function if
-     defined.  (Fixing "chains" of dynamic taxys.)
-   • Function ‘taxy-magit-section-insert’ applies text properties from
-     the inserted string to the indentation string (so commands that
-     rely on text properties at the beginning of a line will work).
-
-
-File: README.info,  Node: 02,  Next: 01,  Prev: 03,  Up: Changelog
-
-4.8 0.2
-=======
-
-* Menu:
-
-* Changes: Changes (1).
-* Additions: Additions (4).
-* Fixes: Fixes (3).
-
-
-File: README.info,  Node: Changes (1),  Next: Additions (4),  Up: 02
-
-4.8.1 Changes
--------------
-
-   • Function ‘taxy-take-keyed*’ is renamed to ‘taxy-take-keyed’,
-     replacing the old function: it’s more powerful, and there’s little
-     reason to maintain two versions.
-
-
-File: README.info,  Node: Additions (4),  Next: Fixes (3),  Prev: Changes (1), 
 Up: 02
-
-4.8.2 Additions
----------------
-
-   • Struct ‘taxy’ now has a ‘:make’ slot, a function called to make new
-     sub-taxys by ‘take-take-keyed’ (defaulting to ‘make-taxy’).  This
-     is useful when defining structs specialized on ‘taxy’.
-   • Struct ‘taxy-magit-section’ now has an ‘:indent’ slot, a number of
-     characters by which to indent each level of sub-taxy, applied
-     automatically by function ‘taxy-magit-section-insert’.
-   • Each element of the new ‘taxy-take-keyed’’s ‘KEY-FNS’ argument may
-     now be a function or a list of functions (or a list of a list of
-     functions, etc.).  Lists of functions create "chains" of
-     independent, dynamic taxys descending from a single root taxy.  See
-     .
-
-
-File: README.info,  Node: Fixes (3),  Prev: Additions (4),  Up: 02
-
-4.8.3 Fixes
------------
-
-   • ‘taxy-magit-section’’s ‘insert-object’ function.
-   • ‘taxy-fill’ now applies objects to the root taxy if no sub-taxys
-     take them.
-
-
-File: README.info,  Node: 01,  Prev: 02,  Up: Changelog
-
-4.9 0.1
-=======
-
-First tagged version.
-
-
-File: README.info,  Node: Development,  Next: Credits,  Prev: Changelog,  Up: 
Top
-
-5 Development
-*************
-
-Bug reports, feature requests, suggestions — _oh my_!
-
-* Menu:
-
-* Copyright assignment::
-
-
-File: README.info,  Node: Copyright assignment,  Up: Development
-
-5.1 Copyright assignment
-========================
-
-This package is part of GNU Emacs (https://www.gnu.org/software/emacs/),
-being distributed in GNU ELPA (https://elpa.gnu.org/).  Contributions to
-this project must follow GNU guidelines, which means that, as with other
-parts of Emacs, patches of more than a few lines must be accompanied by
-having assigned copyright for the contribution to the FSF.  Contributors
-who wish to do so may contact emacs-devel@gnu.org <emacs-devel@gnu.org>
-to request the assignment form.
-
-
-File: README.info,  Node: Credits,  Next: License,  Prev: Development,  Up: Top
-
-6 Credits
-*********
-
-   • Thanks to Stefan Monnier for his feedback, and for maintaining GNU
-     ELPA.
-
-
-File: README.info,  Node: License,  Prev: Credits,  Up: Top
-
-7 License
-*********
-
-GPLv3
-
-
-
-Tag Table:
-Node: Top218
-Node: Examples2246
-Node: Numbery (starting basically)2565
-Node: Lettery (filling incrementally)8326
-Node: Sporty (understanding completely)10840
-Node: Applications16827
-Node: Installation17302
-Node: Usage17615
-Node: Reusable taxys19770
-Node: Threading macros23923
-Node: Modifying filled taxys24462
-Node: Dynamic taxys25280
-Node: Multi-level dynamic taxys27929
-Node: "Chains" of independent multi-level dynamic taxys30122
-Node: Defining a classification domain-specific language33053
-Node: Magit section37216
-Node: Reference37913
-Node: Functions38121
-Node: Macros40099
-Node: Changelog40749
-Node: 09-pre40974
-Node: 0841080
-Node: Additions41205
-Node: Fixes41349
-Node: 0741487
-Node: Additions (1)41612
-Node: 0641931
-Node: Additions (2)42056
-Node: 0543406
-Node: Additions (3)43551
-Node: Fixes (1)44661
-Node: 0444819
-Node: 0345041
-Node: Changes45170
-Node: Fixes (2)45533
-Node: 0245968
-Node: Changes (1)46137
-Node: Additions (4)46429
-Node: Fixes (3)47288
-Node: 0147542
-Node: Development47641
-Node: Copyright assignment47847
-Node: Credits48435
-Node: License48625
-
-End Tag Table
-
-
-Local Variables:
-coding: utf-8
-End:



reply via email to

[Prev in Thread] Current Thread [Next in Thread]