[Python-checkins] python/dist/src/Tools/scripts texcheck.py,1.5,1.6

rhettinger@users.sourceforge.net rhettinger@users.sourceforge.net
Thu, 15 May 2003 20:06:43 -0700


Update of /cvsroot/python/python/dist/src/Tools/scripts
In directory sc8-pr-cvs1:/tmp/cvs-serv17876

Modified Files:
	texcheck.py 
Log Message:
* Added file globbing to make it easier to check many LaTeX files.
* Delimiter mismatch now prints a warning instead of raising an exception.
* Offer style warnings for use of e.g. and i.e.
* Bypass false positive warnings for forward slashes in urls and in /rfc822.
* Put non-LaTex delimiter matching first to make -d option more reliable.


Index: texcheck.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Tools/scripts/texcheck.py,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** texcheck.py	14 May 2003 18:15:55 -0000	1.5
--- texcheck.py	16 May 2003 03:06:39 -0000	1.6
***************
*** 6,16 ****
  Designed to catch common markup errors including:
  * Unbalanced or mismatched parenthesis, brackets, and braces.
! * Unbalanced of mismatched \begin and \end blocks.
  * Misspelled or invalid LaTeX commands.
  * Use of forward slashes instead of backslashes for commands.
! * Table line size mismatches (only \lineii used in a tableii).
  
! Command line usage:
!     python texcheck.py [-h] [-k keyword] foobar.tex
  
  Options:
--- 6,16 ----
  Designed to catch common markup errors including:
  * Unbalanced or mismatched parenthesis, brackets, and braces.
! * Unbalanced or mismatched \\begin and \\end blocks.
  * Misspelled or invalid LaTeX commands.
  * Use of forward slashes instead of backslashes for commands.
! * Table line size mismatches.
  
! Sample command line usage:
!     python texcheck.py -k chapterheading -m lib/librandomtex *.tex
  
  Options:
***************
*** 20,24 ****
      -h:         Help
      -s lineno:  Start at lineno (useful for skipping complex sections).
!     -v:         Verbose.  Shows current delimiter and unclosed delimiters.
  """
  
--- 20,24 ----
      -h:         Help
      -s lineno:  Start at lineno (useful for skipping complex sections).
!     -v:         Verbose.  Trace the matching of //begin and //end blocks.
  """
  
***************
*** 28,31 ****
--- 28,32 ----
  import getopt
  from itertools import izip, count, islice
+ import glob
  
  cmdstr = r"""
***************
*** 64,72 ****
          o_lineno, o_symbol = openers.pop()
      except IndexError:
!         msg = "Delimiter mismatch.  On line %d, encountered closing '%s' without corresponding open" % (c_lineno, c_symbol)
!         raise Exception, msg
      if o_symbol in pairmap.get(c_symbol, [c_symbol]): return
!     msg = "Opener '%s' on line %d was not closed before encountering '%s' on line %d" % (o_symbol, o_lineno, c_symbol, c_lineno)
!     raise Exception, msg
  
  def checkit(source, opts, morecmds=[]):
--- 65,73 ----
          o_lineno, o_symbol = openers.pop()
      except IndexError:
!         print "\nDelimiter mismatch.  On line %d, encountered closing '%s' without corresponding open" % (c_lineno, c_symbol)
!         return
      if o_symbol in pairmap.get(c_symbol, [c_symbol]): return
!     print "\nOpener '%s' on line %d was not closed before encountering '%s' on line %d" % (o_symbol, o_lineno, c_symbol, c_lineno)
!     return
  
  def checkit(source, opts, morecmds=[]):
***************
*** 76,80 ****
          -m          munge parenthesis and brackets
          -d          delimiters only checking
!         -v          verbose listing of delimiters
          -s lineno:  linenumber to start scan (default is 1).
  
--- 77,81 ----
          -m          munge parenthesis and brackets
          -d          delimiters only checking
!         -v          verbose trace of delimiter matching
          -s lineno:  linenumber to start scan (default is 1).
  
***************
*** 94,98 ****
      else:
          pairmap = {']':'[', ')':'('}        # Normal opener for a given closer
!     openpunct = sets.Set('([')  # Set of valid openers
  
      delimiters = re.compile(r'\\(begin|end){([_a-zA-Z]+)}|([()\[\]])')
--- 95,99 ----
      else:
          pairmap = {']':'[', ')':'('}        # Normal opener for a given closer
!     openpunct = sets.Set('([')              # Set of valid openers
  
      delimiters = re.compile(r'\\(begin|end){([_a-zA-Z]+)}|([()\[\]])')
***************
*** 114,135 ****
          line = line.rstrip()
  
!         if '/' in line and '-d' not in opts:
!             # Warn whenever forward slashes encountered with a LaTeX command
!             for cmd in falsetexcmd.findall(line):
!                 if '\\' + cmd in validcmds:
!                     print 'Warning, forward slash used on line %d with cmd: /%s' % (lineno, cmd)
! 
!         if '-d' not in opts:
!             # Validate commands
!             nc = line.find(r'\newcommand')
!             if nc != -1:
!                 start = line.find('{', nc)
!                 end = line.find('}', start)
!                 validcmds.add(line[start+1:end])
!             for cmd in texcmd.findall(line):
!                 if cmd not in validcmds:
!                     print r'Warning, unknown tex cmd on line %d: \%s' % (lineno, cmd)
! 
!         # Check balancing of open/close parenthesis and brackets
          for begend, name, punct in delimiters.findall(line):
              if '-v' in opts:
--- 115,119 ----
          line = line.rstrip()
  
!         # Check balancing of open/close parenthesis, brackets, and begin/end blocks
          for begend, name, punct in delimiters.findall(line):
              if '-v' in opts:
***************
*** 155,160 ****
                  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)
--- 139,163 ----
                  except IndexError:
                      print r'Warning, unmatched } on line %s.' % (lineno,)
! 
!         # Optionally, skip LaTeX specific checks
!         if '-d' in opts:
!             continue
! 
!         # Warn whenever forward slashes encountered with a LaTeX command
!         for cmd in falsetexcmd.findall(line):
!             if '822' in line or '.html' in line:
!                 continue    # Ignore false positives for urls and for /rfc822
!             if '\\' + cmd in validcmds:
!                 print 'Warning, forward slash used on line %d with cmd: /%s' % (lineno, cmd)
! 
!         # Validate commands
!         nc = line.find(r'\newcommand')
!         if nc != -1:
!             start = line.find('{', nc)
!             end = line.find('}', start)
!             validcmds.add(line[start+1:end])
!         for cmd in texcmd.findall(line):
!             if cmd not in validcmds:
!                 print r'Warning, unknown tex cmd on line %d: \%s' % (lineno, cmd)
  
          # Check table levels (make sure lineii only inside tableii)
***************
*** 169,172 ****
--- 172,180 ----
              tablelevel = ''
  
+         # Style guide warnings
+         if 'e.g.' in line or 'i.e.' in line:
+             print r'Style warning, avoid use of i.e or e.g. on line %d' % (lineno,)
+ 
+ 
      lastline = lineno
      for lineno, symbol in openers:
***************
*** 190,202 ****
          return 1
  
      morecmds = [v for k,v in optitems if k=='-k']
  
!     try:
!         f = open(arglist[0])
!     except IOError:
!         print 'Cannot open file %s.' % arglist[0]
!         return 2
  
!     return(checkit(f, opts, morecmds))
  
  if __name__ == '__main__':
--- 198,223 ----
          return 1
  
+     for i, filespec in enumerate(arglist):
+         if '*' in filespec or '?' in filespec:
+             arglist[i:i+1] = glob.glob(filespec)
+ 
      morecmds = [v for k,v in optitems if k=='-k']
+     err = []
  
!     for filename in arglist:
!         print '=' * 30
!         print "Checking", filename
!         try:
!             f = open(filename)
!         except IOError:
!             print 'Cannot open file %s.' % arglist[0]
!             return 2
  
!         try:
!             err.append(checkit(f, opts, morecmds))
!         finally:
!             f.close()
! 
!     return max(err)
  
  if __name__ == '__main__':