forked from SublimeText/LaTeXTools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
latex_installed_packages.py
165 lines (133 loc) · 4.44 KB
/
latex_installed_packages.py
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# -*- coding:utf-8 -*-
from __future__ import print_function
import sublime
import sublime_plugin
import os
import json
from collections import defaultdict
from functools import partial
import threading
import traceback
if sublime.version() < '3000':
# we are on ST2 and Python 2.X
_ST3 = False
strbase = basestring
from latextools_utils.external_command import (
check_output, CalledProcessError
)
else:
_ST3 = True
strbase = str
from .latextools_utils.external_command import (
check_output, CalledProcessError
)
__all__ = ['LatexGenPkgCacheCommand']
def _get_tex_searchpath(file_type):
if file_type is None:
raise Exception('file_type must be set for _get_tex_searchpath')
command = ['kpsewhich']
command.append('--show-path={0}'.format(file_type))
try:
return check_output(command)
except CalledProcessError as e:
sublime.set_timeout(
partial(
sublime.error_message,
'An error occurred while trying to run kpsewhich. '
'Files in your TEXMF tree could not be accessed.'
),
0
)
if e.output:
print(e.output)
traceback.print_exc()
except OSError:
sublime.set_timeout(
partial(
sublime.error_message,
'Could not run kpsewhich. Please ensure that your texpath '
'setting is configured correctly in your LaTeXTools '
'settings.'
),
0
)
traceback.print_exc()
return None
def _get_files_matching_extensions(paths, extensions=[]):
if isinstance(extensions, strbase):
extensions = [extensions]
matched_files = defaultdict(lambda: [])
for path in paths.split(os.pathsep):
# our current directory isn't usually meaningful from a WindowCommand
if path == '.':
continue
# !! sometimes occurs in the results on POSIX; remove them
path = path.replace(u'!!', u'')
path = os.path.normpath(path)
if not os.path.exists(path): # ensure path exists
continue
if len(extensions) > 0:
for _, _, files in os.walk(path):
for f in files:
for ext in extensions:
if f.endswith(u''.join((os.extsep, ext))):
matched_files[ext].append(os.path.splitext(f)[0])
else:
for _, _, files in os.walk(path):
for f in files:
matched_files['*'].append(os.path.splitext(f)[0])
matched_files = dict([(key, sorted(set(value), key=lambda s: s.lower()))
for key, value in matched_files.items()])
return matched_files
def _generate_package_cache():
installed_tex_items = _get_files_matching_extensions(
_get_tex_searchpath('tex'),
['sty', 'cls']
)
installed_bst = _get_files_matching_extensions(
_get_tex_searchpath('bst'),
['bst']
)
# create the cache object
pkg_cache = {
'pkg': installed_tex_items['sty'],
'bst': installed_bst['bst'],
'cls': installed_tex_items['cls']
}
# For ST3, put the cache files in cache dir
# and for ST2, put it in the user packages dir
# and change the name
if _ST3:
cache_path = os.path.normpath(
os.path.join(
sublime.cache_path(),
"LaTeXTools"
))
else:
cache_path = os.path.normpath(
os.path.join(
sublime.packages_path(),
"User"
))
if not os.path.exists(cache_path):
os.makedirs(cache_path)
pkg_cache_file = os.path.normpath(
os.path.join(cache_path, 'pkg_cache.cache' if _ST3 else 'latextools_pkg_cache.cache'))
with open(pkg_cache_file, 'w+') as f:
json.dump(pkg_cache, f)
sublime.set_timeout(
partial(
sublime.status_message,
'Finished generating LaTeX package cache'
),
0
)
# Generates a cache for installed latex packages, classes and bst.
# Used for fill all command for \documentclass, \usepackage and
# \bibliographystyle envrioments
class LatexGenPkgCacheCommand(sublime_plugin.WindowCommand):
def run(self):
# use a separate thread to update cache
thread = threading.Thread(target=_generate_package_cache)
thread.daemon = True
thread.start()