#! /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 .
"""
__version__ = "@VERSION@"
__author__ = "Martin Thorsen Ranang "
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
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 ...]',)
# 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()