diff --git a/line.py b/line.py index 7e5b774..96c8958 100644 --- a/line.py +++ b/line.py @@ -1,7 +1,154 @@ from os.path import join, dirname, realpath, isfile from sublime import HIDDEN, PERSISTENT, load_settings, cache_path import subprocess, os, glob, re, platform -from .webcolors import webcolors + +css3_names_to_hex = {'aliceblue': '#f0f8ff', + 'antiquewhite': '#faebd7', + 'aqua': '#00ffff', + 'aquamarine': '#7fffd4', + 'azure': '#f0ffff', + 'beige': '#f5f5dc', + 'bisque': '#ffe4c4', + 'black': '#000000', + 'blanchedalmond': '#ffebcd', + 'blue': '#0000ff', + 'blueviolet': '#8a2be2', + 'brown': '#a52a2a', + 'burlywood': '#deb887', + 'cadetblue': '#5f9ea0', + 'chartreuse': '#7fff00', + 'chocolate': '#d2691e', + 'coral': '#ff7f50', + 'cornflowerblue': '#6495ed', + 'cornsilk': '#fff8dc', + 'crimson': '#dc143c', + 'cyan': '#00ffff', + 'darkblue': '#00008b', + 'darkcyan': '#008b8b', + 'darkgoldenrod': '#b8860b', + 'darkgray': '#a9a9a9', + 'darkgrey': '#a9a9a9', + 'darkgreen': '#006400', + 'darkkhaki': '#bdb76b', + 'darkmagenta': '#8b008b', + 'darkolivegreen': '#556b2f', + 'darkorange': '#ff8c00', + 'darkorchid': '#9932cc', + 'darkred': '#8b0000', + 'darksalmon': '#e9967a', + 'darkseagreen': '#8fbc8f', + 'darkslateblue': '#483d8b', + 'darkslategray': '#2f4f4f', + 'darkslategrey': '#2f4f4f', + 'darkturquoise': '#00ced1', + 'darkviolet': '#9400d3', + 'deeppink': '#ff1493', + 'deepskyblue': '#00bfff', + 'dimgray': '#696969', + 'dimgrey': '#696969', + 'dodgerblue': '#1e90ff', + 'firebrick': '#b22222', + 'floralwhite': '#fffaf0', + 'forestgreen': '#228b22', + 'fuchsia': '#ff00ff', + 'gainsboro': '#dcdcdc', + 'ghostwhite': '#f8f8ff', + 'gold': '#ffd700', + 'goldenrod': '#daa520', + 'gray': '#808080', + 'grey': '#808080', + 'green': '#008000', + 'greenyellow': '#adff2f', + 'honeydew': '#f0fff0', + 'hotpink': '#ff69b4', + 'indianred': '#cd5c5c', + 'indigo': '#4b0082', + 'ivory': '#fffff0', + 'khaki': '#f0e68c', + 'lavender': '#e6e6fa', + 'lavenderblush': '#fff0f5', + 'lawngreen': '#7cfc00', + 'lemonchiffon': '#fffacd', + 'lightblue': '#add8e6', + 'lightcoral': '#f08080', + 'lightcyan': '#e0ffff', + 'lightgoldenrodyellow': '#fafad2', + 'lightgray': '#d3d3d3', + 'lightgrey': '#d3d3d3', + 'lightgreen': '#90ee90', + 'lightpink': '#ffb6c1', + 'lightsalmon': '#ffa07a', + 'lightseagreen': '#20b2aa', + 'lightskyblue': '#87cefa', + 'lightslategray': '#778899', + 'lightslategrey': '#778899', + 'lightsteelblue': '#b0c4de', + 'lightyellow': '#ffffe0', + 'lime': '#00ff00', + 'limegreen': '#32cd32', + 'linen': '#faf0e6', + 'magenta': '#ff00ff', + 'maroon': '#800000', + 'mediumaquamarine': '#66cdaa', + 'mediumblue': '#0000cd', + 'mediumorchid': '#ba55d3', + 'mediumpurple': '#9370d8', + 'mediumseagreen': '#3cb371', + 'mediumslateblue': '#7b68ee', + 'mediumspringgreen': '#00fa9a', + 'mediumturquoise': '#48d1cc', + 'mediumvioletred': '#c71585', + 'midnightblue': '#191970', + 'mintcream': '#f5fffa', + 'mistyrose': '#ffe4e1', + 'moccasin': '#ffe4b5', + 'navajowhite': '#ffdead', + 'navy': '#000080', + 'oldlace': '#fdf5e6', + 'olive': '#808000', + 'olivedrab': '#6b8e23', + 'orange': '#ffa500', + 'orangered': '#ff4500', + 'orchid': '#da70d6', + 'palegoldenrod': '#eee8aa', + 'palegreen': '#98fb98', + 'paleturquoise': '#afeeee', + 'palevioletred': '#d87093', + 'papayawhip': '#ffefd5', + 'peachpuff': '#ffdab9', + 'peru': '#cd853f', + 'pink': '#ffc0cb', + 'plum': '#dda0dd', + 'powderblue': '#b0e0e6', + 'purple': '#800080', + 'red': '#ff0000', + 'rosybrown': '#bc8f8f', + 'royalblue': '#4169e1', + 'saddlebrown': '#8b4513', + 'salmon': '#fa8072', + 'sandybrown': '#f4a460', + 'seagreen': '#2e8b57', + 'seashell': '#fff5ee', + 'sienna': '#a0522d', + 'silver': '#c0c0c0', + 'skyblue': '#87ceeb', + 'slateblue': '#6a5acd', + 'slategray': '#708090', + 'slategrey': '#708090', + 'snow': '#fffafa', + 'springgreen': '#00ff7f', + 'steelblue': '#4682b4', + 'tan': '#d2b48c', + 'teal': '#008080', + 'thistle': '#d8bfd8', + 'tomato': '#ff6347', + 'turquoise': '#40e0d0', + 'violet': '#ee82ee', + 'wheat': '#f5deb3', + 'white': '#ffffff', + 'whitesmoke': '#f5f5f5', + 'yellow': '#ffff00', + 'yellowgreen': '#9acd32'} class Line: @@ -56,7 +203,7 @@ def color(self): def generate_webcolors(self): """Generates a list of web color names.""" - self.WEB_COLORS = dict((name, color) for (name, color) in webcolors.css3_names_to_hex.items()) + self.WEB_COLORS = dict((name, color) for (name, color) in css3_names_to_hex.items()) self.WEB_COLORS_REGEX = "("+ "|".join(self.WEB_COLORS.keys()) +")" def web_color(self): diff --git a/webcolors.py b/webcolors.py deleted file mode 100644 index 7729160..0000000 --- a/webcolors.py +++ /dev/null @@ -1,725 +0,0 @@ -""" -Utility functions for with the color names and color value formats -defined by the HTML and CSS specifications for use in documents on the -Web. - - -What this module supports -------------------------- - -This module supports the following methods of specifying sRGB colors, -and conversions between them: - -* Six-digit hexadecimal. - -* Three-digit hexadecimal. - -* Integer ``rgb()`` triplet. - -* Percentage ``rgb()`` triplet. - -* Varying selections of predefined color names. - -This module does not support ``hsl()`` triplets, nor does it support -opacity/alpha-channel information via ``rgba()`` or ``hsla()``. - -If you need to convert between RGB-specified colors and HSL-specified -colors, or colors specified via other means, consult `the colorsys -module`_ in the Python standard library, which can perform conversions -amongst several common color systems. - -.. _the colorsys module: http://docs.python.org/library/colorsys.html - - -Normalization and conventions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -For colors specified via hexadecimal values, this module will accept -input in the following formats: - -* A hash mark (#) followed by three hexadecimal digits, where digits - A-F may be upper- or lower-case. - -* A hash mark (#) followed by six hexadecimal digits, where digits A-F - may be upper- or lower-case. - -For output which consists of a color specified via hexadecimal values, -and for functions which perform intermediate conversion to hexadecimal -before returning a result in another format, this module always -normalizes such values to the following format: - -* A hash mark (#) followed by six hexadecimal digits, with digits A-F - forced to lower-case. - -The function :func:`normalize_hex` in this module can be used to -perform this normalization manually if desired. - -For colors specified via predefined names, this module will accept -input in the following formats: - -* An entirely lower-case name, such as ``aliceblue``. - -* A name using CamelCase, such as ``AliceBlue``. - -For output which consists of a color specified via a predefined name, -and for functions which perform intermediate conversion to a -predefined name before returning a result in another format, this -module always normalizes such values to be entirely lower-case. - -For purposes of identifying the specification from which to draw the -selection of defined color names, this module recognizes the following -identifiers: - -``html4`` - The HTML 4 named colors. - -``css2`` - The CSS 2 named colors. - -``css21`` - The CSS 2.1 named colors. - -``css3`` - The CSS 3/SVG named colors. - -The CSS 1 specification is not represented here, as it merely -"suggested" a set of color names, and declined to provide values for -them. - - -Mappings of color names ------------------------ - -For each set of defined color names -- HTML 4, CSS 2, CSS 2.1 and CSS -3 -- this module exports two mappings: one of normalized color names -to normalized hexadecimal values, and one of normalized hexadecimal -values to normalized color names. These eight mappings are as follows: - -``html4_names_to_hex`` - Mapping of normalized HTML 4 color names to normalized hexadecimal - values. - -``html4_hex_to_names`` - Mapping of normalized hexadecimal values to normalized HTML 4 - color names. - -``css2_names_to_hex`` - Mapping of normalized CSS 2 color names to normalized hexadecimal - values. Because CSS 2 defines the same set of named colors as HTML - 4, this is merely an alias for ``html4_names_to_hex``. - -``css2_hex_to_names`` - Mapping of normalized hexadecimal values to normalized CSS 2 color - nams. For the reasons described above, this is merely an alias for - ``html4_hex_to_names``. - -``css21_names_to_hex`` - Mapping of normalized CSS 2.1 color names to normalized - hexadecimal values. This is identical to ``html4_names_to_hex``, - except for one addition: ``orange``. - -``css21_hex_to_names`` - Mapping of normalized hexadecimal values to normalized CSS 2.1 - color names. As above, this is identical to ``html4_hex_to_names`` - except for the addition of ``orange``. - -``css3_names_to_hex`` - Mapping of normalized CSS3 color names to normalized hexadecimal - values. - -``css3_hex_to_names`` - Mapping of normalized hexadecimal values to normalized CSS3 color - names. - -""" - -import math -import re - - -def _reversedict(d): - """ - Internal helper for generating reverse mappings; given a - dictionary, returns a new dictionary with keys and values swapped. - - """ - return dict(zip(d.values(), d.keys())) - - -HEX_COLOR_RE = re.compile(r'^#([a-fA-F0-9]{3}|[a-fA-F0-9]{6})$') - -SUPPORTED_SPECIFICATIONS = ('html4', 'css2', 'css21', 'css3') - - -# Mappings of color names to normalized hexadecimal color values. -################################################################# - -html4_names_to_hex = {'aqua': '#00ffff', - 'black': '#000000', - 'blue': '#0000ff', - 'fuchsia': '#ff00ff', - 'green': '#008000', - 'grey': '#808080', - 'lime': '#00ff00', - 'maroon': '#800000', - 'navy': '#000080', - 'olive': '#808000', - 'purple': '#800080', - 'red': '#ff0000', - 'silver': '#c0c0c0', - 'teal': '#008080', - 'white': '#ffffff', - 'yellow': '#ffff00'} - -css2_names_to_hex = html4_names_to_hex - -css21_names_to_hex = dict(html4_names_to_hex, orange='#ffa500') - -css3_names_to_hex = {'aliceblue': '#f0f8ff', - 'antiquewhite': '#faebd7', - 'aqua': '#00ffff', - 'aquamarine': '#7fffd4', - 'azure': '#f0ffff', - 'beige': '#f5f5dc', - 'bisque': '#ffe4c4', - 'black': '#000000', - 'blanchedalmond': '#ffebcd', - 'blue': '#0000ff', - 'blueviolet': '#8a2be2', - 'brown': '#a52a2a', - 'burlywood': '#deb887', - 'cadetblue': '#5f9ea0', - 'chartreuse': '#7fff00', - 'chocolate': '#d2691e', - 'coral': '#ff7f50', - 'cornflowerblue': '#6495ed', - 'cornsilk': '#fff8dc', - 'crimson': '#dc143c', - 'cyan': '#00ffff', - 'darkblue': '#00008b', - 'darkcyan': '#008b8b', - 'darkgoldenrod': '#b8860b', - 'darkgray': '#a9a9a9', - 'darkgrey': '#a9a9a9', - 'darkgreen': '#006400', - 'darkkhaki': '#bdb76b', - 'darkmagenta': '#8b008b', - 'darkolivegreen': '#556b2f', - 'darkorange': '#ff8c00', - 'darkorchid': '#9932cc', - 'darkred': '#8b0000', - 'darksalmon': '#e9967a', - 'darkseagreen': '#8fbc8f', - 'darkslateblue': '#483d8b', - 'darkslategray': '#2f4f4f', - 'darkslategrey': '#2f4f4f', - 'darkturquoise': '#00ced1', - 'darkviolet': '#9400d3', - 'deeppink': '#ff1493', - 'deepskyblue': '#00bfff', - 'dimgray': '#696969', - 'dimgrey': '#696969', - 'dodgerblue': '#1e90ff', - 'firebrick': '#b22222', - 'floralwhite': '#fffaf0', - 'forestgreen': '#228b22', - 'fuchsia': '#ff00ff', - 'gainsboro': '#dcdcdc', - 'ghostwhite': '#f8f8ff', - 'gold': '#ffd700', - 'goldenrod': '#daa520', - 'gray': '#808080', - 'grey': '#808080', - 'green': '#008000', - 'greenyellow': '#adff2f', - 'honeydew': '#f0fff0', - 'hotpink': '#ff69b4', - 'indianred': '#cd5c5c', - 'indigo': '#4b0082', - 'ivory': '#fffff0', - 'khaki': '#f0e68c', - 'lavender': '#e6e6fa', - 'lavenderblush': '#fff0f5', - 'lawngreen': '#7cfc00', - 'lemonchiffon': '#fffacd', - 'lightblue': '#add8e6', - 'lightcoral': '#f08080', - 'lightcyan': '#e0ffff', - 'lightgoldenrodyellow': '#fafad2', - 'lightgray': '#d3d3d3', - 'lightgrey': '#d3d3d3', - 'lightgreen': '#90ee90', - 'lightpink': '#ffb6c1', - 'lightsalmon': '#ffa07a', - 'lightseagreen': '#20b2aa', - 'lightskyblue': '#87cefa', - 'lightslategray': '#778899', - 'lightslategrey': '#778899', - 'lightsteelblue': '#b0c4de', - 'lightyellow': '#ffffe0', - 'lime': '#00ff00', - 'limegreen': '#32cd32', - 'linen': '#faf0e6', - 'magenta': '#ff00ff', - 'maroon': '#800000', - 'mediumaquamarine': '#66cdaa', - 'mediumblue': '#0000cd', - 'mediumorchid': '#ba55d3', - 'mediumpurple': '#9370d8', - 'mediumseagreen': '#3cb371', - 'mediumslateblue': '#7b68ee', - 'mediumspringgreen': '#00fa9a', - 'mediumturquoise': '#48d1cc', - 'mediumvioletred': '#c71585', - 'midnightblue': '#191970', - 'mintcream': '#f5fffa', - 'mistyrose': '#ffe4e1', - 'moccasin': '#ffe4b5', - 'navajowhite': '#ffdead', - 'navy': '#000080', - 'oldlace': '#fdf5e6', - 'olive': '#808000', - 'olivedrab': '#6b8e23', - 'orange': '#ffa500', - 'orangered': '#ff4500', - 'orchid': '#da70d6', - 'palegoldenrod': '#eee8aa', - 'palegreen': '#98fb98', - 'paleturquoise': '#afeeee', - 'palevioletred': '#d87093', - 'papayawhip': '#ffefd5', - 'peachpuff': '#ffdab9', - 'peru': '#cd853f', - 'pink': '#ffc0cb', - 'plum': '#dda0dd', - 'powderblue': '#b0e0e6', - 'purple': '#800080', - 'red': '#ff0000', - 'rosybrown': '#bc8f8f', - 'royalblue': '#4169e1', - 'saddlebrown': '#8b4513', - 'salmon': '#fa8072', - 'sandybrown': '#f4a460', - 'seagreen': '#2e8b57', - 'seashell': '#fff5ee', - 'sienna': '#a0522d', - 'silver': '#c0c0c0', - 'skyblue': '#87ceeb', - 'slateblue': '#6a5acd', - 'slategray': '#708090', - 'slategrey': '#708090', - 'snow': '#fffafa', - 'springgreen': '#00ff7f', - 'steelblue': '#4682b4', - 'tan': '#d2b48c', - 'teal': '#008080', - 'thistle': '#d8bfd8', - 'tomato': '#ff6347', - 'turquoise': '#40e0d0', - 'violet': '#ee82ee', - 'wheat': '#f5deb3', - 'white': '#ffffff', - 'whitesmoke': '#f5f5f5', - 'yellow': '#ffff00', - 'yellowgreen': '#9acd32'} - - -# Mappings of normalized hexadecimal color values to color names. -################################################################# - -html4_hex_to_names = _reversedict(html4_names_to_hex) - -css2_hex_to_names = html4_hex_to_names - -css21_hex_to_names = _reversedict(css21_names_to_hex) - -css3_hex_to_names = _reversedict(css3_names_to_hex) - - -# Normalization routines. -################################################################# - -def normalize_hex(hex_value): - """ - Normalize a hexadecimal color value to the following form and - return the result:: - - #[a-f0-9]{6} - - In other words, the following transformations are applied as - needed: - - * If the value contains only three hexadecimal digits, it is - expanded to six. - - * The value is normalized to lower-case. - - If the supplied value cannot be interpreted as a hexadecimal color - value, ``ValueError`` is raised. - - Examples: - - >>> normalize_hex('#0099cc') - '#0099cc' - >>> normalize_hex('#0099CC') - '#0099cc' - >>> normalize_hex('#09c') - '#0099cc' - >>> normalize_hex('#09C') - '#0099cc' - >>> normalize_hex('0099cc') - Traceback (most recent call last): - ... - ValueError: '0099cc' is not a valid hexadecimal color value. - - """ - try: - hex_digits = HEX_COLOR_RE.match(hex_value).groups()[0] - except AttributeError: - raise ValueError("'%s' is not a valid hexadecimal color value." % hex_value) - if len(hex_digits) == 3: - hex_digits = ''.join(map(lambda s: 2 * s, hex_digits)) - return '#%s' % hex_digits.lower() - - -# Conversions from color names to various formats. -################################################################# - -def name_to_hex(name, spec='css3'): - """ - Convert a color name to a normalized hexadecimal color value. - - The optional keyword argument ``spec`` determines which - specification's list of color names will be used; valid values are - ``html4``, ``css2``, ``css21`` and ``css3``, and the default is - ``css3``. - - The color name will be normalized to lower-case before being - looked up, and when no color of that name exists in the given - specification, ``ValueError`` is raised. - - Examples: - - >>> name_to_hex('white') - '#ffffff' - >>> name_to_hex('navy') - '#000080' - >>> name_to_hex('goldenrod') - '#daa520' - >>> name_to_hex('goldenrod', spec='html4') - Traceback (most recent call last): - ... - ValueError: 'goldenrod' is not defined as a named color in html4. - - """ - if spec not in SUPPORTED_SPECIFICATIONS: - raise TypeError("'%s' is not a supported specification for color name lookups; supported specifications are: %s." % (spec, - ', '.join(SUPPORTED_SPECIFICATIONS))) - normalized = name.lower() - try: - hex_value = globals()['%s_names_to_hex' % spec][normalized] - except KeyError: - raise ValueError("'%s' is not defined as a named color in %s." % (name, spec)) - return hex_value - - -def name_to_rgb(name, spec='css3'): - """ - Convert a color name to a 3-tuple of integers suitable for use in - an ``rgb()`` triplet specifying that color. - - The optional keyword argument ``spec`` determines which - specification's list of color names will be used; valid values are - ``html4``, ``css2``, ``css21`` and ``css3``, and the default is - ``css3``. - - The color name will be normalized to lower-case before being - looked up, and when no color of that name exists in the given - specification, ``ValueError`` is raised. - - Examples: - - >>> name_to_rgb('white') - (255, 255, 255) - >>> name_to_rgb('navy') - (0, 0, 128) - >>> name_to_rgb('goldenrod') - (218, 165, 32) - - """ - return hex_to_rgb(name_to_hex(name, spec=spec)) - - -def name_to_rgb_percent(name, spec='css3'): - """ - Convert a color name to a 3-tuple of percentages suitable for use - in an ``rgb()`` triplet specifying that color. - - The optional keyword argument ``spec`` determines which - specification's list of color names will be used; valid values are - ``html4``, ``css2``, ``css21`` and ``css3``, and the default is - ``css3``. - - The color name will be normalized to lower-case before being - looked up, and when no color of that name exists in the given - specification, ``ValueError`` is raised. - - Examples: - - >>> name_to_rgb_percent('white') - ('100%', '100%', '100%') - >>> name_to_rgb_percent('navy') - ('0%', '0%', '50%') - >>> name_to_rgb_percent('goldenrod') - ('85.49%', '64.71%', '12.5%') - - """ - return rgb_to_rgb_percent(name_to_rgb(name, spec=spec)) - - -# Conversions from hexadecimal color values to various formats. -################################################################# - -def hex_to_name(hex_value, spec='css3'): - """ - Convert a hexadecimal color value to its corresponding normalized - color name, if any such name exists. - - The optional keyword argument ``spec`` determines which - specification's list of color names will be used; valid values are - ``html4``, ``css2``, ``css21`` and ``css3``, and the default is - ``css3``. - - The hexadecimal value will be normalized before being looked up, - and when no color name for the value is found in the given - specification, ``ValueError`` is raised. - - Examples: - - >>> hex_to_name('#ffffff') - 'white' - >>> hex_to_name('#fff') - 'white' - >>> hex_to_name('#000080') - 'navy' - >>> hex_to_name('#daa520') - 'goldenrod' - >>> hex_to_name('#daa520', spec='html4') - Traceback (most recent call last): - ... - ValueError: '#daa520' has no defined color name in html4. - - """ - if spec not in SUPPORTED_SPECIFICATIONS: - raise TypeError("'%s' is not a supported specification for color name lookups; supported specifications are: %s." % (spec, - ', '.join(SUPPORTED_SPECIFICATIONS))) - normalized = normalize_hex(hex_value) - try: - name = globals()['%s_hex_to_names' % spec][normalized] - except KeyError: - raise ValueError("'%s' has no defined color name in %s." % (hex_value, spec)) - return name - - -def hex_to_rgb(hex_value): - """ - Convert a hexadecimal color value to a 3-tuple of integers - suitable for use in an ``rgb()`` triplet specifying that color. - - The hexadecimal value will be normalized before being converted. - - Examples: - - >>> hex_to_rgb('#fff') - (255, 255, 255) - >>> hex_to_rgb('#000080') - (0, 0, 128) - - """ - hex_digits = normalize_hex(hex_value) - return tuple(map(lambda s: int(s, 16), - (hex_digits[1:3], hex_digits[3:5], hex_digits[5:7]))) - - -def hex_to_rgb_percent(hex_value): - """ - Convert a hexadecimal color value to a 3-tuple of percentages - suitable for use in an ``rgb()`` triplet representing that color. - - The hexadecimal value will be normalized before converting. - - Examples: - - >>> hex_to_rgb_percent('#ffffff') - ('100%', '100%', '100%') - >>> hex_to_rgb_percent('#000080') - ('0%', '0%', '50%') - - """ - return rgb_to_rgb_percent(hex_to_rgb(hex_value)) - - -# Conversions from integer rgb() triplets to various formats. -################################################################# - -def rgb_to_name(rgb_triplet, spec='css3'): - """ - Convert a 3-tuple of integers, suitable for use in an ``rgb()`` - color triplet, to its corresponding normalized color name, if any - such name exists. - - The optional keyword argument ``spec`` determines which - specification's list of color names will be used; valid values are - ``html4``, ``css2``, ``css21`` and ``css3``, and the default is - ``css3``. - - If there is no matching name, ``ValueError`` is raised. - - Examples: - - >>> rgb_to_name((255, 255, 255)) - 'white' - >>> rgb_to_name((0, 0, 128)) - 'navy' - - """ - return hex_to_name(rgb_to_hex(rgb_triplet), spec=spec) - - -def rgb_to_hex(rgb_triplet): - """ - Convert a 3-tuple of integers, suitable for use in an ``rgb()`` - color triplet, to a normalized hexadecimal value for that color. - - Examples: - - >>> rgb_to_hex((255, 255, 255)) - '#ffffff' - >>> rgb_to_hex((0, 0, 128)) - '#000080' - - """ - return '#%02x%02x%02x' % rgb_triplet - - -def rgb_to_rgb_percent(rgb_triplet): - """ - Convert a 3-tuple of integers, suitable for use in an ``rgb()`` - color triplet, to a 3-tuple of percentages suitable for use in - representing that color. - - This function makes some trade-offs in terms of the accuracy of - the final representation; for some common integer values, - special-case logic is used to ensure a precise result (e.g., - integer 128 will always convert to '50%', integer 32 will always - convert to '12.5%'), but for all other values a standard Python - ``float`` is used and rounded to two decimal places, which may - result in a loss of precision for some values. - - Examples: - - >>> rgb_to_rgb_percent((255, 255, 255)) - ('100%', '100%', '100%') - >>> rgb_to_rgb_percent((0, 0, 128)) - ('0%', '0%', '50%') - >>> rgb_to_rgb_percent((218, 165, 32)) - ('85.49%', '64.71%', '12.5%') - - """ - # In order to maintain precision for common values, - # 256 / 2**n is special-cased for values of n - # from 0 through 4, as well as 0 itself. - specials = {255: '100%', 128: '50%', 64: '25%', - 32: '12.5%', 16: '6.25%', 0: '0%'} - return tuple(map(lambda d: specials.get(d, '%.02f%%' % ((d / 255.0) * 100)), - rgb_triplet)) - - -# Conversions from percentage rgb() triplets to various formats. -################################################################# - -def rgb_percent_to_name(rgb_percent_triplet, spec='css3'): - """ - Convert a 3-tuple of percentages, suitable for use in an ``rgb()`` - color triplet, to its corresponding normalized color name, if any - such name exists. - - The optional keyword argument ``spec`` determines which - specification's list of color names will be used; valid values are - ``html4``, ``css2``, ``css21`` and ``css3``, and the default is - ``css3``. - - If there is no matching name, ``ValueError`` is raised. - - Examples: - - >>> rgb_percent_to_name(('100%', '100%', '100%')) - 'white' - >>> rgb_percent_to_name(('0%', '0%', '50%')) - 'navy' - >>> rgb_percent_to_name(('85.49%', '64.71%', '12.5%')) - 'goldenrod' - - """ - return rgb_to_name(rgb_percent_to_rgb(rgb_percent_triplet), spec=spec) - - -def rgb_percent_to_hex(rgb_percent_triplet): - """ - Convert a 3-tuple of percentages, suitable for use in an ``rgb()`` - color triplet, to a normalized hexadecimal color value for that - color. - - Examples: - - >>> rgb_percent_to_hex(('100%', '100%', '0%')) - '#ffff00' - >>> rgb_percent_to_hex(('0%', '0%', '50%')) - '#000080' - >>> rgb_percent_to_hex(('85.49%', '64.71%', '12.5%')) - '#daa520' - - """ - return rgb_to_hex(rgb_percent_to_rgb(rgb_percent_triplet)) - - -def _percent_to_integer(percent): - """ - Internal helper for converting a percentage value to an integer - between 0 and 255 inclusive. - - """ - num = float(percent.split('%')[0]) / 100.0 * 255 - e = num - math.floor(num) - return e < 0.5 and int(math.floor(num)) or int(math.ceil(num)) - - -def rgb_percent_to_rgb(rgb_percent_triplet): - """ - Convert a 3-tuple of percentages, suitable for use in an ``rgb()`` - color triplet, to a 3-tuple of integers suitable for use in - representing that color. - - Some precision may be lost in this conversion. See the note - regarding precision for ``rgb_to_rgb_percent()`` for details; - generally speaking, the following is true for any 3-tuple ``t`` of - integers in the range 0...255 inclusive:: - - t == rgb_percent_to_rgb(rgb_to_rgb_percent(t)) - - Examples: - - >>> rgb_percent_to_rgb(('100%', '100%', '100%')) - (255, 255, 255) - >>> rgb_percent_to_rgb(('0%', '0%', '50%')) - (0, 0, 128) - >>> rgb_percent_to_rgb(('85.49%', '64.71%', '12.5%')) - (218, 165, 32) - - """ - return tuple(map(_percent_to_integer, rgb_percent_triplet)) - - -if __name__ == '__main__': - import doctest - doctest.testmod()