Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse nested braces in log #21

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 27 additions & 9 deletions latexrun
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def main():
action=ArgParserWarnAction, dest='nowarns', default=set(['underfull']),
help='Enable/disable warning from CLASS, which can be any package name, '
'LaTeX warning class (e.g., font), bad box type '
'(underfull, overfull, loose, tight), or "all"')
'(underfull, overfull, loose, tight), strict parsing (strict-parse), or "all"')
arg_parser.add_argument(
'-O', metavar='DIR', dest='obj_dir', default='latex.out',
help='Directory for intermediate files and control database '
Expand Down Expand Up @@ -230,6 +230,21 @@ def mkdir_p(path):
pass
else: raise

def nested_parenthesis_end(string, opening, closing, lax_checking=False):
"""Return index where closing character corresponds to opening character"""
stack = []
for i, c in enumerate(string):
if c in opening:
stack.append(c)
elif c in closing and stack:
start_ch = stack.pop()
if not lax_checking and opening.index(start_ch) != closing.index(c):
# Mismatch, e.g. expected ')', found '}'
return -1
if not stack:
return i
return -1

class DB:
"""A latexrun control database."""

Expand Down Expand Up @@ -1272,16 +1287,18 @@ class LaTeXFilter:
self.__file_stack.pop()
else:
self.__message('warning', None,
"extra `)' in log; file names may be wrong ")
"extra `)' in log; file names may be wrong")
elif ch == '{':
# TeX uses this for various things we want to ignore, like
# file names and print_mark. Consume up to the '}'
epos = self.__data.find('}', self.__pos)
if epos != -1:
self.__pos = epos + 1
else:
lax_checking = "strict-parse" in self.__suppress
epos = nested_parenthesis_end(self.__data[self.__pos-1:], '{[(', '}])',
lax_checking=lax_checking)
if epos == -1:
self.__message('warning', None,
"unbalanced `{' in log; file names may be wrong")
else:
self.__pos += epos
elif ch == '}':
self.__message('warning', None,
"extra `}' in log; file names may be wrong")
Expand Down Expand Up @@ -1423,14 +1440,15 @@ class LaTeXFilter:
return
# Back up to the end of the known message text
self.__pos = origpos + m.end()
if self.__lookingat('\n'):
if self.__lookingatre(r'\s*\n'):
# We have a newline, so consume it and look for the
# offending text.
self.__pos += 1
# If there is offending text, it will start with a font
# name, which will start with a \.
if 'hbox' in msg and self.__lookingat('\\'):
self.__consume_line(unwrap=True)
if 'hbox' in msg and self.__lookingatre(r'(\[\]\s?)*\s*\\'):
consumed = self.__consume_line(unwrap=True)
if self.TRACE: print('consuming `<{}>\''.format(consumed))
msg = self.__simplify_message(msg) + ' (page {})'.format(self.__pageno)
cls = msg.split(None, 1)[0].lower()
self.__message('warning', lineno, msg, cls=cls)
Expand Down
16 changes: 16 additions & 0 deletions test/T-mismatched-brace.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
% Test mismatched braces parsing warning.

\documentclass{article}

\begin{document}

\typeout{Error \{ foo bar }

baz.

\end{document}

%% status: 0

%% output:
%% T-mismatched-brace.tex: warning: unbalanced `{' in log; file names may be wrong
19 changes: 19 additions & 0 deletions test/T-mismatched-brace2.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
% Test mismatched braces parsing warning.

\documentclass{article}

\begin{document}

\typeout{Error \{ foo bar ) \} }

baz.

\end{document}

%% status: 0

%% output:
%% T-mismatched-brace2.tex: warning: unbalanced `{' in log; file names may be wrong
%% T-mismatched-brace2.tex: warning: extra `}' in log; file names may be wrong
%% T-mismatched-brace2.tex: warning: extra `)' in log; file names may be wrong

2 changes: 1 addition & 1 deletion test/run
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def test(latexrun_path, latexrun_args, input_path):
if input_path.endswith('.tex'):
cmd = latexrun_cmd + [os.path.basename(input_path)]
elif input_path.endswith('.sh'):
cmd = ['sh', os.path.basename(input_path)] + latexrun_cmd
cmd = ['bash', os.path.basename(input_path)] + latexrun_cmd

p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
cwd=input_dir or None)
Expand Down