(in-package :clim-doc)

(define-tex-macro "dodocf" "#1#2#3" (name args kind)
  (dodocf name args kind $input nil))
(define-tex-macro "Dodocf" "#1#2#3" (name args kind)
  (dodocf name args kind $input t))
(define-tex-macro "dodocv" "#1#2" (name kind)
  (dodocf name nil kind $input nil))
(define-tex-macro "Dodocv" "#1#2" (name kind)
  (dodocf name nil kind $input t))

(defparameter *def-stopper*
  '("paragraph" "appendix" "part" "chapter" "section" "subsection" "subsubsection"
    "dodocf" "Dodocf" "dodocv" "Dodocv"
    "stopdef" "fed"))

(defvar *signatures* nil)

(defun all-data (x)
  (cond ((stringp x) x)
        ((reduce (lambda (x y) (concatenate 'string x y))
                 (mapcar #'all-data (node-children x))
                 :initial-value ""))))

(defun all-data* (x)
  (reduce (lambda (x y) (concatenate 'string x y))
          (mapcar #'all-data x)
          :initial-value ""))

(defun dodocf (name args kind input flag)
  (let* ((body (let ((*stop-words* (append *def-stopper* *stop-words*)))
                 (slurp-stream input))))
    ;; NOTE: in theory (not flag) should do, but manual.tex has it wrong.
    (cond ((if (not *defun-tweak-p*)
               (not flag)
               (and (null body) (member (peek-token input)
                                        '((:CS "Dodocf") (:CS "dodocf")) ;xxx???
                                        :test #'equal)))
           ;; okay try to append this together, we do it the evil way...
           ;; *signatures* is read by the next invocation of dodocf
           (push (list name args kind) *signatures*)
           nil)
          (t
           (push (list name args kind) *signatures*)
           (setf *signatures* (reverse *signatures*))
           (let ((signatures (mapcar (lambda (s) (mapcar #'expand-tokens s)) *signatures*)))
             (prog1
                 (append
                  (list `(:DEFUN
                          (:noexpand ,(mapcar (lambda (sig)
                                                `(:SIGNATURE
                                                  :NAME   ,(list `(:CL ,@(first sig)))
                                                  :PARAMS ,(list `(:I  ,@(second sig)))
                                                  :KIND   ,(third sig)))
                                              signatures))
                          (:noexpand ,body))))
               (setf *signatures* nil)))))))

;;;; =====

(define-tex-macro "concept" "#1" (blah)
  ;; definition
  (list `(:CONCEPT ,@blah)))

(define-tex-macro "term" "#1" (blah)
  ;; use
  (list `(:TERM ,@blah)))

;;; for manual.tex

(define-tex-macro " begin enumerate0" "" ()
  (let ((body (slurp-stream $input)))
    (let ((items nil)
          (item nil))
      (dolist (k body)
        (cond ((equal k '(++ITEM++))
               (push (reverse item) items)
               (setf item nil))
              (t
               (push k item))))
      (push (reverse item) items)
      (setf items (reverse items))
      (list `(:NOEXPAND
              ((:OL
                ,@(mapcar (lambda (x)
                            `(:LI ,@x))
                          (cdr items)))))) )))

(define-tex-macro " end enumerate0" "" ()
  (list (make-token :eof)))

(define-environment "itemize0" "" ()
  ;; sometimes we still catch stray items
  (let ((items nil)
        (item nil))
    (dolist (k $body)
      (cond ((equal k '(++ITEM++))
             (push (reverse item) items)
             (setf item nil))
            (t
             (push k item))))
    (push (reverse item) items)
    (setf items (reverse items))
    (list `(:NOEXPAND
            ((:UL
              ,@(mapcar (lambda (x)
                          `(:LI ,@x))
                        (cdr items)))))) ))

;;; fixups

;; \newskip  \normalparskip        
;; \normalparskip = 0pc

(define-tex-macro "normalparskip" "#1pc" (x) (declare (ignore x)) nil)
;; \parindent 0pc
;; \parskip   1pc
(define-tex-macro "parindent" "#1pc" (x) x nil)
(define-tex-macro "parskip"   "#1pc" (x) x nil)

;; \vspace*{50pt}
;; {\huge\bf Acknowledgments}\par
;; \vskip 40pt

(define-tex-macro "vspace"  "#1" (x) x nil)
(define-tex-macro "vspace*"  "#1" (x) x nil)

(define-tex-macro "vskip"   "#1pt" (x) x nil)

(define-tex-macro "setcounter" "#1#2" (x y)
  (declare (ignore x y))
  nil)

(define-tex-macro "renewcommand" "#1#2" (x y)
    x y
    ;; now we actually could define this
    nil)

;;;;

;; although we almost grok the stuff below, we just skip it:

#||
(def-skip 
    "{\catcode`\-=\active
\gdef\cl{\bgroup
  \catcode`\-=\active \def-{{\tt \char`\-}\penalty\exhyphenpenalty}%
  \@cl}}
\def\@cl#1{\tt#1\egroup}")
||#