Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

S-Expressions to HTML

Name: Anonymous 2012-09-23 16:57

(define (tagged-list? expr)
  (and (pair? expr) (symbol? (car expr))))

(define (sexp->html expr)
  (cond ((null? expr) "")
        ((string? expr) expr)
        ((tagged-list? expr)
         (make-element (symbol->string (car expr)) "" (cdr expr)))
        ((pair? expr)
         (string-append (sexp->html (car expr))
                        (sexp->html (cdr expr))))
        (else (error "cannot be converted to html" expr))))

(define (make-element name attrs expr)
  (cond ((null? expr) (string-append "<" name attrs "/>"))
        ((tagged-list? expr)
         (make-element name
                       (string-append attrs
                                      " " (symbol->string (car expr))
                                      "=\"" (cadr expr) "\"")
                       (cddr expr)))
        (else
          (string-append "<" name attrs ">" (sexp->html expr) "</" name ">"))))


Sample input:
(let ((title "Hello, world!")
      (urls '("https://boards.4chan.org/g/"
              "https://www.reddit.com/r/programming"
              "https://news.ycombinator.com")))
  (display
    (sexp->html
      `(html lang "en-us"
             (head
               (meta charset "utf-8")
               (title ,title)
               (style type "text/css"
                      "o { text-decoration: overline; }"
                      "spoiler { background-color: #000; }"
                      "spoiler:hover { background-color: transparent; }"))
             (body
               (h1 ,title)
               (p "Welcome to " (spoiler "/prog/") "." (br)
                  (b (i (o (u "ENTERPRISE")))) " solutions!")
               (h2 "Places you should go back to.")
               (ul ,(map (lambda (url) `(li (a href ,url ,url)))
                         urls)))))))


Output:
http://pastebin.com/v4cTnfTJ (spam filter won't let me post HTML)

Name: Anonymous 2012-09-23 18:04

>>10

the problem with using nested calls of string append is that there is unneeded copying. Consider the following:


class BadConcatExample {
  public static String concat(String[] strings) {
    String acc = "":
    for(String string : strings) {
      acc = acc + string;
    }
    return acc;
  }
}


versus:


class EnterpriseConcatExample {
  public static String concat(String[] strings) {
    StringBuilder acc = new StringBuilder();
    for(String string : strings) {
      acc.append(string);
    }
    return acc.toString();
  }
}


In the first example, there are many unneeded strings produced by the string concatenations. In fact, the first one takes \Omega(n^2) time. Whereas the second collects the strings in an ordered list, and then finally concatenates all of them once they entire collection is assembled. When all the strings are known at the time of the concatenation, the length of the final string is known, and the buffer can be allocated and each string copied once into its place. Thus, the entire operation can be done in linear time.

Your application is more complex than these example. In the examples a flat list is translated into a single string, whereas you must translate a tree of strings into a single string. You are right in that flattening a tree using append will be inefficient. A custom routine could be used for this though. It's hard to write though. I'll post it when I'm done.

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List