Source code for bibble.util.str_transform_m
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 bibtexparser.middlewares.middleware import (BlockMiddleware,
26 LibraryMiddleware)
27from bibtexparser.middlewares.names import NameParts
28from bibtexparser import model
29
30# ##-- end 3rd party imports
31
32from .name_parts import NameParts_d
33
34# ##-- types
35# isort: off
36import abc
37import collections.abc
38from typing import TYPE_CHECKING, cast, assert_type, assert_never
39from typing import Generic, NewType
40# Protocols:
41from typing import Protocol, runtime_checkable
42# Typing Decorators:
43from typing import no_type_check, final, override, overload
44
45if TYPE_CHECKING:
46 from jgdv import Maybe, Either, Result
47 from typing import Final
48 from typing import ClassVar, Any, LiteralString
49 from typing import Never, Self, Literal
50 from typing import TypeGuard
51 from collections.abc import Iterable, Iterator, Callable, Generator
52 from collections.abc import Sequence, Mapping, MutableMapping, Hashable
53
54 type String = model.String
55 type StrLike = str|NameParts|list|set|String
56##--|
57
58# isort: on
59# ##-- end types
60
61##-- logging
62logging = logmod.getLogger(__name__)
63##-- end logging
64OBRACE : Final[str] = "{"
65CBRACE : Final[str] = "}"
66
67##--|
68
[docs]
69class StringTransform_m:
70 """ Mixin for handling transform of strings
71 refactored from bibtexparser middlewares.
72
73 Implement _transform_raw_str,
74 and call transform_string_like
75 """
76
[docs]
77 def _transform_all_strings(self, vals:list[str]) -> Result[list[str], ValueError]:
78 """Called for every python (value, not key) string found on Entry and String blocks
79 Errors are modified in place.
80 """
81 res = []
82 errs = []
83 for s in vals:
84 match self._transform_raw_str(s):
85 case ValueError() as x:
86 errs += x.args
87 case str() as x:
88 res.append(x)
89 else:
90 if bool(errs):
91 return ValueError(*errs)
92
93 return res
94
[docs]
95 def _transform_nameparts(self, parts:NameParts) -> Result[NameParts, ValueError]:
96 parts.first = self._transform_all_strings(parts.first)
97 parts.last = self._transform_all_strings(parts.last)
98 parts.von = self._transform_all_strings(parts.von)
99 parts.jr = self._transform_all_strings(parts.jr)
100 return parts
101
[docs]
102 def transform_strlike(self, slike:StrLike) -> Result[StrLike,ValueError]:
103 """
104 Transform str likes: str,s
105 """
106 match slike:
107 case model.String(value=str() as sval):
108 match self.transform_strlike(sval):
109 case ValueError() as err:
110 res = err
111 case str() as x:
112 slike.value = x
113 res = slike
114 case str() as sval if sval.startswith(OBRACE) and sval.endswith(CBRACE):
115 match self._transform_raw_str(sval[0:-1]):
116 case ValueError() as err:
117 res = err
118 case str() as x:
119 res = "".join([OBRACE, x, CBRACE])
120 case str() as sval:
121 res = self._transform_raw_str(sval)
122 case NameParts() as np:
123 res = self._transform_nameparts(np)
124 case list() as vals:
125 res = []
126 errs = []
127 for x in vals:
128 match self.transform_strlike(x):
129 case ValueError() as err:
130 errs += err.args
131 case str() as x:
132 res.append(x)
133 else:
134 if bool(errs):
135 res = ValueError(*errs)
136 case set() as vals:
137 res = []
138 errs = []
139 for x in vals:
140 match self.transform_strlike(x):
141 case ValueError() as err:
142 errs += err.args
143 case str() as x:
144 res.append(x)
145 else:
146 if bool(errs):
147 res = ValueError(*errs)
148 else:
149 res = set(res)
150 case x:
151 logging.info(
152 f" [{self.metadata_key()}] Cannot python-str transform: {x}"
153 f" with value type {type(x)}"
154 )
155 res = x
156
157 return res