kernpy 0.0.2__py3-none-any.whl → 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. kernpy/__init__.py +215 -0
  2. kernpy/__main__.py +217 -0
  3. kernpy/core/__init__.py +119 -0
  4. kernpy/core/_io.py +48 -0
  5. kernpy/core/base_antlr_importer.py +61 -0
  6. kernpy/core/base_antlr_spine_parser_listener.py +196 -0
  7. kernpy/core/basic_spine_importer.py +43 -0
  8. kernpy/core/document.py +965 -0
  9. kernpy/core/dyn_importer.py +30 -0
  10. kernpy/core/dynam_spine_importer.py +42 -0
  11. kernpy/core/error_listener.py +51 -0
  12. kernpy/core/exporter.py +535 -0
  13. kernpy/core/fing_spine_importer.py +42 -0
  14. kernpy/core/generated/kernSpineLexer.interp +444 -0
  15. kernpy/core/generated/kernSpineLexer.py +535 -0
  16. kernpy/core/generated/kernSpineLexer.tokens +236 -0
  17. kernpy/core/generated/kernSpineParser.interp +425 -0
  18. kernpy/core/generated/kernSpineParser.py +9954 -0
  19. kernpy/core/generated/kernSpineParser.tokens +236 -0
  20. kernpy/core/generated/kernSpineParserListener.py +1200 -0
  21. kernpy/core/generated/kernSpineParserVisitor.py +673 -0
  22. kernpy/core/generic.py +426 -0
  23. kernpy/core/gkern.py +526 -0
  24. kernpy/core/graphviz_exporter.py +89 -0
  25. kernpy/core/harm_spine_importer.py +41 -0
  26. kernpy/core/import_humdrum_old.py +853 -0
  27. kernpy/core/importer.py +285 -0
  28. kernpy/core/importer_factory.py +43 -0
  29. kernpy/core/kern_spine_importer.py +73 -0
  30. kernpy/core/mens_spine_importer.py +23 -0
  31. kernpy/core/mhxm_spine_importer.py +44 -0
  32. kernpy/core/pitch_models.py +338 -0
  33. kernpy/core/root_spine_importer.py +58 -0
  34. kernpy/core/spine_importer.py +45 -0
  35. kernpy/core/text_spine_importer.py +43 -0
  36. kernpy/core/tokenizers.py +239 -0
  37. kernpy/core/tokens.py +2011 -0
  38. kernpy/core/transposer.py +300 -0
  39. kernpy/io/__init__.py +14 -0
  40. kernpy/io/public.py +355 -0
  41. kernpy/polish_scores/__init__.py +13 -0
  42. kernpy/polish_scores/download_polish_dataset.py +357 -0
  43. kernpy/polish_scores/iiif.py +47 -0
  44. kernpy/test_grammar.sh +22 -0
  45. kernpy/util/__init__.py +14 -0
  46. kernpy/util/helpers.py +55 -0
  47. kernpy/util/store_cache.py +35 -0
  48. kernpy/visualize_analysis.sh +23 -0
  49. kernpy-1.0.0.dist-info/METADATA +501 -0
  50. kernpy-1.0.0.dist-info/RECORD +51 -0
  51. {kernpy-0.0.2.dist-info → kernpy-1.0.0.dist-info}/WHEEL +1 -2
  52. kernpy/example.py +0 -1
  53. kernpy-0.0.2.dist-info/LICENSE +0 -19
  54. kernpy-0.0.2.dist-info/METADATA +0 -19
  55. kernpy-0.0.2.dist-info/RECORD +0 -7
  56. kernpy-0.0.2.dist-info/top_level.txt +0 -1
@@ -0,0 +1,239 @@
1
+ from __future__ import annotations
2
+
3
+ from copy import deepcopy
4
+ from enum import Enum
5
+ from abc import ABC, abstractmethod
6
+ from typing import List, Union, Set
7
+
8
+ from kernpy.core import DECORATION_SEPARATOR, Token, TOKEN_SEPARATOR
9
+
10
+
11
+ class Encoding(Enum): # TODO: Eventually, polymorphism will be used to export different types of kern files
12
+ """
13
+ Options for exporting a kern file.
14
+
15
+ Example:
16
+ >>> import kernpy as kp
17
+ >>> # Load a file
18
+ >>> doc, _ = kp.load('path/to/file.krn')
19
+ >>>
20
+ >>> # Save the file using the specified encoding
21
+ >>> exported_content = kp.dumps(tokenizer=kp.Encoding.normalizedKern)
22
+ """
23
+ eKern = 'ekern'
24
+ normalizedKern = 'kern'
25
+ bKern = 'bkern'
26
+ bEkern = 'bekern'
27
+
28
+ def prefix(self) -> str:
29
+ """
30
+ Get the prefix of the kern type.
31
+
32
+ Returns (str): Prefix of the kern type.
33
+ """
34
+ if self == Encoding.eKern:
35
+ return 'e'
36
+ elif self == Encoding.normalizedKern:
37
+ return ''
38
+ elif self == Encoding.bKern:
39
+ return 'b'
40
+ elif self == Encoding.bEkern:
41
+ return 'be'
42
+ else:
43
+ raise ValueError(f'Unknown kern type: {self}. '
44
+ f'Supported types are: '
45
+ f"{'-'.join([kern_type.name for kern_type in Encoding.__members__.values()])}")
46
+
47
+
48
+ class Tokenizer(ABC):
49
+ """
50
+ Tokenizer interface. All tokenizers must implement this interface.
51
+
52
+ Tokenizers are responsible for converting a token into a string representation.
53
+ """
54
+ def __init__(self, *, token_categories: Set['TokenCategory']):
55
+ """
56
+ Create a new Tokenizer.
57
+
58
+ Args:
59
+ token_categories Set[TokenCategory]: List of categories to be tokenized.
60
+ If None, an exception will be raised.
61
+ """
62
+ if token_categories is None:
63
+ raise ValueError('Categories must be provided. Found None.')
64
+
65
+ self.token_categories = token_categories
66
+
67
+
68
+ @abstractmethod
69
+ def tokenize(self, token: Token) -> str:
70
+ """
71
+ Tokenize a token into a string representation.
72
+
73
+ Args:
74
+ token (Token): Token to be tokenized.
75
+
76
+ Returns (str): Tokenized string representation.
77
+
78
+ """
79
+ pass
80
+
81
+
82
+ class KernTokenizer(Tokenizer):
83
+ """
84
+ KernTokenizer converts a Token into a normalized kern string representation.
85
+ """
86
+ def __init__(self, *, token_categories: Set['TokenCategory']):
87
+ """
88
+ Create a new KernTokenizer.
89
+
90
+ Args:
91
+ token_categories (Set[TokenCategory]): List of categories to be tokenized. If None will raise an exception.
92
+ """
93
+ super().__init__(token_categories=token_categories)
94
+
95
+ def tokenize(self, token: Token) -> str:
96
+ """
97
+ Tokenize a token into a normalized kern string representation.
98
+ This format is the classic Humdrum **kern representation.
99
+
100
+ Args:
101
+ token (Token): Token to be tokenized.
102
+
103
+ Returns (str): Normalized kern string representation. This is the classic Humdrum **kern representation.
104
+
105
+ Examples:
106
+ >>> token.encoding
107
+ '2@.@bb@-·_·L'
108
+ >>> KernTokenizer().tokenize(token)
109
+ '2.bb-_L'
110
+ """
111
+ return EkernTokenizer(token_categories=self.token_categories).tokenize(token).replace(TOKEN_SEPARATOR, '').replace(DECORATION_SEPARATOR, '')
112
+
113
+
114
+ class EkernTokenizer(Tokenizer):
115
+ """
116
+ EkernTokenizer converts a Token into an eKern (Extended **kern) string representation. This format use a '@' separator for the \
117
+ main tokens and a '·' separator for the decorations tokens.
118
+ """
119
+
120
+ def __init__(self, *, token_categories: Set['TokenCategory']):
121
+ """
122
+ Create a new EkernTokenizer
123
+
124
+ Args:
125
+ token_categories (List[TokenCategory]): List of categories to be tokenized. If None will raise an exception.
126
+ """
127
+ super().__init__(token_categories=token_categories)
128
+
129
+ def tokenize(self, token: Token) -> str:
130
+ """
131
+ Tokenize a token into an eKern string representation.
132
+ Args:
133
+ token (Token): Token to be tokenized.
134
+
135
+ Returns (str): eKern string representation.
136
+
137
+ Examples:
138
+ >>> token.encoding
139
+ '2@.@bb@-·_·L'
140
+ >>> EkernTokenizer().tokenize(token)
141
+ '2@.@bb@-·_·L'
142
+
143
+ """
144
+ return token.export(filter_categories=lambda cat: cat in self.token_categories)
145
+
146
+
147
+ class BekernTokenizer(Tokenizer):
148
+ """
149
+ BekernTokenizer converts a Token into a bekern (Basic Extended **kern) string representation. This format use a '@' separator for the \
150
+ main tokens but discards all the decorations tokens.
151
+ """
152
+
153
+ def __init__(self, *, token_categories: Set['TokenCategory']):
154
+ """
155
+ Create a new BekernTokenizer
156
+
157
+ Args:
158
+ token_categories (Set[TokenCategory]): List of categories to be tokenized. If None will raise an exception.
159
+ """
160
+ super().__init__(token_categories=token_categories)
161
+
162
+ def tokenize(self, token: Token) -> str:
163
+ """
164
+ Tokenize a token into a bekern string representation.
165
+ Args:
166
+ token (Token): Token to be tokenized.
167
+
168
+ Returns (str): bekern string representation.
169
+
170
+ Examples:
171
+ >>> token.encoding
172
+ '2@.@bb@-·_·L'
173
+ >>> BekernTokenizer().tokenize(token)
174
+ '2@.@bb@-'
175
+ """
176
+ ekern_content = token.export(filter_categories=lambda cat: cat in self.token_categories)
177
+
178
+ if DECORATION_SEPARATOR not in ekern_content:
179
+ return ekern_content
180
+
181
+ reduced_content = ekern_content.split(DECORATION_SEPARATOR)[0]
182
+ if reduced_content.endswith(TOKEN_SEPARATOR):
183
+ reduced_content = reduced_content[:-1]
184
+
185
+ return reduced_content
186
+
187
+
188
+ class BkernTokenizer(Tokenizer):
189
+ """
190
+ BkernTokenizer converts a Token into a bkern (Basic **kern) string representation. This format use \
191
+ the main tokens but not the decorations tokens. This format is a lightweight version of the classic
192
+ Humdrum **kern format.
193
+ """
194
+
195
+ def __init__(self, *, token_categories: Set['TokenCategory']):
196
+ """
197
+ Create a new BkernTokenizer
198
+
199
+ Args:
200
+ token_categories (Set[TokenCategory]): List of categories to be tokenized. If None will raise an exception.
201
+ """
202
+ super().__init__(token_categories=token_categories)
203
+
204
+
205
+ def tokenize(self, token: Token) -> str:
206
+ """
207
+ Tokenize a token into a bkern string representation.
208
+ Args:
209
+ token (Token): Token to be tokenized.
210
+
211
+ Returns (str): bkern string representation.
212
+
213
+ Examples:
214
+ >>> token.encoding
215
+ '2@.@bb@-·_·L'
216
+ >>> BkernTokenizer().tokenize(token)
217
+ '2.bb-'
218
+ """
219
+ return BekernTokenizer(token_categories=self.token_categories).tokenize(token).replace(TOKEN_SEPARATOR, '')
220
+
221
+
222
+ class TokenizerFactory:
223
+ @classmethod
224
+ def create(cls, type: str, *, token_categories: List['TokenCategory']) -> Tokenizer:
225
+ if type is None:
226
+ raise ValueError('A tokenization type must be provided. Found None.')
227
+
228
+ if type == Encoding.normalizedKern.value:
229
+ return KernTokenizer(token_categories=token_categories)
230
+ elif type == Encoding.eKern.value:
231
+ return EkernTokenizer(token_categories=token_categories)
232
+ elif type == Encoding.bKern.value:
233
+ return BekernTokenizer(token_categories=token_categories)
234
+ elif type == Encoding.bEkern.value:
235
+ return BkernTokenizer(token_categories=token_categories)
236
+
237
+ raise ValueError(f"Unknown kern type: {type}. "
238
+ f"Supported types are: "
239
+ f"{'-'.join([kern_type.name for kern_type in Encoding.__members__.values()])}")