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,196 @@
1
+ from .generated.kernSpineParserListener import kernSpineParserListener
2
+ from .generated.kernSpineParser import kernSpineParser
3
+ from .tokens import BarToken, SimpleToken, TokenCategory, Subtoken, ChordToken, BoundingBox, \
4
+ BoundingBoxToken, ClefToken, KeySignatureToken, TimeSignatureToken, MeterSymbolToken, BarToken, NoteRestToken, \
5
+ KeyToken, InstrumentToken
6
+
7
+ from typing import List
8
+
9
+
10
+ class BaseANTLRSpineParserListener(kernSpineParserListener):
11
+ def __init__(self):
12
+ self.token = None
13
+
14
+ self.first_chord_element = None
15
+ self.chord_tokens = None
16
+ self.duration_subtokens = []
17
+ self.diatonic_pitch_and_octave_subtoken = None
18
+ self.accidental_subtoken = None
19
+ # self.decorations = {} # in order to standardize the order of decorators, we map the different properties to their class names
20
+ # We cannot order it using the class name because there are rules with subrules, such as ties, or articulations. We order it using the encoding itself
21
+ self.decorations: List[Subtoken] = []
22
+ self.in_chord = False
23
+ # self.page_start_rows = [] # TODO
24
+ self.measure_start_rows = []
25
+ self.last_bounding_box = None
26
+
27
+ def enterStart(self, ctx: kernSpineParser.StartContext):
28
+ self.token = None
29
+ self.duration_subtokens = []
30
+ self.diatonic_pitch_and_octave_subtoken = None
31
+ self.accidental_subtoken = None
32
+ # self.decorations = {}
33
+ self.decorations = []
34
+
35
+ # def process_decorations(self, ctx: ParserRuleContext):
36
+ # # in order to standardize the order of note decorators, we map the different properties to their class names
37
+ # decorations = {}
38
+ #
39
+ # for child in ctx.getChildren():
40
+ # # all decorations have just a child
41
+ # if child.getChildCount() != 1:
42
+ # raise Exception('Only 1 decoration child expected, and found ' + child.getChildCount() + ', check '
43
+ # 'the '
44
+ # 'grammar')
45
+ # clazz = type(child.getChild(0))
46
+ # decoration_type = clazz.__name__
47
+ # if decoration_type in decorations:
48
+ # logging.warning(
49
+ # f'The decoration {decoration_type} is duplicated') # TODO Dar información de línea, columna - ¿lanzamos excepción? - hay algunas que sí pueden estar duplicadas? Barrados?
50
+ # decorations[decoration_type] = child.getText()
51
+ # for key in sorted(decorations.keys()):
52
+ # subtoken = Subtoken(decorations[key], TokenCategory.DECORATION)
53
+ # self.duration_subtoken.append(subtoken)
54
+
55
+ def exitDuration(self, ctx: kernSpineParser.DurationContext):
56
+ self.duration_subtokens = [Subtoken(ctx.modernDuration().getText(), TokenCategory.DURATION)]
57
+ for i in range(len(ctx.augmentationDot())):
58
+ self.duration_subtokens.append(Subtoken(".", TokenCategory.DURATION))
59
+
60
+ if ctx.graceNote():
61
+ self.duration_subtokens.append(Subtoken(ctx.graceNote().getText(), TokenCategory.DURATION))
62
+
63
+ if ctx.appoggiatura():
64
+ self.duration_subtokens.append(Subtoken(ctx.appoggiatura().getText(), TokenCategory.DURATION))
65
+
66
+ def exitDiatonicPitchAndOctave(self, ctx: kernSpineParser.DiatonicPitchAndOctaveContext):
67
+ self.diatonic_pitch_and_octave_subtoken = Subtoken(ctx.getText(), TokenCategory.PITCH)
68
+
69
+ def exitNoteDecoration(self, ctx: kernSpineParser.NoteDecorationContext):
70
+ # clazz = type(ctx.getChild(0))
71
+ # decoration_type = clazz.__name__
72
+ # if decoration_type in self.decorations:
73
+ # logging.warning(
74
+ # f'The decoration {decoration_type} is duplicated after reading {ctx.getText()}') # TODO Dar información de línea, columna - ¿lanzamos excepción? - hay algunas que sí pueden estar duplicadas? Barrados?
75
+
76
+ # self.decorations[decoration_type] = ctx.getText()
77
+ # We cannot order it using the class name because there are rules with subrules, such as ties, or articulations. We order it using the encoding itself. NOT YET!
78
+ decoration_encoding = ctx.getText()
79
+ decoration_subtoken = Subtoken(decoration_encoding, TokenCategory.DECORATION)
80
+ self.decorations.append(decoration_subtoken)
81
+
82
+ def exitRestDecoration(self, ctx: kernSpineParser.NoteDecorationContext):
83
+ # clazz = type(ctx.getChild(0))
84
+ # decoration_type = clazz.__name__
85
+ # if decoration_type in self.decorations:
86
+ # logging.warning(
87
+ # f'The decoration {decoration_type} is duplicated after reading {ctx.getText()}') # TODO Dar información de línea, columna - ¿lanzamos excepción? - hay algunas que sí pueden estar duplicadas? Barrados?
88
+
89
+ # self.decorations[decoration_type] = ctx.getText()
90
+ # We cannot order it using the class name because there are rules with subrules, such as ties, or articulations. We order it using the encoding itself
91
+ decoration = ctx.getText();
92
+ if decoration != '/' and decoration != '\\':
93
+ decoration_encoding = ctx.getText()
94
+ decoration_subtoken = Subtoken(decoration_encoding, TokenCategory.DECORATION)
95
+ self.decorations.append(decoration_subtoken)
96
+
97
+ def addNoteRest(self, ctx, pitchduration_subtokens):
98
+ # subtoken = Subtoken(self.decorations[key], TokenCategory.DECORATION)
99
+ token = NoteRestToken(ctx.getText(), pitchduration_subtokens, self.decorations)
100
+ if self.in_chord:
101
+ self.chord_tokens.append(token)
102
+ else:
103
+ self.token = token
104
+
105
+ def exitNote(self, ctx: kernSpineParser.NoteContext):
106
+ pitch_duration_tokens = []
107
+ for duration_subtoken in self.duration_subtokens:
108
+ pitch_duration_tokens.append(duration_subtoken)
109
+ pitch_duration_tokens.append(self.diatonic_pitch_and_octave_subtoken)
110
+ if ctx.alteration():
111
+ pitch_duration_tokens.append(Subtoken(ctx.alteration().getText(), TokenCategory.ALTERATION))
112
+
113
+ self.addNoteRest(ctx, pitch_duration_tokens)
114
+
115
+ def exitRest(self, ctx: kernSpineParser.RestContext):
116
+ pitch_duration_tokens = []
117
+ for duration_subtoken in self.duration_subtokens:
118
+ pitch_duration_tokens.append(duration_subtoken)
119
+ pitch_duration_tokens.append(Subtoken('r', TokenCategory.PITCH))
120
+ self.addNoteRest(ctx, pitch_duration_tokens)
121
+
122
+ def enterChord(self, ctx: kernSpineParser.ChordContext):
123
+ self.in_chord = True
124
+ self.chord_tokens = []
125
+
126
+ def exitChord(self, ctx: kernSpineParser.ChordContext):
127
+ self.in_chord = False
128
+ self.token = ChordToken(ctx.getText(), TokenCategory.CHORD, self.chord_tokens)
129
+
130
+ def exitEmpty(self, ctx: kernSpineParser.EmptyContext):
131
+ self.token = SimpleToken(ctx.getText(), TokenCategory.EMPTY)
132
+
133
+ def exitNonVisualTandemInterpretation(self, ctx: kernSpineParser.NonVisualTandemInterpretationContext):
134
+ self.token = SimpleToken(ctx.getText(), TokenCategory.OTHER)
135
+
136
+ def exitVisualTandemInterpretation(self, ctx: kernSpineParser.VisualTandemInterpretationContext):
137
+ self.token = SimpleToken(ctx.getText(), TokenCategory.ENGRAVED_SYMBOLS)
138
+
139
+ def exitOtherContextual(self, ctx: kernSpineParser.ContextualContext):
140
+ self.token = SimpleToken(ctx.getText(), TokenCategory.OTHER_CONTEXTUAL)
141
+
142
+ def exitClef(self, ctx: kernSpineParser.ClefContext):
143
+ self.token = ClefToken(ctx.getText())
144
+
145
+ def exitKeySignature(self, ctx: kernSpineParser.KeySignatureContext):
146
+ self.token = KeySignatureToken(ctx.getText())
147
+
148
+ def exitKeyCancel(self, ctx: kernSpineParser.KeyCancelContext):
149
+ self.token = KeySignatureToken(ctx.getText())
150
+
151
+ def exitKey(self, ctx: kernSpineParser.KeyContext):
152
+ self.token = KeyToken(ctx.getText())
153
+
154
+ def exitTimeSignature(self, ctx: kernSpineParser.TimeSignatureContext):
155
+ self.token = TimeSignatureToken(ctx.getText())
156
+
157
+ def exitMeterSymbol(self, ctx: kernSpineParser.MeterSymbolContext):
158
+ self.token = MeterSymbolToken(ctx.getText())
159
+
160
+ def exitStructural(self, ctx: kernSpineParser.StructuralContext):
161
+ self.token = SimpleToken(ctx.getText(), TokenCategory.STRUCTURAL)
162
+
163
+ def exitXywh(self, ctx: kernSpineParser.XywhContext):
164
+ self.last_bounding_box = BoundingBox(int(ctx.x().getText()), int(ctx.y().getText()), int(ctx.w().getText()),
165
+ int(ctx.h().getText()))
166
+
167
+ def exitBoundingBox(self, ctx: kernSpineParser.BoundingBoxContext):
168
+ page = ctx.pageNumber().getText()
169
+ bbox = BoundingBox(int(ctx.xywh().x().getText()), int(ctx.xywh().y().getText()), int(ctx.xywh().w().getText()),
170
+ int(ctx.xywh().h().getText()))
171
+ self.token = BoundingBoxToken(ctx.getText(), page, bbox)
172
+
173
+ def exitInstrument(self, ctx: kernSpineParser.InstrumentContext):
174
+ self.token = InstrumentToken(ctx.getText())
175
+
176
+
177
+ def exitBarline(self, ctx: kernSpineParser.BarlineContext):
178
+ txt_without_number = ''
179
+ if ctx.EQUAL(0) and ctx.EQUAL(1):
180
+ txt_without_number = '=='
181
+ elif ctx.EQUAL(0):
182
+ txt_without_number = '='
183
+ if ctx.barLineType():
184
+ txt_without_number += ctx.barLineType().getText()
185
+ if ctx.fermata():
186
+ txt_without_number += ctx.fermata().getText()
187
+
188
+ # correct wrong encodings
189
+ if txt_without_number == ':!:':
190
+ txt_without_number = ':|!|:'
191
+ elif txt_without_number == ':|!|:':
192
+ txt_without_number = ':|!|:'
193
+
194
+ self.token = BarToken(txt_without_number)
195
+ self.token.hidden = "-" in ctx.getText() # hidden
196
+
@@ -0,0 +1,43 @@
1
+ from __future__ import annotations
2
+ from typing import Optional
3
+
4
+ from .base_antlr_spine_parser_listener import BaseANTLRSpineParserListener
5
+ from .spine_importer import SpineImporter
6
+ from .spine_importer import SpineImporter
7
+ from .kern_spine_importer import KernSpineImporter, KernSpineListener
8
+ from .tokens import SimpleToken, TokenCategory, Token
9
+
10
+
11
+ class BasicSpineImporter(SpineImporter):
12
+ def __init__(self, verbose: Optional[bool] = False):
13
+ """
14
+ KernSpineImporter constructor.
15
+
16
+ Args:
17
+ verbose (Optional[bool]): Level of verbosity for error messages.
18
+ """
19
+ super().__init__(verbose=verbose)
20
+
21
+ def import_listener(self) -> BaseANTLRSpineParserListener:
22
+ return KernSpineListener() # TODO: Create a custom functional listener for BasicSpineImporter
23
+
24
+ def import_token(self, encoding: str) -> Token:
25
+ self._raise_error_if_wrong_input(encoding)
26
+
27
+ kern_spine_importer = KernSpineImporter()
28
+ token = kern_spine_importer.import_token(encoding)
29
+
30
+ ACCEPTED_CATEGORIES = {
31
+ TokenCategory.STRUCTURAL,
32
+ TokenCategory.SIGNATURES,
33
+ TokenCategory.EMPTY,
34
+ TokenCategory.BARLINES,
35
+ TokenCategory.IMAGE_ANNOTATIONS,
36
+ TokenCategory.BARLINES,
37
+ TokenCategory.COMMENTS,
38
+ }
39
+
40
+ if not any(TokenCategory.is_child(child=token.category, parent=cat) for cat in ACCEPTED_CATEGORIES):
41
+ return SimpleToken(encoding, TokenCategory.OTHER)
42
+
43
+ return token