読者です 読者をやめる 読者になる 読者になる

blechmusikの日記

キー・カスタマイズ・ソフトウェア "DvorakJ" の覚え書きをはじめとして様々なことを書いています。

とある平文テキストのhtmlへの変換処理を emacs で行ってみた

Emacs 雑記

後日追記

続きのエントリー とある平文テキストのhtmlへの変換処理を改良した - blechmusik2の日記 を書いた。


おそらく何度も利用するであろう、とある平文テキストのhtmlへの変換処理を emacs で行ってみた。

(defun make-table-for-info-of-editorials ()
  ;; make-table-for-info-of-editorials
  (interactive)
  (labels ((make-link (link text)
		      (concat
		       "<a href=\""
		       "/resources/hirayama/editorials/"
		       link
		       "\">"
		       text
		       "</a>")
		      ))
    (save-excursion
      (save-restriction
	(dolist (x `(
		     ;; 明治Y年/YYYY の右側のタブを取り除く
		     ("\t\\{5,\\}" "")
		     ("\t" "</td><td>")

		     ;; 各行を <tr></tr> で囲む
		     ("^ </td>\\(.+\\)$"
		      "<tr>\\1</td></tr>")

		     ;; 各年度の項目の見出しを設定する
		     ("<td>\\(和暦\\|西暦\\|月\\|日\\)</td>"
		      "<th>\\1</th>")
		     ("<td>\\(時事・社説・漫言\\|紙面記名\\|全集\\)</td>"
		      "<th>\\1</th>")
		     ("<td>\\(推定起草者\\|推定カテゴリー\\|備考\\)</td>"
		      "<th>\\1</th>")

		     ;; <table> を h3 の前後に追記する
		     ("^\\([^<].+\\)$"
		      ,(concat "</table>"
			       "\n\n"
			       "<h3>\\1</h3>"
			       "\n\n"
			       "<table>"))

		     ;; pdf へのリンクを生成する
		     ("\\(朝鮮国の変乱\\)"
		      ,(make-link "18820309.pdf" "\\1"))
		     ))
	  (goto-char (point-min))
	  (while (re-search-forward (car x) nil t)
	    (replace-match (cadr x))))

	;; バッファのある一行の文字列を取得する - プログラムとかののblog
	;; http://d.hatena.ne.jp/pogin/20120614/1339672095
	(goto-char (point-min))
	(forward-line 1)
	(let ((end-tag-of-table-at-first-line
	       (buffer-substring (point-min) (point))))
	  (delete-region (point-min) (point))
	  (goto-char (point-max))
	  (newline)
	  (insert end-tag-of-table-at-first-line))
	))))

上記の変換処理は4000行強のテキストで2.1秒を要した。少々高速化したいものだ。
計測のために作成した関数はつぎのとおりである。

(defun test ()
  (interactive)
  (labels ((to-number (time)
		      (string-to-number
		       (mapconcat 'identity
				 (mapcar #'(lambda (x)
					     (number-to-string x))
					 time)
				 ""))))
    (let ((start (to-number (current-time))))
      (make-table-for-info-of-editorials)
      (message (concat "result: "
		       (number-to-string
			(/ (- (to-number (current-time)) start)
			   1000000))
		       " sec.")))))