ProjectWeb/Html5ToCss3Converter.py

branch
eric7
changeset 43
2bed42620c99
parent 41
836c696f9565
child 48
17eb790b9a82
equal deleted inserted replaced
42:27f43499da60 43:2bed42620c99
13 import random 13 import random
14 14
15 from PyQt6.QtCore import QObject 15 from PyQt6.QtCore import QObject
16 from PyQt6.QtWidgets import QDialog 16 from PyQt6.QtWidgets import QDialog
17 17
18 from .Html5ToCss3ConverterParameterDialog import ( 18 from .Html5ToCss3ConverterParameterDialog import Html5ToCss3ConverterParameterDialog
19 Html5ToCss3ConverterParameterDialog
20 )
21 19
22 20
23 class Html5ToCss3Converter(QObject): 21 class Html5ToCss3Converter(QObject):
24 """ 22 """
25 Class implementing the HTML5 to CSS3 converter. 23 Class implementing the HTML5 to CSS3 converter.
26 """ 24 """
25
27 CssTemplate7 = "{0}{1}{2}{3}{4}{5}{6}" 26 CssTemplate7 = "{0}{1}{2}{3}{4}{5}{6}"
28 CssTemplate8 = "{0}{1}{2}{3}{4}{5}{6}{7}" 27 CssTemplate8 = "{0}{1}{2}{3}{4}{5}{6}{7}"
29 Placeholders = ('margin:0', 'padding:0', 'border:0', 'font-size:100%', 28 Placeholders = (
30 'font:inherit', 'vertical-align:baseline', 'line-height:1', 29 "margin:0",
31 'outline:0', 'font-weight:inherit', 'font-style:inherit', 30 "padding:0",
32 'font-family:inherit', 'vertical-align:baseline') 31 "border:0",
33 TagsToIgnore = ('head', 'meta', 'noscript', 'script', 'style', 'link', 32 "font-size:100%",
34 'no-js', 'title', 'object', 'col', 'colgroup', 'option', 33 "font:inherit",
35 'param', 'audio', 'basefont', 'isindex', 'svg', 'area', 34 "vertical-align:baseline",
36 'embed', 'br') 35 "line-height:1",
37 36 "outline:0",
37 "font-weight:inherit",
38 "font-style:inherit",
39 "font-family:inherit",
40 "vertical-align:baseline",
41 )
42 TagsToIgnore = (
43 "head",
44 "meta",
45 "noscript",
46 "script",
47 "style",
48 "link",
49 "no-js",
50 "title",
51 "object",
52 "col",
53 "colgroup",
54 "option",
55 "param",
56 "audio",
57 "basefont",
58 "isindex",
59 "svg",
60 "area",
61 "embed",
62 "br",
63 )
64
38 def __init__(self, html, parent=None): 65 def __init__(self, html, parent=None):
39 """ 66 """
40 Constructor 67 Constructor
41 68
42 @param html HTML text to be converted 69 @param html HTML text to be converted
43 @type str 70 @type str
44 @param parent reference to the parent object 71 @param parent reference to the parent object
45 @type QObject 72 @type QObject
46 """ 73 """
47 super().__init__(parent) 74 super().__init__(parent)
48 75
49 self.__html = html 76 self.__html = html
50 77
51 def getCss3(self): 78 def getCss3(self):
52 """ 79 """
53 Public method to get the converted CSS3 text. 80 Public method to get the converted CSS3 text.
54 81
55 @return CSS3 text 82 @return CSS3 text
56 @rtype str 83 @rtype str
57 """ 84 """
58 dlg = Html5ToCss3ConverterParameterDialog() 85 dlg = Html5ToCss3ConverterParameterDialog()
59 if dlg.exec() == QDialog.DialogCode.Accepted: 86 if dlg.exec() == QDialog.DialogCode.Accepted:
60 indentation, placeholders = dlg.getData() 87 indentation, placeholders = dlg.getData()
61 88
62 self.__createSoup() 89 self.__createSoup()
63 90
64 alreadyDone = list(self.TagsToIgnore) 91 alreadyDone = list(self.TagsToIgnore)
65 92
66 css = '@charset "utf-8";{0}'.format(os.linesep) 93 css = '@charset "utf-8";{0}'.format(os.linesep)
67 css += "/* {0} by {1}*/{2}".format( 94 css += "/* {0} by {1}*/{2}".format(
68 datetime.datetime.now().isoformat().split(".")[0], 95 datetime.datetime.now().isoformat().split(".")[0],
69 getpass.getuser(), 96 getpass.getuser(),
70 2 * os.linesep 97 2 * os.linesep,
71 ) 98 )
72 99
73 # step 1: tags 100 # step 1: tags
74 for tag in self.__getTags(): 101 for tag in self.__getTags():
75 if tag not in alreadyDone: 102 if tag not in alreadyDone:
76 css += self.CssTemplate7.format( 103 css += self.CssTemplate7.format(
77 tag, 104 tag,
78 "{", 105 "{",
79 os.linesep, 106 os.linesep,
80 indentation, 107 indentation,
81 random.choice(self.Placeholders) + os.linesep # secok 108 random.choice(self.Placeholders) + os.linesep # secok
82 if placeholders else os.linesep, 109 if placeholders
110 else os.linesep,
83 "}", 111 "}",
84 os.linesep 112 os.linesep,
85 ) 113 )
86 alreadyDone.append(tag) 114 alreadyDone.append(tag)
87 css += "/*{0}*/{1}".format( 115 css += "/*{0}*/{1}".format("-" * 75, os.linesep)
88 "-" * 75, 116
89 os.linesep
90 )
91
92 # step 2: IDs 117 # step 2: IDs
93 for id_ in self.__getIds(): 118 for id_ in self.__getIds():
94 if id_ not in alreadyDone: 119 if id_ not in alreadyDone:
95 css += "/* {0} */{1}".format( 120 css += "/* {0} */{1}".format("_".join(id_).lower(), os.linesep)
96 "_".join(id_).lower(),
97 os.linesep
98 )
99 css += self.CssTemplate8.format( 121 css += self.CssTemplate8.format(
100 "#", 122 "#",
101 id_[1], 123 id_[1],
102 "{", 124 "{",
103 os.linesep, 125 os.linesep,
104 indentation, 126 indentation,
105 random.choice(self.Placeholders) + os.linesep # secok 127 random.choice(self.Placeholders) + os.linesep # secok
106 if placeholders else os.linesep, 128 if placeholders
129 else os.linesep,
107 "}", 130 "}",
108 os.linesep 131 os.linesep,
109 ) 132 )
110 alreadyDone.append(id_) 133 alreadyDone.append(id_)
111 css += "/*{0}*/{1}".format( 134 css += "/*{0}*/{1}".format("-" * 75, os.linesep)
112 "-" * 75, 135
113 os.linesep
114 )
115
116 # step 3: classes 136 # step 3: classes
117 for class_ in self.__getClasses(): 137 for class_ in self.__getClasses():
118 if class_ not in alreadyDone: 138 if class_ not in alreadyDone:
119 css += "/* {0} */{1}".format( 139 css += "/* {0} */{1}".format("_".join(class_).lower(), os.linesep)
120 "_".join(class_).lower(),
121 os.linesep
122 )
123 css += self.CssTemplate8.format( 140 css += self.CssTemplate8.format(
124 ".", 141 ".",
125 ", .".join(class_[1].split()), 142 ", .".join(class_[1].split()),
126 "{", 143 "{",
127 os.linesep, 144 os.linesep,
128 indentation, 145 indentation,
129 random.choice(self.Placeholders) + os.linesep # secok 146 random.choice(self.Placeholders) + os.linesep # secok
130 if placeholders else os.linesep, 147 if placeholders
148 else os.linesep,
131 "}", 149 "}",
132 os.linesep 150 os.linesep,
133 ) 151 )
134 alreadyDone.append(class_) 152 alreadyDone.append(class_)
135 else: 153 else:
136 css = "" 154 css = ""
137 return css.strip() 155 return css.strip()
138 156
139 def __createSoup(self): 157 def __createSoup(self):
140 """ 158 """
141 Private method to get a BeaitifulSoup object with our HTML text. 159 Private method to get a BeaitifulSoup object with our HTML text.
142 """ 160 """
143 from bs4 import BeautifulSoup 161 from bs4 import BeautifulSoup
162
144 self.__soup = BeautifulSoup(BeautifulSoup(self.__html).prettify()) 163 self.__soup = BeautifulSoup(BeautifulSoup(self.__html).prettify())
145 164
146 def __getTags(self): 165 def __getTags(self):
147 """ 166 """
148 Private method to extract all tags of the HTML text. 167 Private method to extract all tags of the HTML text.
149 168
150 @return list of all tags 169 @return list of all tags
151 @rtype list of str 170 @rtype list of str
152 """ 171 """
153 tags = [t.name for t in self.__soup.find_all(True)] 172 tags = [t.name for t in self.__soup.find_all(True)]
154 return list(set(tags)) 173 return list(set(tags))
155 174
156 def __getClasses(self): 175 def __getClasses(self):
157 """ 176 """
158 Private method to extract all classes of the HTML text. 177 Private method to extract all classes of the HTML text.
159 178
160 @return list of tuples containing the tag name and its classes 179 @return list of tuples containing the tag name and its classes
161 as a blank separated string 180 as a blank separated string
162 @rtype list of tuples of (str, str) 181 @rtype list of tuples of (str, str)
163 """ 182 """
164 classes = [(t.name, " ".join(t["class"])) for t in 183 classes = [
165 self.__soup.find_all(True, {"class": True})] 184 (t.name, " ".join(t["class"]))
185 for t in self.__soup.find_all(True, {"class": True})
186 ]
166 return sorted(set(classes)) 187 return sorted(set(classes))
167 188
168 def __getIds(self): 189 def __getIds(self):
169 """ 190 """
170 Private method to extract all IDs of the HTML text. 191 Private method to extract all IDs of the HTML text.
171 192
172 @return list of tuples containing the tag name and its ID 193 @return list of tuples containing the tag name and its ID
173 @rtype list of tuples of (str, str) 194 @rtype list of tuples of (str, str)
174 """ 195 """
175 ids = [(t.name, t["id"]) for t in 196 ids = [(t.name, t["id"]) for t in self.__soup.find_all(True, {"id": True})]
176 self.__soup.find_all(True, {"id": True})]
177 return sorted(set(ids)) 197 return sorted(set(ids))

eric ide

mercurial