;; If not, see <http://www.gnu.org/licenses/>.
-(defconst hatena-version "2.0" "Version number of hatena.el")
+(defconst hatena-version "2.2.0" "Version number of hatena.el")
;; ¢£¥¤¥ó¥¹¥È¡¼¥ëÊýË¡
;; 1) ŬÅö¤Ê¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤³¤Î¥Õ¥¡¥¤¥ë¤ò¤ª¤¯.
;; `hatena-insert-webdiary' ¤Ï¤Æ¤Ê¥Ð¥Ã¥Õ¥¡¤Ç¼Â¹Ô¤¹¤ë¤È¡¢¸½ºß web ¤Ë
;; ¥¢¥Ã¥×¤µ¤ì¤Æ¤¤¤ë¥Õ¥¡¥¤¥ë¤ò¼è¤Ã¤Æ¤¯¤ë¡£ o
;; `hatena-twitter' Æüµ¹¹¿·»þ¤ËTwitter¤ËÄÌÃΤ¹¤ë¤«¤É¤¦¤«¤òÊѤ¨¤Þ¤¹¡£
+;;¡¡¡¡`hatena-image-insert' ¤Ï¤Æ¤Ê¥Õ¥©¥È¥é¥¤¥Õ¤Ë²èÁü¤ò¥¢¥Ã¥×¥í¡¼¥É¤·
+;; ¥¨¥ó¥È¥ê¤Ë²èÁüɽ¼¨ÍѤΥ¿¥°¤òÁÞÆþ¤·¤Þ¤¹¡£
+;; `hatena-get-webdiary' http://d.hatena.ne.jp/usrid/export ¤ò
+;; ¼è¤Ã¤Æ¤¤ÆÊÑ´¹¡£Â¤ê¤Ê¤¤ÆüµÊ¬¤ò¥Õ¥¡¥¤¥ë¤Ë¤¹¡£
;;
;; 4) ¾å°Ì¥â¡¼¥É
;; hatena-diary-mode ¤Ï¥Ç¥Õ¥©¥ë¥È¤Ç html-mode ¤ËÈ碌¤Æ¤¤¤Þ¤¹¡£¤³¤ì¤ò
;; (goto-char (point-min))
;; (replace-regexp "\\([^\n]\\)\n\\([^\n]\\)" "\\1\\2")))
;;
+;; `hatena-diary-mode-before-submit-hook' Æüµ¤ò¥Ý¥¹¥È `hatena-submit' ¤¹¤ë
+;; ľÁ°¤Ë¸Æ¤Ó½Ð¤¹´Ø¿ô¤Ç¤¹¡£`hatena-diary-mode-submit-hook' ¤È¤Ï°ã¤¤¡¢
+;; ¤³¤Î¥Õ¥Ã¥¯¤Ç²Ã¤¨¤é¤ì¤¿Êѹ¹¤Ï¼ê¸µ¤Î¥Õ¥¡¥¤¥ë¤Ë¤â»Ä¤ê¤Þ¤¹¡£
(require 'hatena-vars)
(define-key hatena-diary-mode-map "\C-c\C-b" 'hatena-find-previous)
(define-key hatena-diary-mode-map "\C-c\C-f" 'hatena-find-following)
(define-key hatena-diary-mode-map "\C-ct" 'hatena-change-trivial)
+ (define-key hatena-diary-mode-map "\C-c\C-i" 'hatena-image-insert)
(define-key help-map "4" 'hatena-help-syntax1)
(define-key help-map "5" 'hatena-help-syntax2)
(define-key help-map "6" 'hatena-help-syntax3)
(format-time-string "%Y%m%d"
(apply 'encode-time lst ))))
+(defun hatena-w3c-dtf-time-zone-designator (&optional time universal)
+ (save-match-data
+ (let ((time (or time (current-time))))
+ (let ((tzd (format-time-string "%z" time universal)))
+ (if universal
+ "Z"
+ (if (string-match "\\`\\([-+][0-9][0-9]\\)\\([0-9][0-9]\\)\\'"
+ tzd)
+ (concat (match-string-no-properties 1 tzd) ":"
+ (match-string-no-properties 2 tzd))
+ (error (concat "Unexpected return value of "
+ "(format-time-string \"%%z\" time universal): %s")
+ (prin1-to-string tzd))))))))
+
+(defun hatena-w3c-dtf-string (&optional time universal)
+ ;; ref. "Date and Time Formats" <http://www.w3.org/TR/NOTE-datetime>.
+ (let ((time (or time (current-time))))
+ (concat (format-time-string "%Y-%m-%dT%T" time universal)
+ (hatena-w3c-dtf-time-zone-designator time universal))))
+
+(defun hatena-set-datetime-attribute-to-ins-and-del-elements ()
+ "¥Ð¥Ã¥Õ¥¡Æâ¤Î¤¹¤Ù¤Æ¤ÎINSÍ×ÁÇ¡¦DELÍ×ÁǤ˸½ºß»þ¹ï¤ÎDATETIME°À¤ò
+¥»¥Ã¥È¤¹¤ë¡£´û¤ËDATETIME°À¤¬¥»¥Ã¥È¤µ¤ì¤Æ¤¤¤ëÍ×ÁǤÏÊѹ¹¤·¤Ê¤¤¡£"
+ (save-excursion
+ (save-restriction
+ (save-match-data
+ (widen)
+ (goto-char (point-min))
+ (while (re-search-forward
+ "<\\(ins\\|del\\)\\([ \t\r\n]*\\|[ \t\r\n]+[^>]+?\\)>" nil t)
+ (replace-match
+ (if (save-match-data
+ (string-match "[ \t\r\n]datetime[ \t\r\n]*=[ \t\r\n]*['\"]"
+ (match-string 0)))
+ (match-string 0)
+ (concat "<"
+ (match-string 1) ;"ins" or "del"
+ " datetime=\"" (hatena-w3c-dtf-string) "\""
+ (match-string 2) ;attributes
+ ">"))))))))
+
(defun hatena-submit (&optional file userid)
"¤Ï¤Æ¤ÊÆüµ http://d.hatena.ne.jp/ ¤Ë post ¥á¥½¥Ã¥É¤ÇÆüµ¤òÁ÷¤ë. curl ¤ò»È¤¦. "
(interactive)
(if file nil
(setq file buffer-file-name)
(save-excursion
+ (run-hooks 'hatena-diary-mode-before-submit-hook)
;;"*t*" ¤Ë¤¹¤ë¤« "*pn*" ¤Ë¤¹¤ë¤«
(cond ( (= hatena-entry-type 0)
(progn
(replace-match
(concat "*" (hatena-current-second i) "*")
(setq i (1+ i))
- ))))
+ )))
+ ;; INSÍ×ÁÇ¡¦DELÍ×ÁǤ˸½ºß»þ¹ï¤ÎDATETIME°À¤ò¥»¥Ã¥È¤¹¤ë¡£
+ (hatena-set-datetime-attribute-to-ins-and-del-elements))
(save-buffer))
(if (not userid)
(call-process hatena-curl-command nil nil nil
"-k" "-c" hatena-cookie
"-x" hatena-proxy
- "-d" (concat "name=" hatena-usrid)
- "-d" (concat "password=" password)
+ "-d" (concat "name=" (hatena-url-encode-string hatena-usrid))
+ "-d" (concat "password=" (hatena-url-encode-string password))
"-d" (concat "autologin=1")
"-d" (concat "mode=enter")
"https://www.hatena.ne.jp/login"))
(describe-variable 'hatena-help-syntax-other))
+(defun hatena-image-insert (filename filesize)
+ "²èÁü¤ò¤Ï¤Æ¤Ê¥Õ¥©¥È¥é¥¤¥Õ¤Ë¥¢¥Ã¥×¥í¡¼¥É¤·¡¢Æüµ¤ËÁÞÆþ¤¹¤ë"
+ (interactive "fImage File:\nsFile Size:")
+ (let*
+ ((extension (upcase (substring filename (- (length filename) 3))))
+ (baseurl (concat "http://f.hatena.ne.jp/" hatena-usrid "/"))
+ (url (concat baseurl "up"))
+ (rkm
+ (let* ((md5sum (md5 (with-temp-buffer
+ (insert-file-contents hatena-cookie)
+ (re-search-forward "rk\\s \\([0-9a-zA-Z]+\\)")
+ (concat (buffer-substring
+ (match-beginning 1)
+ (match-end 1)))) nil nil 'utf-8))
+ (p 0)
+ (temp ""))
+ (while (> (length md5sum) p)
+ (setq temp
+ (concat
+ temp
+ (char-to-string (string-to-number
+ (substring md5sum p (+ p 2)) 16))))
+ (setq p (+ p 2)))
+ (substring (base64-encode-string temp) 0 22))))
+ (cond
+ ((or (string= extension "JPG") (string= extension "GIF") (string= extension "PNG"))
+ (with-temp-buffer
+ (call-process hatena-curl-command nil t nil
+ "-L"
+ "-b" hatena-cookie
+ "-x" hatena-proxy
+ "-F" (concat "rkm=" rkm)
+ "-F" "mode=enter"
+ "-F" "fototitle1="
+ "-F" (concat "size=" filesize)
+ "-F" "taglist="
+ "-F" (concat "image1=@" (expand-file-name filename))
+ url)
+ (goto-char (point-min))
+ (re-search-forward "check-\\([0-9]+\\)")
+ (setq hatena-photo (concat "[f:id:" hatena-usrid ":" (buffer-substring
+ (match-beginning 1)
+ (match-end 1)
+ ) "j:image]")))
+ (insert hatena-photo)
+ (newline)
+ (insert-image (create-image (expand-file-name filename)))
+ ))))
+
+
(provide 'hatena-diary-mode)
;;;;;end of file