From 80054aa77b84318b63396ea06453c2edefad6f13 Mon Sep 17 00:00:00 2001 From: Jesse Bannon Date: Sun, 27 Oct 2024 08:09:05 -0700 Subject: [PATCH] [FEATURE] Support newlines and tabs in scripting strings (#1105) Allows the usage of `\n` and `\t` in scripting strings --- src/ytdl_sub/script/parser.py | 12 ++++++++++-- tests/unit/script/functions/test_string_functions.py | 1 + tests/unit/script/types/test_string.py | 6 +++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/ytdl_sub/script/parser.py b/src/ytdl_sub/script/parser.py index 737d6ffa2..0f844e34f 100644 --- a/src/ytdl_sub/script/parser.py +++ b/src/ytdl_sub/script/parser.py @@ -301,8 +301,16 @@ def _parse_string(self, str_open_token: str) -> String: self._pos += len(str_open_token) return String(value=string_value) - self._pos += 1 - string_value += ch + # Read literal "\n" as newlines + if self._read(increment_pos=False, length=2) == "\\n": + string_value += "\n" + self._pos += 2 + elif self._read(increment_pos=False, length=2) == "\\t": + string_value += "\t" + self._pos += 2 + else: + self._pos += 1 + string_value += ch raise STRINGS_NOT_CLOSED diff --git a/tests/unit/script/functions/test_string_functions.py b/tests/unit/script/functions/test_string_functions.py index e5d898f8c..ea3d441d9 100644 --- a/tests/unit/script/functions/test_string_functions.py +++ b/tests/unit/script/functions/test_string_functions.py @@ -132,6 +132,7 @@ def test_contains_any(self, value, expected_output): ("no splits", " | ", None, ["no splits"]), ("one | split", " | ", None, ["one", "split"]), ("max | split | one", " | ", 1, ["max", "split | one"]), + ("multiline\ndescription", "\\n", None, ["multiline", "description"]), ], ) def test_split( diff --git a/tests/unit/script/types/test_string.py b/tests/unit/script/types/test_string.py index c3749845b..08700ace6 100644 --- a/tests/unit/script/types/test_string.py +++ b/tests/unit/script/types/test_string.py @@ -1,6 +1,7 @@ import re import pytest +from unit.script.conftest import single_variable_output from ytdl_sub.script.parser import STRINGS_NOT_CLOSED from ytdl_sub.script.parser import STRINGS_ONLY_ARGS @@ -45,10 +46,13 @@ def test_string_not_arg(self, string: str): ("{%string('backslash \\\\')}", "backslash \\\\"), ("{%string('''triple quote with \" ' \\''')}", "triple quote with \" ' \\"), ('{%string("""triple quote with " \' \\""")}', "triple quote with \" ' \\"), + ("{%string('literal \\n newlines')}", "literal \n newlines"), + ("{%string('supports \t tabs')}", "supports \t tabs"), + ("{%string('literal \\t tabs')}", "literal \t tabs"), ], ) def test_string(self, string: str, expected_string: str): - assert Script({"out": string}).resolve() == ScriptOutput({"out": String(expected_string)}) + assert single_variable_output(string) == expected_string def test_null_is_empty_string(self): assert Script({"out": "{%string(null)}"}).resolve() == ScriptOutput({"out": String("")})