159 lines
3.2 KiB
VimL
159 lines
3.2 KiB
VimL
|
function abook#sum()
|
||
|
let l:st = getpos("'<")[1]
|
||
|
let l:ed = getpos("'>")[1] + 1
|
||
|
|
||
|
let l:curs = {}
|
||
|
let l:wals = {}
|
||
|
|
||
|
let l:lnum = l:st
|
||
|
while l:lnum < l:ed
|
||
|
let [l:record, l:lines] = s:next_record(l:lnum)
|
||
|
if 0 == l:lines
|
||
|
let l:lnum += 1
|
||
|
continue
|
||
|
endif
|
||
|
|
||
|
let [l:record_curs, l:record_wals] = s:sum(l:record)
|
||
|
|
||
|
for l:cur in keys(l:record_curs)
|
||
|
let l:curs = s:extend_or_sum(l:curs, l:cur, l:record_curs[l:cur])
|
||
|
endfor
|
||
|
for l:wal in keys(l:record_wals)
|
||
|
let l:wals = s:extend_or_sum(l:wals, l:wal, l:record_wals[l:wal])
|
||
|
endfor
|
||
|
|
||
|
let l:lnum += l:lines
|
||
|
endwhile
|
||
|
|
||
|
echo l:curs
|
||
|
echo l:wals
|
||
|
endfunction
|
||
|
|
||
|
function abook#tax(rate)
|
||
|
let l:lnum = getcurpos()[1]
|
||
|
|
||
|
let [l:record, l:lines] = s:next_record(l:lnum)
|
||
|
if 0 == l:lines
|
||
|
return
|
||
|
endif
|
||
|
|
||
|
let l:record = s:multiply(l:record, a:rate)
|
||
|
let l:record = split(l:record, "\n", 1)
|
||
|
|
||
|
for l:line in l:record[:-2]
|
||
|
call setline(l:lnum, l:line)
|
||
|
let l:lnum += 1
|
||
|
endfor
|
||
|
endfunction
|
||
|
|
||
|
function s:sum(src)
|
||
|
let l:idx = 0
|
||
|
|
||
|
let l:cur = ""
|
||
|
let l:wal = ""
|
||
|
let l:curs = {}
|
||
|
let l:wals = {}
|
||
|
|
||
|
while 1
|
||
|
let [l:token, l:idx] = s:next_token(a:src, l:idx)
|
||
|
if l:token == ""
|
||
|
return [l:curs, l:wals]
|
||
|
endif
|
||
|
|
||
|
if l:cur != ""
|
||
|
let l:price = str2float(l:token)
|
||
|
|
||
|
let l:curs = s:extend_or_sum(l:curs, l:cur, l:price)
|
||
|
let l:wals = s:extend_or_sum(l:wals, l:wal, l:price)
|
||
|
|
||
|
let l:cur = ""
|
||
|
let l:wal = ""
|
||
|
elseif stridx(l:token, "@") >= 0
|
||
|
let l:cur = split(l:token, "@")[0]
|
||
|
let l:wal = l:token
|
||
|
endif
|
||
|
endwhile
|
||
|
endfunction
|
||
|
|
||
|
function s:multiply(src, rate)
|
||
|
let l:expect_price = 0
|
||
|
|
||
|
let l:idx = 0
|
||
|
let l:offset = 0
|
||
|
|
||
|
let l:dst = a:src
|
||
|
while 1
|
||
|
let [l:token, l:idx] = s:next_token(a:src, l:idx)
|
||
|
if l:token == ""
|
||
|
return l:dst
|
||
|
endif
|
||
|
|
||
|
let l:st = l:idx - len(l:token)
|
||
|
let l:ed = l:idx
|
||
|
|
||
|
if l:expect_price
|
||
|
let l:old_price = str2float(l:token)
|
||
|
let l:new_price = floor(l:old_price * a:rate)
|
||
|
let l:new_price = printf("%.0f", l:new_price)
|
||
|
|
||
|
let l:st += l:offset
|
||
|
let l:ed += l:offset
|
||
|
|
||
|
let l:dst = l:dst[0:l:st-1] . l:new_price . l:dst[l:ed:]
|
||
|
let l:offset += len("".l:new_price) - len(l:token)
|
||
|
|
||
|
let l:expect_price = 0
|
||
|
else
|
||
|
let l:expect_price = stridx(l:token, "@") >= 0
|
||
|
endif
|
||
|
endwhile
|
||
|
endfunction
|
||
|
|
||
|
function s:next_token(str, idx)
|
||
|
let l:st = a:idx
|
||
|
while l:st < len(a:str) && stridx(" \t\n", a:str[l:st]) >= 0
|
||
|
let l:st += 1
|
||
|
endwhile
|
||
|
|
||
|
let l:ed = l:st
|
||
|
while l:ed < len(a:str) && stridx(" \t\n", a:str[l:ed]) < 0
|
||
|
let l:ed += 1
|
||
|
endwhile
|
||
|
|
||
|
return [a:str[l:st:l:ed-1], l:ed]
|
||
|
endfunction
|
||
|
|
||
|
function s:next_record(st)
|
||
|
let l:st = a:st
|
||
|
let l:ed = l:st
|
||
|
|
||
|
let l:record = ""
|
||
|
while 1
|
||
|
let l:curr = l:ed
|
||
|
let l:line = getline(l:ed)
|
||
|
let l:ed += 1
|
||
|
if l:line[0] == "#"
|
||
|
continue
|
||
|
endif
|
||
|
|
||
|
let l:break = stridx("0123456789", l:line[0]) >= 0
|
||
|
if l:st == l:curr && !l:break
|
||
|
return ["", 0]
|
||
|
endif
|
||
|
if l:st < l:curr && l:break
|
||
|
return [l:record, l:ed-l:st-1]
|
||
|
endif
|
||
|
|
||
|
let l:record .= l:line . "\n"
|
||
|
endwhile
|
||
|
endfunction
|
||
|
|
||
|
function s:extend_or_sum(dic, key, num)
|
||
|
if has_key(a:dic, a:key)
|
||
|
let a:dic[a:key] += a:num
|
||
|
return a:dic
|
||
|
else
|
||
|
return extend(a:dic, {a:key: a:num})
|
||
|
endif
|
||
|
endfunction
|