"Fossies" - the Fresh Open Source Software Archive

Member "xhtml2pdf-0.2.5/xhtml2pdf/w3c/cssSpecial.py" (29 Sep 2020, 13480 Bytes) of package /linux/www/xhtml2pdf-0.2.5.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "cssSpecial.py" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 0.2.4_vs_0.2.5.

    1 # -*- coding: utf-8 -*-
    2 
    3 # Copyright 2010 Dirk Holtwick, holtwick.it
    4 #
    5 # Licensed under the Apache License, Version 2.0 (the "License");
    6 # you may not use this file except in compliance with the License.
    7 # You may obtain a copy of the License at
    8 #
    9 #     http://www.apache.org/licenses/LICENSE-2.0
   10 #
   11 # Unless required by applicable law or agreed to in writing, software
   12 # distributed under the License is distributed on an "AS IS" BASIS,
   13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14 # See the License for the specific language governing permissions and
   15 # limitations under the License.
   16 # Copyright 2010 Dirk Holtwick, holtwick.it
   17 #
   18 # Licensed under the Apache License, Version 2.0 (the "License");
   19 # you may not use this file except in compliance with the License.
   20 # You may obtain a copy of the License at
   21 #
   22 #     http://www.apache.org/licenses/LICENSE-2.0
   23 #
   24 # Unless required by applicable law or agreed to in writing, software
   25 # distributed under the License is distributed on an "AS IS" BASIS,
   26 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   27 # See the License for the specific language governing permissions and
   28 # limitations under the License.
   29 
   30 
   31 __reversion__ = "$Revision: 20 $"
   32 __author__ = "$Author: holtwick $"
   33 __date__ = "$Date: 2007-10-09 12:58:24 +0200 (Di, 09 Okt 2007) $"
   34 
   35 """
   36 Helper for complex CSS definitons like font, margin, padding and border
   37 Optimized for use with PISA
   38 """
   39 
   40 #support python 3
   41 #import types
   42 TupleType = tuple
   43 ListType = list
   44 
   45 import logging
   46 
   47 
   48 log = logging.getLogger("ho.css")
   49 
   50 
   51 def toList(value):
   52     if type(value) != ListType:
   53         return [value]
   54     return value
   55 
   56 
   57 _styleTable = {
   58     "normal": "",
   59     "italic": "",
   60     "oblique": "",
   61 }
   62 
   63 _variantTable = {
   64     "normal": None,
   65     "small-caps": None,
   66 }
   67 
   68 _weightTable = {
   69     "light": 300,
   70     "lighter": 300, # fake relativness for now
   71     "normal": 400,
   72     "bold": 700,
   73     "bolder": 700, # fake relativness for now
   74 
   75     "100": 100,
   76     "200": 200,
   77     "300": 300,
   78     "400": 400,
   79     "500": 500,
   80     "600": 600,
   81     "700": 700,
   82     "800": 800,
   83     "900": 900,
   84 
   85     #wx.LIGHT: 300,
   86     #wx.NORMAL: 400,
   87     #wx.BOLD: 700,
   88 }
   89 
   90 #_absSizeTable = {
   91 #    "xx-small" : 3./5.,
   92 #    "x-small": 3./4.,
   93 #    "small": 8./9.,
   94 #    "medium": 1./1.,
   95 #    "large": 6./5.,
   96 #    "x-large": 3./2.,
   97 #    "xx-large": 2./1.,
   98 #    "xxx-large": 3./1.,
   99 #    "larger": 1.25,      # XXX Not totaly CSS conform:
  100 #    "smaller": 0.75,     # http://www.w3.org/TR/CSS21/fonts.html#propdef-font-size
  101 #    }
  102 
  103 _borderStyleTable = {
  104     "none": 0,
  105     "hidden": 0,
  106     "dotted": 1,
  107     "dashed": 1,
  108     "solid": 1,
  109     "double": 1,
  110     "groove": 1,
  111     "ridge": 1,
  112     "inset": 1,
  113     "outset": 1,
  114 }
  115 
  116 '''
  117 _relSizeTable = {
  118     'pt':
  119         # pt: absolute point size
  120         # Note: this is 1/72th of an inch
  121         (lambda value, pt: value),
  122     'px':
  123         # px: pixels, relative to the viewing device
  124         # Note: approximate at the size of a pt
  125         (lambda value, pt: value),
  126     'ex':
  127         # ex: proportional to the 'x-height' of the parent font
  128         # Note: can't seem to dervie this value from wx.Font methods,
  129         # so we'll approximate by calling it 1/2 a pt
  130         (lambda value, pt: 2 * value),
  131     'pc':
  132         # pc: 12:1 pica:point size
  133         # Note: this is 1/6th of an inch
  134         (lambda value, pt: 12*value),
  135     'in':
  136         # in: 72 inches per point
  137         (lambda value, pt: 72*value),
  138     'cm':
  139         # in: 72 inches per point, 2.54 cm per inch
  140         (lambda value, pt,_r=72./2.54: _r*value),
  141     'mm':
  142         # in: 72 inches per point, 25.4 mm per inch
  143         (lambda value, pt,_r=72./25.4: _r*value),
  144     '%':
  145         # %: percentage of the parent's pointSize
  146         (lambda value, pt: 0.01 * pt * value),
  147     'em':
  148         # em: proportional to the 'font-size' of the parent font
  149         (lambda value, pt: pt * value),
  150     }
  151 '''
  152 
  153 
  154 def getNextPart(parts):
  155     if parts:
  156         part = parts.pop(0)
  157     else:
  158         part = None
  159     return part
  160 
  161 
  162 def isSize(value):
  163     return value and ((type(value) is TupleType) or value == "0")
  164 
  165 
  166 def splitBorder(parts):
  167     """
  168     The order of the elements seems to be of no importance:
  169 
  170     http://www.w3.org/TR/CSS21/box.html#border-shorthand-properties
  171     """
  172 
  173     width = style = color = None
  174 
  175     if len(parts) > 3:
  176         log.warning("To many elements for border style %r", parts)
  177 
  178     for part in parts:
  179         # Width
  180         if isSize(part):
  181             width = part
  182 
  183         # Style
  184         elif hasattr(part, 'lower') and part.lower() in _borderStyleTable:
  185             style = part
  186 
  187         # Color
  188         else:
  189             color = part
  190 
  191     # log.debug("Border styles: %r -> %r ", copy_parts, (width, style, color))
  192 
  193     return (width, style, color)
  194 
  195 
  196 def parseSpecialRules(declarations, debug=0):
  197     # print selectors, declarations
  198     # CSS MODIFY!
  199     dd = []
  200 
  201     for d in declarations:
  202 
  203         if debug:
  204             log.debug("CSS special  IN: %r", d)
  205 
  206         name, parts, last = d
  207         oparts = parts
  208         parts = toList(parts)
  209 
  210         # FONT
  211         if name == "font":
  212             # [ [ <'font-style'> || <'font-variant'> || <'font-weight'> ]? <'font-size'> [ / <'line-height'> ]? <'font-family'> ] | inherit
  213             part = getNextPart(parts)
  214             # Style
  215             if part and part in _styleTable:
  216                 dd.append(("font-style", part, last))
  217                 part = getNextPart(parts)
  218                 # Variant
  219             if part and part in _variantTable:
  220                 dd.append(("font-variant", part, last))
  221                 part = getNextPart(parts)
  222                 # Weight
  223             if part and part in _weightTable:
  224                 dd.append(("font-weight", part, last))
  225                 part = getNextPart(parts)
  226                 # Size and Line Height
  227             if isinstance(part, tuple) and len(part) == 3:
  228                 fontSize, slash, lineHeight = part
  229                 assert slash == '/'
  230                 dd.append(("font-size", fontSize, last))
  231                 dd.append(("line-height", lineHeight, last))
  232             else:
  233                 dd.append(("font-size", part, last))
  234                 # Face/ Family
  235             dd.append(("font-face", parts, last))
  236 
  237         # BACKGROUND
  238         elif name == "background":
  239             # [<'background-color'> || <'background-image'> || <'background-repeat'> || <'background-attachment'> || <'background-position'>] | inherit
  240 
  241             # XXX We do not receive url() and parts list, so we go for a dirty work arround
  242             part = getNextPart(parts) or oparts
  243             if part:
  244 
  245                 if hasattr(part, '__iter__') and (type("." in part) or ("data:" in part)):
  246                     dd.append(("background-image", part, last))
  247                 else:
  248                     dd.append(("background-color", part, last))
  249 
  250             if 0:
  251                 part = getNextPart(parts) or oparts
  252                 print ("~", part, parts, oparts, declarations)
  253                 # Color
  254                 if part and (not part.startswith("url")):
  255                     dd.append(("background-color", part, last))
  256                     part = getNextPart(parts)
  257                     # Background
  258                 if part:
  259                     dd.append(("background-image", part, last))
  260                     # XXX Incomplete! Error in url()!
  261 
  262         # MARGIN
  263         elif name == "margin":
  264             if len(parts) == 1:
  265                 top = bottom = left = right = parts[0]
  266             elif len(parts) == 2:
  267                 top = bottom = parts[0]
  268                 left = right = parts[1]
  269             elif len(parts) == 3:
  270                 top = parts[0]
  271                 left = right = parts[1]
  272                 bottom = parts[2]
  273             elif len(parts) == 4:
  274                 top = parts[0]
  275                 right = parts[1]
  276                 bottom = parts[2]
  277                 left = parts[3]
  278             else:
  279                 continue
  280             dd.append(("margin-left", left, last))
  281             dd.append(("margin-right", right, last))
  282             dd.append(("margin-top", top, last))
  283             dd.append(("margin-bottom", bottom, last))
  284 
  285         # PADDING
  286         elif name == "padding":
  287             if len(parts) == 1:
  288                 top = bottom = left = right = parts[0]
  289             elif len(parts) == 2:
  290                 top = bottom = parts[0]
  291                 left = right = parts[1]
  292             elif len(parts) == 3:
  293                 top = parts[0]
  294                 left = right = parts[1]
  295                 bottom = parts[2]
  296             elif len(parts) == 4:
  297                 top = parts[0]
  298                 right = parts[1]
  299                 bottom = parts[2]
  300                 left = parts[3]
  301             else:
  302                 continue
  303             dd.append(("padding-left", left, last))
  304             dd.append(("padding-right", right, last))
  305             dd.append(("padding-top", top, last))
  306             dd.append(("padding-bottom", bottom, last))
  307 
  308         # BORDER WIDTH
  309         elif name == "border-width":
  310             if len(parts) == 1:
  311                 top = bottom = left = right = parts[0]
  312             elif len(parts) == 2:
  313                 top = bottom = parts[0]
  314                 left = right = parts[1]
  315             elif len(parts) == 3:
  316                 top = parts[0]
  317                 left = right = parts[1]
  318                 bottom = parts[2]
  319             elif len(parts) == 4:
  320                 top = parts[0]
  321                 right = parts[1]
  322                 bottom = parts[2]
  323                 left = parts[3]
  324             else:
  325                 continue
  326             dd.append(("border-left-width", left, last))
  327             dd.append(("border-right-width", right, last))
  328             dd.append(("border-top-width", top, last))
  329             dd.append(("border-bottom-width", bottom, last))
  330 
  331         # BORDER COLOR
  332         elif name == "border-color":
  333             if len(parts) == 1:
  334                 top = bottom = left = right = parts[0]
  335             elif len(parts) == 2:
  336                 top = bottom = parts[0]
  337                 left = right = parts[1]
  338             elif len(parts) == 3:
  339                 top = parts[0]
  340                 left = right = parts[1]
  341                 bottom = parts[2]
  342             elif len(parts) == 4:
  343                 top = parts[0]
  344                 right = parts[1]
  345                 bottom = parts[2]
  346                 left = parts[3]
  347             else:
  348                 continue
  349             dd.append(("border-left-color", left, last))
  350             dd.append(("border-right-color", right, last))
  351             dd.append(("border-top-color", top, last))
  352             dd.append(("border-bottom-color", bottom, last))
  353 
  354         # BORDER STYLE
  355         elif name == "border-style":
  356             if len(parts) == 1:
  357                 top = bottom = left = right = parts[0]
  358             elif len(parts) == 2:
  359                 top = bottom = parts[0]
  360                 left = right = parts[1]
  361             elif len(parts) == 3:
  362                 top = parts[0]
  363                 left = right = parts[1]
  364                 bottom = parts[2]
  365             elif len(parts) == 4:
  366                 top = parts[0]
  367                 right = parts[1]
  368                 bottom = parts[2]
  369                 left = parts[3]
  370             else:
  371                 continue
  372             dd.append(("border-left-style", left, last))
  373             dd.append(("border-right-style", right, last))
  374             dd.append(("border-top-style", top, last))
  375             dd.append(("border-bottom-style", bottom, last))
  376 
  377         # BORDER
  378         elif name == "border":
  379             width, style, color = splitBorder(parts)
  380             if width is not None:
  381                 dd.append(("border-left-width", width, last))
  382                 dd.append(("border-right-width", width, last))
  383                 dd.append(("border-top-width", width, last))
  384                 dd.append(("border-bottom-width", width, last))
  385             if style is not None:
  386                 dd.append(("border-left-style", style, last))
  387                 dd.append(("border-right-style", style, last))
  388                 dd.append(("border-top-style", style, last))
  389                 dd.append(("border-bottom-style", style, last))
  390             if color is not None:
  391                 dd.append(("border-left-color", color, last))
  392                 dd.append(("border-right-color", color, last))
  393                 dd.append(("border-top-color", color, last))
  394                 dd.append(("border-bottom-color", color, last))
  395 
  396         # BORDER TOP, BOTTOM, LEFT, RIGHT
  397         elif name in ("border-top", "border-bottom", "border-left", "border-right"):
  398             direction = name[7:]
  399             width, style, color = splitBorder(parts)
  400             # print direction, width
  401             if width is not None:
  402                 dd.append(("border-" + direction + "-width", width, last))
  403             if style is not None:
  404                 dd.append(("border-" + direction + "-style", style, last))
  405             if color is not None:
  406                 dd.append(("border-" + direction + "-color", color, last))
  407 
  408         # REST
  409         else:
  410             dd.append(d)
  411 
  412     if debug and dd:
  413         log.debug("CSS special OUT:\n%s", "\n".join([repr(d) for d in dd]))
  414 
  415     if 0: #declarations!=dd:
  416         print ("###", declarations)
  417         print ("#->", dd)
  418         # CSS MODIFY! END
  419     return dd
  420 
  421 
  422 #import re
  423 #_rxhttp = re.compile(r"url\([\'\"]?http\:\/\/[^\/]", re.IGNORECASE|re.DOTALL)
  424 
  425 def cleanupCSS(src):
  426     # src = _rxhttp.sub('url(', src)
  427     return src