;;; 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 "" tag ">"))
(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 strikethrough
(replace-regexp-in-string
"~~\\(.*\\)~~"
"\\1"
;; Then highlight
(replace-regexp-in-string
"==\\(.*\\)=="
"\\1"
;; Then 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 videos
(replace-regexp-in-string
"!!\\[\\([^\\[]*\\)](\\([^\\[(]*\\))"
(concat (md4tj-begin-tag "video" (list '("src" "\\2") '("type" "video/webm") '("controls" "true"))) "\\1" (md4tj-end-tag "video"))
;; Then emphasis
(replace-regexp-in-string
"\\*\\(.*\\)\\*"
"\\1"
;; Then strong
(replace-regexp-in-string
"\\*\\*\\(.*\\)\\*\\*"
"\\1"
;; First code
(replace-regexp-in-string
"`\\(.*\\)`"
"\\1
" line)))))))))
(defun md4tj-clean-multiline (line)
"Clean LINE of markdown syntax for ul."
(replace-regexp-in-string
"^```" ""
(replace-regexp-in-string
"^[0-9]+\\. " ""
(replace-regexp-in-string "^- " "" line))))
(defun md4tj-clean-code-for-html (line)
"Escape characters in LINE that would be misinterpreted by the browser."
(string-replace
"<" "<"
(string-replace ">" ">" line)))
(defun md4tj-convert-line-to-html (line state)
"Process LINE with STATE and return html."
(let ((cleanline (md4tj-clean-multiline line)))
;; If this is a signal to include another file
(cond ((string-match "^@@INCLUDE" line) (md4tj-parse-to-string (nth 1 (split-string line))))
((string-match "^@@LASTUPDATED" line) (concat "Last updated: " (current-time-string)))
;; If this is some other signal, ignore
((string-match "^@@" line) "")
;; Otherwise, process as normal
(t
(concat
;; Beginning multiline block/ending prev multiline block
(mapconcat #'md4tj-state-to-html state "\n")
;; Body
(cond ((or (eq (nth 1 state) 'code) (eq (nth 1 state) 'begincode)) (md4tj-clean-code-for-html cleanline))
((string-match "^#+ " cleanline) (md4tj-process-header (md4tj-process-line cleanline)))
((string= "---" cleanline) "
\n")
((eq state 'ul) "- ")
((eq state 'ol) "
- ")
((eq state 'code) "")
((eq state 'endul) "