Commit 62aa9946 authored by Raymond Hettinger's avatar Raymond Hettinger

* Added separate checks for matching braces.

* Added more LaTex cmds from the docs.
* Blocked forward-slash warnings with delimiters-only option.
* Put help message on shorter line to fit an 80 char screen.
parent b539d05c
...@@ -14,8 +14,8 @@ Command line usage: ...@@ -14,8 +14,8 @@ Command line usage:
python texcheck.py [-h] [-k keyword] foobar.tex python texcheck.py [-h] [-k keyword] foobar.tex
Options: Options:
-m Munge parenthesis and brackets. [0,n) would normally mismatch. -m Munge parenthesis and brackets. [0,n) would normally mismatch.
-k keyword: Keyword is a valid LaTeX command. Do not include the backslash. -k keyword: Keyword is a valid LaTeX command. Do not include the backslash.
-f: Forward-slash warnings suppressed. -f: Forward-slash warnings suppressed.
-d: Delimiter check only (useful for non-LaTeX files). -d: Delimiter check only (useful for non-LaTeX files).
-h: Help -h: Help
...@@ -52,6 +52,11 @@ cmdstr = r""" ...@@ -52,6 +52,11 @@ cmdstr = r"""
\refmodindex \seerfc \makeindex \makemodindex \renewcommand \refmodindex \seerfc \makeindex \makemodindex \renewcommand
\indexname \appendix \protect \indexiv \mbox \textasciitilde \indexname \appendix \protect \indexiv \mbox \textasciitilde
\platform \seeurl \leftmargin \labelwidth \localmoduletable \platform \seeurl \leftmargin \labelwidth \localmoduletable
\LaTeX \copyright \memberline \backslash \pi \centerline
\caption \vspace \textwidth \menuselection \textless
\makevar \csimplemacro \menuselection \bfcode \sub \release
\email \kwindex \refexmodindex \filenq \e \menuselection
\exindex \linev \newsgroup \verbatim \setshortversion
""" """
def matchclose(c_lineno, c_symbol, openers, pairmap): def matchclose(c_lineno, c_symbol, openers, pairmap):
...@@ -85,8 +90,6 @@ def checkit(source, opts, morecmds=[]): ...@@ -85,8 +90,6 @@ def checkit(source, opts, morecmds=[]):
for cmd in morecmds: for cmd in morecmds:
validcmds.add('\\' + cmd) validcmds.add('\\' + cmd)
openers = [] # Stack of pending open delimiters
if '-m' in opts: if '-m' in opts:
pairmap = {']':'[(', ')':'(['} # Munged openers pairmap = {']':'[(', ')':'(['} # Munged openers
else: else:
...@@ -94,6 +97,10 @@ def checkit(source, opts, morecmds=[]): ...@@ -94,6 +97,10 @@ def checkit(source, opts, morecmds=[]):
openpunct = sets.Set('([') # Set of valid openers openpunct = sets.Set('([') # Set of valid openers
delimiters = re.compile(r'\\(begin|end){([_a-zA-Z]+)}|([()\[\]])') delimiters = re.compile(r'\\(begin|end){([_a-zA-Z]+)}|([()\[\]])')
braces = re.compile(r'({)|(})')
openers = [] # Stack of pending open delimiters
bracestack = [] # Stack of pending open braces
tablestart = re.compile(r'\\begin{(?:long)?table([iv]+)}') tablestart = re.compile(r'\\begin{(?:long)?table([iv]+)}')
tableline = re.compile(r'\\line([iv]+){') tableline = re.compile(r'\\line([iv]+){')
...@@ -107,7 +114,7 @@ def checkit(source, opts, morecmds=[]): ...@@ -107,7 +114,7 @@ def checkit(source, opts, morecmds=[]):
for lineno, line in izip(count(startline), islice(source, startline-1, None)): for lineno, line in izip(count(startline), islice(source, startline-1, None)):
line = line.rstrip() line = line.rstrip()
if '-f' not in opts and '/' in line: if '/' in line and '-f' not in opts and '-d' not in opts:
# Warn whenever forward slashes encountered # Warn whenever forward slashes encountered
line = line.rstrip() line = line.rstrip()
print 'Warning, forward slash on line %d: %s' % (lineno, line) print 'Warning, forward slash on line %d: %s' % (lineno, line)
...@@ -123,7 +130,7 @@ def checkit(source, opts, morecmds=[]): ...@@ -123,7 +130,7 @@ def checkit(source, opts, morecmds=[]):
if cmd not in validcmds: if cmd not in validcmds:
print r'Warning, unknown tex cmd on line %d: \%s' % (lineno, cmd) print r'Warning, unknown tex cmd on line %d: \%s' % (lineno, cmd)
# Check balancing of open/close markers (parens, brackets, etc) # Check balancing of open/close parenthesis and brackets
for begend, name, punct in delimiters.findall(line): for begend, name, punct in delimiters.findall(line):
if '-v' in opts: if '-v' in opts:
print lineno, '|', begend, name, punct, print lineno, '|', begend, name, punct,
...@@ -138,6 +145,18 @@ def checkit(source, opts, morecmds=[]): ...@@ -138,6 +145,18 @@ def checkit(source, opts, morecmds=[]):
if '-v' in opts: if '-v' in opts:
print ' --> ', openers print ' --> ', openers
# Balance opening and closing braces
for open, close in braces.findall(line):
if open == '{':
bracestack.append(lineno)
if close == '}':
try:
bracestack.pop()
except IndexError:
print r'Warning, unmatched } on line %s.' % (lineno,)
if '-v' in opts:
print ' --> ', bracestack
# Check table levels (make sure lineii only inside tableii) # Check table levels (make sure lineii only inside tableii)
m = tablestart.search(line) m = tablestart.search(line)
if m: if m:
...@@ -152,6 +171,8 @@ def checkit(source, opts, morecmds=[]): ...@@ -152,6 +171,8 @@ def checkit(source, opts, morecmds=[]):
lastline = lineno lastline = lineno
for lineno, symbol in openers: for lineno, symbol in openers:
print "Unmatched open delimiter '%s' on line %d" % (symbol, lineno) print "Unmatched open delimiter '%s' on line %d" % (symbol, lineno)
for lineno in bracestack:
print "Unmatched { on line %d" % (lineno,)
print 'Done checking %d lines.' % (lastline,) print 'Done checking %d lines.' % (lastline,)
return 0 return 0
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment