Is there an Emacs Lisp library for generating HTML?

前端 未结 5 1250
情深已故
情深已故 2020-12-24 16:00

I\'m looking for a solution that allows me to write native Emacs Lisp code and at compile time turns it into HTML, like Franz\'s htmlgen:

(html
 ((:div class         


        
相关标签:
5条回答
  • 2020-12-24 16:05

    I had a similar requirement to be able to parse xml using xml-parse functions, transform it, and then output it back as a xml string.

    Trey's solution almost worked except I needed to retain the whitespace xml elements. So I wrote my own implementation here:

    https://github.com/upgradingdave/xml-to-string

    0 讨论(0)
  • 2020-12-24 16:06

    This is not quite what you're looking for, but there's a 20 minute video where a guy creates a simple website using UCW, the UnCommon Web application framework. It's all done in Emacs using lisp...

    Here is a link to the transcript (all the code (~25 lines) is available at the end of the transcript).

    0 讨论(0)
  • 2020-12-24 16:16

    This could be a starting point: http://www.emacswiki.org/emacs/HtmlLite

    0 讨论(0)
  • 2020-12-24 16:19

    Meanwhile, I found some code that contains something similar I want. Now I can write:

    (views-with-html
     ((body)
      (h1 "Title")
      ((p (class . "entry")) "Hello, World!")))
    

    The implementation has a few limitations (e.g. hard-coded element list), but it seems to be a good starting point.

    0 讨论(0)
  • 2020-12-24 16:20

    As you found out, xmlgen generates XML from a list structure. What I did find disappointing with the ``xmlgen` package that the format it supports is not quite the inverse of Emacs' xml parser.

    I did add this to my copy of xmlgen:

    ;; this creates a routine to be the inverse of what xml-parse does
    ;;;###autoload
    (defun xml-gen (form &optional in-elm level)
      "Convert a sexp to xml:
      '(p :class \"big\")) => \"<p class=\\\"big\\\" />\""
      (let ((level (or level 0)))
        (cond
         ((numberp form) (number-to-string form))
         ((stringp form) form)
         ((listp form)
          (destructuring-bind (xml attrs) (xml-gen-extract-plist form)
            (let ((el (car xml)))
              (unless (symbolp el)
                (error "Element must be a symbol (got '%S')." el))
              (setq el (symbol-name el))
              (concat "<" el (xml-gen-attr-to-string attrs)
                      (if (> (length xml) 1)
                          (concat ">" (mapconcat
                                       (lambda (s) (xml-gen s el (1+ level)))
                                       (cdr xml)
                                       "")
                                  "</" el ">")
                        "/>"))))))))
    
    (defun xml-gen-attr-to-string (plist)
      (reduce 'concat (mapcar (lambda (p) (concat " " (symbol-name (car p)) "=\"" (cdr p) "\"")) plist)))
    
    (defun xml-gen-extract-plist (list)
      (list (cons (car list) (let ((kids (xml-node-children list)))
                               (if (= 1 (length kids))
                                   kids
                                 (remove-if-not 'listp kids))))
            (xml-node-attributes list)))
    

    Note: the interface for this is xml-gen (not xmlgen which is the original parsing).

    With this interface, the following holds:

    (string-equal (xml-gen (car (xml-parse-region <some-region-of-xml>)))
                  <some-region-of-xml>)
    

    and

    (equal (car (xml-parse-region (insert (xml-gen <some-xml-form>))))
           <some-xml-form>)
    

    The new xml-gen does not strive to preserve the whitespace around that the xml-parse-region routine generates.

    0 讨论(0)
提交回复
热议问题