;;;; thesis-re-working functions (for making HTML from LaTeX)
;;; Time-stamp: <2005-01-07 10:29:46 john>

(defconst thesis-directory (substitute-in-file-name "$COMMON/www/thesis/"))

(defconst thesis-chapters-directory (expand-file-name "chapters" thesis-directory))

(defun thesis-forall-html (function)
  "Apply FUNCTION to all thesis HTML files."
  (let ((files (cons (expand-file-name "thesis.html" thesis-directory)
		     (directory-files thesis-chapters-directory
				      t
				      "\\.html$" t))))
    (save-window-excursion
      (dolist (file files)
	(message "Processing %s" file)
	(find-file file)
	(save-excursion
	  (goto-char (point-min))
	  (funcall function))
	(message "Processed %s" file))))
  (message "Finished applying %S to thesis files" function))

(defun thesis-replace-string (pattern replacement)
  "For all thesis files, replace PATTERN with REPLACEMENT."
  (interactive "sReplace string: 
sReplace string %s with: ")
  (thesis-forall-html
   (function
    (lambda ()
      (replace-string pattern replacement)))))

(defun thesis-replace-regexp (pattern replacement)
  "For all thesis files, replace PATTERN with REPLACEMENT."
  (interactive "sReplace regexp: 
sReplace regexp %s with: ")
  (thesis-forall-html
   (function
    (lambda ()
      (replace-regexp pattern replacement)))))

(defun thesis-query-replace-regexp (pattern replacement)
  "For all thesis files, query-replace PATTERN with REPLACEMENT."
  (interactive "sQuery-replace regexp: 
sQuery-replace regexp %s with: ")
  (thesis-forall-html
   (function
    (lambda ()
      (query-replace-regexp pattern replacement)))))

(defun thesis-fix-subscripts ()
  "Fix the subscripts in an html file."
  (interactive)
  (let ((end-marker (make-marker)))
    (while (search-forward "<math>" (point-max) t)
      (let ((start (point)))
	(set-marker end-marker (search-forward "</math>" (point-max) t))
	(goto-char start)
	(while (search-forward "_" end-marker t)
	  (replace-match "<span class=\"sub\">" t t)
	  ;; (goto-char start)		; won't find the first one again, have changed it by now
	  (when (search-forward "_" end-marker t)
	    (replace-match "</span>")))))))

(defun thesis-fix-all-subscripts ()
  (interactive)
  (thesis-forall-html 'thesis-fix-subscripts))

(defun thesis-fix-math ()
  (apply-replace-regexp-alist
   '(("<math>" . "<span class=\"math\">")
     ("</math>" . "</span>"))))

(defun thesis-fix-all-math ()
  (interactive)
  (thesis-forall-html 'thesis-fix-math))

(defun thesis-fix-dollardollarmath ()
  (while (search-forward "$$" (point-max) t)
    (replace-match "<p class=\"formula\">" t t)
    (if (search-forward "$$" (point-max) t)
	(replace-match "</p>" t t))))

(defun thesis-fix-dollarmath ()
  (while (search-forward "$" (point-max) t)
    (replace-match "<span class=\"math\">" t t)
    (if (search-forward "$" (point-max) t)
	(replace-match "</span>" t t))))

(defun thesis-fix-all-dollarmath ()
  (interactive)
  (thesis-forall-html 'thesis-fix-dollarmath))

(defun thesis-refix-dollarmath ()
  (while (search-forward "<p class=\"formula\">" (point-max) t)
    (replace-match "<blockquote class=\"formula\">" t t)
    (if (search-forward "</p>" (point-max) t)
	(replace-match "</blockquote>" t t))))

(defun thesis-refix-all-dollarmath ()
  (interactive)
  (thesis-forall-html 'thesis-refix-dollarmath))

(defun thesis-fix-subscript-compound ()
  "Fix the compound subscripts in an html file."
  (interactive)
  (let ((end-marker (make-marker)))
    (while (re-search-forward "class=\"\\(formula\\|math\\)\"" (point-max) t)
      (let ((start (point))
	    (place nil))
	(set-marker end-marker (re-search-forward "</\\(span\\|blockquote\\)>" (point-max) t))
	(goto-char start)
	(while (setq place (search-forward "_{" end-marker t))
	  (goto-char (1- place))
	  (forward-sexp 1)
	  (delete-backward-char 1 nil)
	  (insert "</span>")
	  (goto-char place)
	  (delete-backward-char 1 nil)
	  (insert "<span class=\"subscript\">"))))
    (set-marker end-marker nil)))
	  
(defun thesis-fix-all-subscript-compound ()
  (interactive)
  (thesis-forall-html 'thesis-fix-subscript-compound))

(defun thesis-fix-subscript-simple ()
  "Fix the simple subscripts in an html file."
  (interactive)
  (let ((end-marker (make-marker)))
    (while (re-search-forward "class=\"\\(formula\\|math\\)\"" (point-max) t)
      (let ((start (point))
	    (place nil))
	(set-marker end-marker (re-search-forward "</\\(span\\|blockquote\\)>" (point-max) t))
	(goto-char start)
	(while (setq place (re-search-forward "_\\([a-z0-9]\\)" end-marker t))
	  (replace-match "<span class=\"subscript\">\\1</span>" t nil))))
    (set-marker end-marker nil)))

(defun thesis-fix-all-subscript-simple ()
  (interactive)
  (thesis-forall-html 'thesis-fix-subscript-simple))


(defun downcaseregexplist (patterns)
  "Downcase all the PATTERNS in the buffer."
  (dolist (pattern patterns)
    (goto-char (point-min))
     (while (re-search-forward pattern (point-max) t)
       (replace-match (downcase (buffer-substring (match-beginning 0) (match-end 0)))
		      t t))))

(defun foo ()
  (let ((case-fold-search t))
    (webmaster:apply-throughout-tree
     "~/www/thesis/" 'downcaseregexplist
     '(("</?[a-z]+" "#[a-z_]+" "name=\"[^\"]+\"" "[_a-z+]=\"")))))

(defun fixcomments ()
  (interactive)
  (save-excursion
    (goto-char (point-min))
    (while (re-search-forward "<!\\([^-][^-][^>]+[^-][^-]\\)>" (point-max) t)
      (replace-match (format "<!-- %s -->" (buffer-matched 1)) t t))))


(defun replace-region (b1a b1b b2)
  "Replace region in current buffer with active region of B2"
  (interactive "r
bBuffer to get replacement for region: ")
  (interactive
   (list (region-beginning)
	 (region-end)
	 (completing-read "Get replacement from buffer: "
			  (mapcar 'list (buffer-list))
			  nil t
			  (buffer-name (second (buffer-list))))))
  (kill-region b1a b1b)
  (let* ((buf (current-buffer))
	 (text (progn
		 (set-buffer b2)
		 (buffer-substring (region-beginning) (region-end)))))
    (set-buffer buf)
    (insert text)))

(defun check-chapter-section-names ()
  (interactive)
  (find-file "~/www/thesis/thesis.html")
  (save-excursion
    (let ((chapnum 0)
	  (secnum 0)
	  (doit t))
      (goto-char (point-min))
      (while (re-search-forward "href=\"chapters/\\(.+\\.html\\)\"" (point-max) t)
	(let ((chapter (buffer-matched 1)))
	  (unless (string-match "sum" chapter)
	    (incf chapnum)
	    (setq secnum 0)
	    (let* (
		   (chapfile (format "chapters/%s" chapter))
		   (pattern (format "href=\"%s#\\(.+\\)\"" chapfile))
		   )
	      (message "%s (searching for %s)" chapfile pattern)
	      (beginning-of-line 1)
	      (if doit (insert (format " <!-- chapter %d -->" chapnum)))
	      (end-of-line 1)
	      (mark-reference doit chapfile chapnum)
	      (while (re-search-forward pattern (point-max) t)
		(incf secnum)
		(let ((section (buffer-matched 1)))
		  (message "%s: %s" chapfile section)
		  (beginning-of-line 1)
		  (if doit (insert (format " <!-- section %d.%d -->" chapnum secnum)))
		  (end-of-line 1)
		  (mark-reference doit chapfile chapnum section secnum)))))))
      (message "done, OK"))))

(defun mark-reference (doit chapter-file chapter &optional reference-name reference)
  (save-window-excursion
    (find-file chapter-file)
    (goto-char (point-min))
    (if (search-forward (if reference-name
			    (format "name=\"%s\"" reference-name)
			  "<body"))
	(progn
	  (beginning-of-line 1)
	  (when doit
	    (if reference-name
		(insert (format "<!-- reference target: %d.%d -->\n" chapter reference))
	      (insert (format "<!-- reference target: %d -->\n" chapter))))
	  (end-of-line 1))
      (error "Could not find %s" (if reference-name reference-name "body")))))

(defun unmark-references ()
  (save-excursion
    (goto-char (point-min))
    (while (re-search-forward "<!-- reference target: [0-9]+\\(\\.[0-9]+\\)? -->" (point-max) t)
      (replace-match ""))))

(defun unmark-all-references ()
  (interactive)
  (thesis-forall-html 'unmark-references))

(defvar xref-files nil)

(defun check-cross-reference (url)
  "Check one cross-reference"
  (message "url is %s" url)
  (let ((case-fold-search t))
    (cond
     ((string-match "\\([a-z][-/a-z]+\\.html\\)#\\([-_a-z]+\\)" url)
      (let ((file (substring url (match-beginning 1) (match-end 1)))
	    (label (substring url (match-beginning 2) (match-end 2))))
	(message "in file %s, label %s" file label)
	(if (file-exists-p file)
	    (let* ((filepair (assoc file xref-files))
		   (hit (member label (cdr filepair)))
		   )
	      (if hit
		  (message "already seen %s#%s" file label)
		(save-window-excursion
		  (find-file file)
		  (unless filepair
		    (setq filepair (cons file nil)
			  xref-files (cons filepair xref-files)))
		  (save-excursion
		    (goto-char (point-min))
		    (let ((case-fold-search nil))
		      (if (search-forward (format "name=\"%s\"" label) (point-max) t)
			  (progn
			    (rplacd filepair (cons label (cdr filepair)))
			    (message "%s#%s OK" file label)
			    )
			(error "Label %s not defined in file %s, referenced from %s:%d"
			       label file
			       webmaster:latest-file-in-tree webmaster:latest-url-position)
			))
		    )
		  )))
	  (error "file %s, referenced from %s, byte %d, not found"
		 file
		 webmaster:latest-file-in-tree
		 webmaster:latest-url-position))
	))
     ((string-match "^#\\([-_a-z]+\\)" url)
      (let ((label (substring url (match-beginning 1) (match-end 1))))
	(if (save-excursion
	      (goto-char (point-min))
	      (search-forward (format "name=\"%s\"" label) (point-max) t))
	    (message "Local label %s OK" label)
	  (error "local label %s not defined in %s" label webmaster:latest-file-in-tree)
	  )
	)
      )
     ))
  nil)


(defun check-cross-references ()
  (interactive)
  (setq xref-files nil)
  (webmaster:apply-to-urls-throughout-tree "/usr/home/jcgs/www/thesis/" t
					   '(check-cross-reference))
  (with-output-to-temp-buffer "*Xrefs found*"
    (dolist (file xref-files)
      (princ (format "File %s\n" (car file)))
      (dolist (label (cdr file))
	(princ (format "  %s\n" label))
	)
      )
    ))

(setq reference-targets nil)

(defun reference-target (url)
  "Return the \"reference target\" string for a reference in my thesis."
  (save-match-data
    (let ((pair (assoc url reference-targets)))
      (if pair
	  (cdr pair)
	(if (string-match "^\\([^#/]*\\)#\\(.+\\)$" url)
	    (let ((file (substring url (match-beginning 1) (match-end 1)))
		  (label (substring url (match-beginning 2) (match-end 2))))
	      (if (or (null file) (string= file "")) (setq file (buffer-file-name)))
	      (if (file-exists-p file)
		  (save-window-excursion
		    (find-file file)
		    (save-excursion
		      (goto-char (point-min))
		      (if (re-search-forward (format "name=\"%s\"" label) (point-max) t)
			  (if (re-search-backward "<!-- reference target: \\([.0-9]+\\) -->"
						  (point-min) t)
			      (let ((target (buffer-matched 1)))
				(push (cons url target) reference-targets)
				target))
			(message "label %s not found in %s" label file)
			nil)))
		(message "file %s not found" file)
		nil))
	  (message "URL %s not in the form we want" url)
	  nil)))))

(defun numberize-section-references ()
  (interactive)
  (goto-char (point-min))
  (while (re-search-forward "section <a href=\"\\([^\"]+\\)\">\\([^\"0-9]+\\)</a>"
			    (point-max) t)
    (let* ((reference (buffer-matched 1))
	   (text (buffer-matched 2))
	   (reference-target (reference-target reference))
	   )
      (message "%s %s --> %s" reference text reference-target)
      (replace-match reference-target t t nil 2)
      (if (not (y-or-n-p "OK? ")) (error "bad replacement")
	))))

(defun thesis-fix-heading-caps ()
  (interactive)
  (goto-char (point-min))
  (while (re-search-forward "<h[1-6]><a [^>]+>\\([^<]+\\)</a></h[1-6]>" (point-max) t)
    (goto-char (match-beginning 1))
    (capitalize-word 1)
    (while (< (point) (match-end 1))
      (downcase-word 1))))

;;; end of thesis.el
