Source code for korona.html.tags.anchor

# -*- coding: utf-8 -*-
"""Module for constructing anchor <a> tag."""

from __future__ import absolute_import

from ...warning import warn
from ...exceptions import TagAttributeError, AttributeValueError

from ..root.global_attributes import GlobalAttributes
from ...lib.utils import (
    validate_url,
    validate_string_attribute,
    validate_attribute_values
)
from ...templates.html.tags import anchor

RECTANGLE_SHAPE_COORDINATES = 4
CIRCLE_SHAPE_COORDINATES = 3
CHARACTER_SETS = ['UTF-8', 'ISO-8859-1']

ATTRIBUTES = {
    'charset': {
        'description': 'Specifies the character-set of a linked '
                       'document.',
        'values': None
    },
    'coords': {
        'description': 'Specifies the coordinates of a link.',
        'values': None
    },
    'download': {
        'description': 'Specifies that the target will be downloaded '
                       'when a user clicks on the hyper link.',
        'values': None
    },
    'href': {
        'descirption': 'Specifies the URL of the page the link goes '
                       'to.',
        'values': None
    },
    'hreflang': {
        'description': 'Specifies the language of the linked '
                       'document.',
        'values': None
    },
    # TODO: Add media attribute.
    'name': {
        'description': 'Specifies the name of an anchor.',
        'values': None
    },
    'rel': {
        'description': 'Specifies the relationship between the current'
                       ' document and the linked document.',
        'values': ['alternate',
                   'author',
                   'bookmark',
                   'help',
                   'license',
                   'next',
                   'nofollow',
                   'noreferrer',
                   'prefetch',
                   'prev',
                   'search',
                   'tag']
    },
    'rev': {
        'description': 'Specifies the relationship between the linked '
                       'document and the current document.',
        'values': ['alternate',
                   'stylesheet',
                   'start',
                   'next',
                   'prev',
                   'contents',
                   'index',
                   'glossary',
                   'copyright',
                   'chapter',
                   'section',
                   'subsection',
                   'appendix',
                   'help',
                   'bookmark',
                   'nofollow']
    },
    'shape': {
        'description': 'Specifies the shape of a link.',
        'values': ['default', 'rect', 'circle', 'poly']
    },
    'target': {
        'description': 'Specifies where to open the linked document.',
        'values': None
    },
    'type': {
        'description': 'Specifies the media type of the linked '
                       'document.',
        'values': None
    }
}


[docs]class A(object): """Class for constructing anchor tag. Args: charset (str): Specifies the character-set of a linked document. coords (mixed): A list/tuple/string of coordinate values. download (str): Specifies that the target will be downloaded when a user clicks on the hyper link. href (str): Specifies the URL of the page the link goes to. hreflang (str): Specifies the language of the linked document. name (str): Specifies the name of an anchor. rel (str): Specifies the relationship between the current document and the linked document. rev (str): Specifies the relationship between the linked document and the current document. shape (str): Specifies the shape of a link. target(str): Specifies where to open the linked document. type (str): Specifies the media type of the linked document. text (str): Anchor tag text. (Ex. <a>text</a>) .. versionadded:: 0.1.0 .. versionchanged:: 0.2.0 Renamed the method construct_tag to construct. .. versionchanged:: 0.3.1 Added URL validation for href attribute. .. versionchanged:: 0.4.3-dev Now the user can be displayed with warnings for charset attribute. Used custom exceptions for all the attributes. Removed the method :func:`validate_values`. """ def __init__(self, charset=None, coords=None, download=None, href=None, hreflang=None, name=None, rel=None, rev=None, shape=None, target=None, type=None, text=None): self.tag = 'a' self.validate_charset(charset) coordinates = self.get_coords(shape=shape, coords=coords) self.pre_validate(href=href, attribute_name='download', value=download) validate_url(attribute_name='download', url=download) validate_url(attribute_name='href', url=href) self.pre_validate(href=href, attribute_name='hreflang', value=hreflang) self.pre_validate(href=href, attribute_name='rel', value=rel) validate_string_attribute(tag=self.tag, attribute_name='rel', attribute_value=rel) validate_attribute_values( tag=self.tag, attribute_name='rel', attribute_value=rel, default_values=ATTRIBUTES['rel']['values']) validate_string_attribute(tag=self.tag, attribute_name='rev', attribute_value=rev) validate_attribute_values( tag=self.tag, attribute_name='rev', attribute_value=rev, default_values=ATTRIBUTES['rev']['values']) validate_string_attribute(tag=self.tag, attribute_name='shape', attribute_value=shape) validate_attribute_values( tag=self.tag, attribute_name='shape', attribute_value=shape, default_values=ATTRIBUTES['shape']['values']) self.pre_validate(href=href, attribute_name='type', value=type) self.values = {'charset': charset, 'coords': coordinates, 'download': download, 'href': href, 'hreflang': hreflang, 'name': name, 'rel': rel, 'rev': rev, 'shape': shape, 'target': target, 'type': type, 'text': text}
[docs] def construct(self): """Returns the constructed anchor tag <a></a>.""" return anchor.render(self.values)
[docs] def validate_charset(self, charset): """Validates charset attribute. Warn the user showing the common character sets used. """ if not charset: return # If the attribute value is not a string raise a AttributeValueError. if not isinstance(charset, str): raise AttributeValueError('<{tag}>: {value} should be a string' .format(tag=self.tag, value=charset)) if charset.upper() not in CHARACTER_SETS: warn('Common character sets used are: {charsets}' .format(charsets=','.join(CHARACTER_SETS)))
[docs] def get_coords(self, shape, coords): """Returns coordinates after a series of validations. Args: shape (str): Shape of a link (Ex. rect/circle/poly/etc.) coords (mixed): A list/tuple/str of coordinate values. Returns: str: A string of coordinate values. """ if not coords: return if (coords and not shape) or (shape and not coords): raise TagAttributeError('<a>: shape attribute should be present ' 'when coords are specified.') if isinstance(coords, str): coords = coords.split(',') if isinstance(coords, dict): raise AttributeValueError('<a>: {0} should be either ' 'list/tuple/str not a dictionary' .format(coords)) if shape == 'rect' and len(coords) != RECTANGLE_SHAPE_COORDINATES: raise TagAttributeError('<a>: {0} coordinates should be given for ' 'rectangle shape' .format(RECTANGLE_SHAPE_COORDINATES)) if shape == 'circle' and len(coords) != CIRCLE_SHAPE_COORDINATES: raise TagAttributeError('<a>: {0} coordinates should be given ' 'for circle shape' .format(CIRCLE_SHAPE_COORDINATES)) return ','.join(str(coord) for coord in coords)
[docs] def pre_validate(self, href, attribute_name, value): """Validates whether an attribute is dependant on another attribute or not. Some of the attributes requires href attribute to be set. """ if not value: return if not href: raise TagAttributeError('<a>: {attribute_name} attribute is only ' 'used when href attribute is set.' .format(attribute_name=attribute_name))