Newline (`\n`) breaks encoding in some cases
Hello,
I tried to get a multi-line rMQR like this:
FOO BAR
via console:
rmqr "FOO
BAR" ./mytest.png
This breaks things:
Details
Traceback (most recent call last):
File "./.venv/bin/rmqr", line 8, in <module>
sys.exit(main())
^^^^^^
File "./.venv/lib/python3.12/site-packages/rmqrcode/console.py", line 57, in main
qr = _make_qr(args.DATA, ecc=ecc, version=args.version, fit_strategy=fit_strategy)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "./.venv/lib/python3.12/site-packages/rmqrcode/console.py", line 22, in _make_qr
qr = rMQR.fit(data, ecc=ecc, fit_strategy=fit_strategy)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "./.venv/lib/python3.12/site-packages/rmqrcode/rmqrcode.py", line 73, in fit
return rMQROptimizer.compute(data, ecc, fit_strategy)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "./.venv/lib/python3.12/site-packages/rmqrcode/rmqrcode.py", line 500, in compute
qr.make()
File "./.venv/lib/python3.12/site-packages/rmqrcode/rmqrcode.py", line 147, in make
encoded_data = self._encode_data()
^^^^^^^^^^^^^^^^^^^
File "./.venv/lib/python3.12/site-packages/rmqrcode/rmqrcode.py", line 182, in _encode_data
res += segment["encoder_class"].encode(segment["data"], character_count_indicator_length)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "./.venv/lib/python3.12/site-packages/rmqrcode/encoder/encoder_base.py", line 40, in encode
res += cls._encoded_bits(data)
^^^^^^^^^^^^^^^^^^^^^^^
File "./.venv/lib/python3.12/site-packages/rmqrcode/encoder/alphanumeric_encoder.py", line 68, in _encoded_bits
value = cls.CHARACTER_MAP[s[0]]
~~~~~~~~~~~~~~~~~^^^^^^
KeyError: '\n'
However,
rmqr "FO
bBAR" ./mytest.png
works. I also thought that numbers as last pre-\n character lead to a different error, but it seems to happen with multiple combinations (FOO\nbBar also does not work) and giving reproducable examples is quite difficult. In any case, it is easy to experience with using pipes, even/odd counts of characters (e.g. FOOO vs FOO), etc.
The whole (mis)behaviour is also given when using rmqr.fit("FOO\nBAR" [...]) inside a script.
I tried to debug this myself, but the code seems to be a bit above my skill level :-/ Please let me know if I can help!
The Alphanumeric mode cannot encode the newline character (\n). Therefore, the method AlphanumericEncoder.is_valid_characters('\n') is expected to return False. However, it currently returns True.
The same issue occurs with the NumericEncoder.
from rmqrcode.encoder import *
print(NumericEncoder.is_valid_characters('\n')) # expected: False, actual: True
print(AlphanumericEncoder.is_valid_characters('\n')) # expected: False, actual: True
This issue was fixed in a pull request #59.
rmqr "FOO
BAR" ./mytest.png