« HTML + CSS で数式組版 (その7) | トップページ | HTML + CSS で数式組版 (その9) »

2009年3月21日 (土)

HTML + CSS で数式組版 (その8)

HTML の出力です。

HTML を出力するだけならカンタン、と思いきや妙に手こずってしまいました。入出力は、関数プログラミングの鬼門かも。 Common Lisp は、モナドとかじゃなくて、普通に副作用で出力するのですけど。

変更箇所

(defun gen-html-elem (ast)
  (cond ((atom ast) nil)
        ((and (atom (car ast)) (atom (caddr ast)))
         (cond ((eq (car ast) 'text)
                (list 'span
                      (list 'class
                            (format nil "~A~A" (car ast) (cadr ast)))
                      (list 'text (caddr ast))))
               (t nil)))
        ((atom (car ast))
         (list 'div  ;; cons list -> list
               (list 'class
                     (format nil "~A~A" (car ast) (cadr ast)))
               (gen-html-elem (caddr ast))))
        ((and (atom (caadr ast)) (eq (caadr ast) 'argend)) ;; ignore argend.
         (cons (gen-html-elem (car ast))
               (gen-html-elem (cddr ast))))
        (t
         (cons (gen-html-elem (car ast))
               (gen-html-elem (cdr ast))))))

gen-html-elem 関数に、色々と忘れものをしていたので、変更を行いました。

追加箇所

(defun elem-childs (elem)
  (cond ((atom elem) nil)
        ((atom (car elem))
         (elem-childs (cdr elem)))
        ((atom (caar elem))
         (elem-childs (cdr elem)))
        (t (car elem))))

(defun output-attrs (attrs stm outfn)
  (cond ((atom attrs) nil)
        ((and (atom (caar attrs)) (atom (cadar attrs)))
         (let ((n (caar attrs))
               (v (cadar attrs)))
           (progn
             (funcall outfn n v stm)
             (output-attrs (cdr attrs) stm outfn))))
        (t (output-attrs (cdr attrs) stm outfn))))

(defun output-html (elem stm)
  (cond ((atom elem) nil)
        ((atom (car elem))
         (let ((c (car elem))
               (cs (cdr elem)))
           (format stm "<~A" c)
           (output-attrs
            cs stm
            (lambda (n v stm)
              (if (eq n 'text) nil
                (format stm " ~A=\"~A\"" n v))))
           (format stm ">~%")
           (output-attrs
            cs stm
            (lambda (n v stm)
              (if (eq n 'text)
                  (format stm "~A~%" v))))
           (output-html (elem-childs cs) stm)
           (format stm "</~A>~%" c)))
        (t (progn
             (output-html (car elem) stm)
             (output-html (cdr elem) stm)))))

(setf *buffer-name* "*math2html*")

(defun math2html (str)
  (let ((ast (parse-string str 0)))
    (let ((elem
           `(html ((body ((div (class "math")
                               ,(gen-html-elem ast))))))
           )
          (b (get-buffer-create *buffer-name*)))
      (erase-buffer b)
      (with-open-stream (stm (make-buffer-stream b))
        (output-html elem stm))
      b)))

最後の関数、 math2html を eval すると:

(math2html "x =\\frac{a}{b}+ c")
=>#<buffer: *math2html*>

バッファに HTML を出力します。長いので、 span エレメントの改行を消してます。実際には、エレメントごとに改行した状態で出力されます。

<html>
<body>
<div class="math">
<span class="text1">x</span>
<span class="text3">=</span>
<div class="frac8">
<div class="argbegin9">
<span class="text10">a</span>
</div>
<div class="argbegin12">
<span class="text13">b</span>
</div>
</div>
<span class="text15">+</span>
<span class="text17">c</span>
</div>
</body>
</html>

|

« HTML + CSS で数式組版 (その7) | トップページ | HTML + CSS で数式組版 (その9) »

コメント

コメントを書く



(ウェブ上には掲載しません)


コメントは記事投稿者が公開するまで表示されません。



トラックバック

この記事のトラックバックURL:
http://app.f.cocolog-nifty.com/t/trackback/80472/28731057

この記事へのトラックバック一覧です: HTML + CSS で数式組版 (その8):

« HTML + CSS で数式組版 (その7) | トップページ | HTML + CSS で数式組版 (その9) »