epub converter: prettify css_reader.py

This commit is contained in:
shirshasa
2021-04-29 12:48:50 +03:00
parent e06bc58257
commit 0a9124c046
2 changed files with 56 additions and 30 deletions

View File

@@ -1,4 +1,6 @@
import re
from typing import List
import cssutils
from bs4 import BeautifulSoup
@@ -18,9 +20,8 @@ sizes_pr = [-1, 0.5, 0.56, 0.63, 0.69, 0.75, 0.81, 0.88, 0.94, 1.0, 1.06, 1.13,
sizes_px = ['10px', '10px', '11px', '12px', '13px', '14px', '15px', '16px', '17px', '18px', '19px', '20px', '21px',
'22px', '23px', '24px', '25px', '26px', '27px', '28px', '29px', '30px', '31px', '32px', '33px', '34px',
'35px',
'36px', '37px', '38px', '39px', '40px', '41px', '42px', '43px', '44px', '45px', '46px', '47px', '48px',
'49px', '50px', '64px', '72px']
'35px', '36px', '37px', '38px', '39px', '40px', '41px', '42px', '43px', '44px', '45px', '46px', '47px',
'48px', '49px', '50px', '64px', '72px']
def convert_font_size(value):
@@ -52,6 +53,13 @@ def convert_font_size(value):
return ''
"""
LIVECARTA_STYLE_ATTRS = { css property: value }
Style properties that can be used to fit livecarta css style convention.
If property has empty list, it means that any value can be converted.
If property has not empty list, it means that only certain property-value combinations can be transformed.
"""
LIVECARTA_STYLE_ATTRS = {
'text-indent': [],
'font-variant': ['small-caps'],
@@ -69,6 +77,13 @@ LIVECARTA_STYLE_ATTRS = {
'color': [],
'background-color': [],
}
"""
LIVECARTA_STYLE_ATTRS_MAPPING = { property: mapping function }
Warning, if LIVECARTA_STYLE_ATTRS is changed, LIVECARTA_STYLE_ATTRS_MAPPING should be updated
to suit livecarta style convention.
"""
LIVECARTA_STYLE_ATTRS_MAPPING = {
'text-indent': lambda x: LawCartaConfig.INDENT,
'font-variant': lambda x: x,
@@ -80,6 +95,9 @@ LIVECARTA_STYLE_ATTRS_MAPPING = {
'background-color': lambda x: LawCartaConfig.HTML42LIVECARTA_COLORS.get(str2color_name(x), ''),
}
"""
LIVECARTA_STYLE_ATTRS_SHOULD_BE_TAG = { (property, value): tag }
"""
LIVECARTA_STYLE_ATTRS_SHOULD_BE_TAG = {
('font-weight', 'bold'): 'strong',
('font-weight', '600'): 'strong',
@@ -95,7 +113,9 @@ LIVECARTA_STYLE_ATTRS_SHOULD_BE_TAG = {
}
def check_style_to_be_tag(style):
def check_style_to_be_tag(style) -> List[tuple]:
""" Some css style properties converts to tags.
Search for them and prepare list of properties to be removed from style string"""
to_remove = []
for k in LIVECARTA_STYLE_ATTRS_SHOULD_BE_TAG:
if f'{k[0]}:{k[1]}' in style:
@@ -103,6 +123,29 @@ def check_style_to_be_tag(style):
return to_remove
def update_property_to_livecarta_convention(rule, property_):
if property_.name not in LIVECARTA_STYLE_ATTRS:
# property not in LIVECARTA_STYLE_ATTRS, remove from css file
rule.style[property_.name] = ''
elif LIVECARTA_STYLE_ATTRS.get(property_.name):
# check property value to decide weather to remove or not the property_
cleaned_property = property_.value.replace('\"', '')
if cleaned_property in LIVECARTA_STYLE_ATTRS[property_.name]:
if property_.name in LIVECARTA_STYLE_ATTRS_MAPPING:
# apply transformation
func = LIVECARTA_STYLE_ATTRS_MAPPING[property_.name]
rule.style[property_.name] = func(cleaned_property)
else:
# property + value not in LIVECARTA_STYLE_ATTRS, remove from css file
rule.style[property_.name] = ''
else:
# property can have any value
if property_.name in LIVECARTA_STYLE_ATTRS_MAPPING:
func = LIVECARTA_STYLE_ATTRS_MAPPING[property_.name]
cleaned_property = property_.value.replace('\"', '')
rule.style[property_.name] = func(cleaned_property)
def clean_css(css):
@@ -110,35 +153,18 @@ def clean_css(css):
for rule in sheet:
if rule.type == rule.STYLE_RULE:
for property_ in rule.style:
if property_.name not in LIVECARTA_STYLE_ATTRS:
rule.style[property_.name] = ''
# not remove based on property value
elif LIVECARTA_STYLE_ATTRS.get(property_.name):
tmp = property_.value.replace('\"', '')
if tmp in LIVECARTA_STYLE_ATTRS[property_.name]:
if property_.name in LIVECARTA_STYLE_ATTRS_MAPPING:
func = LIVECARTA_STYLE_ATTRS_MAPPING[property_.name]
tmp = property_.value.replace('\"', '')
rule.style[property_.name] = func(tmp)
else:
rule.style[property_.name] = ''
else:
if property_.name in LIVECARTA_STYLE_ATTRS_MAPPING:
func = LIVECARTA_STYLE_ATTRS_MAPPING[property_.name]
tmp = property_.value.replace('\"', '')
rule.style[property_.name] = func(tmp)
update_property_to_livecarta_convention(rule, property_)
css_text = sheet._getCssText().decode()
return css_text
def add_inline_style_to_html_soup(soup1, css_text):
livecarta_p_ids = []
livecarta_tmp_ids = []
h_regex = f'(^h[{LawCartaConfig.SUPPORTED_LEVELS + 1}-9]$)'
for i, x in enumerate(soup1.find_all(re.compile('(^p$)|(^span$)|(^li$)|(^ul$)' + h_regex))):
for i, x in enumerate(soup1.find_all(re.compile('(^p$)|(^span$)|(^li$)|(^ul$)|(^ol$)' + h_regex))):
x.attrs['livecarta_id'] = i
livecarta_p_ids.append(i)
livecarta_tmp_ids.append(i)
html_with_inline_style = transform(str(soup1), css_text=css_text,
remove_classes=False,
@@ -146,7 +172,7 @@ def add_inline_style_to_html_soup(soup1, css_text):
disable_validation=True)
soup2 = BeautifulSoup(html_with_inline_style, features='lxml')
for i in livecarta_p_ids:
for i in livecarta_tmp_ids:
tag = soup1.find(attrs={'livecarta_id': i})
tag_initial_name = tag.name
tag_with_style = soup2.find(attrs={'livecarta_id': i})

View File

@@ -1,13 +1,13 @@
from webcolors import html4_hex_to_names, hex_to_rgb, rgb_to_name
def closest_colour_rgb(requested_colour):
def closest_colour_rgb(requested_color):
min_colours = {}
for key, name in html4_hex_to_names.items():
r_c, g_c, b_c = hex_to_rgb(key)
rd = (r_c - requested_colour[0]) ** 2
gd = (g_c - requested_colour[1]) ** 2
bd = (b_c - requested_colour[2]) ** 2
rd = (r_c - requested_color[0]) ** 2
gd = (g_c - requested_color[1]) ** 2
bd = (b_c - requested_color[2]) ** 2
min_colours[(rd + gd + bd)] = name
return min_colours[min(min_colours.keys())]