org-modeのexportで文字の装飾が出力されない

org-modeの文字の装飾

テスト用のファイルをexportさせていると

*太字*
/斜体/
_下線付き_
+取消線付き+
~等幅~

と書かれた内容が出力されない。はてな記法自体に対応する記法は存在していないが、何も出力されないのはよろしくない。そのため、ox-hatena.elに下記を追加してみた。

(org-export-define-backend 'hatena
 ...
    (bold . org-hatena-bold)
    (italic . org-hatena-italic)
    (underline . org-hatena-underline)
    (verbatim . org-hatena-verbatim)
    (strike-through . org-hatena-strike-through)
 ...
)

;;;;; Bold
(defun org-hatena-bold (bold contents info)
  (format "%s" contents))
;;;;; Italic
(defun org-hatena-italic (italic contents info)
  (format "%s" contents))
;;;;; Underline
(defun org-hatena-underline (underline contents info)
  (format "%s" contents))
;;;;; verbatim
(defun org-hatena-verbatim (verbatim contents info)
  (format "%s" contents))
;;;;; Strike-through
(defun org-hatena-strike-through (strike-through contents info)
  (format "%s" contents))

これで試してみたら、大体は出力された。んが、等幅(verbatim)が出力されない。

等幅(verbatim)が出力されない原因

ox-ascii等では出力されるため原因を調べはじめると、そもそもox-asciiでorg-ascii-verbatimが呼ばれていない。verbatimなのにorg-ascii-codeが呼ばれている。試しに、

(code . org-hatena-code)
   ...
;;;;; Code
(defun org-hatena-code (code contents info)
  (format "%s" (org-element-property :value code)))

を追加してみると、等幅(verbatim)が出力された。何じゃそれ、と叫んでしまった。
これを確認したのは、org-versinは"8.2.7b"です。たぶんorg-modeのバグです。

codeの存在を知る

=コード=

と言う表記もあるそうだ。で、同じようにox-asciiで動きを確認してみる。

M-x debug-on-entry org-ascii-code
M-x debug-on-entry org-ascii-verbatim

として

=code=

をasciiでexportすると*Backtrace* は

org-ascii-verbatim((verbatim (:value "code" :begin 1 .....
org-export-data((verbatim (:value "code" :begin  ......

となって、案の定、org-ascii-verbatimが呼ばれている。そこで、

 ...
    (verbatim . org-hatena-verbatim)
 ...
(defun org-hatena-verbatim (verbatim contents info)
  (format "%s" (org-element-property :value verbatim)))

としてみたが、hatenaで出力されるときだけ呼ばれない。ここで、原因がわからずに時間を費やして、ようやくわかった。

orgの記法で書いたhowmのファイルからhowmのタイトル行を、export時に消去する正規表現がマッチしてしまっていた。howmで定義されている正規表現を持ってきて、間違いがないようにした。

(defun my-headline-removal (backend)
  (interactive)
  (when (eq backend 'hatena)
  (goto-char (point-min))
  (while (re-search-forward "^=\\( +\\(.*\\)\\|\\)$\\|^\\[[1-2][0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9][ \t]?\\([0-2][0-9]:[0-5][0-9]\\)?\\]" nil t)
    (goto-char (match-beginning 0))
      (kill-whole-line)
	(goto-char (point-at-bol)))))
(add-hook 'org-export-before-processing-hook 'my-headline-removal)

これで、ようやくcodeも出力することが出来た。

文字装飾

装飾した文字を出力できる様になったが、装飾内容を削除した状態で出力しているので、良くない。はてなダイアリーはHTMLタグを直接書くことも許容しているようなので

;;;;; Bold
(defun org-hatena-bold (bold contents info)
  (format "<b>%s</b>" contents))
;;;;; Italic
(defun org-hatena-italic (italic contents info)
  (format "<i>%s</i>" contents))
;;;;; Underline
(defun org-hatena-underline (underline contents info)
  (format "<span style=\"text-decoration: underline;\">%s</span>" contents))
;;;;; Code
(defun org-hatena-code (code contents info)
  (format "<code>%s</code>" (org-element-property :value code)))
;;;;; verbatim
(defun org-hatena-verbatim (verbatim contents info)
  (format "<code>%s</code>" (org-element-property :value verbatim)))

とした。これで
太字
斜体
下線付き
取消線付き
等幅
コード
とそれなりに出力する様になった。