続・Vimで国語辞典を見る(同音異義語 対応版)
先ほど作った、Yahoo!辞書の国語辞典を閲覧するためのVimScriptですが、同音異義語や同じ表記だけど違う読みの語に対応しないのがどうもなあ……と感じ、ちょっと手を入れてみました。
http://takepierrot.hatenablog.jp/entry/2012/06/03/054938
ちょっと長くなってしまいましたが、以下がスクリプトになります。
" 出力用のバッファの管理 function! Jiten_Window() if !exists('s:bufnr') let s:bufnr = -1 " A number that doesn't exist. endif if !bufexists(s:bufnr) split edit `='[kokugo jiten output]'` let s:bufnr = bufnr('%') nnoremap <buffer> q <C-w>c nnoremap <buffer> <CR> :call CallDic()<CR> nnoremap <buffer> K :call CallRuigigo()<CR> setlocal bufhidden=hide buftype=nofile noswapfile nobuflisted setf txt elseif bufwinnr(s:bufnr) != -1 execute bufwinnr(s:bufnr) 'wincmd w' else split execute 'buffer' s:bufnr endif normal ggdG endfunction " 国語辞典をチェック fun! CallDic() if getreg('z') == '' normal viw"zy endif let s:str = getreg('z') call Jiten_Window() call Dic_check_itiran(s:str) call setreg('z', '') endf nnoremap <Leader>lk :call CallDic()<CR> function! Dic_check_itiran(str) perl << EOF use utf8; use URI; use URI::QueryParam; use Web::Query; use Encode; my $keyword = decode_utf8(VIM::Eval('a:str')); if ($keyword =~ /^\d+$/) { VIM::DoCommand("call Dic_check_input($keyword)"); return; } my (@id_list, @words); my $page = 1; for my $i (0 .. 20) { my $uri_itiran = URI->new('http://dic.search.yahoo.co.jp/dsearch'); $uri_itiran->query_form( stype => 'exact', p => $keyword, dic_id => 'dic_jj', b => $page + $i * 10, ); my $itiran = wq($uri_itiran)->find('div.result-r ol[start]'); if ($itiran->find('li')->text) { $itiran->find('li')->each(sub { my ($num, $wq) = @_; my $uri = URI->new($wq->find('a')->attr('href')); push @words, $wq->find('h3')->text; push @id_list, $uri->query_param('index'); }); } else { last; } } if (scalar @id_list == 1) { my $num = shift @id_list; VIM::Msg($num); $num = sprintf '%d', $num; VIM::DoCommand("call Dic_check_input($num)"); } elsif (scalar @id_list == 0) { $main::curbuf->Set(1, "「$keyword」に該当する文字列は辞書にはありません"); } else { my @list; push @list, sprintf("%-8d[id] %s", $id_list[$_], $words[$_]) for 0 .. $#id_list; $main::curbuf->Append(0, @list); } EOF endfunction fun! Dic_check_input(str) perl << EOF use utf8; use URI; use Web::Query; use Encode; my $uri_result = URI->new('http://dic.yahoo.co.jp/dsearch'); my $numeric = sprintf '%08s', decode_utf8(VIM::Eval('a:str'));; $uri_result->query_form( dtype => 0, index => $numeric, ); my $wq = wq($uri_result)->find('div.content-detail'); my $title = $wq->find('h1')->text; my $html = $wq->find('table.d-detail')->html; $html =~ s|<br />|\\n|g; my $descr = Web::Query->new_from_html($html)->text; $descr =~ s/(\\n)+/\n/g; $descr =~ s/^ //mg; $descr =~ s/^([1-9])/[$1]/mg; my $honmon = $title . "\n" . $descr; $main::curbuf->Append(0, split(/\n/, $honmon)); EOF endf
同音異義語などの語句を検索すると、このように候補の語句が一覧表示されます。
IDの数字上でReturnキーを押すと、目的の語句の意味が確認できます。
このIDの数字、実は0で埋める8桁固定長なのですが、数字の頭に0がついた状態でVimScriptに評価させると、数字を勝手に変換しやがる場合があります。VimScript内で数字をほかの関数に渡すときは、「sprintf '%d', $num」で評価して余計な0をとっておく。URIモジュールでクエリを作るときは「sprintf '%08s', $num」で評価して0を追加するという感じに対処するのが安全みたいです。