X-Git-Url: https://git.mdrn.pl/librarian.git/blobdiff_plain/77004f7537a472419bf9701c8522a774a0c29245..HEAD:/src/librarian/elements/base.py diff --git a/src/librarian/elements/base.py b/src/librarian/elements/base.py index b0d16ed..2d656ae 100644 --- a/src/librarian/elements/base.py +++ b/src/librarian/elements/base.py @@ -37,19 +37,21 @@ class WLElement(etree.ElementBase): EPUB_ATTR = {} EPUB_CLASS = None EPUB_START_CHUNK = False - + + FB2_TAG = None + CAN_HAVE_TEXT = True STRIP = False + NUMBERING = None text_substitutions = [ ('---', '—'), ('--', '–'), - #('...', '…'), # Temporary turnoff for epub + ('...', '…'), (',,', '„'), ('"', '”'), ('\ufeff', ''), - - ("'", "\u2019"), # This was enabled for epub. + ("'", "\u2019"), ] @property @@ -85,6 +87,15 @@ class WLElement(etree.ElementBase): except AttributeError: return parent.in_context_of(setting) + def get_context_map(self, setting, key, default=None): + parent = self.getparent() + if parent is None: + return default + try: + return getattr(parent, setting)[key] + except AttributeError: + return parent.get_context_map(setting, key, default) + def signal(self, signal): parent = self.getparent() if parent is not None: @@ -108,9 +119,9 @@ class WLElement(etree.ElementBase): text = text or '' for e, s in self.text_substitutions: text = text.replace(e, s) - # FIXME: TEmporary turnoff -# text = re.sub(r'\s+', ' ', text) -### TODO: Added now for epub + + if getattr(builder, 'normalize_whitespace', False): + text = re.sub(r'\s+', ' ', text) if getattr(builder, 'hyphenator', None) is not None: newt = '' @@ -124,7 +135,8 @@ class WLElement(etree.ElementBase): return text - def _build_inner(self, builder, build_method): + def build_inner(self, builder): + build_method = builder.build_method_fn child_count = len(self) if self.CAN_HAVE_TEXT and self.text: text = self.normalize_text(self.text, builder) @@ -134,9 +146,14 @@ class WLElement(etree.ElementBase): text = text.rstrip() builder.push_text(text) for i, child in enumerate(self): + real_child_count = 0 if isinstance(child, WLElement): getattr(child, build_method)(builder) - elif getattr(builder, 'debug') and child.tag is etree.Comment: + self.after_child(builder, real_child_count) + real_child_count += 1 + + # FIXME base builder api + elif getattr(builder, 'debug', False) and child.tag is etree.Comment: builder.process_comment(child) if self.CAN_HAVE_TEXT and child.tail: text = self.normalize_text(child.tail, builder) @@ -144,49 +161,77 @@ class WLElement(etree.ElementBase): text = text.rstrip() builder.push_text(text) - def _txt_build_inner(self, builder): - self._build_inner(builder, 'txt_build') + def after_child(self, builder, child_count): + fn = getattr(builder, 'after_child_fn', None) + if fn: + getattr(self, builder.after_child_fn)(builder, child_count) + + def txt_after_child(self, builder, child_count): + pass + + def txt_build_inner(self, builder): + self.build_inner(builder) def txt_build(self, builder): - if hasattr(self, 'TXT_LEGACY_TOP_MARGIN'): - builder.push_legacy_margin(self.TXT_LEGACY_TOP_MARGIN) - else: - builder.push_margin(self.TXT_TOP_MARGIN) + builder.push_margin(self.TXT_TOP_MARGIN) builder.push_text(self.TXT_PREFIX, True) - self._txt_build_inner(builder) + self.txt_build_inner(builder) builder.push_text(self.TXT_SUFFIX, True) - if hasattr(self, 'TXT_LEGACY_BOTTOM_MARGIN'): - builder.push_legacy_margin(self.TXT_LEGACY_BOTTOM_MARGIN) - else: - builder.push_margin(self.TXT_BOTTOM_MARGIN) + builder.push_margin(self.TXT_BOTTOM_MARGIN) - def _html_build_inner(self, builder): - self._build_inner(builder, 'html_build') + def html_build_inner(self, builder): + self.build_inner(builder) def get_html_attr(self, builder): attr = self.HTML_ATTR.copy() if self.HTML_CLASS: attr['class'] = self.HTML_CLASS - # always copy the id attribute (?) - if self.attrib.get('id'): - attr['id'] = self.attrib['id'] - elif getattr(self, 'SHOULD_HAVE_ID', False) and '_compat_section_id' in self.attrib: - attr['id'] = self.attrib['_compat_section_id'] + if builder.with_ids: + # always copy the id attribute (?) + if self.attrib.get('id'): + attr['id'] = self.attrib['id'] + if self.attrib.get('_id'): + attr['id'] = self.attrib['_id'] return attr def html_build(self, builder): + # Do we need a number? + numbering = self.numbering + if numbering == 'main': + if builder.with_numbering and self.has_visible_numbering: + builder.add_visible_number(self) + if self.HTML_TAG: builder.start_element( self.HTML_TAG, self.get_html_attr(builder), ) - self._html_build_inner(builder) + self.html_build_inner(builder) if self.HTML_TAG: builder.end_element() - def _epub_build_inner(self, builder): - self._build_inner(builder, 'epub_build') + def fb2_build(self, builder): + if self.SECTION_PRECEDENCE: + builder.start_section(self.SECTION_PRECEDENCE) + builder.start_element('title') + builder.start_element('p') + + if self.FB2_TAG: + builder.start_element( + self.FB2_TAG, + #self.get_fb2_attr(builder), + ) + + self.build_inner(builder) + if self.FB2_TAG: + builder.end_element() + if self.SECTION_PRECEDENCE: + builder.end_element() + builder.end_element() + + def epub_build_inner(self, builder): + self.build_inner(builder) def get_epub_attr(self, builder): attr = self.EPUB_ATTR.copy() @@ -232,7 +277,7 @@ class WLElement(etree.ElementBase): attr ) - self._epub_build_inner(builder) + self.epub_build_inner(builder) if self.EPUB_TAG: builder.end_element() @@ -315,15 +360,38 @@ class WLElement(etree.ElementBase): return snipelem + @property + def numbering(self): + numbering = self.NUMBERING + if numbering is None or self.in_context_of('DISABLE_NUMBERING'): + return None + numbering = self.get_context_map('SUPPRESS_NUMBERING', numbering, numbering) + return numbering + + @property + def id_prefix(self): + prefix = self.numbering + if prefix == 'main': + # TODO: self.context.main_numbering_prefix + prefix = 'f' # default numbering prefix + return prefix + + def assign_id(self, document): + numbering = self.numbering + if numbering: + number = str(document.counters[numbering]) + self.attrib['_id'] = self.id_prefix + number + document.counters[numbering] += 1 + + if numbering == 'main': + self.attrib['_visible_numbering'] = str(document.counters['_visible']) + document.counters['_visible'] += 1 + + if numbering == 'fn': + self.attrib['_visible_numbering'] = number + def get_link(self): - sec = getattr(self, 'SHOULD_HAVE_ID', False) and self.attrib.get('_compat_section_id') - if sec: - return sec - parent_index = self.getparent().index(self) - if parent_index: - return self.getparent()[parent_index - 1].get_link() - else: - return self.getparent().get_link() + return self.attrib.get('_id') or self.getparent().get_link() class Snippet(WLElement):