After keep working on maintaining our blog at kipuamutay, it's time to improve our tools for writing articles regularly.
Rough edges
The idea of having a blog was always keep writing at least once a month, this process is not so easy when you post in 2 languages (English / Spanish) and besides that we should generate the RSS manually. This post is trying to explain how to remove the rough edges when integrating emacs, our blog, and our hosting service.
Improving Workflow
We have already written Creating a blog with emacs-muse. Nevertheless this process has several manual steps as generating the html articles index and the rss file. . What we would like is once the writing part of the article is finished just use a single function which does:
- Publish the Article
- Copy the first 2 paragraphs and thus adds the entry in the html articles index .
- Generate the rss file from the articles index document.
- Post or upload the generated, modified and/or the source files to the hosting server.
The goal is not so hard and with some emacs lisp we will succeed
Coding some emacs lisp
From the first article we have used the function muse-publish-this-file, same this time.
Index of articles in html from which blog visitors can locate and read blog articles
Our workflow includes blog.muse file aka articles index document
from which the generated
index.html aka html articles index
as well as kipuamutay-news.xml
aka rss file.
(defun kipuamutay/mb-muse2blog-add-index-entry (&optional fname-param) "fullfill the index page (describes every post) It uses a snippet called blogi" (interactive) (let ((oldbuf (current-buffer)) (fname (if fname-param fname-param buffer-file-name)) (file-to-add-entry (concat (file-name-directory fname) "blog.muse"))) (save-current-buffer (if fname (find-file fname) ) (goto-char (point-min)) (mark-paragraph 2) (forward-word) (forward-char) (exchange-point-and-mark) (forward-char -1) (exchange-point-and-mark) (let ((beg (point))) (exchange-point-and-mark) (copy-region-as-kill beg (point))) ;;kill-ring-save equivalent (find-file file-to-add-entry) (goto-char (point-min)) (search-forward "* ") (forward-char -2) ;"* " (insert "blogi") (yas/expand) (yank) ; (current-kill 0) (search-backward "#keywords") (beginning-of-line) (kill-line 2) ; save the buffer (save-buffer) )) )
Adding item to the html index.
We will code a function that publishes the file blog.muse and then pick up the last entry from blog.html and move it to the file index.html finally we modify the link for pointing out to the article URL.
(defun kipuamutay/mb-muse2blog-add-html-entry (&optional fname-sans-path-sans-extension) "publish blog.html add html entry to index.html replaces link with the article url" (interactive) (let* ((cur-dir default-directory) (article-fname (concat cur-dir "blog.muse")) (oldbuf (current-buffer)) (html-src-entry-file (concat default-directory "blog.html")) (html-target-entry-file (concat default-directory "index.html")) (article-name (if fname-sans-path-sans-extension fname-sans-path-sans-extension (file-name-sans-extension (substring buffer-file-name (length (file-name-directory buffer-file-name)))))) ) ;(article-name (file-name-sans-extension (substring buffer-file-name (length (file-name-directory buffer-file-name)))))) (if (not (string= (muse-mp-detect-language article-fname) "NN")) (unless (muse-publish-file article-fname "kipuamutay-blog-xhtml" cur-dir t) (message (concat "The published version is up-to-date; use" " C-u C-c C-T to force an update."))) (message (concat "No language on current directory" " locate the muse file You want to publish."))) (save-current-buffer (find-file html-src-entry-file) (goto-char (point-min)) (search-forward "<div class=\"entry\">") (beginning-of-line) (let ((beg (point))) (search-forward "<div class=\"entry\">" nil t 2)(beginning-of-line)(forward-char -2) (copy-region-as-kill beg (point))) (find-file html-target-entry-file) (goto-char (point-min)) (search-forward "<div class=\"entry\">") (beginning-of-line) (yank) (insert "\n\n") (search-backward "<div class=\"entry\">") (search-forward "_url_url") (let ((beg (point))) (beginning-of-line) (search-forward "_")(forward-char -1)(delete-region beg (point))) (insert article-name) (save-buffer) (set-buffer oldbuf) )) )
Adding entry to the RSS for news readers
We will code a function that publishes the file blog.muse and then pick up the last entry from blog.xml and move it to the file kipuamutay-news.xml finally we modify the links for pointing out to the article URL.
(defun kipuamutay/mb-muse2blog-add-rss-item (&optional fname-sans-path-sans-extension) "publish blog.xml add item to kipuamutay-news.xml replaces links with article url" (interactive) (let* ( (cur-dir default-directory) (article-fname (concat cur-dir "blog.muse")) (oldbuf (current-buffer)) (rss-src-entry-file (concat default-directory "blog.xml")) (rss-target-entry-file (concat default-directory "kipuamutay-news.xml")) (article-name (if fname-sans-path-sans-extension fname-sans-path-sans-extension (file-name-sans-extension (substring buffer-file-name (length (file-name-directory buffer-file-name)))))) ;(article-name (file-name-sans-extension (substring buffer-file-name (length (file-name-directory buffer-file-name))))) (language (muse-mp-detect-language)) (article-url-sans-extension (concat "http://www.kipuamutay.com/" language "/blog/" article-name ))) (if (not (string= (muse-mp-detect-language article-fname) "NN")) (unless (muse-publish-file article-fname "blog-rss" cur-dir t) (message (concat "The published version is up-to-date; use" " C-u C-c C-T to force an update."))) (message (concat "No language on current directory" " locate the muse file You want to publish."))) (save-current-buffer (find-file rss-src-entry-file) (goto-char (point-min)) (search-forward "<item>") (backward-word) (forward-char -1) (let ((beg (point))) (forward-sexp)(copy-region-as-kill beg (point))) (find-file rss-target-entry-file) (goto-char (point-min)) (search-forward "<item>") (backward-word) (forward-char -1) (yank) (insert "\n\n ") (forward-char (- (length "\n\n "))) (backward-sexp) ; blog.html#_Mejorando_el_proceso_de_escribir_articulos_en_el_blog_url_url (let ((beg (point)) ) (forward-sexp) (search-backward "_url_url") (forward-word 2) (let ((beg (point))) (search-backward "blog.html")(copy-region-as-kill beg (point))) (goto-char beg) (forward-sexp) (while (search-backward (current-kill 0) beg t) (replace-match article-url-sans-extension nil t)) ) (save-buffer) (set-buffer oldbuf) )) )
Function for publishing a file to the hosting server given a language
In this function, we use curl and the hosting server login info to publish a file.
(defun kipuamutay/mb-muse2blog-upload-file-to-hosting-server (&optional fname-param) "upload file to kipuamutay host" (interactive) (let* ((oldbuf (current-buffer)) (fname (if fname-param fname-param (substring buffer-file-name (length (file-name-directory buffer-file-name))))) (ftp-host "my-domain.com") (ftp-user "my-user") ;(ftp-pass (read-passwd "ftp password: ")) (ftp-pass (offlineimap-get-password "ftp.my-domain.com" "")) (language (muse-mp-detect-language)) (ftp-dir (concat "public_html" "/" language "/blog/" )) ;;check (ftp-url (format "ftp://%s:%s@%s/%s" ftp-user ftp-pass ftp-host ftp-dir))) (save-current-buffer (message (format "Uploading file : '%s'" fname)) ;; (setq max-mini-window-height 0) (if (not (file-directory-p fname)) (if (not (= 0 (shell-command (concat "curl " "-T \"" fname "\"" " \"" ftp-url "\"")))) (error "Error uploading '%s'" (concat fname)))) (switch-to-buffer "*Uploaded files*") (insert (concat fname "\n")) (set-buffer oldbuf) ) ) )
Putting it all together
This function uses all the functions above. This function means also the goal we set in Improving Workflow.
(defun kipuamutay/mb-muse2blog (&optional fname-param) "publish a file to a host check if we can use this function from emacs shell run this on the blog folder" (interactive) ; publish article (let ((cur-dir default-directory) (fname (if fname-param fname-param buffer-file-name)) ) (if (not (string= (muse-mp-detect-language fname) "NN")) (unless (muse-publish-file fname "kipuamutay-page-html" cur-dir t) (message (concat "The published version is up-to-date; use" " C-u C-c C-T to force an update."))) (message (concat "No language on current directory" " locate the muse file You want to publish."))) ) (let* ( (fname (if fname-param fname-param buffer-file-name)) ; with complete path (fname-sans-path (substring fname (length (file-name-directory fname)))) ; without path (fname-sans-path-sans-extension (file-name-sans-extension fname-sans-path)) ; without path&&without_extension ) ; publish index.html (kipuamutay/mb-muse2blog-add-index-entry fname) ; works on blog.muse (call it from article.muse file) ;(kipuamutay/mb-muse-publish-index-kipu ); publish to a tmp file (blog.html) (kipuamutay/mb-muse2blog-add-html-entry fname-sans-path-sans-extension); mv to index.html ; publish kipuamutay-news.xml ;(kipuamutay/mb-muse-publish-blog-rss); publish to a tmp file blog.rss (kipuamutay/mb-muse2blog-add-rss-item fname-sans-path-sans-extension); move to kipuamutay-news.xml ; upload 4 files to the host server (ask 4 confirmation) (if (y-or-n-p "upload the files? ") (progn (kipuamutay/mb-muse2blog-upload-file-to-hosting-server fname-sans-path) ;.muse (kipuamutay/mb-muse2blog-upload-file-to-hosting-server (concat fname-sans-path-sans-extension ".html")) ;.html (kipuamutay/mb-muse2blog-upload-file-to-hosting-server "index.html") (kipuamutay/mb-muse2blog-upload-file-to-hosting-server "kipuamutay-news.xml") )) ))
That's all for now. On the next post We are going to put our first image.
Last change: 27.12.2012 23:03 |