Example #1
0
def get_globalconfigfilename():
    """ Return the complete path of the global config file, or None if that
        that is not possible. The config file will be created if it does
        not exist.
    """
    globalconfigfilename = None
    try:
        # make sure $HOME environment variable is set
        set_home_env()
        # set config file name as the default:
        # $HOME/.texpreview/CONFIGFILENAME
        if os.path.isdir(os.environ.get("HOME")):
            globalconfigfiledir = os.path.normpath(\
                                    os.path.join(os.environ.get("HOME"), \
                                                ".texpreview"))
            globalconfigfilename = os.path.normpath(\
                                    os.path.join(globalconfigfiledir, \
                                                CONFIGFILENAME))
            if not os.path.isdir(globalconfigfiledir):
                # create new globalconfigdir
                try:
                    Out.write("Creating %s\n" % globalconfigfiledir, \
                                                                VERB_DEBUG)
                    os.mkdir(globalconfigfiledir)
                except OSError, data:
                    Out.write(data + "\n", VERB_WARN)
            if not os.path.isfile(globalconfigfilename):
                create_configfile(globalconfigfilename)
        else:
Example #2
0
def clean_exit(texfileobjects, postcommand):
    """Cleanup, postcommand, exit"""
    Out.write("\n\ntexpreview.py is finishing ...\n")
    cleanup(texfileobjects)
    run_command(postcommand, description = 'postcommand')
    Out.write("\nDone\n")
    sys.exit(0)
Example #3
0
def hard_defaults():
    """ Return an options dict with the hard coded default options """
    Out.write("Setting hard default options\n", VERB_DEBUG)
    options = {}
    options['smart'] = True
    options['noconfig'] = False
    options['watchfiles'] = []
    options['texcompiler'] = 'pdflatex'
    options['compileroptions'] = ''
    options['viewer'] = 'kpdf'
    options['makeindex'] = True
    options['bibtex'] = True
    options['makeindexbin'] = 'makeindex %'
    options['bibtexbin'] = 'makeindex %'
    options['dvi'] = False
    options['exit_after_compile'] = False
    options['dvipdf'] = 'dvipdf %.dvi'
    options['no_cleanup'] = False
    options['extracompiler'] = ''
    options['precommand'] = ''
    options['postcommand'] = ''
    options['verbosity'] = VERB_STATUS
    options['cverbosity'] = VERB_WARN
    options['color'] = False
    options['cleanup'] = '%.dvi %.backup %.blg %.log %.toc %.bbl %.out ' \
                              + '%.bak %.snm %.idx %.ilg %.ind %.nav %.aux ' \
                              + '%.lot %.lof %.preview.pdf'
    options['autowatch'] = True
    return options
Example #4
0
def print_running_message():
    """ Print a message informing the user that the program is running,
        and how it can be controlled
    """
    Out.write("\n\ntexpreview.py is running ... \n\t" \
      + "Press CTRL+C to do a complete unconditional "\
      + "recompile of all files.\n\t" \
      + "Press CTRL+C twice to exit the program\n", VERB_SILENT)
Example #5
0
def run_command(cmd, description=""):
    """ Run cmd in shell """
    if cmd is not None:
        cmd = str(cmd).strip()
        if cmd != '':
            if description != '':
                Out.write("Running %s: %s\n" % (description, cmd))
            else:
                Out.write("Running %s\n" % cmd)
            os.system(cmd + " 2>&1")
Example #6
0
def set_home_env():
    """ Try to make sure the $HOME environment variable is set, even
        on a Windows system.
    """
    if  os.environ.get("HOME") is None:
        Out.write("HOME is not set, we will try to set it.\n", VERB_DEBUG)
        # We're probably on a Windows system.
        # Set HOME as HOMEDRIVE + HOMEPATH
        if  os.environ.get("HOMEDRIVE") is not None \
            and os.environ.get("HOMEPATH") is not None:
            os.environ.setdefault("HOME", \
                os.path.normpath( \
                    os.path.join(os.environ.get("HOMEDRIVE"), \
                                    os.environ.get("HOMEPATH")) ))
            Out.write("Set HOME to '%s'.\n" \
                      % os.environ.get("HOME") , VERB_DEBUG)
Example #7
0
def cmdline_to_dict():
    """ Parse the command line options into a dictionary
    """
    Out.write("Entering cmdline_to_dict\n", VERB_DEBUG)
    try:
        opts, files = getopt.getopt(sys.argv[1:], "hw:c:v:o:e",
                      ["help", "watch=", "compiler=","viewer=", "makeindex",
                       "dvi", "options=", "exit", "nocleanup",
                       "dvipdf=", "config=", "noconfig", "dumpconfig",
                       "bibtex", "bibtexbin=", "makeindexbin=", "nomakeindex",
                       "nobibtex", "precommand=", "postcommand=",
                       'cleanup=', "noautowatch", "autowatch", "smart",
                       "stupid", "extracompiler=", "verbosity=", "debug",
                       "cverbosity=", "color", "nocolor"])
    except getopt.GetoptError, details:
        Out.write(details + "\n", VERB_ERR)
        sys.exit(2)
Example #8
0
def get_configfilelist(cmdlineoptions):
    """ Return a list of configfiles to be used in this run.

        First, there is the global conf file in
            $HOME/.texpreview/texpreview.cfg
        Second, there is a possible local config texpreview.cfg file
            in the current directory.
        Third, there can be an additional file given on the command
            line with the --config switch

       If the --noconfig command line switch is given, global and
       and local conf files are ignored, but files given by --config
       are still parsed
    """
    # Global conf, local conf, take --config from cmdlineoptions
    Out.write("Getting list of configfiles.\n", VERB_DEBUG)
    result = []
    if not cmdlineoptions.has_key('no_config'):
        # add the global and the local config file
        # first, the global config file
        if USE_GLOBAL_CONFIG:
            globalconfigfilename = get_globalconfigfilename()
            if globalconfigfilename is not None:
                result.append(globalconfigfilename)
        # second, the local config file
        localconfigfilename = None
        if os.path.isfile("./" + CONFIGFILENAME):
            localconfigfilename = "./" + CONFIGFILENAME
            result.append(localconfigfilename)
    else:
        Out.write("no_config option is set. No global or local " \
                  + "config file used.\n", VERB_DEBUG)
    # beyond the global and local config file, an additional config file can
    # be given on the command line with the --config option.
    if cmdlineoptions.has_key('config'):
        configfilename = cmdlineoptions['config']
        Out.write("Taking config file %s from command line\n" \
                  % configfilename, VERB_DEBUG)
        if os.path.isfile(configfilename):
            result.append(configfilename)
        else:
            Out.write("Couldn't find the config file %s" % configfilename + \
                " that you provided with --config\n", VERB_WARN)
    Out.write("Returning list of config files: %s\n" % str(result), VERB_DEBUG)
    return result
Example #9
0
def run_compile_loop(texfileobjects):
    """ Run the compile loop for an array of Texfile objects
    """
    Out.write("Going into compile loop.\n", VERB_DEBUG)
    print_running_message()
    while True:
        try:
            time.sleep(1)
            for texfileobject in texfileobjects:
                if texfileobject.has_changed():
                    if texfileobject.options['smart']:
                        texfileobject.smartcompile()
                    else:
                        Out.write("Recompiling in stupid mode\n")
                        texfileobject.run_latex()
                        if texfileobject.options['dvi']:
                            texfileobject.convert_dvi()
                        texfileobject.create_previewfile()
                    print_running_message()
        except KeyboardInterrupt:
            try:
                Out.write("Hit Ctrl+C again to quit\n", VERB_SILENT)
                time.sleep(1)
                for texfileobject in texfileobjects:
                    texfileobject.fullcompile()
                print_running_message()
            except KeyboardInterrupt:
                for texfileobject in texfileobjects:
                    texfileobject.cleanup()
                return True # Success
Example #10
0
def create_configfile(configfilename=None):
    """ Create a new config file with default options at the location
        configfilname, or STDOUT if configfilename is None
    """
    try:
        if configfilename is None:
            configfilename = 'STDOUT'
            configfile = sys.stdout
        else:
            try:
                Out.write("Creating new configfile at %s\n" % configfilename)
                configfile = open(configfilename, "w")
            except IOError, data:
                Out.write("Can't write to %s:%s\n" % (configfilename, data), \
                                                                      VERB_WARN)
                return None
        try:
            configfile.write("[options]\n")
            configfile.write("smart = True\n")
            configfile.write("texcompiler = pdflatex\n")
            configfile.write("compileroptions = \n")
            configfile.write("viewer = kpdf\n")
            configfile.write("bibtex = True\n")
            configfile.write("makeindex = True\n")
            configfile.write("dvi = False\n")
            configfile.write("autowatch = True\n")
            configfile.write("color = False\n")
            configfile.write("verbosity = %s\n" % VERB_STATUS)
            configfile.write("cverbosity = %s\n" % VERB_WARN)
            configfile.write("exit_after_compile = False\n")
            configfile.write("cleanup = %.dvi %.backup %.blg %.log " \
                             + "%.bbl %.out %.bak %.snm %.idx %.ilg %.ind " \
                             +  "%.nav %.aux %.lot %.lof %.toc "
                             +  "%.preview.pdf\n")
            configfile.write("dvipdf = dvipdf %.dvi\n")
            configfile.write("makeindexbin = makeindex %\n")
            configfile.write("bibtexbin = bibtex %\n")
            configfile.write("no_cleanup = False\n")
            configfile.write("precommand = \n")
            configfile.write("postcommand = \n")
            configfile.write("extracompiler = \n")
            configfile.write("\n")
            configfile.write("[files]\n")
            configfile.write("# You can enter the files that you want to " \
                                + "compile in this section.\n")
            configfile.write("#   1 = main1.tex\n")
            configfile.write("#   2 = main2.tex\n")
            configfile.write("#   ...\n")
            configfile.write("\n")
            configfile.write("[watchfiles]\n")
            configfile.write("# You can enter the files that you want " \
                                + "to watch for changes in this section\n")
            configfile.write("#   1 = file1.tex\n")
            configfile.write("#   2 = includes/*.tex\n")
            configfile.write("#   ...\n")
        except IOError, data:
            Out.write("Error writing to %s:%s\n" % (configfilename, data), \
                                                                      VERB_WARN)
Example #11
0
def cleanup(texfileobjects):
    """ Clean up all texfiles before exiting """
    Out.write("Cleaning up\n")
    for texfileobject in texfileobjects:
        texfileobject.cleanup()
    Out.write("Finished Cleanup\n")
Example #12
0
def transfer_options(cmdlineoptions, options):
    """ Transfer the values set in the cmdlineoptions dict into the
        options dict
    """
    Out.write("Entering transfer_options\n", VERB_DEBUG)
    keys = ['watchfiles', 'texcompiler', 'compileroptions', 'dvi',
            'makeindex', 'bibtex', 'makeindexbin', 'bibtexbin',
            'no_cleanup', 'exit_after_compile', 'viewer', 'precommand',
            'postcommand', 'cleanup', 'autowatch', 'extracompiler', 'smart',
            'cverbosity', 'verbosity', 'color']
    for key in keys:
        if cmdlineoptions.has_key(key):
            options[key] = cmdlineoptions[key]
            Out.write("Transferred option '%s' (value '%s') " \
                      % (key, options[key]) \
                      + "from cmdlineoptions to options.\n", VERB_DEBUG)
    if cmdlineoptions.has_key('files'):
        if options.has_key('files'):
            options['files'] += cmdlineoptions['files']
            Out.write("Added files from cmdlineoptions:\n", VERB_DEBUG)
            Out.write("files are now: %s\n" % options['files'], VERB_DEBUG)
        else:
            options['files'] = cmdlineoptions['files']
            Out.write("Set files from cmdlineoptions:\n", VERB_DEBUG)
            Out.write("files are now: %s\n" % options['files'], VERB_DEBUG)
    return options
Example #13
0
def read_configfiles(options, configfiles):
    """ Return an options dict that consists of the original options
        combined with the options set in the config files.

        Declaration of an option in a config file overrides that same
        option in any earlier config file.
    """
    Out.write("Reading options from configfiles: %s\n" \
              % configfiles, VERB_DEBUG)
    result = {}
    # copy original options
    for key in options.keys():
        Out.write("read_configfiles: option '%s' to '%s' " \
                  % (key, options[key]) + "from original options\n", VERB_DEBUG)
        result[key] = options[key]
    # go through the config files
    for configfile in configfiles:
        Out.write("Reading config file from %s\n" % configfile)
        parser = ConfigParser.ConfigParser()
        try:
            parser.read(configfile)
            # get regular options
            fields = {
                'texcompiler' : parser.get,
                'compileroptions' : parser.get,
                'viewer' : parser.get,
                'makeindex' : parser.getboolean,
                'bibtex' : parser.getboolean,
                'makeindexbin' : parser.get,
                'bibtexbin' : parser.get,
                'dvi' : parser.getboolean,
                'exit_after_compile' : parser.getboolean,
                'dvipdf' : parser.get,
                'precommand' : parser.get,
                'postcommand' : parser.get,
                'extracompiler' : parser.get,
                'autowatch' : parser.getboolean,
                'cleanup' : parser.get,
                'smart' : parser.get,
                'no_cleanup' : parser.getboolean,
                'verbosity' : parser.getint,
                'cverbosity' : parser.getint,
                'color' : parser.getboolean
            }
            for field in fields:
                if parser.has_option('options', field):
                    getter = fields[field]
                    result[field] = getter('options', field)
                    Out.write("read_configfiles: Set option " \
                              + "'%s' to '%s' " % (field, result[field]) \
                              +"from config file\n", VERB_DEBUG)
            # get compilation files
            try:
                if parser.has_section('files'):
                    for (field, value) in parser.items('files'):
                        if os.path.isfile(value):
                            try:
                                result['files'].append(value)
                                Out.write("read_configfiles: Appended " \
                                          + "%s to 'files' list.\n" \
                                          % value, VERB_DEBUG)
                            except (IndexError, KeyError):
                                result['files'] = [value]
                                Out.write("read_configfiles: Started 'files' " \
                                          +"list with %s.\n"
                                          % value, VERB_DEBUG)
                        else:
                            Out.write("The file %s " % value \
                                      + "that you want to compile does " \
                                      + "not exist.\n", VERB_ERR)
                else:
                    Out.write("There is no files section in %s\n"
                              % configfile, VERB_DEBUG)
            except:
                Out.write("Error getting compilation files from %s\n" \
                          % configfile, VERB_WARN)
            # get watch files
            try:
                if parser.has_section('watchfiles'):
                    for (field, value) in parser.items('watchfiles'):
                        try:
                            result['watchfiles'].append(value)
                            Out.write("read_configfiles: " \
                                      + "Appended %s to 'watchfiles' list.\n" \
                                      % value, VERB_DEBUG)
                        except (IndexError, KeyError):
                            result['watchfiles'] = [value]
                            Out.write("read_configfiles: Started " \
                                      + "'watchfiles' list with %s.\n" \
                                      % value, VERB_DEBUG)
                else:
                    Out.write("There is no watchfiles section in %s\n" \
                              % configfile, VERB_DEBUG)
            except:
                Out.write("Error getting watch files from %s\n" \
                          % configfile, VERB_WARN)
        except:
            Out.write("Error parsing %s\n" % configfile, VERB_WARN)
    return result
Example #14
0
def main():
    """Command line program for compiling tex files """

    # command line parsing
    cmdlineoptions = cmdline_to_dict()
    configure_output(cmdlineoptions)

    # display help before dealing with config files etc.
    if cmdlineoptions.has_key('help'):
        usage()
        sys.exit()
    # dump config file if that is asked for
    if cmdlineoptions.has_key('dumpconfig'):
        create_configfile()
        sys.exit()

    # hard coded default options
    options = hard_defaults()
    # merge the hard coded defaults with options from the configfiles
    options = read_configfiles(options, get_configfilelist(cmdlineoptions))
    # add options from the  command line
    options = transfer_options(cmdlineoptions, options)
    configure_output(options)


    # Exit if there is no file to compile
    if len(options['files']) == 0:
        Out.write("You have not provided any file to compile. " \
                  "Nothing to do. Exit.\n", VERB_ERR)
        sys.exit(2)

    # Generate Texfile objects
    texfileobjects = []
    for texfile in options['files']:
        if not texfile.endswith('.tex'):
            texfile = texfile + '.tex'
        if os.path.isfile(texfile):
            texfileobject = Texfile(texfile)
            texfileobject.options = options.copy()
            if options['exit_after_compile']:
                texfileobject.options['viewer'] = None
            for watchfile in options['watchfiles']:
                texfileobject.add_watchfile(watchfile)
            texfileobject.options['cleanup'] \
                = options['cleanup'].split()
            texfileobjects.append(texfileobject)
        else:
            Out.write("The file %s that you want to compile does not exist.\n" \
                      % texfile, VERB_ERR)

    # autowatch
    if options['autowatch']:
        for texfileobject in texfileobjects:
            includefiles = texfileobject.get_includes()
            for includefile in includefiles:
                if includefile not in texfileobject.watchfilelist():
                    Out.write("autowatch: Adding %s to %s watchfilelist\n" \
                         % (includefile, texfileobject.filename), VERB_DEBUG)
                    texfileobject.add_watchfile(includefile)

    # Precommand
    run_command(options['precommand'], description = 'precommand')

    # Initial compilation
    for texfileobject in texfileobjects:
        if not texfileobject.firstcompile():
            cleanup(texfileobjects)
            Out.write("Initial compilation failed\n", VERB_ERR)
            exit(2)
        # open viewer
        texfileobject.launch_viewer()

    # exit if --exit
    if options['exit_after_compile']:
        clean_exit(texfileobjects, options['postcommand'])
    # Go into compile loop
    run_compile_loop(texfileobjects)

    # Finish
    clean_exit(texfileobjects, options['postcommand'])
Example #15
0
def configure_output(options_dict):
    """ Set color and verbosity of Out depending on what is set in
        options_dict
    """
    Out.write("Entering configure_output\n", VERB_DEBUG)
    if options_dict.has_key('color'):
        if options_dict['color']:
            Out.activate_color()
    if options_dict.has_key('verbosity'):
        try:
            Out.streams['direct']['verbosity'] = int(options_dict['verbosity'])
            Out.write("Set verbosity to %s\n" \
                               % Out.streams['direct']['verbosity'], VERB_DEBUG)
        except ValueError:
            Out.write("Verbosity was not an integer in configure_output\n", \
                      VERB_WARN)
    if options_dict.has_key('cverbosity'):
        try:
            Out.streams['sub']['verbosity'] = int(options_dict['cverbosity'])
            Out.write("Set cverbosity to %s\n" \
                               % Out.streams['sub']['verbosity'], VERB_DEBUG)
        except ValueError:
            Out.write("Cverbosity was not an integer in configure_output\n", \
                      VERB_WARN)
Example #16
0
# not use a global config file in any way (or create one if it's missing).
# Local config files or config files specified via --config are still
# used.
USE_GLOBAL_CONFIG = True

# Standard filename of the config file. You'll have to adapt the documentation
# if you change this.
CONFIGFILENAME = 'texpreview.cfg'


def samefile(file1, file2):
    """ Fallback replacement for os.path.samefile (e.g. on Windows) """
    return ( os.path.abspath(file1.lower()) == \
                                           os.path.abspath(file2.lower()) )
if not hasattr(os.path, 'samefile'):
    Out.write("Using fallback function for os.path.samefile.\n", VERB_DEBUG)
    os.path.samefile = samefile


def cmdline_to_dict():
    """ Parse the command line options into a dictionary
    """
    Out.write("Entering cmdline_to_dict\n", VERB_DEBUG)
    try:
        opts, files = getopt.getopt(sys.argv[1:], "hw:c:v:o:e",
                      ["help", "watch=", "compiler=","viewer=", "makeindex",
                       "dvi", "options=", "exit", "nocleanup",
                       "dvipdf=", "config=", "noconfig", "dumpconfig",
                       "bibtex", "bibtexbin=", "makeindexbin=", "nomakeindex",
                       "nobibtex", "precommand=", "postcommand=",
                       'cleanup=', "noautowatch", "autowatch", "smart",