001  (ns beowulf.manual
002    "Experimental code for accessing the manual online."
003    (:require [clojure.string :refer [ends-with? join trim]]))
004  
005  (def ^:dynamic *manual-url*
006    "https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf")
007  
008  (def ^:constant index
009    "This is data extracted from the index pages of `Lisp 1.5 Programmer's Manual`.
010     It's here in the hope that we can automatically link to an online PDF link
011     to the manual when the user invokes a function probably called `DOC` or `HELP`."
012    {:RECIP
013     {:fn-name "RECIP",
014      :call-type "SUBR",
015      :implementation "",
016      :page-nos ["26" "64"]},
017     :QUOTE
018     {:fn-name "QUOTE",
019      :call-type "FSUBR",
020      :implementation "",
021      :page-nos ["10" "22" "71"]},
022     :RECLAIM
023     {:fn-name "RECLAIM",
024      :call-type "SUBR",
025      :implementation "PSEUDO-FUNCTION ",
026      :page-nos ["67"]},
027     :NUMOB
028     {:fn-name "NUMOB",
029      :call-type "SUBR",
030      :implementation "PSEUDO-FUNCTION ",
031      :page-nos ["86"]},
032     :EVLIS
033     {:fn-name "EVLIS",
034      :call-type "SUBR",
035      :implementation "",
036      :page-nos ["71"]},
037     :DASH
038     {:fn-name "DASH",
039      :call-type "SUBR",
040      :implementation "PREDICATE APVAL",
041      :page-nos ["85" "87 "]},
042     :EQUAL
043     {:fn-name "EQUAL",
044      :call-type "SUBR",
045      :implementation "PREDICATE",
046      :page-nos ["11" "26" "57"]},
047     :PRIN1
048     {:fn-name "PRIN1",
049      :call-type "SUBR",
050      :implementation "PSEUDO-FUNCTION ",
051      :page-nos ["65" "84"]},
052     :REMFLAG
053     {:fn-name "REMFLAG",
054      :call-type "SUBR",
055      :implementation "PSEUDO-FUNCTION ",
056      :page-nos ["41" "60"]},
057     :DEFINE
058     {:fn-name "DEFINE",
059      :call-type "EXPR",
060      :implementation "PSEUDO-FUNCTION",
061      :page-nos ["15" "18" "58"]},
062     :PUNCHLAP
063     {:fn-name "PUNCHLAP",
064      :call-type "EXPR",
065      :implementation "PSEUDO-FUNCTION LIBRARY",
066      :page-nos ["68" "76"]},
067     :STARTREAD
068     {:fn-name "STARTREAD",
069      :call-type "SUBR",
070      :implementation "PSEUDO-FUNCTION",
071      :page-nos ["87"]},
072     :PERIOD
073     {:fn-name "PERIOD",
074      :call-type "APVAL",
075      :implementation "",
076      :page-nos ["69" "85"]},
077     :CP1
078     {:fn-name "CP1",
079      :call-type "SUBR",
080      :implementation "",
081      :page-nos ["66"]},
082     :NCONC
083     {:fn-name "NCONC",
084      :call-type "SUBR",
085      :implementation "PSEUDO-FUNCTION ",
086      :page-nos ["62"]},
087     :EQ
088     {:fn-name "EQ",
089      :call-type "SUBR",
090      :implementation "PREDICATE",
091      :page-nos ["3" "23" "57"]},
092     :RPLACD
093     {:fn-name "RPLACD",
094      :call-type "SUBR",
095      :implementation "PSEUDO-FUNCTION",
096      :page-nos ["41" "58"]},
097     :PROG2
098     {:fn-name "PROG2",
099      :call-type "SUBR",
100      :implementation "",
101      :page-nos ["42" "66"]},
102     :UNCOUNT
103     {:fn-name "UNCOUNT",
104      :call-type "SUBR",
105      :implementation "PSEUDO-FUNCTION",
106      :page-nos ["34" "66"]},
107     :ERROR1
108     {:fn-name "ERROR1",
109      :call-type "SUBR",
110      :implementation "PSEUDO-FUNCTION",
111      :page-nos ["88"]},
112     :EXPT
113     {:fn-name "EXPT",
114      :call-type "SUBR",
115      :implementation "",
116      :page-nos ["26" "64"]},
117     :NOT
118     {:fn-name "NOT",
119      :call-type "SUBR",
120      :implementation "PREDICATE",
121      :page-nos ["21" "23" "58"]},
122     :SLASH
123     {:fn-name "SLASH",
124      :call-type "APVAL",
125      :implementation "",
126      :page-nos ["69" "85"]},
127     :RPLACA
128     {:fn-name "RPLACA",
129      :call-type "SUBR",
130      :implementation "PSEUDO-FUNCTION",
131      :page-nos ["41" "58"]},
132     :QUOTIENT
133     {:fn-name "QUOTIENT",
134      :call-type "SUBR",
135      :implementation "",
136      :page-nos ["26" "64"]},
137     :UNPACK
138     {:fn-name "UNPACK",
139      :call-type "SUBR",
140      :implementation "PSEUDO-FUNCTION",
141      :page-nos ["87"]},
142     :CONC
143     {:fn-name "CONC",
144      :call-type "FEXPR",
145      :implementation "",
146      :page-nos ["61"]},
147     :CAR
148     {:fn-name "CAR",
149      :call-type "SUBR",
150      :implementation "",
151      :page-nos ["2" "56"]},
152     :GENSYM
153     {:fn-name "GENSYM",
154      :call-type "SUBR",
155      :implementation "",
156      :page-nos ["66"]},
157     :PROP
158     {:fn-name "PROP",
159      :call-type "SUBR",
160      :implementation "FUNCTIONAL ",
161      :page-nos [" 59"]},
162     :MEMBER
163     {:fn-name "MEMBER",
164      :call-type "SUBR",
165      :implementation "PREDICATE ",
166      :page-nos ["11" "62"]},
167     :UNTRACESET
168     {:fn-name "UNTRACESET",
169      :call-type "EXPR",
170      :implementation "PSEUDO-FUNCTION",
171      :page-nos ["68"]},
172     :UNTRACE
173     {:fn-name "UNTRACE",
174      :call-type "EXPR",
175      :implementation "PSEUDO-FUNCTION",
176      :page-nos ["32" "66"]},
177     :MINUSP
178     {:fn-name "MINUSP",
179      :call-type "SUBR",
180      :implementation "PREDICATE ",
181      :page-nos ["26" "64"]},
182     :F
183     {:fn-name "F",
184      :call-type "APVAL",
185      :implementation "",
186      :page-nos ["22" "69"]},
187     :SPECIAL
188     {:fn-name "SPECIAL",
189      :call-type "SUBR",
190      :implementation "PSEUDO-FUNCTION",
191      :page-nos ["64" "78"]},
192     :LPAR
193     {:fn-name "LPAR",
194      :call-type "APVAL",
195      :implementation "",
196      :page-nos ["69" "85"]},
197     :GO
198     {:fn-name "GO",
199      :call-type "FSUBR",
200      :implementation "PSEUDO-FUNCTION",
201      :page-nos ["30" "72"]},
202     :MKNAM
203     {:fn-name "MKNAM",
204      :call-type "SUBR",
205      :implementation "",
206      :page-nos ["86"]},
207     :COMMON
208     {:fn-name "COMMON",
209      :call-type "SUBR",
210      :implementation "PSEUDO-FUNCTION",
211      :page-nos ["64" "78"]},
212     :NUMBERP
213     {:fn-name "NUMBERP",
214      :call-type "SUBR",
215      :implementation "PREDICATE ",
216      :page-nos ["26" "64"]},
217     :CONS
218     {:fn-name "CONS",
219      :call-type "SUBR",
220      :implementation "",
221      :page-nos ["2" "56"]},
222     :PLUS
223     {:fn-name "PLUS",
224      :call-type "FSUBR",
225      :implementation "",
226      :page-nos ["25" "63"]},
227     :SET
228     {:fn-name "SET",
229      :call-type "SUBR",
230      :implementation "PSEUDO-FUNCTION",
231      :page-nos ["30" "71"]},
232     :DOLLAR
233     {:fn-name "DOLLAR",
234      :call-type "APVAL",
235      :implementation "",
236      :page-nos ["69" "85"]},
237     :SASSOC
238     {:fn-name "SASSOC",
239      :call-type "SUBR",
240      :implementation "FUNCTIONAL",
241      :page-nos ["60"]},
242     :SELECT
243     {:fn-name "SELECT",
244      :call-type "FEXPR",
245      :implementation "",
246      :page-nos ["66"]},
247     :OPDEFINE
248     {:fn-name "OPDEFINE",
249      :call-type "EXPR",
250      :implementation "PSEUDO-FUNCTION ",
251      :page-nos ["65" "75"]},
252     :PAUSE
253     {:fn-name "PAUSE",
254      :call-type "SUBR",
255      :implementation "PSEUDO-FUNCTION",
256      :page-nos ["67"]},
257     :AND
258     {:fn-name "AND",
259      :call-type "FSUBR",
260      :implementation "PREDICATE",
261      :page-nos ["21" "58"]},
262     :COMMA
263     {:fn-name "COMMA",
264      :call-type "APVAL",
265      :implementation "",
266      :page-nos ["69" "85"]},
267     :EFFACE
268     {:fn-name "EFFACE",
269      :call-type "SUBR",
270      :implementation "PSEUDO-FUNCTION",
271      :page-nos ["63"]},
272     :CSETQ
273     {:fn-name "CSETQ",
274      :call-type "FEXPR",
275      :implementation "PSEUDO-FUNCTION",
276      :page-nos ["59"]},
277     :OPCHAR
278     {:fn-name "OPCHAR",
279      :call-type "SUBR",
280      :implementation "PREDICATE ",
281      :page-nos [" 87"]},
282     :PRINTPROP
283     {:fn-name "PRINTPROP",
284      :call-type "EXPR",
285      :implementation "PSEUDO-FUNCTION LIBRARY ",
286      :page-nos ["68"]},
287     :PLB
288     {:fn-name "PLB",
289      :call-type "SUBR",
290      :implementation "PSEUDO- FUNCTION",
291      :page-nos ["67"]},
292     :DIGIT
293     {:fn-name "DIGIT",
294      :call-type "SUBR",
295      :implementation "PREDICATE ",
296      :page-nos ["87"]},
297     :PUNCHDEF
298     {:fn-name "PUNCHDEF",
299      :call-type "EXPR",
300      :implementation "PSEUDO-FUNCTION LIBRARY",
301      :page-nos ["68"]},
302     :ARRAY
303     {:fn-name "ARRAY",
304      :call-type "SUBR",
305      :implementation "PSEUDO-FUNCTION",
306      :page-nos ["27" "64"]},
307     :MAX
308     {:fn-name "MAX",
309      :call-type "FSUBR",
310      :implementation "",
311      :page-nos ["26" "64"]},
312     :INTERN
313     {:fn-name "INTERN",
314      :call-type "SUBR",
315      :implementation "PSEUDO-FUNCTION",
316      :page-nos ["67" "87"]},
317     :NIL
318     {:fn-name "NIL",
319      :call-type "APVAL",
320      :implementation "",
321      :page-nos ["22" "69"]},
322     :TIMES
323     {:fn-name "TIMES",
324      :call-type "FSUBR",
325      :implementation "",
326      :page-nos ["26" "64"]},
327     :ERROR
328     {:fn-name "ERROR",
329      :call-type "SUBR",
330      :implementation "PSEUDO-FUNCTION",
331      :page-nos ["32" "66"]},
332     :PUNCH
333     {:fn-name "PUNCH",
334      :call-type "SUBR",
335      :implementation "PSEUDO-FUNCTION",
336      :page-nos ["65" "84"]},
337     :REMPROP
338     {:fn-name "REMPROP",
339      :call-type "SUBR",
340      :implementation "PSEUDO-FUNCTION",
341      :page-nos ["41" "59"]},
342     :DIVIDE
343     {:fn-name "DIVIDE",
344      :call-type "SUBR",
345      :implementation "",
346      :page-nos ["26" "64"]},
347     :OR
348     {:fn-name "OR",
349      :call-type "FSUBR",
350      :implementation "PREDICATE ",
351      :page-nos ["21" "58"]},
352     :SUBLIS
353     {:fn-name "SUBLIS",
354      :call-type "SUBR",
355      :implementation "",
356      :page-nos ["12" "61"]},
357     :LAP
358     {:fn-name "LAP",
359      :call-type "SUBR",
360      :implementation "PSEUDO-FUNCTION ",
361      :page-nos ["65" "73"]},
362     :PROG
363     {:fn-name "PROG",
364      :call-type "FSUBR",
365      :implementation "",
366      :page-nos ["29" "71"]},
367     :T
368     {:fn-name "T",
369      :call-type "APVAL",
370      :implementation "",
371      :page-nos ["22" "69"]},
372     :GREATERP
373     {:fn-name "GREATERP",
374      :call-type "SUBR",
375      :implementation "PREDICATE",
376      :page-nos ["26" "64"]},
377     :CSET
378     {:fn-name "CSET",
379      :call-type "EXPR",
380      :implementation "PSEUDO-FUNCTION",
381      :page-nos ["17" "59"]},
382     :FUNCTION
383     {:fn-name "FUNCTION",
384      :call-type "FSUBR",
385      :implementation "",
386      :page-nos ["21" "71"]},
387     :LENGTH
388     {:fn-name "LENGTH",
389      :call-type "SUBR",
390      :implementation "",
391      :page-nos ["62"]},
392     :MINUS
393     {:fn-name "MINUS",
394      :call-type "SUBR",
395      :implementation "",
396      :page-nos ["26" "63"]},
397     :COND
398     {:fn-name "COND",
399      :call-type "FSUBR",
400      :implementation "",
401      :page-nos ["18"]},
402     :APPEND
403     {:fn-name "APPEND",
404      :call-type "SUBR",
405      :implementation "",
406      :page-nos ["11" "61"]},
407     :CDR
408     {:fn-name "CDR",
409      :call-type "SUBR",
410      :implementation "",
411      :page-nos ["3" "56"]},
412     :OBLIST
413     {:fn-name "OBLIST",
414      :call-type "APVAL",
415      :implementation "",
416      :page-nos ["69"]},
417     :READ
418     {:fn-name "READ",
419      :call-type "SUBR",
420      :implementation "PSEUDO-FUNCTION ",
421      :page-nos ["5" "84"]},
422     :ERRORSET
423     {:fn-name "ERRORSET",
424      :call-type "SUBR",
425      :implementation "PSEUDO-FUNCTION",
426      :page-nos ["35" "66"]},
427     :UNCOMMON
428     {:fn-name "UNCOMMON",
429      :call-type "SUBR",
430      :implementation "PSEUDO-FUNCTION ",
431      :page-nos ["64" "78"]},
432     :EVAL
433     {:fn-name "EVAL",
434      :call-type "SUBR",
435      :implementation "",
436      :page-nos ["71"]},
437     :MIN
438     {:fn-name "MIN",
439      :call-type "FSUBR",
440      :implementation "",
441      :page-nos ["26" "64"]},
442     :PAIR
443     {:fn-name "PAIR",
444      :call-type "SUBR",
445      :implementation "",
446      :page-nos ["60"]},
447     :BLANK
448     {:fn-name "BLANK",
449      :call-type "APVAL",
450      :implementation "",
451      :page-nos ["69" "85"]},
452     :SETQ
453     {:fn-name "SETQ",
454      :call-type "FSUBR",
455      :implementation "PSEUDO-FUNCTION",
456      :page-nos ["30" "71"]},
457     :GET
458     {:fn-name "GET",
459      :call-type "SUBR",
460      :implementation "",
461      :page-nos ["41" "59"]},
462     :PRINT
463     {:fn-name "PRINT",
464      :call-type "SUBR",
465      :implementation "PSEUDO-FUNCTION ",
466      :page-nos ["65" "84"]},
467     :ENDREAD
468     {:fn-name "ENDREAD",
469      :call-type "SUBR",
470      :implementation "PSEUDO-FUNCTION",
471      :page-nos ["8 8"]},
472     :RETURN
473     {:fn-name "RETURN",
474      :call-type "SUBR",
475      :implementation "PSEUDO-FUNCTION",
476      :page-nos ["30" "72"]},
477     :LITER
478     {:fn-name "LITER",
479      :call-type "SUBR",
480      :implementation "PREDICATE ",
481      :page-nos ["87"]},
482     :EOF
483     {:fn-name "EOF",
484      :call-type "APVAL",
485      :implementation "",
486      :page-nos ["69" "88"]},
487     :TRACE
488     {:fn-name "TRACE",
489      :call-type "EXPR",
490      :implementation "PSEUDO-FUNCTION",
491      :page-nos ["32" "66" "79"]},
492     :TRACESET
493     {:fn-name "TRACESET",
494      :call-type "EXPR",
495      :implementation "PSEUDO-FUNCTION LIBRARY",
496      :page-nos ["68"]},
497     :PACK
498     {:fn-name "PACK",
499      :call-type "SUBR",
500      :implementation "PSEUDO-FUNCTION ",
501      :page-nos ["86"]},
502     :NULL
503     {:fn-name "NULL",
504      :call-type "SUBR",
505      :implementation "PREDICATE ",
506      :page-nos ["11" "57"]},
507     :CLEARBUFF
508     {:fn-name "CLEARBUFF",
509      :call-type "SUBR",
510      :implementation "PSEUDO-FUNCTION",
511      :page-nos ["86"]},
512     :LESSP
513     {:fn-name "LESSP",
514      :call-type "SUBR",
515      :implementation "PREDICATE ",
516      :page-nos ["26" "64"]},
517     :TERPRI
518     {:fn-name "TERPRI",
519      :call-type "SUBR",
520      :implementation "PSEUDO-FUNCTION",
521      :page-nos ["65" "84"]},
522     :ONEP
523     {:fn-name "ONEP",
524      :call-type "SUBR",
525      :implementation "PREDICATE ",
526      :page-nos [" 26" "64"]},
527     :EXCISE
528     {:fn-name "EXCISE",
529      :call-type "SUBR",
530      :implementation "PSEUDO-FUNCTION",
531      :page-nos ["67" "77"]},
532     :REMOB
533     {:fn-name "REMOB",
534      :call-type "SUBR",
535      :implementation "PSEUDO-FUNCTION ",
536      :page-nos ["67"]},
537     :MAP
538     {:fn-name "MAP",
539      :call-type "SUBR",
540      :implementation "FUNCTIONAL ",
541      :page-nos ["63"]},
542     :COMPILE
543     {:fn-name "COMPILE",
544      :call-type "SUBR",
545      :implementation "PSEUDO-FUNCTION",
546      :page-nos ["64" "76"]},
547     :ADD1
548     {:fn-name "ADD1",
549      :call-type "SUBR",
550      :implementation "",
551      :page-nos ["26" "64"]},
552     :ADVANCE
553     {:fn-name "ADVANCE",
554      :call-type "SUBR",
555      :implementation "PSEUDO-FUNCTION",
556      :page-nos ["88"]},
557     :SEARCH
558     {:fn-name "SEARCH",
559      :call-type "SUBR",
560      :implementation "FUNCTIONAL",
561      :page-nos ["63"]},
562     :APPLY
563     {:fn-name "APPLY",
564      :call-type "SUBR",
565      :implementation "",
566      :page-nos ["70"]},
567     :READLAP
568     {:fn-name "READLAP",
569      :call-type "SUBR",
570      :implementation "PSEUDO-FUNCTION ",
571      :page-nos ["65" "76"]},
572     :UNSPECIAL
573     {:fn-name "UNSPECIAL",
574      :call-type "SUBR",
575      :implementation "",
576      :page-nos ["64" "78"]},
577     :SUBST
578     {:fn-name "SUBST",
579      :call-type "SUBR",
580      :implementation "",
581      :page-nos ["11" "61"]},
582     :COPY
583     {:fn-name "COPY",
584      :call-type "SUBR",
585      :implementation "",
586      :page-nos ["62"]},
587     :LOGOR
588     {:fn-name "LOGOR",
589      :call-type "FSUBR",
590      :implementation "",
591      :page-nos ["26" "64"]},
592     :LABEL
593     {:fn-name "LABEL",
594      :call-type "FSUBR",
595      :implementation "",
596      :page-nos ["8" "18" "70"]},
597     :FIXP
598     {:fn-name "FIXP",
599      :call-type "SUBR",
600      :implementation "PREDICATE",
601      :page-nos ["26" "64"]},
602     :SUB1
603     {:fn-name "SUB1",
604      :call-type "SUBR",
605      :implementation "",
606      :page-nos ["26" "64"]},
607     :ATTRIB
608     {:fn-name "ATTRIB",
609      :call-type "SUBR",
610      :implementation "PSEUDO-FUNCTION",
611      :page-nos ["59"]},
612     :DIFFERENCE
613     {:fn-name "DIFFERENCE",
614      :call-type "SUBR",
615      :implementation "",
616      :page-nos ["26" "64"]},
617     :REMAINDER
618     {:fn-name "REMAINDER",
619      :call-type "SUBR",
620      :implementation "",
621      :page-nos ["26" "64"]},
622     :REVERSE
623     {:fn-name "REVERSE",
624      :call-type "SUBR",
625      :implementation "",
626      :page-nos ["6 2"]},
627     :EOR
628     {:fn-name "EOR",
629      :call-type "APVAL",
630      :implementation "",
631      :page-nos ["69" "88"]},
632     :PLUSS
633     {:fn-name "PLUSS",
634      :call-type "APVAL",
635      :implementation "",
636      :page-nos ["69" "85"]},
637     :TEMPUS-FUGIT
638     {:fn-name "TEMPUS-FUGIT",
639      :call-type "SUBR",
640      :implementation "PSEUDO-FUNCTION",
641      :page-nos ["67"]},
642     :LOAD
643     {:fn-name "LOAD",
644      :call-type "SUBR",
645      :implementation "PSEUDO-FUNCTION",
646      :page-nos ["67"]},
647     :CHARCOUNT
648     {:fn-name "CHARCOUNT",
649      :call-type "APVAL",
650      :implementation "",
651      :page-nos ["69" "87"]},
652     :RPAR
653     {:fn-name "RPAR",
654      :call-type "APVAL",
655      :implementation "",
656      :page-nos ["69" "85"]},
657     :COUNT
658     {:fn-name "COUNT",
659      :call-type "SUBR",
660      :implementation "PSEUDO-FUNCTION",
661      :page-nos ["34" "66"]},
662     :SPEAK
663     {:fn-name "SPEAK",
664      :call-type "SUBR",
665      :implementation "PSEUDO-FUNCTION",
666      :page-nos ["34" "66 "]},
667     :LOGXOR
668     {:fn-name "LOGXOR",
669      :call-type "FSUBR",
670      :implementation "",
671      :page-nos ["27" "64"]},
672     :FLOATP
673     {:fn-name "FLOATP",
674      :call-type "SUBR",
675      :implementation "PREDICATE",
676      :page-nos ["26" "64"]},
677     :ATOM
678     {:fn-name "ATOM",
679      :call-type "SUBR",
680      :implementation "PREDICATE",
681      :page-nos ["3" "57"]},
682     :EQSIGN
683     {:fn-name "EQSIGN",
684      :call-type "APVAL",
685      :implementation "",
686      :page-nos ["69" "85"]},
687     :LIST
688     {:fn-name "LIST",
689      :call-type "FSUBR",
690      :implementation "",
691      :page-nos ["57"]},
692     :MAPLIST
693     {:fn-name "MAPLIST",
694      :call-type "SUBR",
695      :implementation "FUNCTIONAL ",
696      :page-nos ["20" "21" "63"]},
697     :LOGAND
698     {:fn-name "LOGAND",
699      :call-type "FSUBR",
700      :implementation "",
701      :page-nos ["27" "64"]},
702     :FLAG
703     {:fn-name "FLAG",
704      :call-type "EXPR",
705      :implementation "PSEUDO-FUNCTION",
706      :page-nos ["41" "60"]},
707     :MAPCON
708     {:fn-name "MAPCON",
709      :call-type "SUBR",
710      :implementation "FUNCTIONAL PSEUDO- FUNCTION",
711      :page-nos ["63"]},
712     :STAR
713     {:fn-name "STAR",
714      :call-type "APVAL",
715      :implementation "",
716      :page-nos ["69" "85"]},
717     :CURCHAR
718     {:fn-name "CURCHAR",
719      :call-type "APVAL",
720      :implementation "",
721      :page-nos ["69" "87"]},
722     :DUMP
723     {:fn-name "DUMP",
724      :call-type "SUBR",
725      :implementation "PSEUDO-FUNCTION",
726      :page-nos ["67"]},
727     :DEFLIST
728     {:fn-name "DEFLIST",
729      :call-type "EXPR",
730      :implementation "PSEUDO-FUNCTION",
731      :page-nos ["41" "58"]},
732     :LEFTSHIFT
733     {:fn-name "LEFTSHIFT",
734      :call-type "SUBR",
735      :implementation "",
736      :page-nos ["27" "64"]},
737     :ZEROP
738     {:fn-name "ZEROP",
739      :call-type "SUBR",
740      :implementation "PREDICATE",
741      :page-nos ["26" "64"]}})
742  
743  (defn page-url
744    "Format the URL for the page in the manual with this `page-no`."
745    [page-no]
746    (let [n (read-string page-no)
747          n' (when (and (number? n)
748                        (ends-with? *manual-url* ".pdf"))
749               ;; annoyingly, the manual has eight pages of front-matter
750               ;; before numbering starts.
751               (+ n 8))]
752      (format
753       (if (ends-with? *manual-url* ".pdf") "%s#page=%s" "%s#page%s")
754       *manual-url*
755       (or n' (trim (str page-no))))))
756  
757  (defn format-page-references
758    "Format page references from the manual index for the function whose name
759     is `fn-symbol`."
760    [fn-symbol]
761    (let [k (if (keyword? fn-symbol) fn-symbol (keyword fn-symbol))]
762      (join ", "
763            (doall
764             (map
765              (fn [n]
766                (let [p (trim n)]
767                  (format "<a href='%s'>%s</a>"
768                          (page-url p) p)))
769              (:page-nos (index k)))))))