diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6812789..8ab2800 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: - name: Code style run: | poetry run isort --check-only - poetry run black --check + poetry run black --check jubeatools - name: Lint code run: poetry run sh ./utils/check_code.sh - name: Unit tests diff --git a/CHANGELOG.md b/CHANGELOG.md index 95bb5cc..6e47ff2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +# Unreleased +## Fixed +- [jubeat-analyser] + - Accept U+3000 (Ideographic space) as valid whitespace everywhere + - [memo2] + - Accept `t=` commands anywhere in the file + - Accept `b=4` (and only 4) anywhere in the file + + # v1.1.1 ## Fixed - `construct-typing` is now required for all builds diff --git a/jubeatools/formats/jubeat_analyser/command.py b/jubeatools/formats/jubeat_analyser/command.py index abf91bb..cbbfbf4 100644 --- a/jubeatools/formats/jubeat_analyser/command.py +++ b/jubeatools/formats/jubeat_analyser/command.py @@ -48,7 +48,7 @@ command_grammar = Grammar( value_in_quotes = '"' quoted_value '"' quoted_value = ~r"([^\"\\]|\\\"|\\\\)*" number = ~r"-?\d+(\.\d+)?" - ws = ~r"[\t ]*" + ws = ~r"[\t \u3000]*" comment = ~r"//.*" """ ) diff --git a/jubeatools/formats/jubeat_analyser/load_tools.py b/jubeatools/formats/jubeat_analyser/load_tools.py index 9f52e70..2456450 100644 --- a/jubeatools/formats/jubeat_analyser/load_tools.py +++ b/jubeatools/formats/jubeat_analyser/load_tools.py @@ -83,7 +83,7 @@ double_column_chart_line_grammar = Grammar( line = ws position_part ws (timing_part ws)? comment? position_part = ~r"[^*#:|/\s]{4,8}" timing_part = "|" ~r"[^*#:|/\s]*" "|" - ws = ~r"[\t ]*" + ws = ~r"[\t \u3000]*" comment = ~r"//.*" """ ) diff --git a/jubeatools/formats/jubeat_analyser/memo2/load.py b/jubeatools/formats/jubeat_analyser/memo2/load.py index 3ab5c1d..f8bd0f0 100644 --- a/jubeatools/formats/jubeat_analyser/memo2/load.py +++ b/jubeatools/formats/jubeat_analyser/memo2/load.py @@ -102,7 +102,7 @@ memo2_chart_line_grammar = Grammar( bpm = "(" float ")" float = ~r"\d+(\.\d+)?" notes = ~r"[^*#:\(\[|/\s]+" - ws = ~r"[\t ]*" + ws = ~r"[\t \u3000]*" # U+03000 : IDEOGRAPHIC SPACE comment = ~r"//.*" """ ) @@ -180,20 +180,16 @@ class Memo2Parser(JubeatAnalyserParser): self.frames: List[Memo2Frame] = [] def do_b(self, value: str) -> None: - raise RuntimeError( - "beat command (b=...) found, this commands cannot be used in #memo2 files" - ) + if Decimal(value) != 4: + raise RuntimeError( + "Beat command (b=...) found with a value other that 4, this is " + "unexpected in #memo2 files. If you are sure the file is not " + "just actually a #memo1 or #memo file with the wrong format " + "tag, you're welcome to report this error as a bug" + ) def do_t(self, value: str) -> None: - if self.frames: - raise RuntimeError( - "tempo command (t=...) found outside of the file header, " - "this should not happen in #memo2 files" - ) - else: - self.timing_events.append( - BPMEvent(self._current_beat(), BPM=Decimal(value)) - ) + self.timing_events.append(BPMEvent(self._current_beat(), BPM=Decimal(value))) def do_r(self, value: str) -> None: if self.frames: diff --git a/jubeatools/formats/jubeat_analyser/mono_column/load.py b/jubeatools/formats/jubeat_analyser/mono_column/load.py index 21485c1..631cc38 100644 --- a/jubeatools/formats/jubeat_analyser/mono_column/load.py +++ b/jubeatools/formats/jubeat_analyser/mono_column/load.py @@ -42,7 +42,7 @@ mono_column_chart_line_grammar = Grammar( r""" line = ws chart_line ws comment? chart_line = ~r"[^*#:|\-/\s]{4,8}" - ws = ~r"[\t ]*" + ws = ~r"[\t \u3000]*" comment = ~r"//.*" """ ) diff --git a/jubeatools/formats/jubeat_analyser/symbol_definition.py b/jubeatools/formats/jubeat_analyser/symbol_definition.py index 90fd1fa..3a674c4 100644 --- a/jubeatools/formats/jubeat_analyser/symbol_definition.py +++ b/jubeatools/formats/jubeat_analyser/symbol_definition.py @@ -12,7 +12,7 @@ beat_symbol_line_grammar = Grammar( line = "*" symbol ":" number comment? symbol = ws ~r"[^*#:|\-/\s]{1,2}" ws number = ws ~r"\d+(\.\d+)?" ws - ws = ~r"\s*" + ws = ~r"[\t \u3000]*" comment = ~r"//.*" """ ) diff --git a/jubeatools/formats/jubeat_analyser/tests/data/Booths_of_Fighters_memo.txt b/jubeatools/formats/jubeat_analyser/tests/data/Booths_of_Fighters_memo.txt new file mode 100644 index 0000000..ed5e77a --- /dev/null +++ b/jubeatools/formats/jubeat_analyser/tests/data/Booths_of_Fighters_memo.txt @@ -0,0 +1,530 @@ +m="Booths of Fighters.mp3" +o=2320 +t=225 +b=4.0 + +#memo2 + +@@@@|@|||| +CA@@@|A|||| +B@@@|B|||| +D@@@|C|D|| + +B@@@|@|||| +D@@@@|A|B|| +CF@@@|C|D|| +EA@@@|E|F|| + +@@@@|@|||| +CA@@@|A|||| +B@@@|B|||| +D@@@|C|D|| + +BA@@@|@|A|| +@C@@@|B|C|| +@@@|D|E|| +DEFG@@@|F|G|| + +@@@@@|@|||| +CA@@@|A|||| +B@@@|B|||| +D@@@|C|D|| + +B@@@|@|||| +@@@@|A|B|| +C@@@|C|||| +DAE@@@|D|E|| + +@@@@@|@|||| +A@@@|A|||| +CB@@@|B|||| +D@@@|C|D|| + +BBBB@@@|@|||| +A@@@@|A|B|| +@A@@@|||||| +@@@|||||| + +AA@@@|@|||| +@@@@@|||||| +CBB@@@|A|B|| +@C@@@@|||C|| + +@@@|||@|| +C@@@@|||||| +@@@@|||A|| +AB@@@|B|C|| + +@@@@|@|||| +AA@@@|||||| +C@@@@|A|B|| +BCB@@@|||C|| + +DA@@@|||@|| +A@@@@|||A|| +B@@@@|||B|| +C@@@|C|D|| + +DD@@@|@|||| +@@@@@|A|B|| +B@@@|||C|| +AC@@@|D|||| + +DD@@@|@|||| +A@@@|A|B|| +BCC@@@|||C|| +@@@@@|D|||| + +BB@@@|@|||| +EAAC@@@|A|B|| +DD@@@|||C|| +@@@@@|D|E|| + +@BB@@@@|@|A|| +BB@@@|||B|| +@@@|||||| +AAAA@@@|||||| + +@@@@|@|A|| +BB@@@|B|||| +CC@@@@|C|||| +DDA@@@|D|||| + +@DD@@@@|@|A|| +BB@@@|B|C|| +DA@@@|D|||| +ECE@@@|E|||| + +@F@@@@|@|A|| +BBD@@@|B|C|| +DAE@@@|D|E|| +FGC@@@|F|G|| + +@@B@@@|@|A|| +BC@@@|B|C|| +DDE@@@|D|||| +EDA@@@|E|||| + +@@@@@|@|A|| +BCA@@@|B|C|| +DEDG@@@|D|E|| +FFB@@@|F|G|| + +@E@@@@|@|A|| +BBA@@@|B|C|| +D@@@|D|E|| +FFDC@@@|F|||| + +@C@@@|@|AB| +EDDB@@@|C|||| +F@@A@@@|D|EF| +GD@@@|G|||| + +@@B@@@|@|A|| +D@@@|B|C|| +CA@@@|D|||| +EE@@@|E|||| + +@@D@@@|@|||| +AA@@@|A|B|| +CCB@@@|C|D|| +EEF@@@|E|F|| + +@@@@@|@|A|| +BECA@@@|B|C|| +DDF@@@|D|E|| +FBG@@@|F|G|| + +@EG@@@@|@|A|| +BA@@@|B|C|| +DB@@@|D|E|| +FCD@@@|F|G|| + +@@@@|@|||ABCD| +DCBA@@@|||||EFGH| +HGFE@@@|||||IJKL|@ +LKJI@@ + +PONM@@ +@@ +@ +@@@|||||MNOP| + +@@@|||||| +@@@@@|@|||| +AAB@@@|A|B|| +CD@@@|C|D|| + +@A@@@@|@|A|| +CAC@@@|||B|| +DD@@@|C|D|| +BB@@@|||||| + +DG@@@|@|A|| +FB@@@|B|C|| +AE@@@|D|E|| +C@@@@|F|G|| + +EEA@@@|@|A|| +B@@@|B|C|| +C@@@|D|||| +D@@@@@|E|||| + +CB@@@|@|||| +A@@@@@|||||| +@@@@@|A|||| +@A@@@@|B|C|| + +@@@|@|||| +@@@|A|B|| +@A@@@|||||| +B@@@|||||| + +@@EA@@@|@|||| +@D@A@@@|A|||| +@@CA@@@|B|C|| +B@@@|D|E|| + +@@@|@|A|| +@@@@|B|C|| +CA@@@|||||| +CB@@@|||||| + +@@@@@|@|||| +B@B@@@|||A|| +C@C@@@|B|||| +A@@@@|C|||| + +@EEC@@@|@|A|| +A@@@|B|C|| +B@@@|D|E|| +D@@@|||||| + +D@@@|@|||| +@CA@@@|||||| +@@@@@|A|B|| +@B@@@@|C|D|| + +@@@|@|A|| +BD@@@|B|C|| +A@@@|D|E|| +CEE@@@@|||||| + +D@@@@@|@|||| +@@@@|||||| +AC@@@@@|A|B|| +B@@@|C|D|| + +@@@@|@|A|| +BC@@@|B|||| +AC@@@|C|||| +@@@@|||||| + +@@A@@@|@|||| +@D@@@|||||| +B@@@@|A|B|| +@@C@@@|C|D|| + +@BB@@@|@|||| +@@@|A|B|| +A@@@|||||| +@@@@|||||| + +C@@@|@|||| +@B@@@|||||| +D@@@@@|A|B|| +A@@@@@|C|D|| + +@@@@|@|A|| +@@@|B|||| +A@@@|||||| +BB@@@@|||||| + +@B@@@|@|||| +@B@@@@|||||| +@@A@@@|A|||| +A@@@|B|||| +t=200 +CC@@@|@||A| +BB@@@|||B|| +AA@@@|C|||| +@@@@@|||||| +t=175 +A@@@|@|||| +A@@@|||||| +A@@@|A|||| +@@@@@@@|||||| + +C@@@|@|A|| +BA@@@@|B|||| +C@@@|C|||| +DD@@@|D|||| + +A@@@@|@|||| +@@@@|||||| +@A@@@|A|||| +A@@@|||||| + +@@@@|@|||| +C@@@|A|B|| +AB@@@|C|||| +DDC@@@|D|||| + +@A@@@|@|||| +A@@@@|||||| +@@@@|A|||| +A@@@|||||| + +@@@|@|A|| +C@@@|B|||| +@AB@@@|C|||| +CC@@@|||||| + +A@@@@|@|||| +@@@@|||||| +A@@@|A|||| +@@@@|||||| + +BAC@@@|@|||| +A@@@@|A|B|| +C@A@@@|C|||| +@C@@@|||||| + +CC@@@|@||A| +B@C@@@|||B|| +BA@@@|C|||| +@@A@@@|||||| + +D@@@|@|A|| +C@@@|B|||| +BA@@@@|C|||| +@@@@|D|||| + +DDA@@@|@|A|| +CCA@@@|B|C|| +@D@@@|D|||| +@BB@@@|||||| + +C@@@@|@|||| +DD@@@|A|B|| +CEAB@@@|C|D|| +EFF@@@|E|F|| + +CB@@@@|@||A| +A@C@@@|||B|| +CAB@@@|C|||| +@@@@|||||| + +ED@@@|@|A|| +DE@@@|B|||| +DEC@@@|C|||| +BA@@@@|D|E|| + +@@@@@|@|||| +@@@@@|||||| +ABCA@@@|A|B|| +BC@@@|C|||| +t=155 +C@AC@@@|@||A| +@BBA@@@|||B|| +CC@@@|C|||| +A@@@@ + +D@@ +D@@@ +D@@@ +D@@@|D|||| +t=225 +@@@|@|||| +@@@|||||| +@@@|||||| +@@@@@|||||| + +@@@|||||| +@@@|||||| +@@@|||||| +@@@|||||| + +@@@@|@|||| +@@@|||||| +@@@|||||| +@@@|||||| + +@@@|||||| +@@@|||||| +@@@|||||| +@@@|||||| + +C@@@|@|||| +B@@@|A|||| +@@A@@@|B|||| +@@@@|C|||| + +@@C@@@|@|||| +B@@@|A|||| +A@@@|B|||| +@@@@|C|||| + +C@@@|@|||| +@@B@@@|A|||| +A@@@|B|||| +@@@@|C|||| + +@@C@@@|@|||| +B@@@|A|||| +A@@@|B|||| +@@@@|C|||| + +IJK@@@|@AB| +FGH@@@|CDE| +CDE@@@|FGH| +@AB@@@|IJK| + +FG@@@|@AB| +DEA@@@|C||| +BG@@@|DEF| +@GC@@@|G||| + +FDD@@@|@AB| +BB@@@|C||| +CAAG@@@|D||| +@@EE@@@|EFG| + +DD@@@|@AB| +BBC@@@|C||| +AA@@@|D||| +@@FE@@@|E|F| + +@B@@@@|@||| +BE@@@|A||| +DD@@@|B||| +AAC@@@|CDE| + +@@E@@@|@AB| +DAA@@@|C||| +HBB@@@|DEF| +CFIG@@@|GHI| + +@@EE@@@|@AB| +DAAD@@@|C||| +BB@@@|D||| +CFG@@@|EFG| + +@@FF@@@|@AB| +DAA@@@|C||| +BBC@@@|D|E| +DGE@@@|F|G| + +@@C@@@|@FG| +DAA@@@|A||| +BB@@@@|B||| +E@@@|CDE| + +FDIE@@@|@AB| +BJ@@@|CDE| +HAG@@@|FGH| +@@CK@@@|IJK| + +DD@@@|@AB| +CFBB@@@|C||| +AAE@@@|D||| +@@G@@@|EFG| + +EEBB@@@|@AB| +DD@@@|C||| +CAA@@@|D||| +@@F@@@|E|F| + +GDD@@@|@AB| +@@F@@@|C||| +CC@@@|D|| +BEA@@@|EFG| + +DCD@@@|@|A| +AEA@@@||B|| +C@B@@@|C|D| +BE@@@@||E|| + +DFEE@@@|@AB| +BBC@@@|C||| +DAAG@@@|D||| +@@@@@|EFG| + +DF@@@|@AB| +BBEC@@@|C||| +EAA@@@|D|E| +@@DF@@@||F|| + +BA@@@@|@|||| +AC@@@|A|||| +BB@@@|B|||| +@@C@@@|C|||| + +BA@@@|@|||| +AAC@@@|A|||| +C@B@@@|B|||| +@@@@@|C|||| + +@@D@@@|@|||| +C@@@@|||A|| +@@B@@@|B|C|| +@A@@@|||D|| + +@@@@|@|A|| +AD@@@|B|C|| +B@@@|D|||| +CD@@@|||||| + +@@D@@@|@|||| +A@@@@|||||| +@B@@@|A|B|| +@C@@@|C|D|| + +CCB@@@|@|||| +@@@@@|A|B|| +A@@@|C|||| +@@@|||||| + +CD@@@|@|||| +@B@@@|||A|| +@@@@@|B|C|| +A@@@@@|||D|| + +@@@|@|A|| +CC@@@|||B|| +A@@@|C|||| +B@@@@|||||| + +@F@@@|@|A|| +E@@@|B|C|| +ADB@@@|D|E|| +GC@@@@|F|G|| + +@@B@@@|@|A| +@BB@@@||B|| +AACC@@@|C||| +ACC@@@|||||| + +@@@@|@|||| +AC@@@|A|||| +B@@@|B|||| +D@@@|C|D|| + +@F@@@|@|||| +E@@@|A|B|| +DA@@@|C|D|| +BC@@@|E|F|| + +@@@|@|||| +@@@@@|||||| +@@@@|||||| +@@@@|||||| + +@@@|||||| +@@@|||||| +@@@|||||| +@@@|||||| + + + + diff --git a/jubeatools/formats/jubeat_analyser/tests/test_examples.py b/jubeatools/formats/jubeat_analyser/tests/test_examples.py index 061a271..ea6f36d 100644 --- a/jubeatools/formats/jubeat_analyser/tests/test_examples.py +++ b/jubeatools/formats/jubeat_analyser/tests/test_examples.py @@ -9,8 +9,22 @@ from . import data def test_RorataJins_example() -> None: + """This file has a #memo tag but actually uses mono-column formatting, + Here I just check that a friendlier error message is sent because there + is not much else I can to do here, the file is plain old wrong""" with pytest.raises(SyntaxError, match="separator line"): with resources.path(data, "RorataJin's example.txt") as p: format_ = guess_format(p) loader = LOADERS[format_] _ = loader(p) + + +def test_Booths_of_Fighters_memo() -> None: + """This file has 2 quirks my code did not anticipate : + - while it's in #memo2 format, it actually uses b= and t= commands + - the position and timing parts are separated by some less common + whitespace character""" + with resources.path(data, "Booths_of_Fighters_memo.txt") as p: + format_ = guess_format(p) + loader = LOADERS[format_] + _ = loader(p)