|
- ;;;; src/toolkit/toolkit.lisp
-
- (in-package #:cl-deck-builder2.toolkit.utils)
-
- ;; https://stackoverflow.com/a/11965885
- ;; def grouped(l, n):
- ;; for i in xrange(0, len(l), n):
- ;; yield l[i:i+n]
-
- (defun grouped (seq &optional (n 1000))
- "Group elements in a list by some number of elements.
-
- ARGUMENTS
- SEQ The sequence to be grouped.
- N The number of elements per grouping."
- (loop :for i :upto (1- (length seq)) :by n
- :collect (subseq seq i (min (length seq)
- (+ i n)))))
-
- ;; Not sure how I arrived at this gist.
- ;;
- ;; <https://gist.github.com/html/4085786>
- ;;
- ;; My code is modified slightly.
- (defun normalize-newlines (string)
- "Remove or replace #\Return(#\Newline)? sequences with just #\Newline.
-
- The \#Newline following #\Return is optional, so just #\Return also gets turned into #\Newline.
-
- ARGUMENTS
- STRING The target string."
- (ppcre:regex-replace-all
- (format nil "~C(\\n)?" #\Return)
- string
- (format nil "~C" #\Newline)))
-
- ;; Is this necessary? I uploaded a file with a BOM and it exploded.
- (defun strip-bom (string)
- "If STRING is UTF-8 and contains a UTF-8 BOM it will be removed.
-
- ARGUMENTS
- STRING The string to check."
-
- (when string
- (case (type-of (char string 0))
- (extended-char (subseq string 1))
- (t string))))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- (defun query-param (name parsed)
- "Parse query param values. Get the value of the specified element NAME in the query PARSED.
-
- ARGUMENTS
- NAME The query to search for in the parameter list.
- PARSED The parameter list."
- ;; TODO STRING=? STRING-EQUAL?? Maybe I should add a &KEY (test #'STRING=)?
- (assoc-utils:aget parsed name))
-
- ;; (defun generate-pages ()
- ;; "Generate pagination"
- ;; (let ((pages nil))
- ;; (dotimes (i 10)
- ;; (push (list :id (+ 1 i) :start (* 10 i)) pages))
- ;; (reverse pages)))
-
- ;; TODO Passing weird floats to this. How can I put the weird math into here?
- ;;
- ;; I made it into a helper function for now.
- ;; No idea how to even explain this. It works!
- (defun generate-pages-helper (start &optional (max 10) (multiplier 10))
- "Generate pagination up to MAX pages, with MULTIPLIER items per page."
- ;; We always want 10 pages. If we start at page 0, subtract five,
- ;; then take the nearest lowest non-negative integer (0), this gets
- ;; us a comfy left bound.
- (let ((start- (- start 5)))
- ;; If START- is less than zero, make it zero. This gives us a safe
- ;; left bound.
- (when (< start- 0)
- (setf start- 0))
- (loop for i from 0 upto (1- (min (min max 8) (- max start -8))) collect
- `(:id ,(+ start- i) :offset ,(* multiplier (+ start- i))))))
-
- (defun generate-pages (length offset &optional (limit 10))
- "Generate pagination for LENGTH number of pages, with LIMIT number of items per page, offset into the list by OFFSET number of pages.
-
- ARGUMENTS
- LENGTH The length of the array we're generating pages for.
- OFFSET The starting index.
- LIMIT The number of entries per page. Default is 10."
- (generate-pages-helper (floor (/ offset limit))
- (ceiling (/ length limit))
- limit))
-
- (defun get-opposite-direction (direction)
- "Get the opposite direction"
- (if (string= direction "asc")
- "desc"
- "asc"))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;; Idea for RLE from PCL by Paul Graham
- ;; This implementation based on <https://gist.github.com/trhura/5820848>
- ;;
- ;; Nope it's not I wrote my own implementation!
- (defun rle-encode (lst &key (key #'identity) (test #'eq))
- (loop for line in (mapcar key (remove-duplicates lst :key key :test test))
- collect (cons (count line lst :key key :test test) line)))
- ;; (sort * ;#'> :key #'car))
-
- (defun rle-decode (lst)
- (loop for line in lst
- nconc (make-list 3 :initial-element (second line))))
-
- ;; XXX Where does this go?
- (defun rle-encode-plist (plist &key (key #'identity) (test #'eq))
- (rle-encode
- (mapcar (lambda (plist)
- (setf (getf plist :name)
- (princ-to-string (getf plist :name)))
- plist)
- plist)
- :key key :test test))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;; For The Label Maker
- ;; https://tex.stackexchange.com/a/119383
- (defun latex-escape (s)
- (cl-ppcre:regex-replace-all
- "(\\\\backslash)"
- (cl-ppcre:regex-replace-all
- "~"
- (cl-ppcre:regex-replace-all
- "(\\^)"
- (cl-ppcre:regex-replace-all
- "([\$\#&%_{}])"
- (cl-ppcre:regex-replace-all "\\" s "\\backslash")
- "\\\\\\1")
- "\\\\\\1{}")
- "\\\\texttt{\\~{}}")
- "$\\1$"))
|