[email protected] schrieb:
> Charlie Kester <[email protected]> [09-07-01 04:50]:
>> On Tue 30 Jun 2009 at 19:31:41 PDT [email protected] wrote:
>>>
>>>
>>> Hi,
>>>
>>> I want to make from this input (example):
>>>
>>> a d f g h
>>> b c d e f
>>> g h i
>>> a i
>>> b f g j
>>>
>>> this output
>>>
>>>
>>> a d f g h
>>> b c d e f
>>> g h i
>>> a i
>>> b f g j
>>>
>>>
>>> is there any vim script, which does this for me?
>>> I am working under Linux and vim (console).
>>>
>> What are the constraints?
>>
>> Will the input lines always be pre-sorted, as in your example? I.e.,
>> will you ever have a row like "b d a f"? If so, should the
>> "tabulerization" sort it?
>>
>> Will each element always be one character wide and no wider?
>>
>> In your example, for each character between a and j, there is at least
>> one row containing it. Will you need to handle cases where one or more
>> elements in the range are not represented? I.e., should the result
>> contain empty columns?
>>
>>
>>
> Oh ... uuuuhhh ... hrrrmm
>
> Yes, the input was incomplete, sorry.
>
> I will try to complete it:
>
> "a b c" stands for three words that is each character is one word.
> Separation is done by blanks (\s) of a unknown count, anything else
> is part of a word. Or in other words: "a=2.5 Anoth"er"(word)!=23/8:l" are
> two words.
> The words are presorted.
> There are no empty columns.
>
> Hope, that is more complete as my first attempt...
hey, try this one:
com! -range Tabularize <line1>,<line2>call Tabularize()
func! Tabularize() range abort
let wdict = Tabul_GetWDict(getline(a:firstline, a:lastline))
let ordered_words = Tabul_Sort(keys(wdict))
let virtcols = Tabul_GetColumnOffsets(ordered_words)
for lnum in range(a:firstline, a:lastline)
let words = Tabul_GetWords(getline(lnum))
call setline(lnum, Tabul_MkTabLine(Tabul_Sort(words), virtcols))
endfor
endfunc
" return a tabularized line:
func! Tabul_MkTabLine(ordered_words, virtcols)
" ok a bit redundant: both ordered_words and virtcols include
" information about order
let words = copy(a:ordered_words)
let nwords = len(words)
if nwords < 2
return nwords == 1 ? words[0] : ""
endif
let idx = 0
let nextword = words[0]
let indent = repeat(" ", a:virtcols[nextword]-1)
while idx < nwords-1
let word = nextword
let nextword = words[idx+1]
let fmt = printf("%%-%ds",
\ a:virtcols[nextword] - a:virtcols[word])
let words[idx] = printf(fmt, word)
let idx += 1
endwhile
return indent. join(words, "")
endfunc
" for given list of strings: extract the words into a wdict (= set of
" words)
func! Tabul_GetWDict(lines)
let wd = {}
for line in a:lines
for word in Tabul_GetWords(line)
let wd[word] = 1
endfor
endfor
return wd
endfunc
" return words ordered:
func! Tabul_Sort(words)
return sort(a:words)
endfunc
" extract the words from a string as a list
func! Tabul_GetWords(str)
return split(a:str)
endfunc
" assign virtual columns (in the window) for each word in ordered_wlist
func! Tabul_GetColumnOffsets(ordered_wlist)
let gap = 1 " least number of spaces between words
let off = 1 " leftmost virtcol()
let offsets = {}
for word in a:ordered_wlist
let offsets[word] = off
let off += strlen(word) + gap
endfor
return offsets
endfunc
" vim:set tw=72 et sw=2 sts=2:
extra functions for sorting and extracting words from the text ...
should be quite easy to find the positions in the code where
to make changes ...
--
Andy
--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---