1313# You should have received a copy of the GNU General Public License
1414# along with Slice. If not, see <https://www.gnu.org/licenses/>.
1515
16+ import re
17+
1618from fontTools .ttLib import TTFont
1719from PyQt5 .QtCore import QAbstractTableModel , Qt
1820
@@ -197,6 +199,9 @@ def __init__(self, *args):
197199 "Axis 5" ,
198200 ]
199201 self ._h_header = ["Min : Max [Default]" , "Edit Values" ]
202+ self .axis_range_regex = re .compile (
203+ r"(?P<start>\d+(\.\d+)?)\s*\:\s*(?P<end>\d+(\.\d+)?)\s*(\[\s*(?P<default>\d+(\.?\d+)?)\s*\])?"
204+ )
200205
201206 def data (self , index , role ):
202207 if role in (Qt .DisplayRole , Qt .EditRole ):
@@ -285,7 +290,10 @@ def get_instance_data(self):
285290 # it remains a variable axis
286291 pass
287292 elif ":" in axis_value :
288- instance_data [axistag ] = self .parse_subspace_range (axis_value , axistag )
293+ subspace_range = self .parse_subspace_range (axis_value , axistag )[0 ]
294+ # for future L4 sub-space support
295+ # subspace_default = self.parse_subspace_range(axis_value, axistag)[1]
296+ instance_data [axistag ] = subspace_range
289297 else :
290298 # else use the numeric value set in the editor
291299 try :
@@ -299,31 +307,47 @@ def get_instance_data(self):
299307 return instance_data
300308
301309 def parse_subspace_range (self , range_string , axistag ):
302- range_list = range_string .split (":" )
303- # expect 2 values: min and max range sub-space values
304- # formatted as `value1:value2`
305- if len (range_list ) != 2 :
310+ match = self .axis_range_regex .search (range_string )
311+
312+ # confirm that we match on the regular expression parser
313+ # and that there will be group methods to execute on the regex
314+ if not match :
315+ raise ValueError (
316+ f"{ range_string } is not a valid axis range definition for { axistag } ."
317+ )
318+
319+ start_string = match .group ("start" )
320+ end_string = match .group ("end" )
321+ default_string = match .group ("default" )
322+
323+ if not start_string or not end_string :
306324 raise ValueError (
307- f"{ range_string } is not a valid axis range. "
308- f"Use the format `min_value:max_value`"
325+ f"{ range_string } is not a valid axis range definition for { axistag } ."
309326 )
310- # remove any extraneous whitespace (e.g., "100 : 200" entry)
311- # before attempt to cast to a float
327+
328+ float_range_list = []
329+
330+ # cast to float with numeric type validations
312331 try :
313- range_list [0 ] = float (range_list [0 ].strip ())
314- range_list [1 ] = float (range_list [1 ].strip ())
315- except ValueError as e :
316- raise ValueError (f"{ range_string } is not a valid axis value range. { e } " )
317- # order the values in case they were entered in reverse
332+ float_range_list .append (float (start_string ))
333+ except ValueError :
334+ raise ValueError (f"{ start_string } is not a valid axis value for { axistag } ." )
335+
336+ try :
337+ float_range_list .append (float (end_string ))
338+ except ValueError :
339+ raise ValueError (f"{ end_string } is not a valid axis value for { axistag } ." )
340+ # sort the values in case they were entered in reverse numeric order
318341 # e.g., 800:400, not 400:800
319- sorted_range_list = sorted (range_list )
320- # We only support Level 3 sub-spacing due to the support
342+ sorted_range_list = sorted (float_range_list )
343+ # We only support Level 3 sub-spacing now due to the support
321344 # that is available in fontTools lib. Let's check that user
322345 # included the default axis value in the range request
323346 self .subspace_data_validates_includes_default_value (sorted_range_list , axistag )
324- # all seems well, return data formatted as tuple
325- # this is the data format required by fonttools lib
326- return (sorted_range_list [0 ], sorted_range_list [1 ])
347+ # return the tuple range required for L3 support at index 0
348+ # return the default value (currently as string or None) required for
349+ # (future) L4 support at index 1
350+ return ((sorted_range_list [0 ], sorted_range_list [1 ]), default_string )
327351
328352 def subspace_data_validates_includes_default_value (self , range_list , axistag ):
329353 """Validates Level 3 sub-space requirement that restricted axis range
0 commit comments