LaTeX.py
上传用户:market2
上传日期:2018-11-18
资源大小:18786k
文件大小:5k
源码类别:

外挂编程

开发平台:

Windows_Unix

  1. """SCons.Scanner.LaTeX
  2. This module implements the dependency scanner for LaTeX code.
  3. """
  4. #
  5. # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
  6. #
  7. # Permission is hereby granted, free of charge, to any person obtaining
  8. # a copy of this software and associated documentation files (the
  9. # "Software"), to deal in the Software without restriction, including
  10. # without limitation the rights to use, copy, modify, merge, publish,
  11. # distribute, sublicense, and/or sell copies of the Software, and to
  12. # permit persons to whom the Software is furnished to do so, subject to
  13. # the following conditions:
  14. #
  15. # The above copyright notice and this permission notice shall be included
  16. # in all copies or substantial portions of the Software.
  17. #
  18. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
  19. # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  20. # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  21. # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  22. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  23. # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  24. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25. #
  26. __revision__ = "src/engine/SCons/Scanner/LaTeX.py 3057 2008/06/09 22:21:00 knight"
  27. import os.path
  28. import string
  29. import SCons.Scanner
  30. def LaTeXScanner():
  31.     """Return a prototype Scanner instance for scanning LaTeX source files"""
  32.     ds = LaTeX(name = "LaTeXScanner",
  33.                suffixes =  '$LATEXSUFFIXES',
  34.                path_variable = 'TEXINPUTS',
  35.                regex = '\\(include|includegraphics(?:[[^]]+])?|input|bibliography|usepackage){([^}]*)}',
  36.                recursive = 0)
  37.     return ds
  38. class LaTeX(SCons.Scanner.Classic):
  39.     """Class for scanning LaTeX files for included files.
  40.     Unlike most scanners, which use regular expressions that just
  41.     return the included file name, this returns a tuple consisting
  42.     of the keyword for the inclusion ("include", "includegraphics",
  43.     "input", or "bibliography"), and then the file name itself.  
  44.     Based on a quick look at LaTeX documentation, it seems that we 
  45.     need a should append .tex suffix for the "include" keywords, 
  46.     append .tex if there is no extension for the "input" keyword, 
  47.     but leave the file name untouched for "includegraphics." For
  48.     the "bibliography" keyword we need to add .bib if there is
  49.     no extension. (This need to be revisited since if there
  50.     is no extension for an "includegraphics" keyword latex will 
  51.     append .ps or .eps to find the file; while pdftex will use 
  52.     other extensions.)
  53.     """
  54.     def latex_name(self, include):
  55.         filename = include[1]
  56.         if include[0] == 'input':
  57.             base, ext = os.path.splitext( filename )
  58.             if ext == "":
  59.                 filename = filename + '.tex'
  60.         if (include[0] == 'include'):
  61.             filename = filename + '.tex'
  62.         if include[0] == 'bibliography':
  63.             base, ext = os.path.splitext( filename )
  64.             if ext == "":
  65.                 filename = filename + '.bib'
  66.         if include[0] == 'usepackage':
  67.             base, ext = os.path.splitext( filename )
  68.             if ext == "":
  69.                 filename = filename + '.sty'
  70.         return filename
  71.     def sort_key(self, include):
  72.         return SCons.Node.FS._my_normcase(self.latex_name(include))
  73.     def find_include(self, include, source_dir, path):
  74.         i = SCons.Node.FS.find_file(self.latex_name(include),
  75.                                     (source_dir,) + path)
  76.         return i, include
  77.     def scan(self, node, path=()):
  78.         #
  79.         # Modify the default scan function to allow for the regular
  80.         # expression to return a comma separated list of file names
  81.         # as can be the case with the bibliography keyword.
  82.         #
  83.         # cache the includes list in node so we only scan it once:
  84.         if node.includes != None:
  85.             includes = node.includes
  86.         else:
  87.             includes = self.cre.findall(node.get_contents())
  88.             node.includes = includes
  89.         # This is a hand-coded DSU (decorate-sort-undecorate, or
  90.         # Schwartzian transform) pattern.  The sort key is the raw name
  91.         # of the file as specifed on the #include line (including the
  92.         # " or <, since that may affect what file is found), which lets
  93.         # us keep the sort order constant regardless of whether the file
  94.         # is actually found in a Repository or locally.
  95.         nodes = []
  96.         source_dir = node.get_dir()
  97.         for include in includes:
  98.             #
  99.             # Handle multiple filenames in include[1]
  100.             #
  101.             inc_list = string.split(include[1],',')
  102.             for j in range(len(inc_list)):
  103.                 include_local = [include[0],inc_list[j]]
  104.                 n, i = self.find_include(include_local, source_dir, path)
  105.             if n is None:
  106.                 SCons.Warnings.warn(SCons.Warnings.DependencyWarning,
  107.                                     "No dependency generated for file: %s (included from: %s) -- file not found" % (i, node))
  108.             else:
  109.                 sortkey = self.sort_key(include)
  110.                 nodes.append((sortkey, n))
  111.         nodes.sort()
  112.         nodes = map(lambda pair: pair[1], nodes)
  113.         return nodes