Initial import of my home directory
[home/.git] / .vim / compiler / tex.vim
1 "            File: tex.vim
2 "            Type: compiler plugin for LaTeX
3 " Original Author: Artem Chuprina <ran@ran.pp.ru>
4 "   Customization: Srinath Avadhanula <srinath@fastmail.fm>
5 "             CVS: $Id: tex.vim 997 2006-03-20 09:45:45Z srinathava $
6 " Description:  {{{
7 "   This file sets the 'makeprg' and 'errorformat' options for the LaTeX
8 "   compiler. It is customizable to optionally ignore certain warnings and
9 "   provides the ability to set a dynamic 'ignore-warning' level.
10 "
11 "   By default it is set up in a 'non-verbose', 'ignore-common-warnings' mode,
12 "   which means that irrelevant lines from the compilers output will be
13 "   ignored and also some very common warnings are ignored.
14 "   
15 "   Depending on the 'ignore-level', the following kinds of messages are
16 "   ignored. An ignore level of 3 for instance means that messages 1-3 will be
17 "   ignored. By default, the ignore level is set to 4. 
18 "
19 "   1. LaTeX Warning: Specifier 'h' changed to 't'. 
20 "      This errors occurs when TeX is not able to correctly place a floating
21 "      object at a specified location, because of which it defaulted to the
22 "      top of the page.
23 "   2. LaTeX Warning: Underfull box ...
24 "   3. LaTeX Warning: Overfull box ...
25 "      both these warnings (very common) are due to \hbox settings not being
26 "      satisfied nicely.
27 "   4. LaTeX Warning: You have requested ..., 
28 "      This warning occurs in slitex when using the xypic package.
29 "   5. Missing number error:
30 "      Usually, when the name of an included eps file is spelled incorrectly,
31 "      then the \bb-error message is accompanied by a bunch of "missing
32 "      number, treated as zero" error messages. This level ignores these
33 "      warnings.
34 "      NOTE: number 5 is actually a latex error, not a warning!
35 "
36 "   Use 
37 "       TCLevel <level>
38 "   where level is a number to set the ignore level dynamically.
39 "
40 "   When TCLevel is called with the unquoted string strict
41 "      TClevel strict
42 "    then the 'efm' switches to a 'verbose', 'no-lines-ignored' mode which is
43 "    useful when you want to make final checks of your document and want to be
44 "    careful not to let things slip by.
45
46 " TIP: MikTeX has a bug where it sometimes erroneously splits a line number
47 "      into multiple lines. i.e, if the warning is on line 1234. the compiler
48 "      output is:
49 "      LaTeX Warning: ... on input line 123
50 "      4.
51 "      In this case, vim will wrongly interpret the line-number as 123 instead
52 "      of 1234. If you have cygwin, a simple remedy around this is to first
53 "      copy the file vimlatex (provided) into your $PATH, make sure its
54 "      executable and then set the variable g:tex_flavor to vimlatex in your
55 "      ~/.vimrc (i.e putting let "g:tex_flavor = 'vimlatex'" in your .vimrc).
56 "      This problem occurs rarely enough that its not a botheration for most
57 "      people.
58 "
59 " TODO:
60 "   1. menu items for dynamically selecting a ignore warning level.
61 " }}}
62
63 " avoid reinclusion for the same buffer. keep it buffer local so it can be
64 " externally reset in case of emergency re-sourcing.
65 if exists('b:doneTexCompiler') && !exists('b:forceRedoTexCompiler')
66         finish
67 endif
68 let b:doneTexCompiler = 1
69
70 " ==============================================================================
71 " Customization of 'efm':  {{{
72 " This section contains the customization variables which the user can set.
73 " g:Tex_IgnoredWarnings: This variable contains a ยก seperated list of
74 " patterns which will be ignored in the TeX compiler's output. Use this
75 " carefully, otherwise you might end up losing valuable information.
76 if !exists('g:Tex_IgnoredWarnings')
77         let g:Tex_IgnoredWarnings =
78                 \'Underfull'."\n".
79                 \'Overfull'."\n".
80                 \'specifier changed to'."\n".
81                 \'You have requested'."\n".
82                 \'Missing number, treated as zero.'."\n".
83                 \'There were undefined references'."\n".
84                 \'Citation %.%# undefined'
85 endif
86 " This is the number of warnings in the g:Tex_IgnoredWarnings string which
87 " will be ignored.
88 if !exists('g:Tex_IgnoreLevel')
89         let g:Tex_IgnoreLevel = 7
90 endif
91 " There will be lots of stuff in a typical compiler output which will
92 " completely fall through the 'efm' parsing. This options sets whether or not
93 " you will be shown those lines.
94 if !exists('g:Tex_IgnoreUnmatched')
95         let g:Tex_IgnoreUnmatched = 1
96 endif
97 " With all this customization, there is a slight risk that you might be
98 " ignoring valid warnings or errors. Therefore before getting the final copy
99 " of your work, you might want to reset the 'efm' with this variable set to 1.
100 " With that value, all the lines from the compiler are shown irrespective of
101 " whether they match the error or warning patterns.
102 " NOTE: An easier way of resetting the 'efm' to show everything is to do
103 "       TCLevel strict
104 if !exists('g:Tex_ShowallLines')
105         let g:Tex_ShowallLines = 0
106 endif
107
108 " }}}
109 " ==============================================================================
110 " Customization of 'makeprg': {{{
111
112 " There are several alternate ways in which 'makeprg' is set up. 
113 "
114 " Case 1
115 " ------
116 " The first is when this file is a part of latex-suite. In this case, a
117 " variable called g:Tex_DefaultTargetFormat exists, which gives the default
118 " format .tex files should be compiled into. In this case, we use the TTarget
119 " command provided by latex-suite.
120 "
121 " Case 2
122 " ------
123 " The user is using this file without latex-suite AND he wants to directly
124 " specify the complete 'makeprg'. Then he should set the g:Tex_CompileRule_dvi
125 " variable. This is a string which should be directly be able to be cast into
126 " &makeprg. An example of one such string is:
127 "
128 "       g:Tex_CompileRule_dvi = 'pdflatex \\nonstopmode \\input\{$*\}'
129 "
130 " NOTE: You will need to escape back-slashes, {'s etc yourself if you are
131 "       using this file independently of latex-suite.
132 " TODO: Should we also have a check for backslash escaping here based on
133 "       platform?
134 "
135 " Case 3
136 " ------
137 " The use is using this file without latex-suite and he doesnt want any
138 " customization. In this case, this file makes some intelligent guesses based
139 " on the platform. If he doesn't want to specify the complete 'makeprg' but
140 " only the name of the compiler program (for example 'pdflatex' or 'latex'),
141 " then he sets b:tex_flavor or g:tex_flavor. 
142
143 if exists('g:Tex_DefaultTargetFormat')
144         exec 'TTarget '.g:Tex_DefaultTargetFormat
145 elseif exists('g:Tex_CompileRule_dvi')
146         let &l:makeprg = g:Tex_CompileRule_dvi
147 else
148         " If buffer-local variable 'tex_flavor' exists, it defines TeX flavor,
149         " otherwize the same for global variable with same name, else it will be LaTeX
150         if exists("b:tex_flavor")
151                 let current_compiler = b:tex_flavor
152         elseif exists("g:tex_flavor")
153                 let current_compiler = g:tex_flavor
154         else
155                 let current_compiler = "latex"
156         end
157         if has('win32')
158                 let escChars = ''
159         else
160                 let escChars = '{}\'
161         endif
162         " Furthermore, if 'win32' is detected, then we want to set the arguments up so
163         " that miktex can handle it.
164         if has('win32')
165                 let options = '--src-specials'
166         else
167                 let options = ''
168         endif
169         let &l:makeprg = current_compiler . ' ' . options .
170                                 \ escape(' \nonstopmode \input{$*}', escChars)
171 endif
172
173 " }}}
174 " ==============================================================================
175 " Functions for setting up a customized 'efm' {{{
176
177 " IgnoreWarnings: parses g:Tex_IgnoredWarnings for message customization {{{
178 " Description: 
179 function! <SID>IgnoreWarnings()
180         let i = 1
181         while s:Strntok(g:Tex_IgnoredWarnings, "\n", i) != '' &&
182                                 \ i <= g:Tex_IgnoreLevel
183                 let warningPat = s:Strntok(g:Tex_IgnoredWarnings, "\n", i)
184                 let warningPat = escape(substitute(warningPat, '[\,]', '%\\\\&', 'g'), ' ')
185                 exe 'setlocal efm+=%-G%.%#'.warningPat.'%.%#'
186                 let i = i + 1
187         endwhile
188 endfunction 
189
190 " }}}
191 " SetLatexEfm: sets the 'efm' for the latex compiler {{{
192 " Description: 
193 function! <SID>SetLatexEfm()
194
195         let pm = ( g:Tex_ShowallLines == 1 ? '+' : '-' )
196
197         set efm=
198
199         if !g:Tex_ShowallLines
200                 call s:IgnoreWarnings()
201         endif
202
203         setlocal efm+=%E!\ LaTeX\ %trror:\ %m
204         setlocal efm+=%E!\ %m
205
206         setlocal efm+=%+WLaTeX\ %.%#Warning:\ %.%#line\ %l%.%#
207         setlocal efm+=%+W%.%#\ at\ lines\ %l--%*\\d
208         setlocal efm+=%+WLaTeX\ %.%#Warning:\ %m
209
210         exec 'setlocal efm+=%'.pm.'Cl.%l\ %m'
211         exec 'setlocal efm+=%'.pm.'Cl.%l\ '
212         exec 'setlocal efm+=%'.pm.'C\ \ %m'
213         exec 'setlocal efm+=%'.pm.'C%.%#-%.%#'
214         exec 'setlocal efm+=%'.pm.'C%.%#[]%.%#'
215         exec 'setlocal efm+=%'.pm.'C[]%.%#'
216         exec 'setlocal efm+=%'.pm.'C%.%#%[{}\\]%.%#'
217         exec 'setlocal efm+=%'.pm.'C<%.%#>%m'
218         exec 'setlocal efm+=%'.pm.'C\ \ %m'
219         exec 'setlocal efm+=%'.pm.'GSee\ the\ LaTeX%m'
220         exec 'setlocal efm+=%'.pm.'GType\ \ H\ <return>%m'
221         exec 'setlocal efm+=%'.pm.'G\ ...%.%#'
222         exec 'setlocal efm+=%'.pm.'G%.%#\ (C)\ %.%#'
223         exec 'setlocal efm+=%'.pm.'G(see\ the\ transcript%.%#)'
224         exec 'setlocal efm+=%'.pm.'G\\s%#'
225         exec 'setlocal efm+=%'.pm.'O(%*[^()])%r'
226         exec 'setlocal efm+=%'.pm.'P(%f%r'
227         exec 'setlocal efm+=%'.pm.'P\ %\\=(%f%r'
228         exec 'setlocal efm+=%'.pm.'P%*[^()](%f%r'
229         exec 'setlocal efm+=%'.pm.'P(%f%*[^()]'
230         exec 'setlocal efm+=%'.pm.'P[%\\d%[^()]%#(%f%r'
231         if g:Tex_IgnoreUnmatched && !g:Tex_ShowallLines
232                 setlocal efm+=%-P%*[^()]
233         endif
234         exec 'setlocal efm+=%'.pm.'Q)%r'
235         exec 'setlocal efm+=%'.pm.'Q%*[^()])%r'
236         exec 'setlocal efm+=%'.pm.'Q[%\\d%*[^()])%r'
237         if g:Tex_IgnoreUnmatched && !g:Tex_ShowallLines
238                 setlocal efm+=%-Q%*[^()]
239         endif
240         if g:Tex_IgnoreUnmatched && !g:Tex_ShowallLines
241                 setlocal efm+=%-G%.%#
242         endif
243
244 endfunction 
245
246 " }}}
247 " Strntok: extract the n^th token from a list {{{
248 " example: Strntok('1,23,3', ',', 2) = 23
249 fun! <SID>Strntok(s, tok, n)
250         return matchstr( a:s.a:tok[0], '\v(\zs([^'.a:tok.']*)\ze['.a:tok.']){'.a:n.'}')
251 endfun
252
253 " }}}
254 " SetTexCompilerLevel: sets the "level" for the latex compiler {{{
255 function! <SID>SetTexCompilerLevel(...)
256         if a:0 > 0
257                 let level = a:1
258         else
259                 call Tex_ResetIncrementNumber(0)
260                 echo substitute(g:Tex_IgnoredWarnings, 
261                         \ '^\|\n\zs\S', '\=Tex_IncrementNumber(1)." ".submatch(0)', 'g')
262                 let level = input("\nChoose an ignore level: ")
263                 if level == ''
264                         return
265                 endif
266         endif
267         if level == 'strict'
268                 let g:Tex_ShowallLines = 1
269         elseif level =~ '^\d\+$'
270                 let g:Tex_ShowallLines = 0
271                 let g:Tex_IgnoreLevel = level
272         else
273                 echoerr "SetTexCompilerLevel: Unkwown option [".level."]"
274         end
275         call s:SetLatexEfm()
276 endfunction 
277
278 com! -nargs=? TCLevel :call <SID>SetTexCompilerLevel(<f-args>)
279 " }}}
280
281 " }}}
282 " ==============================================================================
283
284 call s:SetLatexEfm()
285
286 if !exists('*Tex_Debug')
287         function! Tex_Debug(...)
288         endfunction
289 endif
290
291 call Tex_Debug("compiler/tex.vim: sourcing this file", "comp")
292
293 " vim: fdm=marker:commentstring=\ \"\ %s