ulthar.xyz > Repos

leibowitz

Experimental Common Lisp object storage abstraction for Unix file systems
About Files Commits git clone https://ulthar.xyz/repos/leibowitz/leibowitz.git

leibowitz/lib/util/util.lisp

Download raw file: lib/util/util.lisp

(defpackage :leibowitz.util
  (:use #:cl)
  (:export #:url
           #:html
           #:collect-lines
           #:read-stream-to-string))

(in-package :leibowitz.util)

(defun html (str)
  (typecase str
    (string (cl-who:escape-string str))
    (T str)))

(defun url (str)
  (typecase str
    (string
     ;; Copied strait from hunchentoot:url-encode except that we
     ;; url-encode single quotes too.
     (with-output-to-string (s)
       (loop for c across str
             for index from 0
             do (cond ((or (char<= #\0 c #\9)
                           (char<= #\a c #\z)
                           (char<= #\A c #\Z)
                           ;; Note the lack of a single-quote here
                           (find c "$-_.!*()" :test #'char=))
                       (write-char c s))
                      (t (loop for octet across (hunchentoot::string-to-octets
                                                 str :start index :end (1+ index)
                                                     :external-format hunchentoot::+utf-8+)
                               do (format s "%~2,'0x" octet)))))))
    (T str)))

(defun collect-lines (&optional (in *standard-input*))
  "Given IN as either a stream or a string, return a list of all
non-empty and non-whitespace lines as strings, without the trailing
newline"
  (labels ((trim-whitespace (line)
             ;; FIXME: Add control characters and non-ascii whitespace
             ;; characters!  `sb-unicode' has some good stuff there.
             ;; As it stands this behaves like isspace(3)
             (string-trim '(#\Space #\Return #\Newline #\Page #\Tab #\Vt) line))
          (collect (s)
            (loop for line = (read-line s nil 'eof)
                  until (eq line 'eof)
                  for content = (trim-whitespace line)
                  unless (zerop (length content))
                    collect content)))
         (etypecase in
    (null NIL)
    (stream (collect in))
    (string (with-input-from-string (s in) (collect s))))))

(defun read-stream-to-string (&optional (in *standard-input*))
  (with-output-to-string (s)
    (loop for line = (read-line in nil 'eof)
          until (eq line 'eof)
          do (format s "~A~%" line))))
Generated 2024-06-10 19:24:14 -0700 by RepoRat