f;;; md4tj_parse --- Summary ;;; Commentary: ;;; Code: (require 'cl-lib) (defun getline () "Get current line from loaded buffer." (buffer-substring-no-properties (line-beginning-position) (line-end-position))) (defun md4tj-begin-tag (tag &optional attrs) "Return beginning html tag for TAG with optional ATTRS." (concat "<" tag (mapconcat 'identity (cl-map 'listp (lambda (l) (concat " " (nth 0 l) "=" (nth 1 l))) attrs) "") ">")) (defun md4tj-end-tag (tag) "Return end html tag for TAG." (concat "")) (defun md4tj-process-header (line) "Process LINE known to be header, return HTML." (let ((level (length (nth 0 (split-string line))))) (if (or (< level 0) (> level 6)) (error (concat "Error parsing: " line "\n")) (concat (md4tj-begin-tag (concat "h" (number-to-string level))) (mapconcat 'identity (cdr (split-string line)) " ") (md4tj-end-tag (concat "h" (number-to-string level))))))) (defun md4tj-process-paragraph (line) "Process LINE that is paragraph, return HTML." (concat (md4tj-begin-tag "p") line (md4tj-end-tag "p"))) (defun md4tj-process-line (line) "Process all inline elements of the LINE, return HTML." ;; Finally links (replace-regexp-in-string "\\[\\(.*\\)\\](\\(.*\\))" (concat (md4tj-begin-tag "a" (list '("href" "\\2"))) "\\1" (md4tj-end-tag "a")) ;; Then images (replace-regexp-in-string "!\\[\\(.*\\)\\](\\(.*\\))" (md4tj-begin-tag "img" (list '("src" "\\2") '("alt" "\\1"))) ;; Then emphasis (replace-regexp-in-string "\\*\\(.*\\)\\*" "\\1" ;; Then strong (replace-regexp-in-string "\\*\\*\\(.*\\)\\*\\*" "\\1" ;; First code (replace-regexp-in-string "`\\(.*\\)`" "\\1" line)))))) ;; Note: a "block" is the smallest unit of parsing ;; It is normally a line of the code, but can be ;; multiple lines in the case of a block (NI) (defun md4tj-process-block (codeblock) "Process CODEBLOCK and return html." (cond ((string-match "^# " codeblock) (md4tj-process-header codeblock)) (t (md4tj-process-paragraph codeblock)))) (defun md4tj-parse (mdfile outfile) "Entry point to parse MDFILE and output to OUTFILE." (with-temp-buffer (insert-file-contents mdfile) (goto-char (point-min)) (while (< (point) (point-max)) (md4tj-process-block (getline)) (forward-line)))) (provide 'md4tj_parse) ;;; md4tj_parse.el ends here