;;; emacs-wiki-code-gen.el --- Code archives generator for c,asm,lisp files based on Mark Triggs Work
;; Author: Anirudh Sasikumar <an1sk@hotmail.com>
;; Original: Mark Triggs (http://dishevelled.net)
;; Version: 0.2
;; URL: http://www.aloofhosting.com/anisk/code/emacs-wiki-code-gen.el

;; This file is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.

;; This file is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING.  If not, write to
;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.

;;; Commentary:

;; This file is for use within emacs-wiki-mode only.
;; Generates a list of files with the option of publishing them to html 
;; using html-fontify in emacs-wiki-mode using a codearchive tag. 
;; Needs SatyaKid's implementation of html-fontify for wiki files.
;; Read http://www.aloofhosting.com/anisk/blog/2004.07.02.html
;; Examples: 
;; <codearchive path="~/publishcode/cfiles/" mode="c-mode" 
;; publish="true">
;; Please forward any errors/bugs/improvements (there are bound to be many) 
;; you have to my email address.

;;; Code:

(defvar emacs-wiki-code-path "~/cfiles/")

(defvar emacs-wiki-code-exclude-regexp 
"[voidnt]+ main()\\|else if[ ]*()\\|if[ ]*()\\|for[ ]*()\\|while[ ]*()\\|switch[ ]*()")

(defun clean (reg str)
  (replace-regexp-in-string reg "" str))

(defun emacs-wiki-code-htmlify (code-path h-mode fname) 
"Create HTML markup for C,C++,Assembly and Elisp files"
(let (buffer-read-only)
  ;automatically restores current buffer after our job 
  ;is done
  (with-current-buffer 
    (set-buffer (generate-new-buffer "*CodeHTML*"))
    ;path for stylesheet changes in code folder
    ;alternate header with menu also having new path
    (insert "#style ../style.css\n"	    
	    "#head headerarch.wiki\n"
	    "#foot footerarch.wiki\n\n"
	    "<fontlock mode=\"" 
	    h-mode "\">\n")
    (setq temppoint (point))
    (insert-file-contents (concat code-path fname))
    (goto-char (point-max))
    (insert "\n<" "/fontlock" ">")
    (emacs-wiki-replace-markup fname)
    (goto-char (point-min))
    ;write the html file
    (let ((backup-inhibited t))
      (write-file
       (expand-file-name  (concat fname ".html")
			  (concat emacs-wiki-publishing-directory
				  "/code"))))
    (kill-buffer (current-buffer))
    )))
 
;;real func
(defun emacs-wiki-code-generate (&optional code-path
code-highlight-mode createhtml) 
"Generate a numbered list of C,C++,Assembly or Elisp files chosen 
using code-highlight-mode in code-path with details and 
function list.If createhtml is set uses emacs-wiki-code-htmlify to create 
html version of all code files." 
(if code-path (setq emacs-wiki-code-path code-path))
(let ((h-mode "c-mode") (filecounter 0) (resfunc " ")
      (filefilter "^[^.].*\\.cpp$\\|^[^.].*\\.c$\\|^[^.].*\\.cc$\\|^[^.].*\\.h$"))
 ;mode defaults to c-mode  
  (if code-highlight-mode (setq h-mode code-highlight-mode))
 ;set the proper file filters depending on the mode chosen
  (if (string= h-mode "asm-mode") (setq filefilter "^[^.].*\\.asm$"))
  (if (string= h-mode "emacs-lisp-mode") (setq filefilter "^[^.].*\\.el$"))
  (mapconcat
   (lambda (file)
     (let (
	  ;first line having format //filename --- detail
	   (header
	    (with-temp-buffer
	      (insert-file (concat emacs-wiki-code-path file))
	      (delete-non-matching-lines
	       (concat "^[\\*/; ]* " file " --\\(-\\)? "))
	      (replace-regexp-in-string
	       (concat "^[\\*/; ]* " file " --- \\(.*\\)$") "\\1"
	       (buffer-string))))
	   (functions
	    (with-temp-buffer
	      (insert-file (concat emacs-wiki-code-path file))
	     ;for c-mode only
	      (if (not (string= h-mode "c-mode")) (setq resfunc nil)
		(delete-non-matching-lines 
		 "^[a-zA-Z \\*]+ [A-Za-z_0-9 \\*]+(.*)[ ]*$")
		(let ((acc (mapconcat
			    'identity
			    (split-string
			     (replace-regexp-in-string
			      "\\(^[a-zA-Z \\*]+ [A-Za-z_0-9 \\*]+\\)(.*)[ ]*$"
			      "\\1()"
			      (buffer-string)) " ") " ")))
	          ;housekeeping
		  (setq acc (clean emacs-wiki-code-exclude-regexp acc))
		  (setq acc 
			(replace-regexp-in-string "[\n][\n]+" "\n" 
						  (clean "[ ][ ]+" acc)))
		  (setq acc (clean "^\n" acc))
		 ;housekeeping done
		  (if (or (string= acc "") (< (length acc) 3))
		      (setq resfunc nil)
		    (setq resfunc acc))));end of c-mode
	      (if (not (string= h-mode "emacs-lisp-mode")) resfunc
		(delete-non-matching-lines "^ *(defun [^ ]+ ")
		(let ((acc (mapconcat
			    'identity
			    (split-string
			     (replace-regexp-in-string
			      "^.*(defun \\([^ ]+\\) .*$"
			      "(defun \\1)"
			      (buffer-string)) " ") " ")))
		  (if (string= acc "")
		      (setq resfunc nil)
		    (setq resfunc acc))
		  ));end of emacs-lisp-mode
	      )))
       (if createhtml  
	   (emacs-wiki-code-htmlify emacs-wiki-code-path h-mode file))
       (concat ani-wiki-begin-frame-code
	       (int-to-string (setq filecounter (+ filecounter 1))) ". " file " "	      
	       (if createhtml 
		   (concat "<a href=\"code/" file ".html\">View</a>")
		 "<code> [Not yet ready for publication] </code>")
	       (if (> (length header) 0)
		   (concat "<br /><strong>Details:</strong> " header)
		 "")
	       "<br />"
	       (format "<strong>Size:</strong> %s bytes "
		       (nth 7 (file-attributes ;; size
			       (file-truename
				(concat emacs-wiki-code-path file)))))
	       (format "<strong>Last modified:</strong> %s <br />"
		       (format-time-string "%B %e, %Y %l:%M %p"
					   (nth 5 (file-attributes ;; last modification time
						   (file-truename
						    (concat emacs-wiki-code-path file))))))
	       (if functions
		   (concat "<strong>Functions:</strong><br />\n"
			   "<fontlock mode=\"" h-mode "\">\n"  
			   functions "<" "/fontlock" ">")
		 "") 
	       ani-wiki-end-frame-code "\n<br />")))
   (remove-if-not
    (lambda (file) (string-match filefilter file))
    (sort (directory-files emacs-wiki-code-path) 'string<)) "\n")))

;;For my c code archive generator
(defun emacs-wiki-codearchive-tag (beg end attrs)
  (let ((c-path emacs-wiki-code-path) (fontlockmode "c-mode"))                           
    (if (cdr (assoc "path" attrs)) 
	(setq c-path (cdr (assoc "path" attrs))))
    (if (cdr (assoc "mode" attrs)) 
	(setq fontlockmode (cdr (assoc "mode" attrs))))
    (save-excursion)
    ;;if there is a publish attribute, then create htmlified file
    (if (cdr (assoc "publish" attrs)) 
	(insert (emacs-wiki-code-generate c-path fontlockmode t))
      (insert (emacs-wiki-code-generate c-path fontlockmode)))
    (goto-char end)))

(push '("codearchive" nil t nil emacs-wiki-codearchive-tag) emacs-wiki-markup-tags)

Copyright © 2004-2011 Anirudh Sasikumar. All rights reserved.
Last Updated: November 29, 2011 4:41 PM