Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I copy the table from Calc (or Tracker)

In my research I know three ways:

1: Record a macro: @a0f cw & <ESC>;.;.I\hline <ESC>A \\ (the spaces count ;) )
And then VG:normal @a<ENTER>

2: VG:s/ / \& /gv:<UP><ENTER>gv:<UP><ENTER>
and then other macro for the \hline and \\

3: f <C-v>kkk23jc & <ESC>;.;.
And again I\hlineA \\<ESC>


Is there another way?

Sample input:

0.79    0.80    5.40    6.48
0.86    0.87    4.57    5.81
0.93    0.94    4.04    5.32

Output:

\hline 0.79 & 0.80 & 5.40 & 6.48 \\
\hline 0.86 & 0.87 & 4.57 & 5.81 \\
\hline 0.93 & 0.94 & 4.04 & 5.32 \\
share|improve this question
    
Do you have a short sample of input and wanted output? –  Sukminder Mar 30 '13 at 6:35
    
Thanks @Sukminder, there is :). In the 3er way, 23 represent the number of lines (I reduce the number of lines to three in the i/o) –  David Mar 30 '13 at 6:40
    
I may be missing something (what kind of macros is that? for LibreOffice Calc or the like?), but what about exporting to CSV and then running sed on the CSV? –  njsg Mar 30 '13 at 7:46
    
@njsg: Q is tagged vim. –  Sukminder Mar 30 '13 at 8:02
    
What about exporting to CSV and reading in the file directly with LaTeX instead of converting it to LaTeX tables? That way changing the data is much easier, too. –  Marco Mar 30 '13 at 10:08
add comment

1 Answer

up vote 1 down vote accepted

This is perhaps not what you want, but: When I come across such situations, and if it is likely that I'm going to do it more then a few times I usually write a function for it. (One problem with this is that I tend to go a bit overboard.)

The procedure can be done using macro as well, but what I like about using functions is the flexibility to customize it.


As macro c, record by:

qc:s/\s\+/ \& /g<Enter>:s/^/\\hline /<Enter>:s/$/\\\\/<Enter>q

    s/\s\+/ \& /g   Substitute 1+ spaces with " & ", globally.
    s/^/\\hline /   Substitute start of line with \hline.
    s/$/\\\\/       Substitute end of line with \\.

Select range:

<Ctrl>+v23j
:norm @c

Here is an example using function. Add to .vimrc, or better, to a file in some auto-load directory.

What this does is execute LaTeXTable() on selected lines. In addition it adds header and footer for table unless argument 1 is 0. So:

  • Ctrl+v
  • Select lines.
    • :LEXTABLEEnter Create table lines including start and end.
    • :LEXTABLE 0Enter Create table lines only.
    • :LEXTABLE c l l cEnter Create table lines and use 'c l l c' as column specifiers.

Sample code:

function! LaTeXTable(...) range
    " Replace consecutive spaces with " & "
    '<,'>s/\s\+/ \& /g
    " Replace start with \hline
    '<,'>s/^\s*/\\hline /
    " Replace end with \\
    '<,'>s/\s*$/ \\\\/

    " If argument is 0 then do not add table def
    if a:1 == "0"
        return
    " Else if argument is not empty use it as column specifier
    elseif a:1 != ""
        let cc = a:1
    " Else split first line on & and make all center c
    else
        let ands = split(getline(a:firstline), '&')
        call map(ands, '"c"')
        let cc = join(ands, " ")
    endif

    " Add start of table
    call append(a:firstline - 1,"\\begin{tabular}{ " . cc . " }")
    " Add end of table
    call append(a:lastline  + 1,"\\end{tabular}")
endfun

" -nargs=? allow 0 or 1 argument
" -range   use range
" LEXTABLE name
" silent   do not echo what is done
" <line.>  range
" <q-args> Quote argument
command! -nargs=? -range LEXTABLE silent <line1>,<line2>call LaTeXTable(<q-args>)

If one usually do not want to add start/end of table one can easily change the function to say:

if arg is empty or 0, then do not create,
if arg=1 auto, then auto generate
else use as string
.

It would perhaps be preferable:

if a:1 == "" || a:1 == "0"
    return
elseif a:1 != "1"
    let cc=a:1
else
    let ands = split(getline(a:firstline), '&')
    call map(ands, '"c"')
    let cc = join(ands, " ")
endif

So then:

:'<,'>LEXTABLE<Enter>           # Only parse lines, no header.
:'<,'>LEXTABLE 0<Enter>         # Only parse lines, no header.
:'<,'>LEXTABLE 1<Enter>         # Auto generate column specifiers.
:'<,'>LEXTABLE c l<Enter>       # Use 'c l' as column specifiers.
:'<,'>LEXTABLE c | l l<Enter>   # Use 'c | l l' as column specifiers.

By this one could further expand to use profiles for tables, as in e.g. if argument is "P1" use "c c c c c", if "P2" use "c l c l c" etc.

All this and more one would perhaps try to take a look at Vim-LaTeX and the like.


From the above one would get:

Selected lines:

0.79    0.80    5.40    6.48
0.86    0.87    4.57    5.81
0.93    0.94    4.04    5.32

Command:

:'<,'>LEXTABLE c | l l l

Result:

\begin{tabular}{ c | l l l }
\hline 0.79 & 0.80 & 5.40 & 6.48 \\
\hline 0.86 & 0.87 & 4.57 & 5.81 \\
\hline 0.93 & 0.94 & 4.04 & 5.32 \\
\end{tabular}
share|improve this answer
    
Excelent post! I uses Vim-LaTeX, your function must be in that suite. –  David Mar 30 '13 at 17:34
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.