summaryrefslogtreecommitdiffstats
path: root/autoload/vimtex/parser.vim
blob: e1a7970f16f72c7a0c2555c312f6f0bfa6d85b8e (plain) (blame)
1
2
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
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1

" vimtex - LaTeX plugin for Vim
"
" Maintainer: Karl Yngve Lervåg
" Email:      karl.yngve@gmail.com
"

function! vimtex#parser#tex(file, ...) abort " {{{1
  return vimtex#parser#tex#parse(a:file, a:0 > 0 ? a:1 : {})
endfunction

" }}}1
function! vimtex#parser#preamble(file, ...) abort " {{{1
  return vimtex#parser#tex#parse_preamble(a:file, a:0 > 0 ? a:1 : {})
endfunction

" }}}1
function! vimtex#parser#auxiliary(file) abort " {{{1
  return vimtex#parser#auxiliary#parse(a:file)
endfunction

" }}}1
function! vimtex#parser#fls(file) abort " {{{1
  return vimtex#parser#fls#parse(a:file)
endfunction

" }}}1
function! vimtex#parser#toc(...) abort " {{{1
  let l:vimtex = a:0 > 0 ? a:1 : b:vimtex

  let l:cache = vimtex#cache#open('parsertoc', {
        \ 'persistent': 0,
        \ 'default': {'entries': [], 'ftime': -1},
        \})
  let l:current = l:cache.get(l:vimtex.tex)

  " Update cache if relevant
  let l:ftime = l:vimtex.getftime()
  if l:ftime > l:current.ftime
    let l:cache.modified = 1
    let l:current.ftime = l:ftime
    let l:current.entries = vimtex#parser#toc#parse(l:vimtex.tex)
  endif

  return deepcopy(l:current.entries)
endfunction

" }}}1
function! vimtex#parser#bib(file, ...) abort " {{{1
  return vimtex#parser#bib#parse(a:file, a:0 > 0 ? a:1 : {})
endfunction

" }}}1

function! vimtex#parser#get_externalfiles() abort " {{{1
  let l:preamble = vimtex#parser#preamble(b:vimtex.tex)

  let l:result = []
  for l:line in filter(l:preamble, 'v:val =~# ''\\externaldocument''')
    let l:name = matchstr(l:line, '{\zs[^}]*\ze}')
    call add(l:result, {
          \ 'tex' : l:name . '.tex',
          \ 'aux' : l:name . '.aux',
          \ 'opt' : matchstr(l:line, '\[\zs[^]]*\ze\]'),
          \ })
  endfor

  return l:result
endfunction

" }}}1
function! vimtex#parser#selection_to_texfile(type, ...) range abort " {{{1
  "
  " Get selected lines. Method depends on type of selection, which may be
  " either of
  "
  " 1. range from argument
  " 2. Command range
  " 3. Visual mapping
  " 4. Operator mapping
  "
  if a:type ==# 'arg'
    let l:lines = getline(a:1[0], a:1[1])
  elseif a:type ==# 'cmd'
    let l:lines = getline(a:firstline, a:lastline)
  elseif a:type ==# 'visual'
    let l:lines = getline(line("'<"), line("'>"))
  else
    let l:lines = getline(line("'["), line("']"))
  endif

  "
  " Use only the part of the selection that is within the
  "
  "   \begin{document} ... \end{document}
  "
  " environment.
  "
  let l:start = 0
  let l:end = len(l:lines)
  for l:n in range(len(l:lines))
    if l:lines[l:n] =~# '\\begin\s*{document}'
      let l:start = l:n + 1
    elseif l:lines[l:n] =~# '\\end\s*{document}'
      let l:end = l:n - 1
      break
    endif
  endfor

  "
  " Check if the selection has any real content
  "
  if l:start >= len(l:lines)
        \ || l:end < 0
        \ || empty(substitute(join(l:lines[l:start : l:end], ''), '\s*', '', ''))
    return {}
  endif

  "
  " Define the set of lines to compile
  "
  let l:lines = vimtex#parser#preamble(b:vimtex.tex)
        \ + ['\begin{document}']
        \ + l:lines[l:start : l:end]
        \ + ['\end{document}']

  "
  " Write content to temporary file
  "
  let l:file = {}
  let l:file.root = b:vimtex.root
  let l:file.base = b:vimtex.name . '_vimtex_selected.tex'
  let l:file.tex  = l:file.root . '/' . l:file.base
  let l:file.pdf = fnamemodify(l:file.tex, ':r') . '.pdf'
  let l:file.log = fnamemodify(l:file.tex, ':r') . '.log'
  call writefile(l:lines, l:file.tex)

  return l:file
endfunction

" }}}1

endif