From 2e4b2bf03d49c355a98d10eed5707430b012a74a Mon Sep 17 00:00:00 2001 From: Sam Soffes Date: Wed, 5 Feb 2020 15:31:32 -0800 Subject: [PATCH] Add strict fonts rule (#53) --- README.md | 8 ++++-- xiblint/__init__.py | 2 +- xiblint/rules/strict_fonts.py | 53 +++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 xiblint/rules/strict_fonts.py diff --git a/README.md b/README.md index 812c9b0..cc8fd50 100644 --- a/README.md +++ b/README.md @@ -56,13 +56,17 @@ in the .xib or .storyboard file. Ensures there are no links to other storyboards in different bundles. +- `strict_fonts` + + Ensures all font names and sizes are in an allowed set. Configure `allowed_fonts` with an array of dictionaries containing a `name` and `size` in a custom rule configuration using `rules_config` (see below). + - `strict_font_names` - Ensures all fonts are in an allowed set. Configure `allowed_fonts` and `allow_system_fonts` (default is `true`) in a custom rule configuration using `rules_config` (see below). + Ensures all font namess are in an allowed set. Configure `allowed_fonts` and `allow_system_fonts` (default is `true`) in a custom rule configuration using `rules_config` (see below). This is a good option if `strict_fonts` is too strict. - `strict_font_sizes` - Ensures all fonts are above a minimum font size. Configure `minimum_size` (default is `0`) and/or `maximum_size` (default is `1000`) in a custom rule configuration using `rules_config` (see below). + Ensures all font sizes are above a minimum font size. Configure `minimum_size` (default is `0`) and/or `maximum_size` (default is `1000`) in a custom rule configuration using `rules_config` (see below). This is a good option if `strict_fonts` is too strict. - `unavailable_custom_classes` diff --git a/xiblint/__init__.py b/xiblint/__init__.py index 97f30d1..cdf390c 100644 --- a/xiblint/__init__.py +++ b/xiblint/__init__.py @@ -1 +1 @@ -__version__ = '0.9.11' +__version__ = '0.9.12' diff --git a/xiblint/rules/strict_fonts.py b/xiblint/rules/strict_fonts.py new file mode 100644 index 0000000..0c1bc2d --- /dev/null +++ b/xiblint/rules/strict_fonts.py @@ -0,0 +1,53 @@ +from xiblint.rules import Rule +from xiblint.xibcontext import XibContext + + +class StrictFonts(Rule): + """ + Ensures font name and size combinations are in the allowed set. This would generally be used instead + of strict_font_names and strict_font_sizes. + + Example configuration: + { + "allowed_fonts": [ + { + "name": "ComicSans-Regular", + "size": 14 + }, + { + "name": "ComicSans-Bold", + "size": 14 + } + ] + } + """ + def check(self, context): # type: (XibContext) -> None + allowed_fonts = [(d["name"], d["size"]) for d in self.config.get('allowed_fonts', [])] + + for element in context.tree.findall('.//font') + context.tree.findall('.//fontDescription'): + size_attribute_name = None + + if element.tag == 'font': + # Skip tags nested in a localization comment + container = element.parent.parent.parent + if container.tag == 'attributedString' and container.get('key') == 'userComments': + continue + + size_attribute_name = 'size' + else: + size_attribute_name = 'pointSize' + + raw_size = element.get(size_attribute_name) + if raw_size is None: + context.error(element, 'Invalid <{}> found. Must have a {}.'.format(element.tag, size_attribute_name)) + continue + + size = int(raw_size) + + name = element.get('name') + if name is None: + context.error(element, 'Invalid <{}> found. Must have a name.'.format(element.tag)) + continue + + if (name, size) not in allowed_fonts: + context.error(element, 'Invalid font found {} {}. Please use an allowed font.'.format(name, size))