| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 
 | "=============================================================================
" 	     File: folding.vim
"      Author: Srinath Avadhanula
"      		   modifications/additions by Zhang Linbo
" 	      CVS: $Id: folding.vim 1031 2008-05-29 22:16:45Z tmaas $
"     Created: Tue Apr 23 05:00 PM 2002 PST
" 
"  Description: functions to interact with Syntaxfolds.vim
"=============================================================================
nnoremap <unique> <Plug>Tex_RefreshFolds :call MakeTexFolds(1)<cr>
augroup LatexSuite
	au LatexSuite User LatexSuiteFileType 
		\ call Tex_Debug('folding.vim: catching LatexSuiteFileType', 'fold') | 
		\ call Tex_SetFoldOptions()
augroup END
" Tex_SetFoldOptions: sets maps for every buffer {{{
" Description: 
function! Tex_SetFoldOptions()
	if exists('b:doneSetFoldOptions')
		return
	endif
	let b:doneSetFoldOptions = 1
	setlocal foldtext=TexFoldTextFunction()
	if g:Tex_Folding && g:Tex_AutoFolding
		call MakeTexFolds(0)
	endif
	let s:ml = exists('g:mapleader') ? g:mapleader : "\\"
	call Tex_MakeMap(s:ml."rf", "<Plug>Tex_RefreshFolds", 'n', '<silent> <buffer>')
endfunction " }}}
" Tex_FoldSections: creates section folds {{{
" Author: Zhang Linbo
" Description:
" 	This function takes a comma seperated list of "sections" and creates fold
" 	definitions for them. The first item is supposed to be the "shallowest" field
" 	and the last is the "deepest". See g:Tex_FoldedSections for the default
" 	definition of the lst input argument.
"
" 	**works recursively**
function! Tex_FoldSections(lst, endpat)
	let i = match(a:lst, ',')
	if i > 0
		let s = strpart(a:lst, 0, i)
	else
		let s = a:lst
	endif
	if s =~ '%%fakesection'
		let s = '^\s*' . s
	else
		let s = '^\s*\\' . s . '\W'
	endif
	let endpat = s . '\|' . a:endpat
	if i > 0
		call Tex_FoldSections(strpart(a:lst,i+1), endpat)
	endif
	let endpat = '^\s*\\appendix\W\|' . endpat
	call AddSyntaxFoldItem(s, endpat, 0, -1)
endfunction
" }}}
" MakeTexFolds: function to create fold items for latex. {{{
"
" used in conjunction with MakeSyntaxFolds().
" see ../plugin/syntaxFolds.vim for documentation
function! MakeTexFolds(force)
	if exists('g:Tex_Folding') && !g:Tex_Folding
		return
	endif
	if &ft != 'tex'
		return
	end
	" Setup folded items lists g:Tex_Foldedxxxx
	" 	1. Use default value if g:Tex_Foldedxxxxxx is not defined
	" 	2. prepend default value to g:Tex_Foldedxxxxxx if it starts with ','
	" 	3. append default value to g:Tex_Foldedxxxxxx if it ends with ','
	" Folding items which are not caught in any of the standard commands,
	" environments or sections.
	let s = 'item,slide,preamble,<<<'
	if !exists('g:Tex_FoldedMisc')
		let g:Tex_FoldedMisc = s
	elseif g:Tex_FoldedMisc[0] == ','
		let g:Tex_FoldedMisc = s . g:Tex_FoldedMisc
	elseif g:Tex_FoldedMisc =~ ',$'
		let g:Tex_FoldedMisc = g:Tex_FoldedMisc . s
	endif
	" By default do not fold any commands. It looks like trying to fold
	" commands is a difficult problem since commands can be arbitrarily nested
	" and the end patterns are not unique unlike the case of environments.
	" For this to work well, we need a regexp which will match a line only if
	" a command begins on that line but does not end on that line. This
	" requires a regexp which will match unbalanced curly braces and that is
	" apparently not doable with regexps.
	let s = ''
    if !exists('g:Tex_FoldedCommands')
		let g:Tex_FoldedCommands = s
	elseif g:Tex_FoldedCommands[0] == ','
		let g:Tex_FoldedCommands = s . g:Tex_FoldedCommands
	elseif g:Tex_FoldedCommands =~ ',$'
		let g:Tex_FoldedCommands = g:Tex_FoldedCommands . s
	endif
	let s = 'verbatim,comment,eq,gather,align,figure,table,thebibliography,'
			\. 'keywords,abstract,titlepage'
    if !exists('g:Tex_FoldedEnvironments')
		let g:Tex_FoldedEnvironments = s
	elseif g:Tex_FoldedEnvironments[0] == ','
		let g:Tex_FoldedEnvironments = s . g:Tex_FoldedEnvironments
	elseif g:Tex_FoldedEnvironments =~ ',$'
		let g:Tex_FoldedEnvironments = g:Tex_FoldedEnvironments . s
	endif
	
    if !exists('g:Tex_FoldedSections')
		let g:Tex_FoldedSections = 'part,chapter,section,%%fakesection,'
								\. 'subsection,subsubsection,paragraph'
	endif
	" the order in which these calls are made decides the nestedness. in
	" latex, a table environment will always be embedded in either an item or
	" a section etc. not the other way around. so we first fold up all the
	" tables. and then proceed with the other regions.
	let b:numFoldItems = 0
	" ========================================================================
	" How to add new folding items {{{
	" ========================================================================
	"
	" Each of the following function calls defines a syntax fold region. Each
	" definition consists of a call to the AddSyntaxFoldItem() function.
	" 
	" The order in which the folds are defined is important. Juggling the
	" order of the function calls will create havoc with folding. The
	" "deepest" folding item needs to be called first. For example, if
	" the \begin{table} environment is a subset (or lies within) the \section
	" environment, then add the definition for the \table first.
	"
	" The AddSyntaxFoldItem() function takes either 4 or 6 arguments. When it
	" is called with 4 arguments, it is equivalent to calling it with 6
	" arguments with the last two left blank (i.e as empty strings)
	"
	" The explanation for each argument is as follows:
	"    startpat: a line matching this pattern defines the beginning of a fold.
	"    endpat  : a line matching this pattern defines the end of a fold.
	"    startoff: this is the offset from the starting line at which folding will
	"              actually start
	"    endoff  : like startoff, but gives the offset of the actual fold end from
	"              the line satisfying endpat.
	"              startoff and endoff are necessary when the folding region does
	"              not have a specific end pattern corresponding to a start
	"              pattern. for example in latex,
	"              \begin{section}
	"              defines the beginning of a section, but its not necessary to
	"              have a corresponding
	"              \end{section}
	"              the section is assumed to end 1 line _before_ another section
	"              starts.
	"    startskip: a pattern which defines the beginning of a "skipped" region.
	"
	"               For example, suppose we define a \itemize fold as follows:
	"               startpat =  '^\s*\\item',
	"               endpat = '^\s*\\item\|^\s*\\end{\(enumerate\|itemize\|description\)}',
	"               startoff = 0,
	"               endoff = -1
	"
	"               This defines a fold which starts with a line beginning with an
	"               \item and ending one line before a line beginning with an
	"               \item or \end{enumerate} etc.
	"
	"               Then, as long as \item's are not nested things are fine.
	"               However, once items begin to nest, the fold started by one
	"               \item can end because of an \item in an \itemize
	"               environment within this \item. i.e, the following can happen:
	"
	"               \begin{itemize}
	"               \item Some text <------- fold will start here
	"                     This item will contain a nested item
	"                     \begin{itemize} <----- fold will end here because next line contains \item...
	"                     \item Hello
	"                     \end{itemize} <----- ... instead of here.
	"               \item Next item of the parent itemize
	"               \end{itemize}
	"
	"               Therefore, in order to completely define a folding item which
	"               allows nesting, we need to also define a "skip" pattern.
	"               startskip and end skip do that.
	"               Leave '' when there is no nesting.
	"    endskip: the pattern which defines the end of the "skip" pattern for
	"             nested folds.
	"
	"    Example: 
	"    1. A syntax fold region for a latex section is
	"           startpat = "\\section{"
	"           endpat   = "\\section{"
	"           startoff = 0
	"           endoff   = -1
	"           startskip = ''
	"           endskip = ''
	"    Note that the start and end patterns are thus the same and endoff has a
	"    negative value to capture the effect of a section ending one line before
	"    the next starts.
	"    2. A syntax fold region for the \itemize environment is:
	"           startpat = '^\s*\\item',
	"           endpat = '^\s*\\item\|^\s*\\end{\(enumerate\|itemize\|description\)}',
	"           startoff = 0,
	"           endoff = -1,
	"           startskip = '^\s*\\begin{\(enumerate\|itemize\|description\)}',
	"           endskip = '^\s*\\end{\(enumerate\|itemize\|description\)}'
	"     Note the use of startskip and endskip to allow nesting.
	"
	"
	" }}}
	" ========================================================================
	
	" {{{ comment lines
	if g:Tex_FoldedMisc =~ '\<comments\>'
		call AddSyntaxFoldItem (
			\ '^%\([^%]\|[^f]\|[^a]\|[^k]\|[^e]\)',
			\ '^[^%]',
			\ 0,
			\ -1 
			\ )
	endif
	" }}}
	" {{{ items
	if g:Tex_FoldedMisc =~ '\<item\>'
		call AddSyntaxFoldItem (
			\ '^\s*\\item',
			\ '^\s*\\item\|^\s*\\end{\(enumerate\|itemize\|description\)}',
			\ 0,
			\ -1,
			\ '^\s*\\begin{\(enumerate\|itemize\|description\)}',
			\ '^\s*\\end{\(enumerate\|itemize\|description\)}'
			\ )
	endif
	" }}}
	" {{{ title
	if g:Tex_FoldedMisc =~ '\<title\>'
		call AddSyntaxFoldItem (
			\ '^\s*\\title\W',
			\ '^\s*\\maketitle',
			\ 0,
			\ 0
			\ )
	endif
	" }}}
 
	" Commands and Environments {{{
	" Fold the commands and environments in 2 passes.
	let pass = 0
	while pass < 2
		if pass == 0
			let lst = g:Tex_FoldedCommands
		else
			let lst = g:Tex_FoldedEnvironments
		endif
		while lst != ''
			let i = match(lst, ',')
			if i > 0
				let s = strpart(lst, 0, i)
				let lst = strpart(lst, i+1)
			else
				let s = lst
				let lst = ''
			endif
			if s != ''
				if pass == 0
					" NOTE: This pattern ensures that a command which is
					" terminated on the same line will not start a fold.
					" However, it will also refuse to fold certain commands
					" which have not terminated. eg:
					" 	\commandname{something \bf{text} and 
					" will _not_ start a fold.
					" In other words, the pattern is safe, but not exact.
					call AddSyntaxFoldItem('^\s*\\'.s.'{[^{}]*$','^[^}]*}',0,0)
				else
					call AddSyntaxFoldItem('^\s*\\begin{'.s,'\(^\|\s\)\s*\\end{'.s,0,0)
				endif
			endif
		endwhile
		let pass = pass + 1
	endwhile
	" }}}
	" Sections {{{
	if g:Tex_FoldedSections != '' 
		call Tex_FoldSections(g:Tex_FoldedSections,
			\ '^\s*\\frontmatter\|^\s*\\mainmatter\|^\s*\\backmatter\|'
			\. '^\s*\\begin{thebibliography\|>>>\|^\s*\\endinput\|'
			\. '^\s*\\begin{slide\|^\s*\\end{document')
	endif
	" }}} 
	
	" {{{ slide
	if g:Tex_FoldedMisc =~ '\<slide\>'
		call AddSyntaxFoldItem (
			\ '^\s*\\begin{slide',
			\ '^\s*\\appendix\W\|^\s*\\chapter\W\|^\s*\\end{slide\|^\s*\\end{document',
			\ 0,
			\ 0
			\ )
	endif
	" }}}
	" {{{ preamble
	if g:Tex_FoldedMisc =~ '\<preamble\>'
		call AddSyntaxFoldItem (
			\ '^\s*\\document\(class\|style\).*{',
			\ '^\s*\\begin{document}',
			\ 0,
			\ -1 
			\ )
	endif
	" }}}
	" Manually folded regions {{{
	if g:Tex_FoldedMisc =~ '\(^\|,\)<<<\(,\|$\)'
		call AddSyntaxFoldItem (
			\ '<<<',
			\ '>>>',
			\ 0,
			\ 0
			\ )
	endif
	" }}}
	
	call MakeSyntaxFolds(a:force)
	normal! zv
endfunction
" }}}
" TexFoldTextFunction: create fold text for folds {{{
function! TexFoldTextFunction()
	let leadingSpace = matchstr('                                       ', ' \{,'.indent(v:foldstart).'}')
	if getline(v:foldstart) =~ '^\s*\\begin{'
		let header = matchstr(getline(v:foldstart),
							\ '^\s*\\begin{\zs\([:alpha:]*\)[^}]*\ze}')
		let caption = ''
		let label = ''
		let i = v:foldstart
		while i <= v:foldend
			if getline(i) =~ '\\caption'
				" distinguish between
				" \caption{fulldesc} - fulldesc will be displayed
				" \caption[shortdesc]{fulldesc} - shortdesc will be displayed
				if getline(i) =~ '\\caption\['
					let caption = matchstr(getline(i), '\\caption\[\zs[^\]]*')
					let caption = substitute(caption, '\zs\]{.*}[^}]*$', '', '')
				else
					let caption = matchstr(getline(i), '\\caption{\zs.*')
					let caption = substitute(caption, '\zs}[^}]*$', '', '')
				end
			elseif getline(i) =~ '\\label'
				let label = matchstr(getline(i), '\\label{\zs.*')
				" :FIXME: this does not work when \label contains a
				" newline or a }-character
				let label = substitute(label, '\([^}]*\)}.*$', '\1', '')
			end
			let i = i + 1
		endwhile
		let ftxto = foldtext()
		" if no caption found, then use the second line.
		if caption == ''
			let caption = getline(v:foldstart + 1)
		end
		let retText = matchstr(ftxto, '^[^:]*').': '.header.
						\ ' ('.label.'): '.caption
		return leadingSpace.retText
	elseif getline(v:foldstart) =~ '^%' && getline(v:foldstart) !~ '^%%fake'
		let ftxto = foldtext()
		return leadingSpace.substitute(ftxto, ':', ': % ', '')
	elseif getline(v:foldstart) =~ '^\s*\\document\(class\|style\).*{'
		let ftxto = leadingSpace.foldtext()
		return substitute(ftxto, ':', ': Preamble: ', '')
	else
		return leadingSpace.foldtext()
	end
endfunction
" }}}
" vim:fdm=marker:ff=unix:noet:ts=4:sw=4
 |