#! /usr/bin/python # -*- coding: utf-8 -*- # $Id$ """ 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 . """ __author__ = "Martin Thorsen Ranang " __revision__ = "$Rev$" __version__ = "@VERSION@" import logging from config import FIELD_SEPARATORS from paren_parser import cartesian from entry import Entry class ConceptEntry(Entry): _generated_fields = [ # The values of REFERENCE are how this entry will be referred # to in the text (\co{}). 'reference', 'reference_short', # The values of TYPESET_IN_TEXT determines how the entry will # be typeset in the text. If it was referred to in its plural # form, the entry typeset will also be typeset with plural # inflection. 'typeset_in_text', # The values of TYPESET_IN_INDEX defines how the entry will be # typeset in the index. 'typeset_in_index', ] # Redefining _LINE_FORMAT to handle two Capitalized columns. _line_format = '%(_bold_on)s%%%(_label_width)ds%(_bold_off)s ' \ '%%-%(_column_width)ds ' \ '%%-%(_column_width)ds ' \ '%%-%(_column_width)ds ' \ '%%-%(_column_width)ds' _repr_inflections = ( Entry.INFLECTION_SINGULAR, Entry.INFLECTION_PLURAL, Entry.INFLECTION_SINGULAR_CAPITALIZED, Entry.INFLECTION_PLURAL_CAPITALIZED, ) def __init__(self, index, parent, concept=None, indent_level=None, plural=None, index_as=None, sort_as=None, meta=None, alias=None, **rest): # Set a couple of defining attributes before calling our base # constructor. for attribute in self._generated_fields: setattr(self, attribute, dict.fromkeys([Entry.INFLECTION_SINGULAR, Entry.INFLECTION_PLURAL, ])) # Call the base constructor. Entry.__init__(self, index, parent, meta) # If this entry is an alias for another entry, indicate that # here. self.alias = alias if concept: concept = self.unescape(concept.strip()) else: concept = '' self._setup(concept, self._meta, indent_level) def generate_index_entries(self, page, typeset_page_number=''): inflection = self.index_inflection if self.META_SORT_AS in self._meta: sort_as = self._meta[self.META_SORT_AS] logging.info('Explicit sort key given "%s" (on page %s) => "%s".', self.reference[inflection], page, sort_as) else: sort_as = self.reference[inflection] typeset_in_index = self.typeset_in_index[inflection] # If this is an alias entry, the index entries are affected. # Generate the index entries accordingly. if self.alias: concept, _inflection = self.index.references[self.alias] for entry in concept.generate_index_entries(page, typeset_page_number): yield entry orig_typeset_in_index = concept.typeset_in_index[inflection] yield '\indexentry{%(sort_as)s@' \ '%(typeset_in_index)s|see{%(orig_typeset_in_index)s}}' \ '{0}' % locals() return # Skip the regular index entries. if self.META_COMMENT in self._meta: comment = ' %s' % (self._meta[self.META_COMMENT], ) else: comment = '' parent = self.parent if not parent is None: if self.META_SORT_AS in parent._meta: parent_sort_as = parent._meta[self.META_SORT_AS] logging.info('Explicit parent sort key given "%s" ' '(on page %s) => "%s".', parent.reference[inflection], page, parent_sort_as) else: parent_sort_as = parent.reference[inflection] # Avoid erroneous typesetting of explicit hyphenation # hints. parent_typeset_in_index = self.unescape( parent.typeset_in_index[inflection], '-') #parent_typeset_in_index = parent.typeset_in_index[inflection] yield '\indexentry{' \ '%(parent_sort_as)s@%(parent_typeset_in_index)s!' \ '%(sort_as)s@%(typeset_in_index)s%(comment)s' \ '%(typeset_page_number)s}{%(page)s}' % locals() else: # Avoid erroneous typesetting of explicit hyphenation # hints. typeset_in_index = self.unescape(typeset_in_index, '-') yield '\indexentry{%(sort_as)s@%(typeset_in_index)s%(comment)s' \ '%(typeset_page_number)s}{%(page)s}' \ % locals() def generate_internal_macros(self, inflection): type_name = self.get_entry_type() reference = self.reference[inflection] typeset_in_text = self.typeset_in_text[inflection] #typeset_in_text = self.unescape(self.typeset_in_text[inflection], '-') if self.parent is None: typeset_in_text = self.unescape(typeset_in_text, '-') yield '\\new%(type_name)s{%(reference)s}{%(typeset_in_text)s}' \ '{XC.0}' \ % locals() if self.use_short_reference and self.reference_short[inflection]: reference = self.reference_short[inflection] yield '\\new%(type_name)s{%(reference)s}{%(typeset_in_text)s}' \ '{XC.1}' \ % locals() def get_plain_header(self): return self._line_format \ % (('', ) \ + tuple(self.bold_it(inflection.center(self._column_width)) for inflection in self._repr_inflections)) def __str__(self): if self.alias: alias_line = '\n' \ + self._line_format % ('alias', self.alias, '', '', '') else: alias_line = '' line_fields = [(attribute,) \ + tuple(getattr(self, attribute).has_key(inflection) \ and getattr(self, attribute)[inflection] or '' for inflection in self._repr_inflections) for attribute in self._generated_fields] return '\n'.join([self._line_format % fields for fields in line_fields]) \ + alias_line def _setup(self, concept, meta, indent_level): # Trying to figure out the most appropriate features to # represent a concept entry: (current_inflection, complement_inflection) = \ self.get_current_and_complement_inflection(meta) # The INDEX_INFLECTION value defines how the entry should be # sorted in the index. The value is determined by the value # of INDEX.DEFAULT_INFLECTION and the given inflection of the # current entry. self.index_inflection = current_inflection attribute_variable_map = [ ('reference', 'reference'), ('reference_short', 'reference'), ('typeset_in_text', 'typeset'), ('typeset_in_index', 'typeset')] if indent_level == 0: # If CONCEPT, then the current entry is a main entry. reference, typeset = self.format_reference_and_typeset(concept) reference_short = [] # Only used for sub-entries. for attribute, variable in attribute_variable_map: value = ' '.join(locals()[variable]) getattr(self, attribute)[current_inflection] = value if meta.has_key(Entry.META_COMPLEMENT_INFLECTION): reference, typeset \ = self.format_reference_and_typeset(\ meta[Entry.META_COMPLEMENT_INFLECTION]) else: reference, typeset = \ self.get_complement_inflections(reference, typeset, current_inflection) for attribute, variable in attribute_variable_map: value = ' '.join(locals()[variable]) getattr(self, attribute)[complement_inflection] = value else: # This is a sub-entry. for inflection in (current_inflection, complement_inflection): for attribute, value \ in self.expand_sub_entry(concept, inflection, current_inflection, attribute_variable_map).items(): getattr(self, attribute)[inflection] = value for (inflection, attribute) in cartesian( (Entry.INFLECTION_SINGULAR, Entry.INFLECTION_PLURAL, ), [attribute for (attribute, variable) in attribute_variable_map]): concept = getattr(self, attribute)[inflection] getattr(self, attribute)[inflection] \ = self.unescape(concept.strip(), FIELD_SEPARATORS + '-') if current_inflection == Entry.INFLECTION_NONE: getattr(self, attribute)[inflection] = \ getattr(self, attribute)[Entry.INFLECTION_NONE] # Create capitalized versions of the different inflections. for (inflection, attribute) \ in cartesian((Entry.INFLECTION_SINGULAR, Entry.INFLECTION_PLURAL, Entry.INFLECTION_NONE, ), [attribute for attribute, variable \ in attribute_variable_map[:3]]): if hasattr(self, attribute) \ and getattr(self, attribute).has_key(inflection): original = getattr(self, attribute)[inflection] capitalized = self.capitalize(original) if capitalized != original: capitalized_inflection = Entry._capitalized[inflection] getattr(self, attribute)[capitalized_inflection] = capitalized