diff --git a/feed.xml b/feed.xml new file mode 100644 index 0000000..8aac30f --- /dev/null +++ b/feed.xml @@ -0,0 +1 @@ +RSS Testhttp://example.comAn example blog for testing RSS capability of md4tj.en-USTue, 10 Jun 2003 04:00:00 GMTeditor@example.comwebmaster@example.comhttps://www.rssboard.org/rss-specificationmd4tj-rss.elMon, 10 Jul 2023 08:50:16 GMTBlog Post 2j4nkhttps://example.com/blog/blogpost2.htmlhttps://example.com/blog/blogpost2.htmlThu, 02 Mar 2023 19:44:50 ESTBlog Post 1j4nkhttps://example.com/blog/blogpost1.htmlhttps://example.com/blog/blogpost1.htmlThu, 02 Mar 2023 19:44:14 EST \ No newline at end of file diff --git a/md4tj.el b/md4tj.el index 026c9c5..702fb6e 100644 --- a/md4tj.el +++ b/md4tj.el @@ -94,8 +94,8 @@ "`\\(.*\\)`" "\\1" line))))))))) -(defun md4tj-convert-line-to-html (line state inbuf) - "Process LINE with STATE and return html, INBUF provided." +(defun md4tj-convert-line-to-html (line state inbuf outfile) + "Process LINE with STATE and return html, INBUF provided with OUTFILE." (let ((cleanline (md4tj-util-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)))) @@ -106,6 +106,7 @@ ((string-match "^@@DIV" line) (md4tj-begin-tag "div" (list (list "class" (nth 1 (split-string line)))))) ((string-match "^@@ENDDIV" line) (md4tj-end-tag "div")) ((string-match "^@@BLOGINSERT" line) (with-current-buffer inbuf (md4tj-blog-html))) + ((string-match "^@@RSSINSERT" line) (md4tj-rss-link-string (md4tj-rss-file-from-outfile outfile))) ((and (string-match "^$$.*$$" line) (eq (nth 1 state) 'normal)) ;; LaTeX formula (shell-command (concat "./pnglatex" " -d 300" @@ -234,6 +235,8 @@ (set-buffer inbuf) (insert-file-contents mdfile) (goto-char (point-min)) + ;; If we need RSS, go ahead and output the XML file here + (if (md4tj-rss-needs-rss) (md4tj-rss-to-file mdfile (md4tj-rss-file-from-outfile outfile))) (set-buffer outbuf) (insert (md4tj-begin)) (insert (with-current-buffer inbuf (md4tj-head))) @@ -242,7 +245,7 @@ (setq line (with-current-buffer inbuf (md4tj-util-getline))) (setq fullstate (md4tj-next-state line (nth 1 fullstate))) ;; Insert next line(s) into output file - (let ((linehtml (md4tj-convert-line-to-html line fullstate inbuf))) + (let ((linehtml (md4tj-convert-line-to-html line fullstate inbuf outfile))) (insert (concat linehtml (if (string-empty-p linehtml) "" "\n")))) ;; Advance input file by a line (with-current-buffer inbuf (forward-line))) @@ -264,7 +267,7 @@ (while (< (point) (point-max)) (setq line (md4tj-util-getline)) (setq fullstate (md4tj-next-state line (nth 1 fullstate))) - (setq acc (concat acc (md4tj-convert-line-to-html line fullstate nil) "\n")) + (setq acc (concat acc (md4tj-convert-line-to-html line fullstate nil nil) "\n")) (forward-line)) acc))) @@ -369,9 +372,9 @@ (goto-char (point-min)) (if (search-forward-regexp "^@@RSSENABLE" nil t) t nil))) -(defun md4tj-rss-begin-tag (tag &optional attrs) - "Return the RSS text for TAG with ATTRS." - (concat "<" tag (mapconcat (lambda (attr) (concat " " (nth 0 attr) "=" "\"" (nth 1 attr) "\"")) attrs "") ">")) +(defun md4tj-rss-begin-tag (tag &optional attrs self-close) + "Return the RSS text for TAG with ATTRS, SELF-CLOSE if necessary." + (concat "<" tag (mapconcat (lambda (attr) (concat " " (nth 0 attr) "=" "\"" (nth 1 attr) "\"")) attrs "") (if self-close "/" "") ">")) (defun md4tj-rss-end-tag (tag) "Return the RSS text for ending TAG." @@ -394,23 +397,67 @@ "Generate RSS syntax for RSS channel statement tokenized to TOKS." (concat (md4tj-rss-begin-tag (car toks)) (mapconcat #'identity (cdr toks) " ") (md4tj-rss-end-tag (car toks)))) -(defun md4tj-rss-channel () - "Return the RSS text for channel in current buffer." +(defun md4tj-rss-channel (rsslink) + "Return the RSS text for channel in current buffer with RSSLINK." (concat (md4tj-rss-begin-tag "channel") + ;;(md4tj-rss-begin-tag "atom:link" (list (list "href" rsslink) (list "rel" "self") (list "type" "application/rss+xml")) t) (mapconcat #'md4tj-rss-channel-statement-toks-to-rss (md4tj-rss-get-channel-statements) "") (md4tj-rss-begin-tag "docs") "https://www.rssboard.org/rss-specification" (md4tj-rss-end-tag "docs") (md4tj-rss-begin-tag "generator") "md4tj-rss.el" (md4tj-rss-end-tag "generator") (md4tj-rss-begin-tag "lastBuildDate") (format-time-string "%a, %d %b %Y %H:%M:%S GMT") (md4tj-rss-end-tag "lastBuildDate") (md4tj-rss-end-tag "channel"))) -(defun md4tj-rss () - "Return the RSS text for the current buffer." +;; Elt is triple of +;; Title +;; Time +;; Link +(defun md4tj-rss-item (elt) + "Return RSS for ELT." + (concat (md4tj-rss-begin-tag "item") + (md4tj-rss-begin-tag "title") (nth 0 elt) (md4tj-rss-end-tag "title") + ;; NOTE: change "j4nk" to author name + (md4tj-rss-begin-tag "author") "j4nk" (md4tj-rss-end-tag "author") + (md4tj-rss-begin-tag "link") (nth 2 elt) (md4tj-rss-end-tag "link") + (md4tj-rss-begin-tag "guid") (nth 2 elt) (md4tj-rss-end-tag "guid") + (md4tj-rss-begin-tag "pubDate") (format-time-string "%a, %d %b %Y %H:%M:%S %Z" (string-to-number (nth 1 elt))) (md4tj-rss-end-tag "pubDate") + (md4tj-rss-end-tag "item"))) + +(defun md4tj-rss-items () + "Return all RSS for all elements." + (mapconcat 'md4tj-rss-item (md4tj-blog-all-blogs-list) "")) + + + +(defun md4tj-rss (rsslink) + "Return the RSS text for the current buffer at RSSLINK." (save-excursion (when (md4tj-rss-needs-rss) (concat (md4tj-rss-begin) - (md4tj-rss-channel) + (md4tj-rss-channel rsslink) + (md4tj-rss-items) (md4tj-rss-end-tag "rss"))))) + +(defun md4tj-rss-to-file (infile outfile) + "Write INFILE as RSS to OUTFILE." + (with-temp-buffer + (insert-file-contents infile) + (let ((outbuf (generate-new-buffer " outbuf" t)) + (rss-str (md4tj-rss (concat (md4tj-blog-base-url) "/feed.xml")))) + (set-buffer outbuf) + (insert rss-str) + (write-region nil nil outfile nil)))) + +(defun md4tj-rss-link-string (rsslink) + "Return the html of RSS link to RSSLINK as string." + (concat (md4tj-begin-tag "div" (list (list "id" "rssicon"))) (md4tj-begin-tag "a" (list (list "href" rsslink))) (md4tj-begin-tag "img" (list (list "src" "rss.png") (list "alt" "RSS icon") (list "style" "width:20px;height:20px;"))) (md4tj-end-tag "img") (md4tj-end-tag "a") (md4tj-end-tag "div"))) + +(defun md4tj-rss-file-from-outfile (outfile) + "Return the filename that the RSS XML should be output to given OUTFILE." + (concat (file-name-directory outfile) "/feed.xml")) + + + ;; End md4tj rss stuff (provide 'md4tj) diff --git a/rss.png b/rss.png new file mode 100644 index 0000000..ad6c561 Binary files /dev/null and b/rss.png differ diff --git a/test_blog.html b/test_blog.html index aaab687..4bcefbb 100644 --- a/test_blog.html +++ b/test_blog.html @@ -4,6 +4,7 @@ + Test blog @@ -18,11 +19,8 @@ -
-

Blogs

- -
+RSS icon

Blog Post 2

2023 March 02 19:44
diff --git a/test_blog.md4tj b/test_blog.md4tj index 212dc4c..ba8a0c5 100644 --- a/test_blog.md4tj +++ b/test_blog.md4tj @@ -9,9 +9,8 @@ @@RSSCHANNELmanagingEditor editor@example.com @@RSSCHANNELwebMaster webmaster@example.com @@TITLE Test blog - # Blogs - +@@RSSINSERT @@BLOGBASEURL https://example.com/blog/ @@BLOGBASEDIR ./blog/ @@BLOGINSERT diff --git a/test_file.html b/test_file.html index d156cf5..28c7c7d 100644 --- a/test_file.html +++ b/test_file.html @@ -75,7 +75,7 @@ int main() {

This is a div that has monospace text.

-

Last updated: Sun Jul 9 19:26:42 2023

+

Last updated: Mon Jul 10 08:35:47 2023