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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: webcode-tk
3
- Version: 0.7.3
3
+ Version: 0.7.5
4
4
  Summary:
5
5
  Home-page: https://github.com/HundredVisionsGuy/webcode-tk
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "webcode-tk"
3
- version = "0.7.3"
3
+ version = "0.7.5"
4
4
  description = ""
5
5
  authors = ["hundredvisionsguy <cwinikka@gmail.com>"]
6
6
  keywords = ["html", "validation", "css", ]
@@ -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
- - `colortools`: processes CSS color related properties and values.
8
- - `css`: creates Stylesheet objects that store CSS information.
9
- - `html`: gets html files from a project folder, gets the HTML code
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
- - `validator`: sends HTML or CSS code to the W3C Validator to check
15
+ - `validator_tools`: sends HTML or CSS code to the W3C Validator to check
16
16
  for errors.
17
17
  """
18
- __version__ = "0.7.3"
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