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
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 []