how to make HTML from a list in scheme, racket

北城以北 提交于 2021-02-10 06:48:33

问题


This is a very long question ... I am new and joined, so please don't attack me. Apologies for my bad communications in English. I have some defintions:

An HTML(H) is one of

  • Str
  • Tag

A Tag is

  • (cons Sym (listof H))

I want to use mutual recursion,make the HTML into real HTML code. For example,

(list 'html (list 'head (list 'title "Hi")) (list 'body (list 'h1 "Welcome") "Text")) 

Turns into:

"<html><head><title>Hi</title></head><body><h1>Welcome</h1>Text</body></html>"

This should work for any list or string. There are rules for turning it into HTML:

  • A string does not need to turn into HTML.
  • Each Tag (this is from the definitions) begin with <tag> and end with </tag>. So <html> and </html>.

If they enter a string, "Hello", then it does not convert anything. I wrote code here, but it does not work ...

(define (html->string html)
  (cond [(string? html) html]
    [else (append (list "<" (first html) ">") (change-tag (rest html)) (list "</" (first html) ">"))]))


(define (change-tag lst)
  (cond [(empty? lst) empty]
    [else (append (html->string (list (first lst)))
                  (html->string (list (rest lst))))]))

If I enter something like:

(list 'html (list 'head (list 'title "Hi")) (list 'body (list 'h1 "Welcome") "Text")) 

Then it gives me:

(list "<" 'html ">" "<" (list 'head (list 'title "Hi")) ">" "</" (list 'head (list 'title "Hi")) ">" "<" (list  (list 'body  (list 'h1 "Welcome").....etc etc

It is a very long output and it does not work. How to be able to fix this?


回答1:


You have the right idea, but still - there are three main issues with your proposed solution:

  • The output will be a string, not a list, so we must append strings in the recursive steps and return strings in the base cases.
  • Symbols must be explicitly converted to strings if we want to concatenate them with other strings.
  • And last but not least: you're missing a couple of base cases, and these are essential for writing a correct solution: what should happen if the given html is an empty list? What if the first element in a list is not a symbol, but another list?

This will work, take a careful look at the things that changed:

(define (html->string html)
  (cond [(empty? html) ""]
        [(string? html) html]
        [(not (symbol? (first html)))
         (html->string (first html))]
        [else (string-append
               "<" (symbol->string (first html)) ">"
               (change-tag (rest html))
               "</" (symbol->string (first html)) ">")]))

(define (change-tag lst)
  (cond [(empty? lst) ""]
        [else (string-append
               (html->string (first lst))
               (html->string (rest lst)))]))

It works as expected:

(define html
  (list 'html
        (list 'head
              (list 'title "Hi"))
        (list 'body
              (list 'h1 "Welcome")
              "Text")))

(html->string html)
=> "<html><head><title>Hi</title></head><body><h1>Welcome</h1>Text</body></html>"


来源:https://stackoverflow.com/questions/64652970/how-to-make-html-from-a-list-in-scheme-racket

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!