" howm-mode.vim の action-lock に「はてなダイアリー」の isbn/asin 記法
" (isbnにしか正式対応してないです)ぽいものを追加する設定ファイル
scriptencoding utf-8
let s:save_cpoptions = &cpoptions
set cpo&vim
if v:version < 700 ||
\ !has('multi_byte') ||
\ !has('iconv') ||
\ executable('curl') != 1
let &cpoptions = s:save_cpoptions
finish
endif
function! HowmActionlockIsbn(str, head)
let pat = '^\Cisbn:\(\%(\d\{13}\)\|\%(\d\{9}[0-9xX]\)\):detail$'
let isbn = substitute(a:str, pat, '\1', '')
if s:is_isbn10(isbn)
let isbn = s:isbn10to13(isbn)
endif
if !s:is_isbn13(isbn) | return | endif
let asin = s:isbn13toasin(isbn)
" parse
let hatena_url = 'http://d.hatena.ne.jp/asin/' . asin
let body = system('curl ' . hatena_url)
let body = iconv(body, 'euc-jp', &enc)
let body = get(matchlist(body, '
\(\_.*\)'), 1, '')
let title = get(matchlist(body, '\(.\{-}\)
'), 1, '')
let pat = ''
let list_s = get(matchlist(body, pat), 1, '')
let list = split(substitute(list_s, '\%(\r\|\n\|\)', '', 'g'), '')
let dict = {'作者': '', '出版社': '', '発売日': '', 'メディア': ''}
for li in list
for key in keys(dict)
if li =~ key
let s = li
let s = substitute(s, '', '', 'g')
let s = substitute(s, '\{0,1}.\{-}>', '', 'g')
let dict[key] = s
endif
endfor
endfor
let dict['はてな'] = hatena_url
let dict['タイトル'] = title
" output
let s = "%タイトル%\n%作者%\n%出版社%\n%発売日%\n%メディア%\n%はてな%\n"
let s = substitute(s, '%\(.\{-}\)%', '\=s:ss(dict, submatch(1))', 'g')
let p = '\C\(isbn:\)\d\{9}[0-9xX]\(:detail\)'
call setline('.', substitute(getline('.'), p, '\1' . isbn . '\2', 'g'))
call append(line('.'), split(s, "\n", 1))
endfunction
if !exists('g:howm_actionlock_list') | let g:howm_actionlock_list = [] | endif
call add(g:howm_actionlock_list, {'func': function('HowmActionlockIsbn'),
\ 'pat': '\Cisbn:\%(\%(\d\{13}\)\|\%(\d\{9}[0-9xX]\)\):detail' })
" script local functions {{{
function! s:ss(dict, s)
for key in keys(a:dict)
if a:s == key | return get(a:dict, key, '') | endif
endfor
return '%'
endfunction
function! s:get_isbn10_cdigit(isbn)
if a:isbn !~# '\d\{9}' | return 0 | endif
let sum = 0
for i in range(9)
let n = substitute(a:isbn, '^\d\{' . i . '}\(\d\)\d*$', '\1', '')
let sum = sum + n * (10 - i)
endfor
let cdigit = (11 - (sum % 11))
if cdigit == 10
let cdigit = 'X'
elseif cdigit == 11
let cdigit = '0'
else
let cdigit = string(cdigit)
endif
return cdigit
endfunction
function! s:get_isbn13_cdigit(isbn)
if a:isbn !~# '\d\{12}' | return 0 | endif
let sum = 0
for i in range(12)
let n = substitute(a:isbn, '^\d\{' . i . '}\(\d\)\d*$', '\1', '')
let sum = sum + n * (i % 2 == 0 ? 1 : 3)
endfor
let cdigit = (10 - (sum % 10))
let cdigit = string(cdigit == 10 ? 0 : cdigit)
return cdigit
endfunction
function! s:is_isbn10(s)
if a:s !~# '^\d\{9}[0-9xX]$' | return 0 | endif
let isbn10 = substitute(a:s, '^\(\d\{9}\)\([0-9xX]\)$', '\1', '')
let cdigit = substitute(a:s, '^\(\d\{9}\)\([0-9xX]\)$', '\2', '')
return (cdigit =~? s:get_isbn10_cdigit(isbn10))
endfunction
function! s:is_isbn13(s)
if a:s !~# '^\d\{13}$' | return 0 | endif
let isbn13 = substitute(a:s, '^\(\d\{12}\)\(\d\)$', '\1', '')
let cdigit = substitute(a:s, '^\(\d\{12}\)\(\d\)$', '\2', '')
return (cdigit =~? s:get_isbn13_cdigit(isbn13))
endfunction
function! s:isbn10to13(isbn10)
if !s:is_isbn10(a:isbn10) | return '' | endif
let isbn10 = substitute(a:isbn10, '^\(\d\{9}\)\([0-9xX]\)$', '\1', '')
let isbn13 = '978' . isbn10
let cdigit = s:get_isbn13_cdigit(isbn13)
let isbn13 = isbn13 . cdigit
if !s:is_isbn13(isbn13) | return '' | endif
return isbn13
endfunction
function! s:isbn13toasin(isbn13)
let hatena_url = 'http://d.hatena.ne.jp/asin/' . a:isbn13
let tmpfile = tempname()
call system('curl -D ' . tmpfile . ' ' . hatena_url)
let pat = '\clocation:\s*http://d.hatena.ne.jp/asin/\(\d\{9}[0-9x]\)'
let loc = get(filter(readfile(tmpfile), "v:val =~ '" . pat . "'"), 0, '')
call delete(tmpfile)
return get(matchlist(loc, pat), 1, '')
endfunction
" }}}
let &cpoptions = s:save_cpoptions
" vim: set expandtab tabstop=2 shiftwidth=2 foldmethod=marker: