From c1cc3ba92756f93f8f93f1c0ad1ce527eda8ac99 Mon Sep 17 00:00:00 2001 From: Ralph Schleicher Date: Wed, 15 Sep 2021 11:09:38 +0200 Subject: [PATCH 1/2] xml-util.lisp (whitespace-char-p): Don't use a macro if a function is sufficient. --- src/nox/xml-util.lisp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/nox/xml-util.lisp b/src/nox/xml-util.lisp index 8ca7448..be95783 100644 --- a/src/nox/xml-util.lisp +++ b/src/nox/xml-util.lisp @@ -382,12 +382,11 @@ (return (concatenate 'string (nreverse chars))))))) -(defmacro whitespace-char-p (char) - (with-temps (c) - `(let ((,c ,char)) - ;; let's assume this works for now :-) - (or (char= ,c #\Space) - (not (graphic-char-p ,c)))))) +(defun whitespace-char-p (char) + "Return true if CHAR is a whitespace character. +Argument CHAR has to be a character object." + (declare (type character char)) + (or (char= char #\Space) (not (graphic-char-p char)))) (defequal -whitespace-chars- From e44f3bf3fe9faeda95021e5da2f45d0faa40c787 Mon Sep 17 00:00:00 2001 From: Ralph Schleicher Date: Wed, 15 Sep 2021 11:11:05 +0200 Subject: [PATCH 2/2] xml-util.lisp (collapse-whitespace): Full Unicode support. --- src/nox/xml-util.lisp | 44 ++++++++++++++++++------------------------- 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/src/nox/xml-util.lisp b/src/nox/xml-util.lisp index be95783..4314330 100644 --- a/src/nox/xml-util.lisp +++ b/src/nox/xml-util.lisp @@ -415,32 +415,24 @@ Argument CHAR has to be a character object." char))) (defun collapse-whitespace (string) - ;; new version with "poor man's Unicode support" :-( - (labels ((collapse (mode old new) - (if old - (dsb (c &rest old) old - (cond ((zerop (logand (char-code c) #b10000000)) - (if (whitespace-char-p c) - (collapse (if (eq mode :start) :start :white) old new) - (collapse :collect old - (if (eq mode :white) - (list* c #\Space new) - (cons c new))))) - ((= (logand (char-code c) #b11100000) 192) - (collapse :collect (cdr old) - (if (eq mode :white) - (list* (car old) c #\Space new) - (list* (car old) c new)))) - ((= (logand (char-code c) #b11110000) 224) - (collapse :collect (cddr old) - (if (eq mode :white) - (list* (cadr old) (car old) c #\Space new) - (list* (cadr old) (car old) c new)))) - (t - (error "Cannot decode this: ~S" (cons c old))))) - (concatenate 'string (nreverse new))))) - (declare (dynamic-extent #'collapse)) - (collapse :start (coerce string 'list) nil))) + "Remove leading and trailing whitespace characters in STRING +and replace any intermediate sequence of whitespace characters +with a single space character." + (with-output-to-string (stream) + (loop :for char :across string + :with state = :start + :do (cond ((eq state :parse) + (if (whitespace-char-p char) + (setf state :space) + (princ char stream))) + ((not (whitespace-char-p char)) + ;; Found a non-whitespace character after skipping + ;; a sequence of whitespace characters. + (when (eq state :space) + (princ #\Space stream)) + (princ char stream) + (setf state :parse)) + )))) ;;; --------------------------------------------------------------------------------------