diff options
Diffstat (limited to 'support/intex/src/mkintex.py')
-rw-r--r-- | support/intex/src/mkintex.py | 215 |
1 files changed, 215 insertions, 0 deletions
diff --git a/support/intex/src/mkintex.py b/support/intex/src/mkintex.py new file mode 100644 index 0000000000..1b9e74ce0a --- /dev/null +++ b/support/intex/src/mkintex.py @@ -0,0 +1,215 @@ +#! /usr/bin/python +# -*- coding: utf-8 -*- +# $Id$ +from __future__ import with_statement +""" +Copyright (C) 2007, 2008 by Martin Thorsen Ranang + +This file is part of InTeX. + +InTeX is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your +option) any later version. + +InTeX is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with InTeX. If not, see <http://www.gnu.org/licenses/>. +""" +__version__ = "@VERSION@" +__author__ = "Martin Thorsen Ranang <mtr@ranang.org>" + +from contextlib import nested +from itertools import count, imap + +import logging +import optparse +import os +import re +import sys + +from intex.config import INTEX_DEFAULT_INDEX, INTEX_INPUT_EXT, INTEX_OUTPUT_EXT + +from intex.index import Index + +def parse_command_line(command_line_options, usage): + """Parse the command line according to the possible + COMMAND_LINE_OPTIONS. + """ + license_notice = """ +Copyright (C) 2007, 2008 by Martin Thorsen Ranang +License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law. + +Written by Martin Thorsen Ranang.""" + parser = optparse.OptionParser(usage=usage, + version='%%prog %s %s' % (__version__, + license_notice)) + for option, description in command_line_options: + parser.add_option(*option, **description) + + # Parse the command line. + return parser.parse_args() + + +def resolve_auxiliary_and_args(args): + """Resolve the name of the current LaTeX auxiliary file (.aux) + based on the supplied arguments and the current working directory. + """ + aux_re = re.compile('^.*\.aux$', re.IGNORECASE) + auxiliary = [arg for arg in args + if aux_re.match(arg) and os.path.exists(arg)] + args = [arg for arg in args if arg not in auxiliary] + + attempts = count(-2) + + while attempts.next(): + if len(auxiliary) > 1: + logging.error('Please explicitly specify the ' \ + 'LaTeX auxiliary (.aux) file to use.') + sys.exit(1) + + elif not auxiliary: + auxiliary = ['%s.aux' % (arg) for arg in args + if os.path.exists('%s.aux' % (arg))] + args = [arg for arg in args if '%s.aux' % (arg) not in auxiliary] + + else: + auxiliary = auxiliary[0] + break + + return auxiliary, args + + +def main(): + """Module mainline (for standalone execution). + """ + command_line_options = [ + (['-D', '--debug'], + {'dest': 'debug', + 'default': False, + 'action': 'store_true', + 'help': 'whether or not to output debug information'}), + (['-V', '--verbose'], + {'dest': 'verbose', + 'default': False, + 'action': 'store_true', + 'help': 'whether or not to output verbose information'}), + (['-I', '--only-build-index'], + {'dest': 'only_build_index', + 'default': False, + 'action': 'store_true', + 'help': 'only build the internal model of the index'}), + (['-O', '--ito-file'], + {'dest': 'ito_filename', + 'default': None, + 'metavar': 'FILE', + 'help': 'output the new internal InTeX information to FILE ' \ + '(default: %default)'}), + (['-o', '--index-file'], + {'dest': 'index_filename', + 'default': None, + 'metavar': 'FILE', + 'help': 'output the new indexing information to FILE ' \ + '(default: %default)'}), + (['-a', '--acrodef-output'], + {'dest': 'acrodef_output', + 'default': None, + 'metavar': 'FILE', + 'help': 'output acronym definitions to FILE ' \ + '(default: %default)'}), + (['-p', '--persondef-output'], + {'dest': 'persondef_output', + 'default': None, + 'metavar': 'FILE', + 'help': 'output (person) name definitions to FILE ' \ + '(default: %default)'}), + ] + + # Parse the command line options. + options, args = parse_command_line(command_line_options, + usage='%prog [options] ' \ + '<index> [index ...]',) + + # Sort out the name for the basic log. + logging.root.name = os.path.basename(__file__) + + log_level = None + + if options.verbose: + log_level = logging.INFO + if options.debug: + log_level = logging.DEBUG + + # Configure the logging module. + logging.basicConfig(format='%(asctime)s: %(levelname)s: %(message)s', + level=log_level) + + auxiliary, args = resolve_auxiliary_and_args(args) + if not auxiliary: + logging.warning('No LaTeX auxiliary file specified; exiting.') + sys.exit(1) + + if options.index_filename is None: + logging.warning('No output index file specified; exiting.') + sys.exit(1) + + if len(args) == 0: + suffix_re = re.compile('^.*\.%s$' % (INTEX_INPUT_EXT)) + + filenames = [filename + for filename in os.listdir(os.getcwd()) + if suffix_re.match(filename)] + else: + filenames = args + + # If no ITO file was explicitly stated, deduce the implied name. + if options.ito_filename is None: + options.ito_filename = (os.path.splitext(auxiliary)[0] \ + + os.path.extsep + 'ito') + + for filename in filenames: + if not os.path.exists(filename): + logging.error('Input file "%s" not found', filename) + sys.exit(1) + + if options.verbose: + logging.info('Will use "%s" as (main) LaTeX auxiliary file', auxiliary) + logging.info('Will use InTeX input files: %s', + ', '.join(imap('"%s"'.__mod__, filenames))) + + # Instatiate one Index object per file specified on the command + # line. + logging.info('Generating index...') + indices = [Index.from_file(filename) for filename in filenames] + + # Generate all reference indices. + for index in indices: + index.generate_reference_index() + + logging.info('... done (index generated).') + + if options.debug: + for index in indices: + logging.debug('\n%s', index) + + if options.only_build_index: + return + + with nested(open(options.ito_filename, 'w'), + open(options.index_filename, 'w')) \ + as (internal_file, index_file): + not_found = index.interpret_auxiliary(auxiliary, internal_file, + index_file) + + for reference, page in not_found: + logging.warn('On page %s, reference to "%s" was not found ' + 'in the index.', page, reference) + +if __name__ == "__main__": + main() |