Parendown
Parendown adds weak opening parentheses to Racket in the form of a language extension. A more extensive overview of Parendown’s uses can be found in the README at GitHub.
1 The Parendown Language Extension
#lang parendown | package: parendown-lib |
The parendown language is a language extension. To use it, specify another language after parendown on the #lang line. That language will have its readtable extended with a #/ syntax that behaves according to parendown-readtable-handler.
#lang parendown racket/base (displayln #/string-append "Hello, " "world!")
2 The parendown/slash Language Extension
#lang parendown/slash | package: parendown-lib |
The parendown/slash language is a language extension like parendown, but with a more streamlined syntax. To use it, specify another language after parendown/slash on the #lang line. That language will have its readtable extended with a / syntax that behaves according to parendown-readtable-handler.
This acts as a non-symbol-terminating readtable extension, so symbols like syntax/parse and any/c will be usable in the usual way. In order to make sure a / weak opening paren isn’t treated as part of the preceding symbol, it may be necessary to use whitespace in between.
#lang parendown/slash racket/base (displayln /string-append "Hello, " "world!")
Symbols beginning with /, such as the division operator /, may be more difficult to use with this extension in place. However, they can still be referred to using the alternative notations \/... and |/...|. In the case of division, that means writing \/ or |/|.
3 Parendown as a Library
(require parendown) | package: parendown-lib |
There is also a parendown module which lets Racket code use some features of Parendown even when they aren’t using the #lang directly.
syntax
(pd slash-symbol stx ...)
For instance, the form
(pd / begin (displayln / string-append "Hello, " "world!") (displayln / string-append "I can't use " "division!"))
expands to this:
(begin (displayln (string-append "Hello, " "world!")) (displayln (string-append "I can't use " "division!")))
syntax
(pd (stx ...))
This is usually the result of the other case of pd. For instance, the form
(pd / begin (displayln / string-append "Hello, " "world!") (pd / displayln / string-append "I can't use " "division!"))
expands to this:
(begin (displayln (string-append "Hello, " "world!")) (pd (displayln (string-append "I can't use " "division!"))))
This contains another occurrence of pd, and this time, the code
(pd (displayln (string-append "I can't use " "division!")))
expands to this:
(displayln (string-append "I can't use " "division!"))
This behavior makes it so occurrences of the pd form can be generously added wherever they’re suspected to be needed, without causing conflicts with each other.
procedure
(parendown-readtable-handler name in) → any/c
name : char? in : input-port?
(parendown-readtable-handler name in src line col pos) → any/c name : char? in : input-port? src : any/c line : (or/c #f exact-positive-integer?) col : (or/c #f exact-nonnegative-integer?) pos : (or/c #f exact-positive-integer?)
When the terminating character is ] or }, the resulting list’s paren-shape syntax property is set to #\[ or #\{, respectively.
This readtable handler is sensitive to the read-accept-dot and read-accept-infix-dot parameters at the time the handler is invoked. This functionality of Parendown should be considered unstable, since it isn’t quite the same as what (, [, and { do on contemporary versions of Racket. Those characters’ default handlers are sensitive to the values of those parameters at the time the read is originally started, not the time they are encountered during the read. For instance, in contemprary versions of Racket, if (read-accept-dot) is #t at the time read is first called and then a custom reader syntax causes it to be set to #f, a subsequent occurrence of ( in the same read will be processed as though (read-accept-dot) were still #t.
procedure
(parendown-color-lexer weak-open-paren original-get-info) → procedure? weak-open-paren : (and/c string? immutable?) original-get-info : (-> any/c any/c any)