Skip to content
This repository was archived by the owner on Jun 8, 2026. It is now read-only.

Commit 0700066

Browse files
committed
Enhance pyperclip warn. Update requirements
1 parent 4ed90ef commit 0700066

4 files changed

Lines changed: 73 additions & 36 deletions

File tree

pydetex/gui.py

Lines changed: 56 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import ctypes
1818
import os
19+
import platform
1920
import pyperclip
2021
import requests
2122
import string
@@ -25,7 +26,7 @@
2526
from nltk.tokenize import RegexpTokenizer
2627
from outdated import check_outdated
2728
from PyMultiDictionary import MultiDictionary
28-
from typing import Optional, Tuple
29+
from typing import Optional, Tuple, Callable
2930
from warnings import warn
3031

3132
sys.path.append('../')
@@ -36,6 +37,7 @@
3637
import pydetex.utils as ut
3738
import pydetex.version
3839

40+
from pydetex import __url_bug_tracker__
3941
from pydetex._fonts import FONT_TAGS
4042
from pydetex._gui_settings import Settings
4143

@@ -138,7 +140,7 @@ def __init__(self) -> None:
138140
self._tab_spaces = 4
139141

140142
# In text
141-
f1 = tk.Frame(self._root, border=0, width=window_size[0], height=window_size[2])
143+
f1 = tk.Frame(self._root, width=window_size[0], height=window_size[2])
142144
f1.pack(fill='both', padx=10)
143145
f1.pack_propagate(False)
144146

@@ -157,7 +159,7 @@ def __init__(self) -> None:
157159
self._text_in.tab_spaces = self._tab_spaces
158160

159161
# Out text
160-
f2 = tk.Frame(self._root, border=0, width=window_size[0], height=window_size[2])
162+
f2 = tk.Frame(self._root, width=window_size[0], height=window_size[2])
161163
f2.pack(fill='both', padx=10, pady=(window_size[3], 0))
162164
f2.pack_propagate(False)
163165

@@ -199,7 +201,7 @@ def __init__(self) -> None:
199201
# ----------------------------------------------------------------------
200202
# Status bar
201203
# ----------------------------------------------------------------------
202-
ttk.Separator(self._root, orient='horizontal').pack(side='top', fill='x')
204+
ttk.Separator(self._root).pack(side='top', fill='x')
203205
status_fg = '#999999' if ut.IS_OSX else '#666666'
204206

205207
f4 = tk.Frame(self._root, width=window_size[0], height=26)
@@ -208,27 +210,32 @@ def __init__(self) -> None:
208210

209211
# Detected language
210212
show_status = 0.2 if window_size[0] > 750 else 0
211-
self._status_bar_lang = gui_ut.make_label(f4, w=window_size[0] * (0.4 + (0.2 - show_status)), h=20,
212-
side=tk.LEFT, fg=status_fg, bd=0, relief=tk.SUNKEN, anchor=tk.W,
213-
pad=(0, 0, 0, 10), separator=True)
213+
self._status_bar_lang = gui_ut.make_label(
214+
f4, w=window_size[0] * (0.4 + (0.2 - show_status)), h=20,
215+
side=tk.LEFT, fg=status_fg, bd=0, relief=tk.SUNKEN, anchor=tk.W,
216+
pad=(0, 0, 0, 10), separator=True)
214217

215218
# Status
216-
self._status_bar_status = gui_ut.make_label(f4, w=window_size[0] * show_status, h=20, side=tk.LEFT,
217-
fg=status_fg, bd=0, relief=tk.SUNKEN, anchor=tk.W, pad=(0, 0, 0, 5),
218-
separator=True)
219+
self._status_bar_status = gui_ut.make_label(
220+
f4, w=window_size[0] * show_status, h=20, side=tk.LEFT,
221+
fg=status_fg, bd=0, relief=tk.SUNKEN, anchor=tk.W, pad=(0, 0, 0, 5),
222+
separator=True)
219223

220224
# Cursor
221-
self._status_bar_cursor = gui_ut.make_label(f4, w=window_size[0] * 0.11, h=20, side=tk.LEFT, fg=status_fg,
222-
bd=0, relief=tk.SUNKEN, anchor=tk.W, pad=(0, 0, 0, 5))
225+
self._status_bar_cursor = gui_ut.make_label(
226+
f4, w=window_size[0] * 0.11, h=20, side=tk.LEFT, fg=status_fg,
227+
bd=0, relief=tk.SUNKEN, anchor=tk.W, pad=(0, 0, 0, 5))
223228

224229
# Cursor selected
225-
self._status_bar_cursor_sel = gui_ut.make_label(f4, w=window_size[0] * 0.14, h=20, side=tk.LEFT, fg=status_fg,
226-
bd=0, relief=tk.SUNKEN, anchor=tk.W, pad=(0, 0, 0, 5),
227-
separator=True)
230+
self._status_bar_cursor_sel = gui_ut.make_label(
231+
f4, w=window_size[0] * 0.14, h=20, side=tk.LEFT, fg=status_fg,
232+
bd=0, relief=tk.SUNKEN, anchor=tk.W, pad=(0, 0, 0, 5),
233+
separator=True)
228234

229235
# Total processed words
230-
self._status_bar_words = gui_ut.make_label(f4, w=window_size[0] * 0.15, h=20, side=tk.LEFT, fg=status_fg,
231-
bd=0, relief=tk.SUNKEN, anchor=tk.W, pad=(0, 0, 0, 5))
236+
self._status_bar_words = gui_ut.make_label(
237+
f4, w=window_size[0] * 0.15, h=20, side=tk.LEFT, fg=status_fg,
238+
bd=0, relief=tk.SUNKEN, anchor=tk.W, pad=(0, 0, 0, 5))
232239

233240
# ----------------------------------------------------------------------
234241
# Final settings
@@ -240,10 +247,18 @@ def __init__(self) -> None:
240247
self._clip = True
241248
try:
242249
pyperclip.paste()
243-
except pyperclip.PyperclipException:
250+
except Exception as e:
244251
self._clip = False
245-
error = 'pyperclip is not available on your system (copy/paste mechanism). GUI buttons were disabled'
246-
warn(error)
252+
pyperclip_error: str = 'pyperclip is not available on your system (copy/paste mechanism). '
253+
if os.getenv('XDG_SESSION_TYPE') == 'wayland':
254+
pyperclip_error += 'Please install package "wl-clipboard"'
255+
elif platform.system() == 'Linux':
256+
pyperclip_error += 'On Linux, install "xclip" or "xsel"'
257+
else:
258+
pyperclip_error += (f'An unrecognized error happened ({e}). '
259+
f'Please create a new issue on {__url_bug_tracker__}')
260+
pyperclip_error += 'GUI buttons have been disabled'
261+
warn(pyperclip_error)
247262
self._process_clip_button['state'] = tk.DISABLED
248263
self._copy_clip_button['state'] = tk.DISABLED
249264

@@ -263,6 +278,21 @@ def __init__(self) -> None:
263278
self._text_out['state'] = tk.DISABLED
264279
self._root.update()
265280

281+
def __after(self, ms: int, func: Callable) -> str:
282+
"""
283+
Executes function after some milliseconds.
284+
285+
:param ms: Time delay
286+
:param func: Function to be executed
287+
:return: Call ID
288+
"""
289+
try:
290+
# noinspection PyTypeChecker
291+
return self._root.after(ms, func)
292+
except tk.TclError:
293+
pass
294+
return ''
295+
266296
def _open_file(self) -> None:
267297
"""
268298
Opens a file.
@@ -318,7 +348,7 @@ def _status(self, text: str, clear: bool = False, clear_time: int = 500) -> None
318348
self._root.after_cancel(self._status_clear_event_id)
319349
self._status_bar_status['text'] = text
320350
if clear:
321-
self._status_clear_event_id = self._root.after(clear_time, self._status_clear)
351+
self._status_clear_event_id = self.__after(clear_time, self._status_clear)
322352

323353
def _status_clear(self) -> None:
324354
"""
@@ -339,7 +369,7 @@ def _process_in_key(self, event: 'tk.Event') -> Optional['tk.Event']:
339369

340370
if event.char in string.printable and event.char != '':
341371
self._status(self._cfg.lang('status_writing'), True, 1000)
342-
self._detect_language_event_id = self._root.after(100, self._detect_language)
372+
self._detect_language_event_id = self.__after(100, self._detect_language)
343373
self._process_cursor_in(event)
344374
return event
345375

@@ -350,7 +380,7 @@ def _process_cursor_in(self, event: Optional['tk.Event']) -> Optional['tk.Event'
350380
:param event: Event
351381
:return: Event
352382
"""
353-
self._root.after(50, self._process_cursor_event)
383+
self.__after(50, self._process_cursor_event)
354384
return event
355385

356386
def _process_focusin_in(self, event: Optional['tk.Event']) -> Optional['tk.Event']:
@@ -460,8 +490,8 @@ def start(self) -> None:
460490
"""
461491
# noinspection PyProtectedMember
462492
if self._cfg._last_opened_day_diff >= 7:
463-
self._root.after(1000, self._check_version_event)
464-
self._root.after(100, lambda: self._root.lift())
493+
self.__after(1000, self._check_version_event)
494+
self.__after(100, lambda: self._root.lift())
465495
self._text_in.redraw()
466496
self._text_out.redraw()
467497
self._root.mainloop()
@@ -510,7 +540,7 @@ def _process(self) -> None:
510540
self._root['cursor'] = 'wait'
511541
except tk.TclError:
512542
pass
513-
self._root.after(1, lambda: self._process_inner())
543+
self.__after(1, lambda: self._process_inner())
514544

515545
def _process_inner(self) -> None:
516546
"""

pydetex/parsers.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -715,7 +715,9 @@ def output_text_for_some_commands(
715715
# The font format is like .... [font tag]YOUR TAG {[font content]YOUR CONTENT} ...[font normal]. In that case, tag to be
716716
# relaced is 'YOUR TAG {0}, {1}
717717
# All *arguments will be formatted using the tag
718-
commands: List[Tuple[str, List[Union[int, Tuple[int, bool]]], Union[str, Callable[[str, ...], str]], Optional[str], Optional[str], Tuple[bool, bool]]] = [
718+
commands: List[Tuple[
719+
str, List[Union[int, Tuple[int, bool]]], Union[str, Callable[[str, ...], str]], Optional[str], Optional[str], # type: ignore
720+
Tuple[bool, bool]]] = [
719721
('ac', [1], '{0}', 'normal', 'normal', (False, False)), # Acronym
720722
('acf', [1], '{0}', 'normal', 'normal', (False, False)), # Acronym
721723
('acl', [1], '{0}', 'normal', 'normal', (False, False)), # Acronym
@@ -732,11 +734,16 @@ def output_text_for_some_commands(
732734
('hl', [1], '{0}', 'normal', 'hl', (False, False)),
733735
('href', [2], LANG_TT_TAGS.get(lang, 'link'), None, None, (False, False)),
734736
('insertimage', [3], LANG_TT_TAGS.get(lang, 'figure_caption'), None, None, (False, True)), # (Template) Informe
735-
('insertimage', [4], LANG_TT_TAGS.get(lang, 'figure_caption'), None, None, (False, False)), # (Template) Informe
736-
('insertimageboxed', [4], LANG_TT_TAGS.get(lang, 'figure_caption'), None, None, (False, True)), # (Template) Informe
737-
('insertimageboxed', [5], LANG_TT_TAGS.get(lang, 'figure_caption'), None, None, (False, True)), # (Template) Informe
738-
('institutionentry', [1, 2, 3, 4], '{0} ({1}-{2}). {3}', 'normal', 'normal', (False, False)), # (Template) Professional-CV
739-
('institutionentrynodate', [1, 2], '{0}. {3}', 'normal', 'normal', (False, False)), # (Template) Professional-CV
737+
('insertimage', [4], LANG_TT_TAGS.get(lang, 'figure_caption'), None, None, (False, False)),
738+
# (Template) Informe
739+
('insertimageboxed', [4], LANG_TT_TAGS.get(lang, 'figure_caption'), None, None, (False, True)),
740+
# (Template) Informe
741+
('insertimageboxed', [5], LANG_TT_TAGS.get(lang, 'figure_caption'), None, None, (False, True)),
742+
# (Template) Informe
743+
('institutionentry', [1, 2, 3, 4], '{0} ({1}-{2}). {3}', 'normal', 'normal', (False, False)),
744+
# (Template) Professional-CV
745+
('institutionentrynodate', [1, 2], '{0}. {3}', 'normal', 'normal', (False, False)),
746+
# (Template) Professional-CV
740747
('lowercase', [1], lambda t: t.lower(), 'normal', 'normal', (False, False)),
741748
('MakeLowercase', [1], lambda t: t.lower(), 'normal', 'normal', (False, False)),
742749
('MakeUppercase', [1], lambda t: t.upper(), 'normal', 'normal', (False, False)),

pydetex/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,6 @@ def __str__(self) -> str:
3232
patch = property(lambda self: self[2])
3333

3434

35-
vernum = Version(1, 0, 9)
35+
vernum = Version(1, 1, 0)
3636
ver = str(vernum)
3737
rev = ''

requirements.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
beautifulsoup4 >= 4.12.3
1+
beautifulsoup4 >= 4.11.1
22
flatlatex >= 0.15
33
langdetect >= 1.0.9
4-
nltk == 3.8.1
4+
nltk >= 3.9.1
55
outdated >= 0.2.2
66
Pillow >= 9.4.0
7-
PyMultiDictionary >= 1.2.4
7+
PyMultiDictionary >= 1.2.5
88
pyperclip >= 1.9.0
99
requests >= 2.32.3
1010
tkmacosx >= 1.0.5

0 commit comments

Comments
 (0)