webcode-tk 0.7.3__tar.gz → 0.7.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {webcode_tk-0.7.3 → webcode_tk-0.7.5}/PKG-INFO +1 -1
- {webcode_tk-0.7.3 → webcode_tk-0.7.5}/pyproject.toml +1 -1
- {webcode_tk-0.7.3 → webcode_tk-0.7.5}/webcode_tk/__init__.py +5 -5
- {webcode_tk-0.7.3 → webcode_tk-0.7.5}/webcode_tk/css_tools.py +119 -1
- {webcode_tk-0.7.3 → webcode_tk-0.7.5}/webcode_tk/html_tools.py +75 -0
- {webcode_tk-0.7.3 → webcode_tk-0.7.5}/LICENSE.rst +0 -0
- {webcode_tk-0.7.3 → webcode_tk-0.7.5}/README.rst +0 -0
- {webcode_tk-0.7.3 → webcode_tk-0.7.5}/webcode_tk/color_keywords.py +0 -0
- {webcode_tk-0.7.3 → webcode_tk-0.7.5}/webcode_tk/color_tools.py +0 -0
- {webcode_tk-0.7.3 → webcode_tk-0.7.5}/webcode_tk/ux_tools.py +0 -0
- {webcode_tk-0.7.3 → webcode_tk-0.7.5}/webcode_tk/validator_tools.py +0 -0
|
@@ -4,15 +4,15 @@
|
|
|
4
4
|
Modules exported by this package:
|
|
5
5
|
- `color_keywords`: helper library to align color keywords with their
|
|
6
6
|
properties and hex and rgb values.
|
|
7
|
-
- `
|
|
8
|
-
- `
|
|
9
|
-
- `
|
|
7
|
+
- `color_tools`: processes CSS color related properties and values.
|
|
8
|
+
- `css_tools`: creates Stylesheet objects that store CSS information.
|
|
9
|
+
- `html_tools`: gets html files from a project folder, gets the HTML code
|
|
10
10
|
from files, gets number of a particular element in a file
|
|
11
11
|
or folder, gets elements as tags, and much more.
|
|
12
12
|
- `ux_tools`: gets readability stats for paragraphs of text (could
|
|
13
13
|
be from just `p` tags or a list of other tags e.g. `li`,
|
|
14
14
|
`div`, etc.).
|
|
15
|
-
- `
|
|
15
|
+
- `validator_tools`: sends HTML or CSS code to the W3C Validator to check
|
|
16
16
|
for errors.
|
|
17
17
|
"""
|
|
18
|
-
__version__ = "0.7.
|
|
18
|
+
__version__ = "0.7.5"
|
|
@@ -1295,7 +1295,12 @@ def get_color_codes_of_type(color_type: str, gradient: str) -> list:
|
|
|
1295
1295
|
|
|
1296
1296
|
|
|
1297
1297
|
def is_required_selector(selector_type: str, selector: str) -> bool:
|
|
1298
|
-
"""checks selector to see if it's required type or not
|
|
1298
|
+
"""checks selector to see if it's required type or not.
|
|
1299
|
+
|
|
1300
|
+
Example: you may wish to loop through selectors and see which
|
|
1301
|
+
ones are class selectors, or id selectors, etc..
|
|
1302
|
+
|
|
1303
|
+
It makes use of the list of regex_patterns for selector type.
|
|
1299
1304
|
|
|
1300
1305
|
Args:
|
|
1301
1306
|
selector_type: the type of selector in question, such as
|
|
@@ -1817,6 +1822,119 @@ def get_project_color_contrast(
|
|
|
1817
1822
|
return results
|
|
1818
1823
|
|
|
1819
1824
|
|
|
1825
|
+
def file_applies_property_by_selector(
|
|
1826
|
+
file_path: str, selector: str, property: str
|
|
1827
|
+
) -> bool:
|
|
1828
|
+
"""determines whether a specific property is applied to selector or not.
|
|
1829
|
+
|
|
1830
|
+
Args:
|
|
1831
|
+
file_path: path to html doc in question.
|
|
1832
|
+
selector: CSS selector (or element) that the property is applied.
|
|
1833
|
+
property: the CSS property we are looking for.
|
|
1834
|
+
|
|
1835
|
+
Returns:
|
|
1836
|
+
applies_property: whether that selector applies the property or not.
|
|
1837
|
+
"""
|
|
1838
|
+
applies_property = False
|
|
1839
|
+
style_sheets = get_all_stylesheets_by_file(file_path)
|
|
1840
|
+
|
|
1841
|
+
# look for the selector get all declaration block
|
|
1842
|
+
declarations = []
|
|
1843
|
+
for sheet in style_sheets:
|
|
1844
|
+
declaration_block = get_declaration_block_from_selector(
|
|
1845
|
+
selector, sheet
|
|
1846
|
+
)
|
|
1847
|
+
if declaration_block:
|
|
1848
|
+
declarations.append(declaration_block)
|
|
1849
|
+
combined_declaration_block = "\n".join(declarations)
|
|
1850
|
+
if combined_declaration_block:
|
|
1851
|
+
# check for property in declaration_block
|
|
1852
|
+
declarations = combined_declaration_block.split(";")
|
|
1853
|
+
for declaration in declarations:
|
|
1854
|
+
try:
|
|
1855
|
+
prop, value = declaration.split(":")
|
|
1856
|
+
if property in prop:
|
|
1857
|
+
applies_property = True
|
|
1858
|
+
break
|
|
1859
|
+
except ValueError:
|
|
1860
|
+
print("Declaration is missing a colon!")
|
|
1861
|
+
return applies_property
|
|
1862
|
+
|
|
1863
|
+
|
|
1864
|
+
def get_declaration_block_from_selector(
|
|
1865
|
+
selector: str, style_sheet: Stylesheet
|
|
1866
|
+
) -> str:
|
|
1867
|
+
declaration_block = ""
|
|
1868
|
+
for ruleset in style_sheet.rulesets:
|
|
1869
|
+
cur_selector = ruleset.selector
|
|
1870
|
+
if selector in cur_selector:
|
|
1871
|
+
# Check for grouped selectors
|
|
1872
|
+
grouped_selectors = cur_selector.split(",")
|
|
1873
|
+
if len(grouped_selectors) > 1:
|
|
1874
|
+
for item in grouped_selectors:
|
|
1875
|
+
if selector in item:
|
|
1876
|
+
if " " not in item:
|
|
1877
|
+
declaration_block += ruleset.declaration_block.text
|
|
1878
|
+
break
|
|
1879
|
+
elif is_selector_at_end_of_descendant(selector, item):
|
|
1880
|
+
declaration_block += ruleset.declaration_block.text
|
|
1881
|
+
break
|
|
1882
|
+
|
|
1883
|
+
# Check for descendant selectors
|
|
1884
|
+
if " " in cur_selector:
|
|
1885
|
+
# we have a descendant selector
|
|
1886
|
+
if is_selector_at_end_of_descendant(selector, cur_selector):
|
|
1887
|
+
declaration_block += ruleset.declaration_block.text
|
|
1888
|
+
continue
|
|
1889
|
+
declaration_block += ruleset.declaration_block.text + "\n"
|
|
1890
|
+
return declaration_block
|
|
1891
|
+
|
|
1892
|
+
|
|
1893
|
+
def is_selector_at_end_of_descendant(selector: str, cur_selector: str) -> bool:
|
|
1894
|
+
"""returns whether a selector is at the end of a descendant selector"""
|
|
1895
|
+
selector_at_end_of_descendant = False
|
|
1896
|
+
selectors = cur_selector.split()
|
|
1897
|
+
if selector in selectors[-1]:
|
|
1898
|
+
# selector must be at the end of descendant selector
|
|
1899
|
+
# or it doesn't count
|
|
1900
|
+
selector_at_end_of_descendant = True
|
|
1901
|
+
return selector_at_end_of_descendant
|
|
1902
|
+
|
|
1903
|
+
|
|
1904
|
+
def get_declaration_value_by_property(
|
|
1905
|
+
block: Union[str, DeclarationBlock], property: str
|
|
1906
|
+
) -> str:
|
|
1907
|
+
"""returns the value of a property from a declaration block
|
|
1908
|
+
|
|
1909
|
+
Args:
|
|
1910
|
+
block: the declaration block in question (could be as a string
|
|
1911
|
+
or as a DeclarationBlock)
|
|
1912
|
+
property: the property we are looking for
|
|
1913
|
+
|
|
1914
|
+
Returns:
|
|
1915
|
+
value: the value of the property"""
|
|
1916
|
+
value = ""
|
|
1917
|
+
try:
|
|
1918
|
+
block = block.text
|
|
1919
|
+
except AttributeError:
|
|
1920
|
+
declarations = block.strip()
|
|
1921
|
+
declarations = block.split(";")
|
|
1922
|
+
for item in declarations:
|
|
1923
|
+
item = item.strip()
|
|
1924
|
+
try:
|
|
1925
|
+
# check for @media rules
|
|
1926
|
+
if "{" in item:
|
|
1927
|
+
item_split = item.split("{")
|
|
1928
|
+
item = item_split[1].strip()
|
|
1929
|
+
prop, val = item.split(":")
|
|
1930
|
+
if prop.lower().strip() == property.lower():
|
|
1931
|
+
value = val.strip()
|
|
1932
|
+
continue
|
|
1933
|
+
except ValueError:
|
|
1934
|
+
print("Doh! no colon")
|
|
1935
|
+
return value
|
|
1936
|
+
|
|
1937
|
+
|
|
1820
1938
|
if __name__ == "__main__":
|
|
1821
1939
|
insane_gradient = """
|
|
1822
1940
|
-moz-radial-gradient(0% 200%, ellipse cover,
|
|
@@ -25,6 +25,7 @@ from lxml import html
|
|
|
25
25
|
STARTS_WITH_OPENING_TAG_RE = "^<[^/]+?>"
|
|
26
26
|
OPENING_TAG_RE = "<[^/]+?>"
|
|
27
27
|
CLOSING_TAG_RE = "</.+?>"
|
|
28
|
+
STYLE_TAG_RE = r"<(\w+)\s[^>]*?style=([\"|\']).*?\2\s?[^>]*?(\/?)>"
|
|
28
29
|
|
|
29
30
|
|
|
30
31
|
def get_all_html_files(dir_path: str) -> list:
|
|
@@ -257,6 +258,80 @@ def uses_inline_styles(markup: Union[Tag, str]) -> bool:
|
|
|
257
258
|
return has_inline_styles
|
|
258
259
|
|
|
259
260
|
|
|
261
|
+
def get_style_attribute_data(file: str) -> list:
|
|
262
|
+
"""returns a list of all tags that contain a style attribute
|
|
263
|
+
|
|
264
|
+
Checks to make sure file path goes to HTML doc and raises an
|
|
265
|
+
exception if not. It will return a list of tuples. The tuples
|
|
266
|
+
each contain filename, tag, and style attribute value (for
|
|
267
|
+
reference).
|
|
268
|
+
|
|
269
|
+
Args:
|
|
270
|
+
file: path to an html document.
|
|
271
|
+
|
|
272
|
+
Returns:
|
|
273
|
+
data: a list of style attribute data (filename, tag, and
|
|
274
|
+
attribute value) or st
|
|
275
|
+
|
|
276
|
+
Raises:
|
|
277
|
+
ValueError: to get a list of attribute values, the file must
|
|
278
|
+
be an HTML document
|
|
279
|
+
"""
|
|
280
|
+
data = []
|
|
281
|
+
file_type = clerk.get_file_type(file)
|
|
282
|
+
if file_type != "html":
|
|
283
|
+
raise ValueError(f"{file} is not an HTML document")
|
|
284
|
+
html_soup = get_html(file)
|
|
285
|
+
|
|
286
|
+
# check the html and body for style attribute
|
|
287
|
+
html_tag = html_soup.find("html")
|
|
288
|
+
style_value = html_tag.attrs.get("style")
|
|
289
|
+
if style_value:
|
|
290
|
+
data.append((file, "html", style_value))
|
|
291
|
+
body_tag = html_soup.find("body")
|
|
292
|
+
style_value = body_tag.attrs.get("style")
|
|
293
|
+
if style_value:
|
|
294
|
+
data.append((file, "body", style_value))
|
|
295
|
+
|
|
296
|
+
# Check all other tags in the body for style attributes
|
|
297
|
+
for tag in body_tag.children:
|
|
298
|
+
# deal with any "tag" that is a navigable string
|
|
299
|
+
tag_string = str(tag).strip()
|
|
300
|
+
if not tag_string:
|
|
301
|
+
continue
|
|
302
|
+
value = tag.attrs.get("style")
|
|
303
|
+
if not value:
|
|
304
|
+
continue
|
|
305
|
+
element = tag.name
|
|
306
|
+
data.append((file, element, value))
|
|
307
|
+
return data
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
def has_style_attribute_data(file: str) -> bool:
|
|
311
|
+
"""returns whether a file has style attributes or not
|
|
312
|
+
|
|
313
|
+
Makes use of get_style_attribute_data(), and if there is any
|
|
314
|
+
data, returns True; otherwise, False
|
|
315
|
+
|
|
316
|
+
Args:
|
|
317
|
+
file: path to an html document.
|
|
318
|
+
|
|
319
|
+
Returns:
|
|
320
|
+
has_style_attribute: a boolean (has or has not) a style
|
|
321
|
+
attribute.
|
|
322
|
+
|
|
323
|
+
Raises:
|
|
324
|
+
ValueError: to get a list of attribute values, the file must
|
|
325
|
+
be an HTML document
|
|
326
|
+
"""
|
|
327
|
+
file_type = clerk.get_file_type(file)
|
|
328
|
+
if file_type != "html":
|
|
329
|
+
raise ValueError(f"{file} is not an HTML document")
|
|
330
|
+
results = get_style_attribute_data(file)
|
|
331
|
+
has_style_attribute = bool(results)
|
|
332
|
+
return has_style_attribute
|
|
333
|
+
|
|
334
|
+
|
|
260
335
|
if __name__ == "__main__":
|
|
261
336
|
file_with_inline_styles = "tests/test_files/sample_with_inline_styles.html"
|
|
262
337
|
markup = clerk.file_to_string(file_with_inline_styles)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|