# -*- coding: utf-8 -*-
from distutils.core import setup

packages = \
['html_processor']

package_data = \
{'': ['*']}

install_requires = \
['bs4>=0.0.1,<0.0.2']

setup_kwargs = {
    'name': 'html-processor',
    'version': '0.0.5',
    'description': 'Package that provides a set of classes around BeautifulSoup for easy HTML modification.',
    'long_description': 'HTML Processor\n==============\n\n|PyPI version|\n\nHTML Processor - a package that provides a set of classes around\n`BeautifulSoup <https://www.crummy.com/software/BeautifulSoup/>`__ for\neasy HTML modification.\n\nWell, what for?\n---------------\n\nSometimes it is necessary to make constant changes in HTML code\naccording to specified rules. For example, it is necessary to insert\nlinks to thumbnails for images inserted into WYSIWYG editor. It would be\ndesirable to be able to describe changes in a more declarative and\nstructured way, rather than write simple scripts.\n\nExample\n-------\n\nIn the example we will do it (Inserting thumbnails in the code for\npictures). Let\'s say we have html, with a description of the characters\nof "Adventure Time":\n\n.. code:: html\n\n    <html>\n      <head>\n        <title>Heroes of Ooo</title>\n      </head>\n      <body>\n        <header>\n          <h1>\n            Heroes of Ooo\n          </h1>\n          <img src="" />\n        </header>\n        <main>\n          <img alt="Delete me" src="#" />\n          <article>\n            <figure>\n              <img alt="Finn Mertens" src="/media/images/heroes/Finn.jpeg" />\n              <figcaption>\n                Finn Mertens\n              </figcaption>\n            </figure>\n            <div>\n              <p>\n                Finn Mertens (simply known as Finn the Human and formerly known as\n                Pen in the original short) the main protagonist of the Cartoon\n                Network series Adventure Time.\n              </p>\n              <p>\n                He was voiced by Jeremy Shada, who also voice as Lance from Voltron:\n                Legendary Defender and Cody Maverick in Surf\'s Up: Wavemania.\n              </p>\n            </div>\n          </article>\n          <article>\n            <figure>\n              <img alt="Jake the Dog" src="/media/images/heroes/Jake.jpeg" />\n              <figcaption>\n                Jake the Dog\n              </figcaption>\n            </figure>\n            <div>\n              <p>\n                Jake is the deuteragonist of Adventure Time. He\'s a magical dog and\n                Finn\'s constant companion, best friend and adoptive brother. Jake\n                has shape shifting abilities so he can "stretch" into different\n                objects.\n              </p>\n              <p>\n                He was voiced by John DiMaggio, who also voiced as Fu Dog from\n                American Dragon: Jake Long.\n              </p>\n            </div>\n          </article>\n        </main>\n      </body>\n    </html>\n\n| We understand that we need to optimize the images.\n| For example, we use `nginx <https://nginx.org/ru/docs/http/ngx_http_image_filter_module.html>`__. We set up paths to change the image frame in the following template: ``/width/path``, where ``width`` - image width, ``path`` - image path.\n\nWe need to replace that code:\n\n.. code:: html\n\n    <img src="/media/images/heroes/Jake.jpeg" />\n\nwith the next:\n\n.. code:: html\n\n    <picture>\n        <source media="(min-width: 1024px)" srcset="/1280/media/images/heroes/Jake.jpeg 1x, /1920/media/images/heroes/Jake.jpeg 1.5x, /2560/media/images/heroes/Jake.jpeg 2x, /3840/media/images/heroes/Jake.jpeg 3x">\n        <source media="(min-width: 768px)" srcset="/1024/media/images/heroes/Jake.jpeg 1x, /1536/media/images/heroes/Jake.jpeg 1.5x, /2048/media/images/heroes/Jake.jpeg 2x, /3072/media/images/heroes/Jake.jpeg 3x">\n        <img loading="lazy" src="/media/images/heroes/Jake.jpeg" srcset="/768/media/images/heroes/Jake.jpeg 1x, /1152/media/images/heroes/Jake.jpeg 1.5x, /1536/media/images/heroes/Jake.jpeg 2x, /2304/media/images/heroes/Jake.jpeg 3x" />\n    </picture>\n\nWe also need to remove images, the source of which is not a link.\n\nIn doing so, we should not be tied specifically to this image and to\nthis location on the page.\n\nLet\'s get started. First we need to create a basic rule that will work\nfor all images on the page:\n\n.. code:: python\n\n    from html_processor import (\n        HtmlProcessor,\n        TagRule,\n    )\n\n\n    class ImageRule(TagRule):\n        tag = \'img\'\n\n\n    def process():\n        source_html = open(\'heroes.html\').read()\n        processor = HtmlProcessor(source_html, rules=[ImageRule])\n\n        with open(\'enhanced-heroes.html\', \'w\') as file:\n            file.write(repr(processor))\n\n\n    if __name__ == \'__main__\':\n        process()\n\nIf we run the script now, you will see that nothing has changed (except\nthe formatting).\n\nThat\'s because we didn\'t describe how we should change the image tags.\nLet\'s do this:\n\n.. code:: python\n\n    ...\n    class ImageRule(TagRule):\n        tag = \'img\'\n\n        rotations = (\n            1,\n            1.5,\n            2,\n            3,\n        )\n        sources = (\n            (1024, 1280),\n            (768, 1024),\n        )\n        default_width = 768\n\n        def get_new_tag(self, attributes, contents=None):\n            src = attributes.get(\'src\', \'\')\n            picture = self.create_tag(\'picture\')\n\n            for min_screen_width, width in self.sources:\n                source = self.create_sources(src, min_screen_width, width)\n                picture.append(source)\n\n            img = self.create_img(src)\n            picture.append(img)\n\n            return picture\n\n        def create_img(self, src):\n            img = self.create_tag()\n            img.attrs[\'src\'] = src\n            img.attrs[\'srcset\'] = self.build_srcset(self.default_width, src)\n            img.attrs[\'loading\'] = \'lazy\'\n\n            return img\n\n        def create_sources(self, src, min_screen_width, width):\n            source = self.create_tag(\'source\')\n            source.attrs[\'media\'] = \'(min-width: {}px)\'.format(min_screen_width)\n            source.attrs[\'srcset\'] = self.build_srcset(width, src)\n\n            return source\n\n        def build_srcset(self, width, src):\n            return \', \'.join([\'/{}{} {}x\'.format(int(width * rotate), src, rotate) for rotate in self.rotations])\n    ...\n\nWe overridden the method ``get_new_tag``. This method is called for all\ntags defined in the attribute ``TagRule.tag``, from which you can return\na new tag ``bs4.Tag``, which will replace the tag found. If we return\n``None``, the tag found does not change.\n\n.. code:: html\n\n    ...\n        <header>\n            <h1>\n            Heroes of Ooo\n            </h1>\n            <picture>\n                <source media="(min-width: 1024px)" srcset="/1280 1x, /1920 1.5x, /2560 2x, /3840 3x"/>\n                <source media="(min-width: 768px)" srcset="/1024 1x, /1536 1.5x, /2048 2x, /3072 3x"/>\n                <img loading="lazy" src="" srcset="/768 1x, /1152 1.5x, /1536 2x, /2304 3x"/>\n            </picture>\n       </header>\n    ...\n        <figure>\n            <picture>\n                <source media="(min-width: 1024px)" srcset="/1280/media/images/heroes/Finn.jpeg 1x, /1920/media/images/heroes/Finn.jpeg 1.5x, /2560/media/images/heroes/Finn.jpeg 2x, /3840/media/images/heroes/Finn.jpeg 3x"/>\n                <source media="(min-width: 768px)" srcset="/1024/media/images/heroes/Finn.jpeg 1x, /1536/media/images/heroes/Finn.jpeg 1.5x, /2048/media/images/heroes/Finn.jpeg 2x, /3072/media/images/heroes/Finn.jpeg 3x"/>\n                <img loading="lazy" src="/media/images/heroes/Finn.jpeg" srcset="/768/media/images/heroes/Finn.jpeg 1x, /1152/media/images/heroes/Finn.jpeg 1.5x, /1536/media/images/heroes/Finn.jpeg 2x, /2304/media/images/heroes/Finn.jpeg 3x"/>\n            </picture>\n            <figcaption>\n                Finn Mertens\n            </figcaption>\n        </figure>\n    ...\n        <figure>\n            <picture>\n                <source media="(min-width: 1024px)" srcset="/1280/media/images/heroes/Jake.jpeg 1x, /1920/media/images/heroes/Jake.jpeg 1.5x, /2560/media/images/heroes/Jake.jpeg 2x, /3840/media/images/heroes/Jake.jpeg 3x"/>\n                <source media="(min-width: 768px)" srcset="/1024/media/images/heroes/Jake.jpeg 1x, /1536/media/images/heroes/Jake.jpeg 1.5x, /2048/media/images/heroes/Jake.jpeg 2x, /3072/media/images/heroes/Jake.jpeg 3x"/>\n                <img loading="lazy" src="/media/images/heroes/Jake.jpeg" srcset="/768/media/images/heroes/Jake.jpeg 1x, /1152/media/images/heroes/Jake.jpeg 1.5x, /1536/media/images/heroes/Jake.jpeg 2x, /2304/media/images/heroes/Jake.jpeg 3x"/>\n            </picture>\n            <figcaption>\n                Jake the Dog\n            </figcaption>\n        </figure>\n    ...\n\n| You may notice that the images have been replaced with tags using media queries and tambneiles links. But we still have the tags of images that do not refer to the images themselves.\n| Let\'s fix this:\n\n.. code:: python\n\n    from urllib.parse import urlparse\n    ...\n        def get_new_tag(self, attributes, contents=None):\n            src = attributes.get(\'src\', \'\')\n            parsed_url = urlparse(src)\n\n            if parsed_url.path:\n                picture = self.create_tag(\'picture\')\n\n                for min_screen_width, width in self.sources:\n                    source = self.create_sources(src, min_screen_width, width)\n                    picture.append(source)\n\n                img = self.create_img(src)\n                picture.append(img)\n\n                return picture\n    ...\n        def is_extract(self, attributes, **kwargs):\n            src = attributes.get(\'src\', \'\')\n            parsed_url = urlparse(src)\n            return False if parsed_url.path else True\n\nWhat we\'ve changed:\n\n-  We return a value from the ``get_new_tag`` method only if the link in\n   the ``src`` attribute contains a path.\n-  Override method ``is_extract``, which returns ``True`` if there is no\n   path referenced in parameter ``src``. This method is responsible for\n   extracting the tag from html. If it returns ``True`` the tag will be\n   extracted, if ``False``, no action will be taken with the tag.\n   ``is_extract`` is only called if method ``get_new_tag`` has not\n   returned anything.\n\nSo, let\'s run the script and get the next result:\n\n.. code:: html\n\n    <html>\n     <head>\n      <title>\n       Heroes of Ooo\n      </title>\n     </head>\n     <body>\n      <header>\n       <h1>\n        Heroes of Ooo\n       </h1>\n      </header>\n      <main>\n       <article>\n        <figure>\n         <picture>\n          <source media="(min-width: 1024px)" srcset="/1280/media/images/heroes/Finn.jpeg 1x, /1920/media/images/heroes/Finn.jpeg 1.5x, /2560/media/images/heroes/Finn.jpeg 2x, /3840/media/images/heroes/Finn.jpeg 3x"/>\n          <source media="(min-width: 768px)" srcset="/1024/media/images/heroes/Finn.jpeg 1x, /1536/media/images/heroes/Finn.jpeg 1.5x, /2048/media/images/heroes/Finn.jpeg 2x, /3072/media/images/heroes/Finn.jpeg 3x"/>\n          <img loading="lazy" src="/media/images/heroes/Finn.jpeg" srcset="/768/media/images/heroes/Finn.jpeg 1x, /1152/media/images/heroes/Finn.jpeg 1.5x, /1536/media/images/heroes/Finn.jpeg 2x, /2304/media/images/heroes/Finn.jpeg 3x"/>\n         </picture>\n         <figcaption>\n          Finn Mertens\n         </figcaption>\n        </figure>\n        <div>\n         <p>\n          Finn Mertens (simply known as Finn the Human and formerly known as            Pen in the original short) the main protagonist of the Cartoon            Network series Adventure Time.\n         </p>\n         <p>\n          He was voiced by Jeremy Shada, who also voice as Lance from Voltron:            Legendary Defender and Cody Maverick in Surf\'s Up: Wavemania.\n         </p>\n        </div>\n       </article>\n       <article>\n        <figure>\n         <picture>\n          <source media="(min-width: 1024px)" srcset="/1280/media/images/heroes/Jake.jpeg 1x, /1920/media/images/heroes/Jake.jpeg 1.5x, /2560/media/images/heroes/Jake.jpeg 2x, /3840/media/images/heroes/Jake.jpeg 3x"/>\n          <source media="(min-width: 768px)" srcset="/1024/media/images/heroes/Jake.jpeg 1x, /1536/media/images/heroes/Jake.jpeg 1.5x, /2048/media/images/heroes/Jake.jpeg 2x, /3072/media/images/heroes/Jake.jpeg 3x"/>\n          <img loading="lazy" src="/media/images/heroes/Jake.jpeg" srcset="/768/media/images/heroes/Jake.jpeg 1x, /1152/media/images/heroes/Jake.jpeg 1.5x, /1536/media/images/heroes/Jake.jpeg 2x, /2304/media/images/heroes/Jake.jpeg 3x"/>\n         </picture>\n         <figcaption>\n          Jake the Dog\n         </figcaption>\n        </figure>\n        <div>\n         <p>\n          Jake is the deuteragonist of Adventure Time. He\'s a magical dog and            Finn\'s constant companion, best friend and adoptive brother. Jake            has shape shifting abilities so he can "stretch" into different            objects.\n         </p>\n         <p>\n          He was voiced by John DiMaggio, who also voiced as Fu Dog from            American Dragon: Jake Long.\n         </p>\n        </div>\n       </article>\n      </main>\n     </body>\n    </html>\n\nThis is what we wanted. You can find out more about the example in\n``examples/insert_thumbnails.py``.\n\nAPI\n---\n\nHtmlProcessor\n~~~~~~~~~~~~~\n\n| The class of processor that starts the html processing rules.\n| You can set the rules of html processing by creating a descendant class and overriding the attribute ``rules``, for example:\n\n.. code:: python\n\n    class TextProcessor(HtmlProcessor):\n        rules = [\n            AdventureTextRule,\n        ]\n\nThe same rules can be set through the constructor:\n\n-  **init**\\ (html: string, rules: List[Rule] = None, unqoute: bool =\n   False) - конструтор принимает строку с html кодом. Так же в него\n   можно передать правила обработки, как список объектов класса\n   ``Rule``, и флаг - стоит ли применять к html строке экранирование\n   через метод ``urllib.parse.unqoute``.\n\nProcessed content can be obtained from the processor in 3 ways:\n\n-  Call ``process`` method. This method will return the object\n   ``bs4.BeautifulSoup``.\n-  str(processor). This call will return a string with processed and\n   unformatted html code.\n-  repr(processor). This call will return a string with processed and\n   formatted html code.\n\nRule\n~~~~\n\nBase class for describing the html code processing rule.\n\nCreating a custom rule\n~~~~~~~~~~~~~~~~~~~~~~\n\n``Rule`` objects contain an attribute ``content`` that contains an\nobject ``BeautifulSoup`` created from the source html code.\n\nTo create its own rules, a class inherited from ``Rule`` the method must\nbe overridden:\n\n-  process() - this method is called to process the object\n   ``Rule.content``.\n\nYou can also override the following methods for convenience:\n\n-  get\\_area - returns the area where objects are searched for. The area\n   is selected from the attribute ``content``.\n-  select(area: BeautifulSoup) - returns the objects that we need to\n   process.\n-  select\\_element(element) - returns ``True`` if the object is suitable\n   for processing and ``False`` if not.\n\nThese methods are needed to make the method ``Rule.get_elements``\nreturned the elements needed for processing.\n\nThe creation of rules can be seen in more detail on the example of\npredefined rule classes, for example ``TagRule`` and ``TextRule``.\n\nPredetermined rules\n~~~~~~~~~~~~~~~~~~~\n\nTagRule\n^^^^^^^\n\n| A rule to process a specific tag.\n| To specify a rule, you need to create a class inherited from ``TagRule`` and define an attribute ``tag`` that takes the tag name as a string, for example ``tag = \'img\'``.\n\nThere are 2 methods for working with a tag that can be overridden:\n\n-  get\\_new\\_tag(self, attributes: dict, contents=None) - the method\n   accepts attribute dictionary ``attributes``, as well as the content\n   of the tag ``contents``. The method is called for each tag found. The\n   method must return ``None`` if we do not want to change the tag, or a\n   new tag ``bs4.Tag``, which will replace the current tag.\n-  is\\_extract(self, attributes: dict, contents=None) - The method\n   accepts attribute dictionary ``attributes``, as well as the content\n   of the tag in ``contents``. The method returns ``True`` if the tag\n   needs to be extracted from html, or ``False`` if nothing needs to be\n   done with the tag. The method is called only if ``get_new_tag`` has\n   not returned anything for the given tag.\n\nTextRule\n^^^^^^^^\n\n| A rule for processing texts inside html.\n| To set a rule, you should create a class inherited from ``TextRule``.\n\nThe following methods are available for string processing.\n\n-  get\\_new\\_string(self, string: str) - takes a string and returns a\n   new string to replace the found one.\n-  is\\_extract(self, string: str) - accepts the string and returns\n   ``True`` if the item with this string must be removed from html, or\n   ``False`` if left. Removed by the string itself, and the tag that\n   this string contains, as well as the content of this tag.\n\n.. |PyPI version| image:: https://badge.fury.io/py/html-processor.svg\n   :target: https://badge.fury.io/py/html-processor\n',
    'author': 'Дмитрий',
    'author_email': 'acrius@mail.ru',
    'url': 'https://github.com/brogency/html-processor',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'python_requires': '>=3.6,<4.0',
}


setup(**setup_kwargs)
