Vim脚本仅在没有错误的情况下编译TeX源并启动PDF [英] Vim script to compile TeX source and launch PDF only if no errors

查看:77
本文介绍了Vim脚本仅在没有错误的情况下编译TeX源并启动PDF的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将Vim用于LaTeX编辑环境.我希望能够在Vim内对源文件进行tex处理,并在编译成功的情况下启动外部视图.

I am switching to using Vim for for my LaTeX editing environment. I would like to be able to tex the source file from within Vim, and launch an external viewing if the compile was successful.

我了解Vim-Latex套件,但是,如果可能的话,宁愿避免使用它:它很笨重,劫持了我的许多 密钥,并弄乱了我的vimruntime有很多文件.

I know about the Vim-Latex suite, but, if possible, would prefer to avoid using it: it is pretty heavy-weight, hijacks a lot of my keys, and clutters up my vimruntime with a lot of files.

这是我现在拥有的:

if exists('b:tex_build_mapped')
    finish
endif
" use maparg or mapcheck to see if key is free
command! -buffer -nargs=* BuildTex call BuildTex(0, <f-args>)
command! -buffer -nargs=* BuildAndViewTex call BuildTex(1, <f-args>)
noremap <buffer> <silent> <F9> <Esc>:call BuildTex(0)<CR>
noremap <buffer> <silent> <S-F9> <Esc>:call BuildTex(1)<CR>
let b:tex_build_mapped = 1

if exists('g:tex_build_loaded')
    finish
endif
let g:tex_build_loaded = 1

function! BuildTex(view_results, ...)
    write
    if filereadable("Makefile")
        " If Makefile is available in current working directory, run 'make' with arguments
        echo "(using Makefile)"
        let l:cmd = "!make ".join(a:000, ' ')
        echo l:cmd
        execute l:cmd
        if a:view_results && v:shell_error == 0
            call ViewTexResults()
        endif
    else
        let b:tex_flavor = 'pdflatex'
        compiler tex
        make %
        if a:view_results && v:shell_error == 0
            call ViewTexResults()
        endif
    endif
endfunction

function! ViewTexResults(...)
    if a:0 == 0
        let l:target = expand("%:p:r") . ".pdf"
    else
        let l:target = a:1
    endif
    if has('mac')
        execute "! open -a Preview ".l:target
    endif
endfunction

问题是即使存在编译错误,也未设置v:shell_error.对于如何检测编译是否成功的任何建议或见解,将不胜感激!谢谢!

The problem is that v:shell_error is not set, even if there are compile errors. Any suggestions or insight on how to detect whether a compile was successful or not would be greatly appreciated! Thanks!

在给出的答案以及对其他方法的一些研究之间,我认为这已得到令人满意的解决.如果有人有兴趣,我会在此处发布解决方案.

Between the answers given here, plus some study of other approaches, I think that this has been satisfactorily solved. I am posting the solution here in case anyone else is interested.

基本上,最好的解决方案似乎是使用橡胶, LaTeX周围的包装,通常可以正常工作",并提供非常干净的输出/错误.如果在系统上找到橡胶,但在当前目录中找不到Makefile,则我在下面介绍的解决方案优先使用Rubber.如果找到了Makefile,它将使用该文件.如果没有Makefile并且未安装Rubber,它将使用pdflatex.在所有情况下,如果源代码无法编译,则(过滤和解析的)错误将发送到QuickFix缓冲区,并自动打开QuickFix窗口.如果编译成功,则会写一条短消息,如果用户要求,则会打开PDF进行查看.

Basically, the best solution appears to be to use Rubber, a wrapper around LaTeX, that generally "just works", and provides very clean output/errors. The solution I present below preferentially uses Rubber if it is found on the system and no Makefile is found in the current directory. If a Makefile is found, it uses that instead. If there is no Makefile and Rubber is not installed, it uses pdflatex. In all cases, if the source fails to compile, the (filtered and parsed) errors are sent to the QuickFix buffer and the QuickFix window is automatically opened. If it compiles successfully, a short message is written, and if the user requested it, the PDF will be opened for viewing.

在我自己的安装中,我从

In my own installation, I have lifted the (excellent) "SetLatexEfm()" function from Vim-Latex to parse and filter the tex build output. If this function is not found, however, the function below defaults to setting an error message format that works fine enough for the errors to be identified and highlighted in the QuickFix window, albeit with lots of crud.

    function! BuildTex(view_results, ...)

        " record position
        let save_cursor = getpos(".")

        " save work
        silent write

        " From: http://stackoverflow.com/questions/2679475/vim-script-to-compile-tex-source-and-launch-pdf-only-if-no-errors
        " If your shell is bash, you can use the ${PIPESTATUS} array variable to get
        " the correct exit code (borrowed from this answer to another question).
        silent setlocal shell=bash
        silent setlocal shellpipe=2>&1\ \|\ tee\ %s;exit\ \${PIPESTATUS[0]}

        let success = 1
        if filereadable("Makefile")
            " If Makefile is available in current working directory, run 'make' with arguments
            echon "compiling using Makefile ..."
            let l:makecmd = "make\\ ".join(a:000, '\\ ')
            silent execute "setlocal makeprg=" . l:makecmd
            try
                " This function is defined in the Vim-Latex package, 
                " and provides excellent parsing and filtering of the error messages
                " when running latex outside of the Rubber wrapper.
                call s:SetLatexEfm()
            catch /E117/
                set errorformat=%E!\ LaTeX\ %trror:\ %m,
                    \%E!\ %m,
                    \%+WLaTeX\ %.%#Warning:\ %.%#line\ %l%.%#,
                    \%+W%.%#\ at\ lines\ %l--%*\\d,
                    \%WLaTeX\ %.%#Warning:\ %m,
                    \%Cl.%l\ %m,
                    \%+C\ \ %m.,
                    \%+C%.%#-%.%#,
                    \%+C%.%#[]%.%#,
                    \%+C[]%.%#,
                    \%+C%.%#%[{}\\]%.%#,
                    \%+C<%.%#>%.%#,
                    \%C\ \ %m,
                    \%-GSee\ the\ LaTeX%m,
                    \%-GType\ \ H\ <return>%m,
                    \%-G\ ...%.%#,
                    \%-G%.%#\ (C)\ %.%#,
                    \%-G(see\ the\ transcript%.%#),
                    \%-G\\s%#,
                    \%+O(%f)%r,
                    \%+P(%f%r,
                    \%+P\ %\\=(%f%r,
                    \%+P%*[^()](%f%r,
                    \%+P[%\\d%[^()]%#(%f%r,
                    \%+Q)%r,
                    \%+Q%*[^()])%r,
                    \%+Q[%\\d%*[^()])%r
            endtry
            silent make
        else
            let l:special_tex_compiler = "rubber"
            if executable(l:special_tex_compiler)
                echon "compiling with Rubber ..."
                silent execute "setlocal makeprg=" . l:special_tex_compiler . "\\ -dfs\\ %"
                setlocal errorformat=%f:%l:\ %m
                silent make %
            else
                echon "compiling ..."
                let b:tex_flavor = 'pdflatex'
                compiler tex
                silent make %
            endif
        endif

        " set/report compile status
        if v:shell_error
            let l:success = 0
            " let l:wheight = winheight(bufnr("%")) / 2
            " execute "copen ".l:wheight
            copen
        else
            let l:success = 1
            cclose
            redraw
            echon "successfully compiled"
        endif

        " view results if successful compile
        if l:success && a:view_results
            call ViewTexResults()
        endif

        " restore position
        call setpos('.', save_cursor)

    endfunction

    function! ViewTexResults(...)
        if a:0 == 0
            let l:target = expand("%:p:r") . ".pdf"
        else
            let l:target = a:1
        endif
        if has('mac')
            silent execute "! open -a Preview ".l:target
            " obviously, you will need to write specific commands for other systems
            " left as an exercise for the reader ...
        endif
    endfunction

    command! -buffer -nargs=* BuildTex call BuildTex(0, <f-args>)
    command! -buffer -nargs=* BuildAndViewTex call BuildTex(1, <f-args>)
    noremap <buffer> <silent> <F9> <Esc>:call BuildTex(0)<CR>
    noremap <buffer> <silent> <S-F9> <Esc>:call BuildTex(1)<CR>


更新:我已经将此文件打包并发布为Vim文件类型的插件脚本,可在以下网站获取: http://www.vim.org/scripts/script.php?script_id=3230 .

推荐答案

假设您属于else-theres-no-makefile部分,则问题可能出在shellpipe变量上.

Assuming you're falling into the else-theres-no-makefile section, the issue may be with the shellpipe variable.

在我的系统(Ubuntu)上,如果shellpipe=2>&1| tee和内置make调用失败,则不会设置v:shell_error.

On my system (Ubuntu), shellpipe=2>&1| tee and the built-in make call doesn't set v:shell_error if it fails.

| tee的返回状态可能是v:shell_error所设置的状态.

The return status of | tee might be what v:shell_error is getting set to.

如果您的shell是bash,则可以使用${PIPESTATUS}数组变量来获取正确的退出代码(从

If your shell is bash, you can use the ${PIPESTATUS} array variable to get the correct exit code (borrowed from this answer to another question).

:set shellpipe=2>&1\ \|\ tee\ %s;exit\ \${PIPESTATUS[0]}

否则,您可以尝试:

:set shellpipe=\>
:make %

这会在失败时设置v:shell_error,但是我不确定这是否会与出错代码行功能混淆(如果有的话).

This sets v:shell_error when it fails but I'm not sure if that will mess with the go-to-error-line-number functionality, if there is any.

查看变量设置为什么:

:set shellpipe?

这篇关于Vim脚本仅在没有错误的情况下编译TeX源并启动PDF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆