0

I'm trying to come up with a way of doing the following in vim. When editing LaTeX documents, I need on a fairly regular basis to toggle between display and inline math modes. Let me explain: suppose I'm wrtting

Consequently, one gets a function $\Omega^2 \mathbb S^2 \to \Omega \mathbb S^1$

And I realize that it is not visually appealing to put the math inline, so I want to get:

Consequently, one gets a function 
\begin{displaymath} 
  \Omega^2 \mathbb S^2 \to \Omega \mathbb S^1
\end{displaymath}

Ideally, I want to get that result by just a few keystrokes when the cursor is inside the equation, and I would like to get the converse transformation by the same command: the command should then detect first if I'm in inline or display mode and then perform the necessary transformation.

I fear to dive in a regexp-hell when there might be a simpler way. Note that I'm fairly new to vim, so the answer might be completely obvious. I'm only using vim-latex as a plugin and I would prefer if there is a vanilla vim way of doing this.

1

Here is a not so elegant solution I created based on my non existent knowledge of latex.

The idea is to create a mapping (replace gs by whatever you prefer) which calls a function which does all the work.

The function checks if the current line has a string surrounded by $ signs (I assumed that's how you delimit your inline expression). If such a string exists we get it in a variable l, remove the $s, remove the string from the line, add the \begin and \end markers and the expression we got before, and use = to reindent everything.

If the string wasn't found then we do the opposite: find the delimiters, remove them, join the lines between them, add the surrounding $ and join with the previous line.

Warning I did this quickly because I thought it was fun but I know nothing about LaTeX and there are probably a lot of edge cases I didn't think about. For example if you use the mapping on a line which is neither a block expression or an inline expression you will completely mess up your buffer.

From my tests this solution works on your example but that's all I can say. Also I suspect that in a few hours one of the Vim Gurus we have on this site will come up with an elegant solution of just a few lines... we'll see :)

nnoremap gs :call ToggleLatexMathMode()<CR>

function! ToggleLatexMathMode()
    " Get the current line and check if we find an expression surrounded by $ signs
    let l=getline('.')
    let inline=match(l, '\$[^$]\+\$')

    " Inline to block
    if (inline >= 0)
        " Get the expression
        let l=matchstr(l, '\$[^$]\+\$')
        " Remove the surrounding $ signs
        let expr=substitute(l, '\$', '', 'g')
        " Remove the expression from the line
        execute 's/\%' . inline  . 'c.\{' . ( len(l)+1 ) . '}//'
        " Append the delimitors and the expression without $ signs
        call append(line('.'), '\end{displaymath}')
        call append(line('.'), expr)
        call append(line('.'), '\begin{displaymath}')
        " Format to get the right indentation
        normal! =}
    " Block to inline
    else
        " Get the lines delimiting the expression
        let start=search('begin{displaymath}', 'b')
        let end=search('end{displaymath}')
        " Delete the surrounding lines
        execute(end . 'd')
        execute(start . 'd')
        " Join the lines in the expression
        execute(start . ',' . (end-2) . 'join')
        " Add the surrounding dollar signs
        call setline(start, substitute(getline(start), '^\s*', '$', '') . '$')
        " Join with the previous line
        normal! kJ
    endif
endfunction
| improve this answer | |
  • Thanks for the piece of code. It is not exactly what I'm after (for example, it will always toggle the first piece of math between $$ on a line) but it gives be a base to work with! – Pece Aug 8 at 14:30
  • Yes that was definitely meant to give you something to start with and not a complete solution :) – statox Aug 9 at 15:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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