--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ProjectWeb/Html5ToCss3Converter.py Wed Dec 31 19:14:36 2014 +0100 @@ -0,0 +1,174 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2014 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing the HTML5 to CSS3 converter. +""" + +from __future__ import unicode_literals + +import os +import datetime +import getpass +import random + +from PyQt5.QtCore import QObject +from PyQt5.QtWidgets import QDialog + +from .Html5ToCss3ConverterParameterDialog import \ + Html5ToCss3ConverterParameterDialog + + +class Html5ToCss3Converter(QObject): + """ + Class implementing the HTML5 to CSS3 converter. + """ + CssTemplate7 = "{0}{1}{2}{3}{4}{5}{6}" + CssTemplate8 = "{0}{1}{2}{3}{4}{5}{6}{7}" + Placeholders = ('margin:0', 'padding:0', 'border:0', 'font-size:100%', + 'font:inherit', 'vertical-align:baseline', 'line-height:1', + 'outline:0', 'font-weight:inherit', 'font-style:inherit', + 'font-family:inherit', 'vertical-align:baseline') + CssToIgnore = ('head', 'meta', 'noscript', 'script', 'style', 'link', + 'no-js', 'title', 'object', 'col', 'colgroup', 'option', + 'param', 'audio', 'basefont', 'isindex', 'svg', 'area', + 'embed', 'br') + + def __init__(self, html, parent=None): + """ + Constructor + + @param html HTML text to be converted (string) + @param parent reference to the parent object (QObject) + """ + super(Html5ToCss3Converter, self).__init__(parent) + + self.__html = html + + def getCss3(self): + """ + Public method to get the converted CSS3 text. + + @return CSS3 text (string) + """ + dlg = Html5ToCss3ConverterParameterDialog() + if dlg.exec_() == QDialog.Accepted: + indentation, placeholders = dlg.getData() + + # TODO: implement this + self.__createSoup() + + alreadyDone = list(self.CssToIgnore) + + css = '@charset "utf-8";{0}'.format(os.linesep) + css += "/* {0} by {1}*/{2}".format( + datetime.datetime.now().isoformat().split(".")[0], + getpass.getuser(), + 2 * os.linesep + ) + + # step 1: tags + for tag in self.__getTags(): + if tag not in alreadyDone: + css += self.CssTemplate7.format( + tag, + "{", + os.linesep, + indentation, + random.choice(self.Placeholders) + os.linesep + if placeholders else os.linesep, + "}", + os.linesep + ) + alreadyDone.append(tag) + css += "/*{0}*/{1}".format( + "-" * 75, + os.linesep + ) + + # step 2: IDs + for id_ in self.__getIds(): + if id_ not in alreadyDone: + css += "/* {0} */{1}".format( + "_".join(id_).lower(), + os.linesep + ) + css += self.CssTemplate8.format( + "#", + id_[1], + "{", + os.linesep, + indentation, + random.choice(self.Placeholders) + os.linesep + if placeholders else os.linesep, + "}", + os.linesep + ) + alreadyDone.append(id_) + css += "/*{0}*/{1}".format( + "-" * 75, + os.linesep + ) + + # step 3: classes + for class_ in self.__getClasses(): + if class_ not in alreadyDone: + css += "/* {0} */{1}".format( + "_".join(class_).lower(), + os.linesep + ) + css += self.CssTemplate8.format( + ".", + ", .".join(class_[1].split()), + "{", + os.linesep, + indentation, + random.choice(self.Placeholders) + os.linesep + if placeholders else os.linesep, + "}", + os.linesep + ) + alreadyDone.append(class_) + else: + css = "" + return css.strip() + + def __createSoup(self): + """ + Private method to get a BeaitifulSoup object with our HTML text. + """ + from bs4 import BeautifulSoup + self.__soup = BeautifulSoup(BeautifulSoup(self.__html).prettify()) + + def __getTags(self): + """ + Private method to extract all tags of the HTML text. + + @return list of all tags (list of strings) + """ + tags = [t.name for t in self.__soup.find_all(True)] + return list(set(tags)) + + def __getClasses(self): + """ + Private method to extract all classes of the HTML text. + + @return list of tuples containing the tag name and its classes + as a blank separated string (list of tuples of two strings) + """ + classes = [(t.name, " ".join(t["class"])) for t in + self.__soup.find_all(True, {"class": True})] + return sorted(list(set(classes))) + + def __getIds(self): + """ + Private method to extract all IDs of the HTML text. + + @return list of tuples containing the tag name and its ID + (list of tuples of two strings) + """ + ids = [(t.name, t["id"]) for t in + self.__soup.find_all(True, {"id": True})] + return sorted(list(set(ids)))