X-Git-Url: https://git.mdrn.pl/librarian.git/blobdiff_plain/83cae63af4330912cdb2546c195af2919afd30ac..bd97f61d25eb0c3e51a29286c7de509146eceb37:/src/librarian/document.py diff --git a/src/librarian/document.py b/src/librarian/document.py index 6e94ff2..6cdf191 100644 --- a/src/librarian/document.py +++ b/src/librarian/document.py @@ -4,12 +4,12 @@ import re from lxml import etree import six from .parser import parser -from . import dcparser, DCNS +from . import dcparser, DCNS, DirDocProvider from .functions import lang_code_3to2 class WLDocument: - def __init__(self, filename=None, url=None): + def __init__(self, filename=None, url=None, provider=None): source = filename or six.moves.urllib.request.urlopen(url) tree = etree.parse(source, parser=parser) self.tree = tree @@ -18,6 +18,10 @@ class WLDocument: DCNS('language'): ["pol"], }, validate_required=False) + self.provider = provider if provider is not None else DirDocProvider('.') + + self.tree.getroot().validate() + @property def meta(self): # Allow metadata of the master element as document meta. @@ -25,9 +29,44 @@ class WLDocument: return self.tree.getroot().meta return master.meta - def build(self, builder, **kwargs): - return builder().build(self, **kwargs) + @property + def children(self): + for part_uri in self.meta.parts or []: + yield type(self)( + filename=self.provider.by_slug(part_uri.slug), + provider=self.provider + ) + + def build(self, builder, base_url=None, **kwargs): + return builder(base_url=base_url).build(self, **kwargs) + + def assign_ids(self, existing=None): + # Find all existing IDs. + existing = existing or set() + que = [self.tree.getroot()] + while que: + item = que.pop(0) + try: + item.normalize_insides() + except AttributeError: + pass + existing.add(item.attrib.get('id')) + que.extend(item) + i = 1 + que = [self.tree.getroot()] + while que: + item = que.pop(0) + que.extend(item) + if item.attrib.get('id'): + continue + if not getattr(item, 'SHOULD_HAVE_ID', False): + continue + while f'e{i}' in existing: + i += 1 + item.attrib['id'] = f'e{i}' + i += 1 + def _compat_assign_ordered_ids(self): """ Compatibility: ids in document order, to be roughly compatible with legacy @@ -62,7 +101,22 @@ class WLDocument: def _compat_assigns_section_ids_in_elem(elem, prefix='sec'): for i, child in enumerate(elem): idfier = '{}{}'.format(prefix, i + 1) - child.attrib['_compat_section_id'] = idfier + try: + child.attrib['_compat_section_id'] = idfier + except: + pass _compat_assigns_section_ids_in_elem(child, idfier + '-') _compat_assigns_section_ids_in_elem(self.tree.getroot().master) + + def editors(self): + persons = set(self.meta.editors + + self.meta.technical_editors) + for child in self.children: + persons.update(child.editors()) + if None in persons: + persons.remove(None) + return persons + + def references(self): + return self.tree.findall('.//ref')