1 | (in-package :named-readtables) |
---|
2 | |
---|
3 | (eval-when (:compile-toplevel :load-toplevel :execute) |
---|
4 | (use-package :mgl-pax)) |
---|
5 | |
---|
6 | (defsection @named-readtables-manual (:title "Named Readtables Manual") |
---|
7 | (named-readtables asdf:system) |
---|
8 | (@named-readtables-introduction section) |
---|
9 | (@named-readtables-overview section) |
---|
10 | (@named-readtables-reference section)) |
---|
11 | |
---|
12 | (defsection @named-readtables-introduction (:title "Introduction") |
---|
13 | "Named-Readtables is a library that provides a namespace for |
---|
14 | readtables akin to the already-existing namespace of packages. In |
---|
15 | particular: |
---|
16 | |
---|
17 | * you can associate readtables with names, and retrieve |
---|
18 | readtables by names; |
---|
19 | |
---|
20 | * you can associate source files with readtable names, and be |
---|
21 | sure that the right readtable is active when compiling/loading |
---|
22 | the file; |
---|
23 | |
---|
24 | * similiarly, your development environment now has a chance to |
---|
25 | automatically determine what readtable should be active while |
---|
26 | processing source forms on interactive commands. (E.g. think of |
---|
27 | `C-c C-c` in Slime (yet to be done)) |
---|
28 | |
---|
29 | It follows that Named-Readtables is a facility for using readtables in |
---|
30 | a localized way. |
---|
31 | |
---|
32 | Additionally, it also attempts to become a facility for using |
---|
33 | readtables in a _modular_ way. In particular: |
---|
34 | |
---|
35 | * it provides a macro to specify the content of a readtable at a |
---|
36 | glance; |
---|
37 | |
---|
38 | * it makes it possible to use multiple inheritance between readtables." |
---|
39 | (@named-readtables-links section) |
---|
40 | (@named-readtables-acknowledgements section)) |
---|
41 | |
---|
42 | (defsection @named-readtables-links (:title "Links") |
---|
43 | "Here is the [official repository][named-readtables-repo] and the |
---|
44 | [HTML documentation][named-readtables-doc] for the latest version. |
---|
45 | |
---|
46 | [named-readtables-repo]: https://github.com/melisgl/named-readtables |
---|
47 | [named-readtables-doc]: http://melisgl.github.io/mgl-pax-world/named-readtables-manual.html") |
---|
48 | |
---|
49 | (defsection @named-readtables-acknowledgements (:title "Acknowledgements") |
---|
50 | "Thanks to Robert Goldman for making me want to write this library. |
---|
51 | |
---|
52 | Thanks to Stephen Compall, Ariel Badichi, David Lichteblau, Bart |
---|
53 | Botta, David Crawford, and Pascal Costanza for being early adopters, |
---|
54 | providing comments and bugfixes.") |
---|
55 | |
---|
56 | (defsection @named-readtables-overview (:title "Overview") |
---|
57 | (@named-readtables-api-notes section) |
---|
58 | (@named-readtables-api-idiosyncrasies section) |
---|
59 | (@named-readtables-preregistered section) |
---|
60 | (@named-readtables-examples section)) |
---|
61 | |
---|
62 | (defsection @named-readtables-api-notes (:title "Notes on the API" :export nil) |
---|
63 | "The API heavily imitates the API of packages. This has the nice |
---|
64 | property that any experienced Common Lisper will take it up without |
---|
65 | effort. |
---|
66 | |
---|
67 | DEFREADTABLE - DEFPACKAGE |
---|
68 | |
---|
69 | IN-READTABLE - IN-PACKAGE |
---|
70 | |
---|
71 | MERGE-READTABLES-INTO - USE-PACKAGE |
---|
72 | |
---|
73 | MAKE-READTABLE - MAKE-PACKAGE |
---|
74 | |
---|
75 | UNREGISTER-READTABLE - DELETE-PACKAGE |
---|
76 | |
---|
77 | RENAME-READTABLE - RENAME-PACKAGE |
---|
78 | |
---|
79 | FIND-READTABLE - FIND-PACKAGE |
---|
80 | |
---|
81 | READTABLE-NAME - PACKAGE-NAME |
---|
82 | |
---|
83 | LIST-ALL-NAMED-READTABLES - LIST-ALL-PACKAGES") |
---|
84 | |
---|
85 | (defsection @named-readtables-api-idiosyncrasies |
---|
86 | (:title "Important API idiosyncrasies" :export nil) |
---|
87 | "There are three major differences between the API of Named-Readtables, |
---|
88 | and the API of packages. |
---|
89 | |
---|
90 | 1. Readtable names are symbols not strings. |
---|
91 | |
---|
92 | Time has shown that the fact that packages are named by strings |
---|
93 | causes severe headache because of the potential of package names |
---|
94 | colliding with each other. |
---|
95 | |
---|
96 | Hence, readtables are named by symbols lest to make the |
---|
97 | situation worse than it already is. Consequently, readtables |
---|
98 | named `CL-ORACLE:SQL-SYNTAX` and `CL-MYSQL:SQL-SYNTAX` can |
---|
99 | happily coexist next to each other. Or, taken to an extreme, |
---|
100 | `SCHEME:SYNTAX` and `ELISP:SYNTAX`. |
---|
101 | |
---|
102 | If, for example to duly signify the importance of your cool |
---|
103 | readtable hack, you really think it deserves a global name, you |
---|
104 | can always resort to keywords. |
---|
105 | |
---|
106 | 2. The inheritance is resolved statically, not dynamically. |
---|
107 | |
---|
108 | A package that uses another package will have access to all the |
---|
109 | other package's exported symbols, even to those that will be |
---|
110 | added after its definition. I.e. the inheritance is resolved at |
---|
111 | run-time, that is dynamically. |
---|
112 | |
---|
113 | Unfortunately, we cannot do the same for readtables in a |
---|
114 | portable manner. |
---|
115 | |
---|
116 | Therefore, we do not talk about \"using\" another readtable but |
---|
117 | about \"merging\" the other readtable's definition into the |
---|
118 | readtable we are going to define. I.e. the inheritance is |
---|
119 | resolved once at definition time, that is statically. |
---|
120 | |
---|
121 | (Such merging can more or less be implemented portably albeit at |
---|
122 | a certain cost. Most of the time, this cost manifests itself at |
---|
123 | the time a readtable is defined, i.e. once at compile-time, so |
---|
124 | it may not bother you. Nonetheless, we provide extra support for |
---|
125 | Sbcl, ClozureCL, and AllegroCL at the moment. Patches for your |
---|
126 | implementation of choice are welcome, of course.) |
---|
127 | |
---|
128 | 3. DEFREADTABLE does not have compile-time effects. |
---|
129 | |
---|
130 | If you define a package via DEFPACKAGE, you can make that |
---|
131 | package the currently active package for the subsequent |
---|
132 | compilation of the same file via IN-PACKAGE. The same is, |
---|
133 | however, not true for DEFREADTABLE and IN-READTABLE for the |
---|
134 | following reason: |
---|
135 | |
---|
136 | It's unlikely that the need for special reader-macros arises for |
---|
137 | a problem which can be solved in just one file. Most often, |
---|
138 | you're going to define the reader macro functions, and set up |
---|
139 | the corresponding readtable in an extra file. |
---|
140 | |
---|
141 | If DEFREADTABLE had compile-time effects, you'd have to wrap |
---|
142 | each definition of a reader-macro function in an EVAL-WHEN to |
---|
143 | make its definition available at compile-time. Because that's |
---|
144 | simply not the common case, DEFREADTABLE does not have a |
---|
145 | compile-time effect. |
---|
146 | |
---|
147 | If you want to use a readtable within the same file as its |
---|
148 | definition, wrap the DEFREADTABLE and the reader-macro function |
---|
149 | definitions in an explicit EVAL-WHEN.") |
---|
150 | |
---|
151 | (defsection @named-readtables-preregistered (:title "Preregistered Readtables" |
---|
152 | :export nil) |
---|
153 | "- NIL, :STANDARD, and :COMMON-LISP designate the |
---|
154 | _standard readtable_. |
---|
155 | |
---|
156 | - :MODERN designates a _case-preserving_ _standard-readtable_. |
---|
157 | |
---|
158 | - :CURRENT designates the _current readtable_.") |
---|
159 | |
---|
160 | (defsection @named-readtables-examples (:title "Examples" :export nil) |
---|
161 | "```commonlisp |
---|
162 | (defreadtable elisp:syntax |
---|
163 | (:merge :standard) |
---|
164 | (:macro-char #\\? #'elisp::read-character-literal t) |
---|
165 | (:macro-char #\\[ #'elisp::read-vector-literal t) |
---|
166 | ... |
---|
167 | (:case :preserve)) |
---|
168 | |
---|
169 | (defreadtable scheme:syntax |
---|
170 | (:merge :standard) |
---|
171 | (:macro-char #\\[ #'(lambda (stream char) |
---|
172 | (read-delimited-list #\\] stream))) |
---|
173 | (:macro-char #\\# :dispatch) |
---|
174 | (:dispatch-macro-char #\\# #\\t #'scheme::read-#t) |
---|
175 | (:dispatch-macro-char #\\# #\\f #'scheme::read-#f) |
---|
176 | ... |
---|
177 | (:case :preserve)) |
---|
178 | |
---|
179 | (in-readtable elisp:syntax) |
---|
180 | |
---|
181 | ... |
---|
182 | |
---|
183 | (in-readtable scheme:syntax) |
---|
184 | |
---|
185 | ... |
---|
186 | ```") |
---|
187 | |
---|
188 | (defsection @named-readtables-reference (:title "Reference") |
---|
189 | (defreadtable macro) |
---|
190 | (in-readtable macro) |
---|
191 | (make-readtable function) |
---|
192 | (merge-readtables-into function) |
---|
193 | (find-readtable function) |
---|
194 | (ensure-readtable function) |
---|
195 | (rename-readtable function) |
---|
196 | (readtable-name function) |
---|
197 | (register-readtable function) |
---|
198 | (unregister-readtable function) |
---|
199 | (copy-named-readtable function) |
---|
200 | (list-all-named-readtables function) |
---|
201 | (named-readtable-designator type) |
---|
202 | (reader-macro-conflict condition) |
---|
203 | (readtable-does-already-exist condition) |
---|
204 | (readtable-does-not-exist condition)) |
---|
205 | |
---|
206 | |
---|
207 | ;;;; Generating own docs |
---|
208 | |
---|
209 | (defun update-readmes () |
---|
210 | (with-open-file (stream (asdf:system-relative-pathname :named-readtables |
---|
211 | "README.md") |
---|
212 | :direction :output |
---|
213 | :if-does-not-exist :create |
---|
214 | :if-exists :supersede) |
---|
215 | (document @named-readtables-manual :stream stream) |
---|
216 | (print-markdown-footer stream)) |
---|
217 | (with-open-file (stream (asdf:system-relative-pathname :named-readtables |
---|
218 | "README") |
---|
219 | :direction :output |
---|
220 | :if-does-not-exist :create |
---|
221 | :if-exists :supersede) |
---|
222 | (describe @named-readtables-manual stream) |
---|
223 | (print-markdown-footer stream))) |
---|
224 | |
---|
225 | (defun print-markdown-footer (stream) |
---|
226 | (format stream "~%* * *~%") |
---|
227 | (format stream "###### \\[generated by ~ |
---|
228 | [MGL-PAX](https://github.com/melisgl/mgl-pax)\\]~%")) |
---|
229 | |
---|
230 | #| |
---|
231 | |
---|
232 | (update-readmes) |
---|
233 | |
---|
234 | |# |
---|