master: sb-manual: add support for [label](uri) and [label][id]
melisgl via Sbcl-commits <[email protected]> Mon, 29 Jun 2026 12:20:04 +0000
| Newsgroups | gmane.lisp.steel-bank.cvs |
|---|---|
| Message-ID | <[email protected]> |
The branch "master" has been updated in SBCL:
via 61e352d1058e9d170e70fe7779c5248572c9b74a (commit)
from 79e63158c90e9af76c356381e7db0297ff88f3a0 (commit)
- Log -----------------------------------------------------------------
commit 61e352d1058e9d170e70fe7779c5248572c9b74a
Author: Gabor Melis <[email protected]>
Date: Mon Jun 8 22:31:45 2026 +0200
sb-manual: add support for [label](uri) and [label][id]
---
contrib/sb-manual/README.md | 38 ++++++++++++++++++++
contrib/sb-manual/TODO.md | 4 ---
contrib/sb-manual/doc/beyond-ansi.lisp | 3 +-
contrib/sb-manual/doc/intro.lisp | 5 +--
contrib/sb-manual/manual.lisp | 2 +-
contrib/sb-manual/markdown.lisp | 65 +++++++++++++++++++++++++++++++---
contrib/sb-manual/sb-manual.texinfo | 2 +-
doc/manual/beyond-ansi.texinfo | 3 +-
doc/manual/intro.texinfo | 5 +--
9 files changed, 110 insertions(+), 17 deletions(-)
diff --git a/contrib/sb-manual/README.md b/contrib/sb-manual/README.md
index 2202db34f..44f478b7e 100644
--- a/contrib/sb-manual/README.md
+++ b/contrib/sb-manual/README.md
@@ -124,6 +124,44 @@ Note how the code block is indented 8 spaces from the `-` character.
The required indentation remains the same if the child paragraph above
is not present.
+## Links
+
+### Plain Links
+
+For short links:
+
+ <http://x.y>
+
+### Explicit Links
+
+For overly long links:
+
+ [label](http://x.y/a?b=c)
+
+When generating Texinfo, this is translated to `@url`, which is
+rendered like a HTML link in HTML and PDF, but with `label (see
+<uri>)` in Info.
+
+PAX will generate a normal link except in plain text, where it simply
+drops the URI.
+
+### Reflinks
+
+In PAX-generated output only, `FUNCTION` is autolinked to its
+definitions. If there is more than one, you can dismambiguate:
+
+ [FUNCTION][type]
+
+PAX will produce a single link in this case. If `(FUNCTION CLASS)` is
+documented in some section, then the link will point to that
+documentation. Else, the link will go to the CLHS. The latter can be
+forced:
+
+ [FUNCTION][(clhs type)]
+
+Since we don't link to definitions in Texinfo (except to sections),
+the above examples are translated to `FUNCTION` there.
+
## Notes
- In many cases, just write a sentence:
diff --git a/contrib/sb-manual/TODO.md b/contrib/sb-manual/TODO.md
index 0759ce6d1..e15a93b4b 100644
--- a/contrib/sb-manual/TODO.md
+++ b/contrib/sb-manual/TODO.md
@@ -24,7 +24,3 @@ In the generated Texinfo, this can be a tad confusing. In output
formats with links (e.g. HTML from PAX), this is clearly preferable.
Nicknames, maybe?
-
-# Implement PAX reflinks, e.g. `[function][type]`
-
-See `PAX::@REFLINKS`.
diff --git a/contrib/sb-manual/doc/beyond-ansi.lisp b/contrib/sb-manual/doc/beyond-ansi.lisp
index 6eee21284..6ddb59adf 100644
--- a/contrib/sb-manual/doc/beyond-ansi.lisp
+++ b/contrib/sb-manual/doc/beyond-ansi.lisp
@@ -515,7 +515,8 @@
it supports extensible sequences directly."
(sb-sequence:emptyp generic-function)
(sb-sequence:dosequence macro)
- "The remaining list parallels the _Sequence Dictionary_, `17.3` CLHS."
+ "The remaining list parallels the _Sequence Dictionary_, see
+ [17.3][clhs] in the ANSI spec."
(sb-sequence:copy-seq generic-function)
(sb-sequence:fill generic-function)
(sb-sequence:subseq generic-function)
diff --git a/contrib/sb-manual/doc/intro.lisp b/contrib/sb-manual/doc/intro.lisp
index 46dac049f..cbebc2c00 100644
--- a/contrib/sb-manual/doc/intro.lisp
+++ b/contrib/sb-manual/doc/intro.lisp
@@ -24,8 +24,9 @@
specified in the _Description_.
- The STRING type is considered to be the union of all types
- `(ARRAY C (SIZE))` for all non-`NIL` subtypes `C` of CHARACTER,
- excluding arrays specialized to the empty type.
+ `(ARRAY C (SIZE))` for all non-`NIL` subtypes `C` of
+ [CHARACTER][type], excluding arrays specialized to the empty
+ type.
- The `:ORDER` long form option in DEFINE-METHOD-COMBINATION method
group specifiers accepts the value NIL as well as
diff --git a/contrib/sb-manual/manual.lisp b/contrib/sb-manual/manual.lisp
index 61e1f549d..38753eb3b 100644
--- a/contrib/sb-manual/manual.lisp
+++ b/contrib/sb-manual/manual.lisp
@@ -38,7 +38,7 @@
(defsection @browsing-live-with-pax (:title "Browsing Live with \\PAX")
"With \\PAX, you can browse the manual live. The documentation of this
feature is available at
- <https://melisgl.github.io/mgl-pax-world/pax-manual.html#MGL-PAX:@BROWSING-LIVE-DOCUMENTATION%20MGL-PAX:SECTION>.
+ [online](https://melisgl.github.io/mgl-pax-world/pax-manual.html#MGL-PAX:@BROWSING-LIVE-DOCUMENTATION%20MGL-PAX:SECTION).
If you are browsing this manual live right now, here is the
equivalent live link: `PAX::@BROWSING-LIVE-DOCUMENTATION`.
diff --git a/contrib/sb-manual/markdown.lisp b/contrib/sb-manual/markdown.lisp
index 1959d1082..b55b6d9b3 100644
--- a/contrib/sb-manual/markdown.lisp
+++ b/contrib/sb-manual/markdown.lisp
@@ -26,8 +26,8 @@
;;; opportunities for codification and linking.
;;;
;;;
-;;; Markdown Support
-;;; ----------------
+;;; Markdown Formatting
+;;; -------------------
;;;
;;; The supported Markdown constructs are:
;;;
@@ -37,8 +37,6 @@
;;;
;;; - Inline code: `monospace` -> @code{monospace}
;;;
-;;; - <http...> -> @url{http...}
-;;;
;;; - Itemized lists (like this one). List items can span multiple
;;; lines.
;;;
@@ -122,6 +120,17 @@
;;;
;;; - Section references: @SECTION-NAME -> @ref{section name}
;;;
+;;; - <http...> -> @url{http...}
+;;;
+;;; - [label](uri) -> @uref{uri, label}
+;;;
+;;; - [label][id] -> label
+;;;
+;;; This just strips Markdown reference links. These are used by
+;;; PAX to disambiguate, e.g. "[FUNCTION][type]" links to the
+;;; FUNCTION class only while FUNCTION links to both the class and
+;;; macro.
+;;;
;;; FIXME:
;;;
;;; - Maybe implement glossary-terms (for books, "safe type", etc).
@@ -587,6 +596,47 @@
(out "}")
(setf i close-pos))
(buffer-codifiable-char char))))
+ ;; Markdown explicit links: [label](url) -> @uref{url, label}
+ ;;
+ ;; Markdown reflinks: [label][id] -> label
+ ((char= char #\[)
+ (let* ((close-bracket (position #\] string :start (1+ i)))
+ (next-char (when (and close-bracket
+ (< (1+ close-bracket) len))
+ (char string (1+ close-bracket))))
+ (open-paren (when (eql next-char #\()
+ (1+ close-bracket)))
+ (close-paren (when open-paren
+ (position #\) string
+ :start (1+ open-paren))))
+ (open-bracket2 (when (eql next-char #\[)
+ (1+ close-bracket)))
+ (close-bracket2
+ (when open-bracket2
+ (position #\] string :start (1+ open-bracket2)))))
+ (cond
+ ;; Explicit link: [label](url)
+ (close-paren
+ (flush-codifiable-buffer)
+ (out "@uref{")
+ (out-escaped (subseq string (1+ open-paren)
+ close-paren))
+ (out ", ")
+ (out (process-inline-markdown
+ (subseq string (1+ i) close-bracket)))
+ (out "}")
+ (setf i close-paren))
+ ;; Reflink: [label][id]
+ (close-bracket2
+ (flush-codifiable-buffer)
+ ;; Process the name, drop the id
+ (out (process-inline-markdown
+ (subseq string (1+ i) close-bracket)))
+ (setf i close-bracket2))
+ ;; Not a recognized link structure, treat as a
+ ;; normal character
+ (t
+ (buffer-codifiable-char char)))))
(t
(buffer-codifiable-char char)))
(incf i))
@@ -600,7 +650,12 @@
(assert (equal (process-inline-markdown "_PRINT_") "@emph{@code{print}}"))
(assert (equal (process-inline-markdown "<httpabc>") "@url{httpabc}"))
(assert (equal (process-inline-markdown "`N`") "@code{n}"))
- (assert (equal (process-inline-markdown "`N`th") "@code{n}th")))
+ (assert (equal (process-inline-markdown "`N`th") "@code{n}th"))
+ (assert (equal (process-inline-markdown "[x](uri)") "@uref{uri, x}"))
+ (assert (equal (process-inline-markdown "[`x`](uri)") "@uref{uri, @code{x}}"))
+ (assert (equal (process-inline-markdown "[function][type]") "function"))
+ (assert (equal (process-inline-markdown "[`function`][type]")
+ "@code{function}")))
;;;; Processing Markdown block elements
diff --git a/contrib/sb-manual/sb-manual.texinfo b/contrib/sb-manual/sb-manual.texinfo
index dc0b27f8d..4f2b9cb6f 100644
--- a/contrib/sb-manual/sb-manual.texinfo
+++ b/contrib/sb-manual/sb-manual.texinfo
@@ -67,7 +67,7 @@ asdf:system.
With PAX, you can browse the manual live. The documentation of this
feature is available at
-@url{https://melisgl.github.io/mgl-pax-world/pax-manual.html#MGL-PAX:@@BROWSING-LIVE-DOCUMENTATION%20MGL-PAX:SECTION}.
+@uref{https://melisgl.github.io/mgl-pax-world/pax-manual.html#MGL-PAX:@@BROWSING-LIVE-DOCUMENTATION%20MGL-PAX:SECTION, online}.
If you are browsing this manual live right now, here is the
equivalent live link: @code{pax::@@browsing-live-documentation}.
diff --git a/doc/manual/beyond-ansi.texinfo b/doc/manual/beyond-ansi.texinfo
index 1ea9acbed..9204ae772 100644
--- a/doc/manual/beyond-ansi.texinfo
+++ b/doc/manual/beyond-ansi.texinfo
@@ -1008,7 +1008,8 @@ otherwise. Signals an error if @code{sequence} is not a sequence.
Executes @code{body} with @code{element} subsequently bound to each element of
@code{sequence}, then returns @code{return}.
@end deffn
-The remaining list parallels the @emph{Sequence Dictionary}, @code{17.3} @code{clhs}.
+The remaining list parallels the @emph{Sequence Dictionary}, see
+17.3 in the ANSI spec.
@anchor{Generic function sb-sequence copy-seq}
@ffindex @sortas{copy-seq sb-sequence} copy-seq [sb-sequence]
diff --git a/doc/manual/intro.texinfo b/doc/manual/intro.texinfo
index 576318783..0cb76cf86 100644
--- a/doc/manual/intro.texinfo
+++ b/doc/manual/intro.texinfo
@@ -32,8 +32,9 @@ exceptions involve internal inconsistencies in the standard.) See
specified in the @emph{Description}.
@item The @code{string} type is considered to be the union of all types
- @code{(array c (size))} for all non-@code{nil} subtypes @code{c} of @code{character},
- excluding arrays specialized to the empty type.
+ @code{(array c (size))} for all non-@code{nil} subtypes @code{c} of
+ @code{character}, excluding arrays specialized to the empty
+ type.
@item The @code{:order} long form option in @code{define-method-combination} method
group specifiers accepts the value @code{nil} as well as
-----------------------------------------------------------------------
hooks/post-receive
--
SBCL