I am working on a blog program working with hunchentoot and clsql.
I am using a applet called editize which edits a subset of HTML and returns
it. externally it works as a input text field. The problem is that it need
the entire HTML file input as a string.
editize.display('document')
This poses a problem because CR LF RT \ " and ' need special handeling.
This function does that.:
(defun script-string (text)
(coerce
(iter (for char in-string text)
(cond
((char= char #\')
(collect #\\)
(collect #\'))
((char= char #\")
(collect #\\)
(collect #\"))
((char= char #\\)
(collect #\\)
(collect #\\))
(t
(unless (or (char= char #\NewLine)
(char= char #\Return)
(char= char #\LineFeed))
(collect char)))))
'string))
As you can see it is a ugly thing..
Is there a better way of doing this?
On 12 Jul., 21:10, "John Thingstad" <··············@chello.no> wrote:
> I am working on a blog program working with hunchentoot and clsql.
> I am using a applet called editize which edits a subset of HTML and returns
> it. externally it works as a input text field. The problem is that it need
> the entire HTML file input as a string.
> editize.display('document')
> This poses a problem because CR LF RT \ " and ' need special handeling.
> This function does that.:
....
>
> As you can see it is a ugly thing..
> Is there a better way of doing this?
I like this way better, you decide if you agree with me :)
(defun script-string2 (text)
(let ((escape-chars (list #\'
#\"
#\\))
(remove-chars (list #\Newline
#\Return
#\Linefeed)))
(iter (for char in-string text)
(when (member char escape-chars :test #'char=)
(collect #\\ result-type 'string))
(unless (member char remove-chars :test #'char=)
(collect char result-type 'string)))))
Blessings,
Simon
·······@gmx.net writes:
> On 12 Jul., 21:10, "John Thingstad" <··············@chello.no> wrote:
>> I am working on a blog program working with hunchentoot and clsql.
>> I am using a applet called editize which edits a subset of HTML and returns
>> it. externally it works as a input text field. The problem is that it need
>> the entire HTML file input as a string.
>> editize.display('document')
>> This poses a problem because CR LF RT \ " and ' need special handeling.
>> This function does that.:
> ....
>>
>> As you can see it is a ugly thing..
>> Is there a better way of doing this?
>
> I like this way better, you decide if you agree with me :)
>
> (defun script-string2 (text)
> (let ((escape-chars (list #\'
> #\"
> #\\))
> (remove-chars (list #\Newline
> #\Return
> #\Linefeed)))
> (iter (for char in-string text)
> (when (member char escape-chars :test #'char=)
> (collect #\\ result-type 'string))
> (unless (member char remove-chars :test #'char=)
> (collect char result-type 'string)))))
Why not just be generic and overboard all at once? Here's a start.
; Exercise for the reader: get rid of the global variable
(defvar *character-substitutions* (make-hash-table))
(defun backslash-escape (character)
(concatenate 'string "\\" (string character)))
(defun ignore-character (character)
(declare (ignore character))
"")
; This one is just for fun; a more general HTML entity conversion
; would be even more exciting
(defun hex-escape (character)
(concatenate 'string "&#" (format nil "~x" (char-code character)) ";"))
; See above for the homework assignment
(loop :for c :in '(#\' #\" #\\)
:do (setf (gethash c *character-substitutions*) 'backslash-escape))
; Likewise
(loop :for c :in '(#\Newline #\Return #\Linefeed)
:do (setf (gethash c *character-substitutions*) 'ignore-character))
; As long as we're not optimizing anything... ;)
(defun sanitize-string (string)
(apply 'concatenate 'string
(loop :for c :across string
:collect (let ((function (gethash c *character-substitutions*)))
(if function
(funcall function c)
(string c))))))
"John Thingstad" <··············@chello.no> writes:
> I am working on a blog program working with hunchentoot and clsql.
> I am using a applet called editize which edits a subset of HTML and returns
> it. externally it works as a input text field. The problem is that it need
> the entire HTML file input as a string.
> editize.display('document')
> This poses a problem because CR LF RT \ " and ' need special handeling.
> This function does that.:
>
> (defun script-string (text)
> (coerce
> (iter (for char in-string text)
> (cond
> ((char= char #\')
> (collect #\\)
> (collect #\'))
> ((char= char #\")
> (collect #\\)
> (collect #\"))
> ((char= char #\\)
> (collect #\\)
> (collect #\\))
> (t
> (unless (or (char= char #\NewLine)
> (char= char #\Return)
> (char= char #\LineFeed))
> (collect char)))))
> 'string))
>
> As you can see it is a ugly thing..
> Is there a better way of doing this?
I don't know if expressing the character substitutions in a
declarative form would make things prettier, but I do wonder about
skipping over the end-of-line characters--does that munge separate
words together?
John Thingstad wrote:
> (cond ...
> Is there a better way of doing this?
(case char
((#\' #\" #\\) (collect #\\) (collect char))
((#\NewLine #\Return #\LineFeed))
(t (collect char)))
(not tested)
--
Dan
www.prairienet.org/~dsb/
"Dan Bensen" <··········@cyberspace.net> skrev i melding
·················@wildfire.prairienet.org...
> John Thingstad wrote:
> > (cond ...
> > Is there a better way of doing this?
>
> (case char
> ((#\' #\" #\\) (collect #\\) (collect char))
> ((#\NewLine #\Return #\LineFeed))
> (t (collect char)))
>
> (not tested)
>
> --
> Dan
> www.prairienet.org/~dsb/
That is beautiful! Just what I wanted.
Thanks!
On Jul 12, 3:10 pm, "John Thingstad" <··············@chello.no> wrote:
[...]
> (defun script-string (text)
> (coerce
> (iter (for char in-string text)
> (cond
> ((char= char #\')
> (collect #\\)
> (collect #\'))
> ((char= char #\")
> (collect #\\)
> (collect #\"))
> ((char= char #\\)
> (collect #\\)
> (collect #\\))
> (t
> (unless (or (char= char #\NewLine)
> (char= char #\Return)
> (char= char #\LineFeed))
> (collect char)))))
> 'string))
> As you can see it is a ugly thing..
> Is there a better way of doing this?
I'm sorry if this is a dumb question, but do you just want to drop the
newlines and such, or turn them into whitespace?
Cheers
Pillsy
>
> I'm sorry if this is a dumb question, but do you just want to drop the
> newlines and such, or turn them into whitespace?
>
> Cheers
> Pillsy
>
In that implementation I just dropped them completely.
As Editize always groups elements in HTML tags that didn't represent
a problem. As it works well generatlly I changed it to produce a #\space
instead. Using the suggestion above it becomes:
(defun script-string (text)
(coerce
(iter (for char in-string text)
(case char
((#\' #\" #\\) (collect #\\) (collect char))
((#\Newline #\Return #\Newline) (collect #\Space))
(t (collect char))))
'string))
In article <············@news.get.no>,
"John Thingstad" <··············@chello.no> wrote:
> I am working on a blog program working with hunchentoot and clsql.
> I am using a applet called editize which edits a subset of HTML and returns
> it. externally it works as a input text field. The problem is that it need
> the entire HTML file input as a string.
> editize.display('document')
> This poses a problem because CR LF RT \ " and ' need special handeling.
> This function does that.:
>
> (defun script-string (text)
> (coerce
> (iter (for char in-string text)
> (cond
> ((char= char #\')
> (collect #\\)
> (collect #\'))
> ((char= char #\")
> (collect #\\)
> (collect #\"))
> ((char= char #\\)
> (collect #\\)
> (collect #\\))
> (t
> (unless (or (char= char #\NewLine)
> (char= char #\Return)
> (char= char #\LineFeed))
> (collect char)))))
> 'string))
>
> As you can see it is a ugly thing..
What do you think is ugly about it?
What would you like to improve?
> Is there a better way of doing this?
--
http://lispm.dyndns.org
On Jul 12, 9:10 pm, "John Thingstad" <··············@chello.no> wrote:
> I am working on a blog program working with hunchentoot and clsql.
> I am using a applet called editize which edits a subset of HTML and returns
> it. externally it works as a input text field. The problem is that it need
> the entire HTML file input as a string.
> editize.display('document')
> This poses a problem because CR LF RT \ " and ' need special handeling.
> This function does that.:
>
> (defun script-string (text)
> (coerce
> (iter (for char in-string text)
> (cond
> ((char= char #\')
> (collect #\\)
> (collect #\'))
> ((char= char #\")
> (collect #\\)
> (collect #\"))
> ((char= char #\\)
> (collect #\\)
> (collect #\\))
> (t
> (unless (or (char= char #\NewLine)
> (char= char #\Return)
> (char= char #\LineFeed))
> (collect char)))))
> 'string))
>
> As you can see it is a ugly thing..
> Is there a better way of doing this?
Yes, that's pretty ugly, with the repeated code and the call to
coerce. I'd have written it like this (making the change of replacing
whitespace with whitespace instead of eliminating it):
(with-output-to-string (out)
(loop for char across string
if (find char #(#\' #\" #\\))
do (write-char #\\ out) (write-char char out)
else if (find char #(#\Newline #\Return #\Linefeed))
do (write-char #\Space out)
else do (write-char char out)))
>
> Yes, that's pretty ugly, with the repeated code and the call to
> coerce. I'd have written it like this (making the change of replacing
> whitespace with whitespace instead of eliminating it):
>
> (with-output-to-string (out)
> (loop for char across string
> if (find char #(#\' #\" #\\))
> do (write-char #\\ out) (write-char char out)
> else if (find char #(#\Newline #\Return #\Linefeed))
> do (write-char #\Space out)
> else do (write-char char out)))
>
>
How about this? Combining all of the feedback I get this.
It seems the best solution.
(defun script-string (text)
(with-output-to-string (out)
(iter (for char in-string text)
(case char
((#\' #\" #\\) (write-char #\\ out) (write-char char out))
(((#\Newline #\Return #\Linefeed)) (write-char #\Space out))
(t (write-char char out))))))
Thaks.
In case anyone is wondering, what extensibility??
Just by adding
(defmethod script-write ((obj list) stream)
(loop for elt in obj do (script-write elt stream)))
(defmethod script-write ((obj number) stream)
(write obj :stream stream))
We now have
CL-USER> (script-string '("hello " 10 " wade's \"test\"
"))
"hello 10 wade\\'s \\\"test\\\" "
CL-USER>
Which one may consider very useful.
Wade