[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
-~----------~----~----~----~------~----~------~--~---

Reply via email to