[Bf-extensions-cvs] [cdf56b2f] master: Fix T70050: Unable to import SVG

Sergey Sharybin noreply at git.blender.org
Thu Sep 19 15:34:21 CEST 2019


Commit: cdf56b2fade83eb8518dedcbdf137bc2d937407d
Author: Sergey Sharybin
Date:   Thu Sep 19 15:31:48 2019 +0200
Branches: master
https://developer.blender.org/rBAcdf56b2fade83eb8518dedcbdf137bc2d937407d

Fix T70050: Unable to import SVG

The issue was caused by parser being confused about ex unit which was
attempted to be parsed as an exponent.

===================================================================

M	io_curve_svg/svg_util.py
M	io_curve_svg/svg_util_test.py

===================================================================

diff --git a/io_curve_svg/svg_util.py b/io_curve_svg/svg_util.py
index 42e900b4..bd744df5 100644
--- a/io_curve_svg/svg_util.py
+++ b/io_curve_svg/svg_util.py
@@ -46,10 +46,13 @@ def check_points_equal(point_a, point_b):
             abs(point_a[1] - point_b[1]) < 1e-6)
 
 match_number = r"-?\d+(\.\d+)?([eE][-+]?\d+)?"
+match_number_optional_fractional = r"-?\d+(\.\d*)?([eE][-+]?\d+)?"
 match_first_comma = r"^\s*(?=,)"
 match_comma_pair = r",\s*(?=,)"
 match_last_comma = r",\s*$"
 
+re_match_number_optional_fractional = re.compile(match_number_optional_fractional)
+
 array_of_floats_pattern = f"({match_number})|{match_first_comma}|{match_comma_pair}|{match_last_comma}"
 re_array_of_floats_pattern = re.compile(array_of_floats_pattern)
 
@@ -62,69 +65,32 @@ def parse_array_of_floats(text):
     return [value_to_float(v[0]) for v in elements]
 
 
-def read_float(s: str, i: int = 0):
+def read_float(text: str, start_index: int = 0):
     """
     Reads floating point value from a string. Parsing starts at the given index.
 
     Returns the value itself (as a string) and index of first character after the value.
     """
-    start = i
-    n = len(s)
-    token = ''
-
-    # Skip leading whitespace characters
-    while i < n and (s[i].isspace() or s[i] == ','):
-        i += 1
-
-    if i == n:
-        return "0", i
-
-    # Read sign
-    if s[i] == '-':
-        token += '-'
-        i += 1
-    elif s[i] == '+':
-        i += 1
-
-    # Read integer part
-    if s[i].isdigit():
-        while i < n and s[i].isdigit():
-            token += s[i]
-            i += 1
-
-    # Fractional part
-    if i < n and s[i] == '.':
-        token += '.'
-        i += 1
-
-        if i < n and s[i].isdigit():
-            while i < n and s[i].isdigit():
-                token += s[i]
-                i += 1
-        elif i == n or s[i].isspace() or s[i] == ',':
-            # Inkscape sometimes uses weird float format with missed
-            # fractional part after dot. Suppose zero fractional part
-            # for this case
-            pass
-        else:
-            raise Exception('Invalid float value near ' + s[start:start + 10])
-
-    # Degree
-    if i < n and (s[i] == 'e' or s[i] == 'E'):
-        token += s[i]
-        i += 1
-        if s[i] == '+' or s[i] == '-':
-            token += s[i]
-            i += 1
-
-        if s[i].isdigit():
-            while i < n and s[i].isdigit():
-                token += s[i]
-                i += 1
-        else:
-            raise Exception('Invalid float value near ' + s[start:start + 10])
-
-    return token, i
+
+    n = len(text)
+
+    # Skip leading whitespace characters and characters which we consider ignorable for float
+    # (like values separator).
+    while start_index < n and (text[start_index].isspace() or text[start_index] == ','):
+        start_index += 1
+    if start_index == n:
+        return "0", start_index
+
+    text_part = text[start_index:]
+    match = re_match_number_optional_fractional.match(text_part)
+
+    if match is None:
+        raise Exception('Invalid float value near ' + text[start_index:start_index + 10])
+
+    token = match.group(0)
+    endptr = start_index + match.end(0)
+
+    return token, endptr
 
 
 def parse_coord(coord, size):
diff --git a/io_curve_svg/svg_util_test.py b/io_curve_svg/svg_util_test.py
index 6f54d5f3..de1d9823 100755
--- a/io_curve_svg/svg_util_test.py
+++ b/io_curve_svg/svg_util_test.py
@@ -118,7 +118,7 @@ class ReadFloatTest(unittest.TestCase):
     def test_not_a_number(self):
         # TODO(sergey): Make this more concrete.
         with self.assertRaises(Exception):
-            value, endptr = read_float("1.2eV", 3)
+            read_float("1.2eV", 3)
 
     def test_missing_fractional(self):
         value, endptr = read_float("1.", 0)
@@ -143,6 +143,9 @@ class ParseCoordTest(unittest.TestCase):
     def test_unit_cm(self):
         self.assertAlmostEqual(parse_coord("1.2cm", 200), 42.51968503937008)
 
+    def test_unit_ex(self):
+        self.assertAlmostEqual(parse_coord("1.2ex", 200), 1.2)
+
     def test_unit_percentage(self):
         self.assertEqual(parse_coord("1.2%", 200), 2.4)



More information about the Bf-extensions-cvs mailing list