Source code for bibble.fields.field_accumulator

  1#!/usr/bin/env python3
  2"""
  3
  4"""
  5
  6# Imports:
  7from __future__ import annotations
  8
  9# ##-- stdlib imports
 10import datetime
 11import enum
 12import functools as ftz
 13import itertools as itz
 14import logging as logmod
 15import pathlib as pl
 16import re
 17import time
 18import types
 19import weakref
 20from uuid import UUID, uuid1
 21
 22# ##-- end stdlib imports
 23
 24# ##-- 3rd party imports
 25from jgdv import Proto, Mixin
 26import bibtexparser
 27import bibtexparser.model as model
 28from bibtexparser import middlewares as ms
 29from bibtexparser.library import Library
 30from bibtexparser.middlewares.middleware import (BlockMiddleware,
 31                                                 LibraryMiddleware)
 32from jgdv.files.tags import SubstitutionFile
 33
 34# ##-- end 3rd party imports
 35
 36# ##-- 1st party imports
 37from bibble.model import MetaBlock
 38from bibble.util.mixins import ErrorRaiser_m, FieldMatcher_m
 39from bibble import _interface as API
 40from . import _interface as FieldsAPI
 41from bibble.util.middlecore import IdenBlockMiddleware
 42
 43# ##-- end 1st party imports
 44
 45# ##-- types
 46# isort: off
 47import abc
 48import collections.abc
 49from typing import TYPE_CHECKING, cast, assert_type, assert_never
 50from typing import Generic, NewType
 51# Protocols:
 52from typing import Protocol, runtime_checkable
 53# Typing Decorators:
 54from typing import no_type_check, final, override, overload
 55
 56if TYPE_CHECKING:
 57    from jgdv import Maybe, Result
 58    from typing import Final
 59    from typing import ClassVar, Any, LiteralString
 60    from typing import Never, Self, Literal
 61    from typing import TypeGuard
 62    from collections.abc import Iterable, Iterator, Callable, Generator
 63    from collections.abc import Sequence, Mapping, MutableMapping, Hashable
 64
 65    type Entry = model.Entry
 66    type Field = model.Field
 67    type Block = model.Block
 68    from bibtexparser.library import Library
 69
 70##--|
 71
 72# isort: on
 73# ##-- end types
 74
 75##-- logging
 76logging = logmod.getLogger(__name__)
 77##-- end logging
 78
[docs] 79@Proto(API.FieldMatcher_p) 80@Mixin(ErrorRaiser_m, FieldMatcher_m) 81class FieldAccumulator(IdenBlockMiddleware): 82 """ Create a set of all the values of a field, of all entries, in a library. 83 84 'name' : the name of the accumulation block to store result in 85 'fields' : the fields to accumulate values of. 86 87 Fields can be individual values, or lists/sets of values 88 89 """ 90 91 92 def __init__(self, *, name:str, fields:list[str], **kwargs): 93 super().__init__(**kwargs) 94 self._attr_target = name 95 match fields: 96 case list(): 97 self._target_fields = fields 98 case x: 99 raise TypeError(type(x)) 100 101 self.set_field_matchers(white=self._target_fields, black=[]) 102 self._collection = set() 103
[docs] 104 def transform(self, library:Library) -> Library: 105 super().transform(library) 106 library.add(FieldsAPI.AccumulationBlock(name=self._attr_target, data=self._collection, fields=self._target_fields)) 107 return library
108
[docs] 109 def transform_Entry(self, entry, library) -> list[Block]: 110 match self.match_on_fields(entry, library): 111 case model.Entry() as x: 112 return [x] 113 case Exception() as err: 114 return [self.make_error_block(entry, err)] 115 case x: 116 raise TypeError(type(x))
117
[docs] 118 def field_h(self, field, entry) -> Result(list[Field], Exception): 119 match field.value: 120 case str() as value: 121 self._collection.add(value) 122 case list() | set() as value: 123 self._collection.update(value) 124 case x: 125 raise TypeError(type(x)) 126 127 return []