Idiomdrottning’s homepage

The awesomeness of require

I wanted a filter in brev (I mean, a procedure) that if a gemtext snippet matched this format:

a line that ends with a quote:

> the second line is a blank line, or it's a quote line

=> an://url/with a mandatory preceding blank line

it should rewrite that to

=> an://url/with a line that ends with a quote:

> the second line is a blank line, or it's a quote line

and if it didn’t match that format, just pass it through unchanged.

Thanks to the fanciest define of all time and its require feature, that was pretty easy.

Require takes two arguments; the first is either a bool or a pred, the second is a value. If the bool is true, or the pred applied to the value is true, then pass through the value. Otherwise backtrack out of the procedure entirely! Through magic time travel♥︎ probably better known as call-with-current-continuation.

First do nothing by default, just pass through all input as it is:

(define (link-linify-source x) x)

Then handle the special case of a string that’s splittable into the pattern we’re looking for.

(define (link-linify-source (= (fn (string-split x "\n" #t))
                               ((? (strse? ":$") hd)
                                (? (disjoin (like? "") (strse? "^>")) lean)
                                . rest)))
  (conc
   (string-intersperse
    (cons*
     (conc
      (string-intersperse
       (take (string-split (require (strse? "^=> ") (last (butlast rest)))) 2))
      " " hd)
     lean
     (drop-right (require (< 2 (length rest)) rest) 3))
    "\n")
   "\n"))

If, in the middle of this mess, we notice that the second-to-last line isn’t a link line, we just nope out as if the filter never even matched, thanks to require. Pretty neat♥︎