Skip to content

Instantly share code, notes, and snippets.

@2nd-player
Last active February 23, 2017 07:37
Show Gist options
  • Save 2nd-player/ce68d17ab9b1f833e35334815609b47a to your computer and use it in GitHub Desktop.
Save 2nd-player/ce68d17ab9b1f833e35334815609b47a to your computer and use it in GitHub Desktop.
#!/usr/local/bin/vim -S
" File: readwiki.vim
" Author: 2nd-player
" Date: Feb 23, 2017
" Copyright: Copyright (C) 2017 2nd-player
"
" This work is currently licensed under the terms of CC BY-NC-SA 2.1 JP.
" https://creativecommons.org/licenses/by-nc-sa/2.1/jp/
"
"== Requirements ==
"The cURL command is required to do HTTP communication.
"== Function ==
":[range]ReadWiki [page]
" Fetch wikitxt and insert them below the specified line.
" this beheviour is imitation of :read command.
"
" Interwiki prefixes in [page] argument will be handled
" if they're registered properly on both "s:server" and "s:pj".
"
"== Usage ==
"load this file first.
" :source ./readwiki.vim
"then use ReadWiki command with your favorite article
" :ReadWiki ピカチュウ
" :ReadWiki en:EP001
" :ReadWiki w:en:Vim (text editor)
let s:save_cpo = &cpo
set cpo&vim
let s:server = {}
let s:server.ep =
\{'de': ['http://www.pokewiki.de/', ['w','wikipedia','wiktionary','wikibooks']]
\,'en': ['http://bulbapedia.bulbagarden.net/w/', ['w','wikipedia','wiktionary','wikibooks','enwp','dewp']]
\,'fr': ['http://www.pokepedia.fr/', ['w','wikipedia','wiktionary','wikibooks']]
\,'it': ['https://wiki.pokemoncentral.it/', ['w','wikipedia','wiktionary','wikibooks']]
\,'ja': ['https://wiki.xn--rckteqa2e.com/w/', ['w','wikipedia','wiktionary','wikibooks']]
\,'pl': ['http://wiki.pokemonpl.net/', ['w','wikipedia','wiktionary','wikibooks']]
\,'zh': ['https://wiki.52poke.com/', ['w','wikipedia','wiktionary','wikibooks']]
\}
let s:server.wp = {}
let s:server.wb = {}
let s:server.wt = {}
let s:iwmap_wmf = ['wikipedia','wiktionary','wikibooks','bulba','pokewiki']
for s:mylang in ['de','en','fr','it','ja','pl','zh']
call extend(s:server.wp,{s:mylang : ["https://".s:mylang.".wikipedia.org/w/", s:iwmap_wmf]})
call extend(s:server.wt,{s:mylang : ["https://".s:mylang.".wiktionary.org/w/", s:iwmap_wmf]})
call extend(s:server.wb,{s:mylang : ["https://".s:mylang.".wikibooks.org/w/", s:iwmap_wmf]})
endfor
let s:pj = {'bulba': ['ep','en']
\,'pokewiki': ['ep','de']
\,'wikipedia': ['wp']
\,'enwp': ['wp','en']
\,'dewp': ['wp','de']
\,'wiktionary': ['wt']
\,'wikibooks': ['wb']
\}
"set alias
let s:pj.w = s:pj.wikipedia
let s:pj.wp = s:pj.wikipedia
let s:pj.wt = s:pj.wiktionary
let s:pj.wb = s:pj.wikibooks
let &cpo = s:save_cpo
unlet s:save_cpo
let s:myproj = 'ep'
let s:mylang = 'ja'
fun! UrlEncodeUTF8(expr)
let l:urlencutf8 = ""
for l:i in range(strchars(a:expr))
let l:c = nr2char(strgetchar(a:expr,l:i),1)
if l:c =~ '[-0-9A-Za-z_.~]'
let l:urlencutf8 .= l:c
else
for l:r in range(strlen(l:c))
let l:urlencutf8 .= "%".printf("%02X",char2nr(strpart(l:c,l:r,1),0))
endfor
endif
endfor
return l:urlencutf8
endfunction
fun! ReadWikitxt(title) range
let l:part = s:FollowInterwiki(a:title)
let l:result = s:GetWikitxt(l:part[0],l:part[1],l:part[2])
if !len(l:result)
return
endif
while l:result[0] =~ '^#[^ \[\]]\+\s*:*\s*\[\[\s*[^\[\]#][^\[\]]*\s*\]\]' && confirm(l:result[0]."\nFollow this link?","&Yes\n&No",1) == 1
let l:part = s:FollowInterwiki(s:FollowLink(l:result[0]),l:part[0],l:part[1])
let l:result = s:GetWikitxt(l:part[0],l:part[1],l:part[2])
if !len(l:result)
return
endif
endw
call append(a:lastline, l:result)
echom '"'.s:server[l:part[0]][l:part[1]][0].'index.php?title='.l:part[2].'"' len(l:result).'L'
endfun
fun! s:GetWikitxt(proj, lang, title)
return systemlist("curl '".s:server[a:proj][a:lang][0]."index.php' --header 'Expect:' -A 'Mozilla/4.0 (readwiki.vim;)' -s --location --data 'action=raw&title=".UrlEncodeUTF8(a:title)."' 2>&1")
"return ["curl '".s:server[a:proj][a:lang][0]."index.php' --header 'Expect:' -A 'Mozilla/4.0 (readwiki.vim;)' -s --location --data 'action=raw&title=".UrlEncodeUTF8(a:title)."' 2>&1"]
endfun
fun! s:FollowInterwiki(title, ...)
let l:title = a:title
if a:0
let l:proj = a:1
let l:lang = a:2
else
let l:proj = s:myproj
let l:lang = s:mylang
endif
while 1
let l:title = s:TrimTitle(l:title)
if l:title !~ ':'
break
endif
let l:part = s:split2(l:title,':')
if has_key(s:server[l:proj],l:part[0])
"interlang
let l:lang = l:part[0]
let l:title = l:part[1]
elseif count(s:server[l:proj][l:lang][1],l:part[0])
let l:title = l:part[1]
let l:tmp = get(s:pj,l:proj.':'.l:lang.':'.l:part[0],s:pj[l:part[0]])
if len(l:tmp) == 2
let l:lang = l:tmp[1]
endif
let l:proj = l:tmp[0]
else
break
endif
endw
return [l:proj, l:lang, l:title]
endfun
fun! s:FollowLink(line)
return strpart(strpart(a:line,0,match(a:line,'[|\]#]',1)), matchend(a:line,'\[\['))
return 0
endfun
fun! s:TrimTitle(title)
return substitute(a:title, '^[: ]*', '', '')
endfun
fun! s:split2(expr, pattern)
"split string into two part
let l:ary = ['', '']
let l:pos = match(a:expr, a:pattern)
if l:pos == -1
let l:ary[0] = a:expr
else
let l:ary[0] = strpart(a:expr,0,l:pos)
let l:ary[1] = strpart(a:expr,matchend(a:expr,a:pattern))
endif
return l:ary
endfun
command! -nargs=1 -range ReadWiki :<line1>,<line2>call ReadWikitxt(<q-args>)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment