Index: main/display-string.lisp
===================================================================
--- main/display-string.lisp	(revision main,22.1.1)
+++ main/display-string.lisp	(revision main,22.1.1)
@@ -0,0 +1,67 @@
+(defpackage #:display-string
+  (:use #:cl #:cdk #:cl-ppcre #:dso-lex)
+  (:export #:enquote #:dequote #:render))
+
+(in-package #:display-string)
+
+
+
+(defun enquote (str)
+  (regex-replace-all "`" str "``"))
+
+(defun dequote (str)
+  (regex-replace-all "`(.)" str "\\1"))
+
+
+
+(defun escape-code (two-char)
+  (aref two-char 1))
+
+(deflexer eat-dstring
+  ("`[SsRrBbUuDdKkPpIi]" escape escape-code)
+  ("(?:[^`]|``)+" literal dequote))
+
+(defun scan-dstring (dstr)
+  (labels ((f (start &optional tokens)
+             (multiple-value-bind (class image end) (eat-dstring dstr start)
+               (if class
+                   (f end (cons (list class image) tokens))
+                   (nreverse tokens)))))
+    (f 0)))
+
+(defun renderlen-part (part)
+  (destructuring-bind (class image) part
+    (if (eq class 'literal)
+        (length image)
+        0)))
+
+(defun renderlen (parts)
+  (let ((lens (mapcar 'renderlen-part parts)))
+    (reduce '+ lens)))
+
+(defconstant +attributes+ '(#\s #.(expt 2 16)
+                            #\u #.(expt 2 17)
+                            #\r #.(expt 2 18)
+                            #\k #.(expt 2 19)
+                            #\d #.(expt 2 20)
+                            #\b #.(expt 2 21)
+                            #\i #.(expt 2 23)
+                            #\p #.(expt 2 24)))
+
+(defun render (dstr window y x)
+  (let ((parts (scan-dstring dstr)))
+    (cdk:wmove window y x)
+    (dolist (p parts)
+      (destructuring-bind (class image) p
+        (if (eq class 'literal)
+            (add-string window image)
+            (let ((on (upper-case-p image))
+                  (attr (getf +attributes+ (char-downcase image))))
+              (if on
+                  (cdk::c-wattron window attr)
+                  (cdk::c-wattroff window attr))))))))
+
+(defun test ()
+  (with-screen (s)
+    (render "Now `B`Ris `bthe`r ``time.'" s 10 10)
+    (input:%wget-wch s)))
