85 omemo.vim (9-1) 書籍JANコード解釈スクリプト(ファイルタイププラグイン作成中)
ファイルタイププラグインを書くことでVimスクリプトを勉強している。詳細はまたそのうち書くつもり。今書いているファイルタイププラグインはメモ用のもの。俺用のメモファイルタイプなので omemo としている。仮だけど。中身はといえば、howmそのまま。URLを開けて、ISBNから書籍情報を取得できて、容易に機能追加ができて、とそういうもの。
そのプラグインの中では、以前書いた howm-actionlock-isbn.vim に手を入れたものを使っている。そのまま流用してはつまらないので、手を入れている。変更点は、「書籍JANコードの2段目のバーコードも解釈できるようにした」ことだ。今回は、その断片を書く。
書籍JANコードの1段目はISBN-13、2段目はCコードと価格情報を表していることがわかった。書籍情報取得先に「ジュンク堂」を追加するスクリプトを書いているうちに、Cコードや価格情報の存在を知ったので、これを使わない手はないなと思った。それが、今回の改造のきっかけになった。
これだけだと動作確認しにくいと思うので、ジュンク堂うんぬんの分もそのうちに公開する。
function! s:get_jan2(c_code, price) let code = '192' . a:c_code . printf('%05d', a:price) return code . s:get_jan2_cdigit(code) endfunction function! s:get_jan2_info(code) if !s:is_jan2(a:code) | return {} | endif let matchlist = matchlist(a:code, '\(\d\{3}\)\(\d\{4}\)\(\d\{5}\)\d') let tax = get(matchlist, 1, '') let c_code = get(matchlist, 2, '') let price = get(matchlist, 3, '') let price = substitute(price, '^0*', '', '') if tax == '191' " 3% のときは内税。四捨五入もする。 let price = price * 10 let price = price * 100 / 103 let price = (price + 5) / 10 " let price = 'P' . price . 'E' elseif tax == '192' " 5% のときは外税。特別な処理は必要ない。 " let price = '\' . price . 'E' endif let price3 = price * 10 let price3 = price3 * 103 / 100 let price3 = (price3 + 5) / 10 let price5 = price * 10 let price5 = price5 * 105 / 100 let price5 = (price5 + 5) / 10 return {'c-code': c_code, 'price': price, 'price3': price3, 'price5': price5} 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:get_jan2_cdigit(code) return s:get_isbn13_cdigit(a:code) 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:is_jan2(s) return s:is_isbn13(a:s) 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