Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
D
django-pipeline
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenEdx
django-pipeline
Commits
fc14ffd4
Commit
fc14ffd4
authored
Mar 23, 2011
by
Timothée Peignier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
remove python csstidy filter
parent
c00984f9
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
0 additions
and
1674 deletions
+0
-1674
compress/filters/csstidy_python/__init__.py
+0
-19
compress/filters/csstidy_python/csstidy.py
+0
-637
compress/filters/csstidy_python/data.py
+0
-422
compress/filters/csstidy_python/optimizer.py
+0
-384
compress/filters/csstidy_python/output.py
+0
-102
compress/filters/csstidy_python/tools.py
+0
-110
No files found.
compress/filters/csstidy_python/__init__.py
deleted
100644 → 0
View file @
c00984f9
from
django.conf
import
settings
from
compress.filter_base
import
FilterBase
from
compress.filters.csstidy_python.csstidy
import
CSSTidy
COMPRESS_CSSTIDY_SETTINGS
=
getattr
(
settings
,
'COMPRESS_CSSTIDY_SETTINGS'
,
{})
class
CSSTidyFilter
(
FilterBase
):
def
filter_css
(
self
,
css
):
tidy
=
CSSTidy
()
for
k
,
v
in
COMPRESS_CSSTIDY_SETTINGS
.
items
():
tidy
.
setSetting
(
k
,
v
)
tidy
.
parse
(
css
)
r
=
tidy
.
Output
(
'string'
)
return
r
compress/filters/csstidy_python/csstidy.py
deleted
100644 → 0
View file @
c00984f9
# CSSTidy - CSS Parse
#
# CSS Parser class
#
# This file is part of CSSTidy.
#
# CSSTidy is free software you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation either version 2 of the License, or
# (at your option) any later version.
#
# CSSTidy is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with CSSTidy if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# @license http://opensource.org/licenses/gpl-license.php GNU Public License
# @package csstidy
# @author Dj Gilcrease (digitalxero at gmail dot com) 2005-2006
import
re
from
optimizer
import
CSSOptimizer
from
output
import
CSSPrinter
import
data
from
tools
import
SortedDict
class
CSSTidy
(
object
):
#Saves the parsed CSS
_css
=
""
_raw_css
=
SortedDict
()
_optimized_css
=
SortedDict
()
#List of Tokens
_tokens
=
[]
#Printer class
_output
=
None
#Optimiser class
_optimizer
=
None
#Saves the CSS charset (@charset)
_charset
=
''
#Saves all @import URLs
_import
=
[]
#Saves the namespace
_namespace
=
''
#Contains the version of csstidy
_version
=
'1.3'
#Stores the settings
_settings
=
{}
# Saves the parser-status.
#
# Possible values:
# - is = in selector
# - ip = in property
# - iv = in value
# - instr = in string (started at " or ' or ( )
# - ic = in comment (ignore everything)
# - at = in @-block
_status
=
'is'
#Saves the current at rule (@media)
_at
=
''
#Saves the current selector
_selector
=
''
#Saves the current property
_property
=
''
#Saves the position of , in selectors
_sel_separate
=
[]
#Saves the current value
_value
=
''
#Saves the current sub-value
_sub_value
=
''
#Saves all subvalues for a property.
_sub_value_arr
=
[]
#Saves the char which opened the last string
_str_char
=
''
_cur_string
=
''
#Status from which the parser switched to ic or instr
_from
=
''
#Variable needed to manage string-in-strings, for example url("foo.png")
_str_in_str
=
False
#=True if in invalid at-rule
_invalid_at
=
False
#=True if something has been added to the current selector
_added
=
False
#Saves the message log
_log
=
SortedDict
()
#Saves the line number
_line
=
1
def
__init__
(
self
):
self
.
_settings
[
'remove_bslash'
]
=
True
self
.
_settings
[
'compress_colors'
]
=
True
self
.
_settings
[
'compress_font-weight'
]
=
True
self
.
_settings
[
'lowercase_s'
]
=
False
self
.
_settings
[
'optimise_shorthands'
]
=
2
self
.
_settings
[
'remove_last_'
]
=
False
self
.
_settings
[
'case_properties'
]
=
1
self
.
_settings
[
'sort_properties'
]
=
False
self
.
_settings
[
'sort_selectors'
]
=
False
self
.
_settings
[
'merge_selectors'
]
=
2
self
.
_settings
[
'discard_invalid_properties'
]
=
False
self
.
_settings
[
'css_level'
]
=
'CSS2.1'
self
.
_settings
[
'preserve_css'
]
=
False
self
.
_settings
[
'timestamp'
]
=
False
self
.
_settings
[
'template'
]
=
'highest_compression'
#Maps self._status to methods
self
.
__statusMethod
=
{
'is'
:
self
.
__parseStatus_is
,
'ip'
:
self
.
__parseStatus_ip
,
'iv'
:
self
.
__parseStatus_iv
,
'instr'
:
self
.
__parseStatus_instr
,
'ic'
:
self
.
__parseStatus_ic
,
'at'
:
self
.
__parseStatus_at
}
self
.
_output
=
CSSPrinter
(
self
)
self
.
_optimizer
=
CSSOptimizer
(
self
)
#Public Methods
def
getSetting
(
self
,
setting
):
return
self
.
_settings
.
get
(
setting
,
False
)
#Set the value of a setting.
def
setSetting
(
self
,
setting
,
value
):
self
.
_settings
[
setting
]
=
value
return
True
def
log
(
self
,
message
,
ttype
,
line
=
-
1
):
if
line
==
-
1
:
line
=
self
.
_line
line
=
int
(
line
)
add
=
{
'm'
:
message
,
't'
:
ttype
}
if
not
self
.
_log
.
has_key
(
line
):
self
.
_log
[
line
]
=
[]
self
.
_log
[
line
]
.
append
(
add
)
elif
add
not
in
self
.
_log
[
line
]:
self
.
_log
[
line
]
.
append
(
add
)
#Checks if a character is escaped (and returns True if it is)
def
escaped
(
self
,
string
,
pos
):
return
not
(
string
[
pos
-
1
]
!=
'
\\
'
or
self
.
escaped
(
string
,
pos
-
1
))
#Adds CSS to an existing media/selector
def
merge_css_blocks
(
self
,
media
,
selector
,
css_add
):
for
prop
,
value
in
css_add
.
iteritems
():
self
.
__css_add_property
(
media
,
selector
,
prop
,
value
,
False
)
#Checks if $value is !important.
def
is_important
(
self
,
value
):
return
'!important'
in
value
.
lower
()
#Returns a value without !important
def
gvw_important
(
self
,
value
):
if
self
.
is_important
(
value
):
ret
=
value
.
strip
()
ret
=
ret
[
0
:
-
9
]
ret
=
ret
.
strip
()
ret
=
ret
[
0
:
-
1
]
ret
=
ret
.
strip
()
return
ret
return
value
def
parse
(
self
,
cssString
):
#Switch from \r\n to \n
self
.
_css
=
cssString
.
replace
(
"
\r\n
"
,
"
\n
"
)
+
' '
self
.
_raw_css
=
{}
self
.
_optimized_css
=
{}
self
.
_curComment
=
''
#Start Parsing
i
=
0
while
i
<
len
(
cssString
):
if
self
.
_css
[
i
]
==
"
\n
"
or
self
.
_css
[
i
]
==
"
\r
"
:
self
.
_line
+=
1
i
+=
self
.
__statusMethod
[
self
.
_status
](
i
)
i
+=
1
;
self
.
_optimized_css
=
self
.
_optimizer
.
optimize
(
self
.
_raw_css
)
def
parseFile
(
self
,
filename
):
try
:
f
=
open
(
filename
,
"r"
)
self
.
parse
(
f
.
read
())
finally
:
f
.
close
()
#Private Methods
def
__parseStatus_is
(
self
,
idx
):
"""
Parse in Selector
"""
ret
=
0
if
self
.
__is_token
(
self
.
_css
,
idx
):
if
self
.
_css
[
idx
]
==
'/'
and
self
.
_css
[
idx
+
1
]
==
'*'
and
self
.
_selector
.
strip
()
==
''
:
self
.
_status
=
'ic'
self
.
_from
=
'is'
return
1
elif
self
.
_css
[
idx
]
==
'@'
and
self
.
_selector
.
strip
()
==
''
:
#Check for at-rule
self
.
_invalid_at
=
True
for
name
,
ttype
in
data
.
at_rules
.
iteritems
():
if
self
.
_css
[
idx
+
1
:
len
(
name
)]
.
lower
()
==
name
.
lower
():
if
ttype
==
'at'
:
self
.
_at
=
'@'
+
name
else
:
self
.
_selector
=
'@'
+
name
self
.
_status
=
ttype
self
.
_invalid_at
=
False
ret
+=
len
(
name
)
if
self
.
_invalid_at
:
self
.
_selector
=
'@'
invalid_at_name
=
''
for
j
in
xrange
(
idx
+
1
,
len
(
self
.
_css
)):
if
not
self
.
_css
[
j
]
.
isalpha
():
break
;
invalid_at_name
+=
self
.
_css
[
j
]
self
.
log
(
'Invalid @-rule: '
+
invalid_at_name
+
' (removed)'
,
'Warning'
)
elif
self
.
_css
[
idx
]
==
'"'
or
self
.
_css
[
idx
]
==
"'"
:
self
.
_cur_string
=
self
.
_css
[
idx
]
self
.
_status
=
'instr'
self
.
_str_char
=
self
.
_css
[
idx
]
self
.
_from
=
'is'
elif
self
.
_invalid_at
and
self
.
_css
[
idx
]
==
';'
:
self
.
_invalid_at
=
False
self
.
_status
=
'is'
elif
self
.
_css
[
idx
]
==
'{'
:
self
.
_status
=
'ip'
self
.
__add_token
(
data
.
SEL_START
,
self
.
_selector
)
self
.
_added
=
False
;
elif
self
.
_css
[
idx
]
==
'}'
:
self
.
__add_token
(
data
.
AT_END
,
self
.
_at
)
self
.
_at
=
''
self
.
_selector
=
''
self
.
_sel_separate
=
[]
elif
self
.
_css
[
idx
]
==
','
:
self
.
_selector
=
self
.
_selector
.
strip
()
+
','
self
.
_sel_separate
.
append
(
len
(
self
.
_selector
))
elif
self
.
_css
[
idx
]
==
'
\\
'
:
self
.
_selector
+=
self
.
__unicode
(
idx
)
#remove unnecessary universal selector, FS#147
elif
not
(
self
.
_css
[
idx
]
==
'*'
and
self
.
_css
[
idx
+
1
]
in
(
'.'
,
'#'
,
'['
,
':'
)):
self
.
_selector
+=
self
.
_css
[
idx
]
else
:
lastpos
=
len
(
self
.
_selector
)
-
1
if
lastpos
==
-
1
or
not
((
self
.
_selector
[
lastpos
]
.
isspace
()
or
self
.
__is_token
(
self
.
_selector
,
lastpos
)
and
self
.
_selector
[
lastpos
]
==
','
)
and
self
.
_css
[
idx
]
.
isspace
()):
self
.
_selector
+=
self
.
_css
[
idx
]
return
ret
def
__parseStatus_ip
(
self
,
idx
):
"""
Parse in property
"""
if
self
.
__is_token
(
self
.
_css
,
idx
):
if
(
self
.
_css
[
idx
]
==
':'
or
self
.
_css
[
idx
]
==
'='
)
and
self
.
_property
!=
''
:
self
.
_status
=
'iv'
if
not
self
.
getSetting
(
'discard_invalid_properties'
)
or
self
.
__property_is_valid
(
self
.
_property
):
self
.
__add_token
(
data
.
PROPERTY
,
self
.
_property
)
elif
self
.
_css
[
idx
]
==
'/'
and
self
.
_css
[
idx
+
1
]
==
'*'
and
self
.
_property
==
''
:
self
.
_status
=
'ic'
self
.
_from
=
'ip'
return
1
elif
self
.
_css
[
idx
]
==
'}'
:
self
.
__explode_selectors
()
self
.
_status
=
'is'
self
.
_invalid_at
=
False
self
.
__add_token
(
data
.
SEL_END
,
self
.
_selector
)
self
.
_selector
=
''
self
.
_property
=
''
elif
self
.
_css
[
idx
]
==
';'
:
self
.
_property
=
''
elif
self
.
_css
[
idx
]
==
'
\\
'
:
self
.
_property
+=
self
.
__unicode
(
idx
)
elif
not
self
.
_css
[
idx
]
.
isspace
():
self
.
_property
+=
self
.
_css
[
idx
]
return
0
def
__parseStatus_iv
(
self
,
idx
):
"""
Parse in value
"""
pn
=
((
self
.
_css
[
idx
]
==
"
\n
"
or
self
.
_css
[
idx
]
==
"
\r
"
)
and
self
.
__property_is_next
(
idx
+
1
)
or
idx
==
len
(
self
.
_css
))
#CHECK#
if
self
.
__is_token
(
self
.
_css
,
idx
)
or
pn
:
if
self
.
_css
[
idx
]
==
'/'
and
self
.
_css
[
idx
+
1
]
==
'*'
:
self
.
_status
=
'ic'
self
.
_from
=
'iv'
return
1
elif
self
.
_css
[
idx
]
==
'"'
or
self
.
_css
[
idx
]
==
"'"
or
self
.
_css
[
idx
]
==
'('
:
self
.
_cur_string
=
self
.
_css
[
idx
]
self
.
_str_char
=
')'
if
self
.
_css
[
idx
]
==
'('
else
self
.
_css
[
idx
]
self
.
_status
=
'instr'
self
.
_from
=
'iv'
elif
self
.
_css
[
idx
]
==
','
:
self
.
_sub_value
=
self
.
_sub_value
.
strip
()
+
','
elif
self
.
_css
[
idx
]
==
'
\\
'
:
self
.
_sub_value
+=
self
.
__unicode
(
idx
)
elif
self
.
_css
[
idx
]
==
';'
or
pn
:
if
len
(
self
.
_selector
)
>
0
and
self
.
_selector
[
0
]
==
'@'
and
data
.
at_rules
.
has_key
(
self
.
_selector
[
1
:])
and
data
.
at_rules
[
self
.
_selector
[
1
:]]
==
'iv'
:
self
.
_sub_value_arr
.
append
(
self
.
_sub_value
.
strip
())
self
.
_status
=
'is'
if
'@charset'
in
self
.
_selector
:
self
.
_charset
=
self
.
_sub_value_arr
[
0
]
elif
'@namespace'
in
self
.
_selector
:
self
.
_namespace
=
' '
.
join
(
self
.
_sub_value_arr
)
elif
'@import'
in
self
.
_selector
:
self
.
_import
.
append
(
' '
.
join
(
self
.
_sub_value_arr
))
self
.
_sub_value_arr
=
[]
self
.
_sub_value
=
''
self
.
_selector
=
''
self
.
_sel_separate
=
[]
else
:
self
.
_status
=
'ip'
elif
self
.
_css
[
idx
]
!=
'}'
:
self
.
_sub_value
+=
self
.
_css
[
idx
]
if
(
self
.
_css
[
idx
]
==
'}'
or
self
.
_css
[
idx
]
==
';'
or
pn
)
and
self
.
_selector
!=
''
:
if
self
.
_at
==
''
:
self
.
_at
=
data
.
DEFAULT_AT
#case settings
if
self
.
getSetting
(
'lowercase_s'
):
self
.
_selector
=
self
.
_selector
.
lower
()
self
.
_property
=
self
.
_property
.
lower
()
if
self
.
_sub_value
!=
''
:
self
.
_sub_value_arr
.
append
(
self
.
_sub_value
)
self
.
_sub_value
=
''
self
.
_value
=
' '
.
join
(
self
.
_sub_value_arr
)
self
.
_selector
=
self
.
_selector
.
strip
()
valid
=
self
.
__property_is_valid
(
self
.
_property
)
if
(
not
self
.
_invalid_at
or
self
.
getSetting
(
'preserve_css'
))
and
(
not
self
.
getSetting
(
'discard_invalid_properties'
)
or
valid
):
self
.
__css_add_property
(
self
.
_at
,
self
.
_selector
,
self
.
_property
,
self
.
_value
)
self
.
__add_token
(
data
.
VALUE
,
self
.
_value
)
if
not
valid
:
if
self
.
getSetting
(
'discard_invalid_properties'
):
self
.
log
(
'Removed invalid property: '
+
self
.
_property
,
'Warning'
)
else
:
self
.
log
(
'Invalid property in '
+
self
.
getSetting
(
'css_level'
)
.
upper
()
+
': '
+
self
.
_property
,
'Warning'
)
self
.
_property
=
''
;
self
.
_sub_value_arr
=
[]
self
.
_value
=
''
if
self
.
_css
[
idx
]
==
'}'
:
self
.
__explode_selectors
()
self
.
__add_token
(
data
.
SEL_END
,
self
.
_selector
)
self
.
_status
=
'is'
self
.
_invalid_at
=
False
self
.
_selector
=
''
elif
not
pn
:
self
.
_sub_value
+=
self
.
_css
[
idx
]
if
self
.
_css
[
idx
]
.
isspace
():
if
self
.
_sub_value
!=
''
:
self
.
_sub_value_arr
.
append
(
self
.
_sub_value
)
self
.
_sub_value
=
''
return
0
def
__parseStatus_instr
(
self
,
idx
):
"""
Parse in String
"""
if
self
.
_str_char
==
')'
and
(
self
.
_css
[
idx
]
==
'"'
or
self
.
_css
[
idx
]
==
"'"
)
and
not
self
.
escaped
(
self
.
_css
,
idx
):
self
.
_str_in_str
=
not
self
.
_str_in_str
temp_add
=
self
.
_css
[
idx
]
# ...and no not-escaped backslash at the previous position
if
(
self
.
_css
[
idx
]
==
"
\n
"
or
self
.
_css
[
idx
]
==
"
\r
"
)
and
not
(
self
.
_css
[
idx
-
1
]
==
'
\\
'
and
not
self
.
escaped
(
self
.
_css
,
idx
-
1
)):
temp_add
=
"
\\
A "
self
.
log
(
'Fixed incorrect newline in string'
,
'Warning'
)
if
not
(
self
.
_str_char
==
')'
and
self
.
_css
[
idx
]
.
isspace
()
and
not
self
.
_str_in_str
):
self
.
_cur_string
+=
temp_add
if
self
.
_css
[
idx
]
==
self
.
_str_char
and
not
self
.
escaped
(
self
.
_css
,
idx
)
and
not
self
.
_str_in_str
:
self
.
_status
=
self
.
_from
regex
=
re
.
compile
(
r'([\s]+)'
,
re
.
I
|
re
.
U
|
re
.
S
)
if
regex
.
match
(
self
.
_cur_string
)
is
None
and
self
.
_property
!=
'content'
:
if
self
.
_str_char
==
'"'
or
self
.
_str_char
==
"'"
:
self
.
_cur_string
=
self
.
_cur_string
[
1
:
-
1
]
elif
len
(
self
.
_cur_string
)
>
3
and
(
self
.
_cur_string
[
1
]
==
'"'
or
self
.
_cur_string
[
1
]
==
"'"
):
self
.
_cur_string
=
self
.
_cur_string
[
0
]
+
self
.
_cur_string
[
2
:
-
2
]
+
self
.
_cur_string
[
-
1
]
if
self
.
_from
==
'iv'
:
self
.
_sub_value
+=
self
.
_cur_string
elif
self
.
_from
==
'is'
:
self
.
_selector
+=
self
.
_cur_string
return
0
def
__parseStatus_ic
(
self
,
idx
):
"""
Parse css In Comment
"""
if
self
.
_css
[
idx
]
==
'*'
and
self
.
_css
[
idx
+
1
]
==
'/'
:
self
.
_status
=
self
.
_from
self
.
__add_token
(
data
.
COMMENT
,
self
.
_curComment
)
self
.
_curComment
=
''
return
1
else
:
self
.
_curComment
+=
self
.
_css
[
idx
]
return
0
def
__parseStatus_at
(
self
,
idx
):
"""
Parse in at-block
"""
if
self
.
__is_token
(
string
,
idx
):
if
self
.
_css
[
idx
]
==
'/'
and
self
.
_css
[
idx
+
1
]
==
'*'
:
self
.
_status
=
'ic'
self
.
_from
=
'at'
return
1
elif
self
.
_css
[
i
]
==
'{'
:
self
.
_status
=
'is'
self
.
__add_token
(
data
.
AT_START
,
self
.
_at
)
elif
self
.
_css
[
i
]
==
','
:
self
.
_at
=
self
.
_at
.
strip
()
+
','
elif
self
.
_css
[
i
]
==
'
\\
'
:
self
.
_at
+=
self
.
__unicode
(
i
)
else
:
lastpos
=
len
(
self
.
_at
)
-
1
if
not
(
self
.
_at
[
lastpos
]
.
isspace
()
or
self
.
__is_token
(
self
.
_at
,
lastpos
)
and
self
.
_at
[
lastpos
]
==
','
)
and
self
.
_css
[
i
]
.
isspace
():
self
.
_at
+=
self
.
_css
[
i
]
return
0
def
__explode_selectors
(
self
):
#Explode multiple selectors
if
self
.
getSetting
(
'merge_selectors'
)
==
1
:
new_sels
=
[]
lastpos
=
0
;
self
.
_sel_separate
.
append
(
len
(
self
.
_selector
))
for
num
in
xrange
(
len
(
self
.
_sel_separate
)):
pos
=
self
.
_sel_separate
[
num
]
if
num
==
(
len
(
self
.
_sel_separate
)):
#CHECK#
pos
+=
1
new_sels
.
append
(
self
.
_selector
[
lastpos
:(
pos
-
lastpos
-
1
)])
lastpos
=
pos
if
len
(
new_sels
)
>
1
:
for
selector
in
new_sels
:
self
.
merge_css_blocks
(
self
.
_at
,
selector
,
self
.
_raw_css
[
self
.
_at
][
self
.
_selector
])
del
self
.
_raw_css
[
self
.
_at
][
self
.
_selector
]
self
.
_sel_separate
=
[]
#Adds a property with value to the existing CSS code
def
__css_add_property
(
self
,
media
,
selector
,
prop
,
new_val
):
if
self
.
getSetting
(
'preserve_css'
)
or
new_val
.
strip
()
==
''
:
return
if
not
self
.
_raw_css
.
has_key
(
media
):
self
.
_raw_css
[
media
]
=
SortedDict
()
if
not
self
.
_raw_css
[
media
]
.
has_key
(
selector
):
self
.
_raw_css
[
media
][
selector
]
=
SortedDict
()
self
.
_added
=
True
if
self
.
_raw_css
[
media
][
selector
]
.
has_key
(
prop
):
if
(
self
.
is_important
(
self
.
_raw_css
[
media
][
selector
][
prop
])
and
self
.
is_important
(
new_val
))
or
not
self
.
is_important
(
self
.
_raw_css
[
media
][
selector
][
prop
]):
del
self
.
_raw_css
[
media
][
selector
][
prop
]
self
.
_raw_css
[
media
][
selector
][
prop
]
=
new_val
.
strip
()
else
:
self
.
_raw_css
[
media
][
selector
][
prop
]
=
new_val
.
strip
()
#Checks if the next word in a string from pos is a CSS property
def
__property_is_next
(
self
,
pos
):
istring
=
self
.
_css
[
pos
:
len
(
self
.
_css
)]
pos
=
istring
.
find
(
':'
)
if
pos
==
-
1
:
return
False
;
istring
=
istring
[:
pos
]
.
strip
()
.
lower
()
if
data
.
all_properties
.
has_key
(
istring
):
self
.
log
(
'Added semicolon to the end of declaration'
,
'Warning'
)
return
True
return
False
;
#Checks if a property is valid
def
__property_is_valid
(
self
,
prop
):
return
(
data
.
all_properties
.
has_key
(
prop
)
and
data
.
all_properties
[
prop
]
.
find
(
self
.
getSetting
(
'css_level'
)
.
upper
())
!=
-
1
)
#Adds a token to self._tokens
def
__add_token
(
self
,
ttype
,
cssdata
,
do
=
False
):
if
self
.
getSetting
(
'preserve_css'
)
or
do
:
if
ttype
==
data
.
COMMENT
:
token
=
[
ttype
,
cssdata
]
else
:
token
=
[
ttype
,
cssdata
.
strip
()]
self
.
_tokens
.
append
(
token
)
#Parse unicode notations and find a replacement character
def
__unicode
(
self
,
idx
):
##FIX##
return
''
#Starts parsing from URL
##USED?
def
__parse_from_url
(
self
,
url
):
try
:
if
"http"
in
url
.
lower
()
or
"https"
in
url
.
lower
():
f
=
urllib
.
urlopen
(
url
)
else
:
f
=
open
(
url
)
data
=
f
.
read
()
return
self
.
parse
(
data
)
finally
:
f
.
close
()
#Checks if there is a token at the current position
def
__is_token
(
self
,
string
,
idx
):
return
(
string
[
idx
]
in
data
.
tokens
and
not
self
.
escaped
(
string
,
idx
))
#Property Methods
def
_getOutput
(
self
):
self
.
_output
.
prepare
(
self
.
_optimized_css
)
return
self
.
_output
.
render
def
_getLog
(
self
):
ret
=
""
ks
=
self
.
_log
.
keys
()
ks
.
sort
()
for
line
in
ks
:
for
msg
in
self
.
_log
[
line
]:
ret
+=
"Type: "
+
msg
[
't'
]
+
"
\n
"
ret
+=
"Message: "
+
msg
[
'm'
]
+
"
\n
"
ret
+=
"
\n
"
return
ret
def
_getCSS
(
self
):
return
self
.
_css
#Properties
Output
=
property
(
_getOutput
,
None
)
Log
=
property
(
_getLog
,
None
)
CSS
=
property
(
_getCSS
,
None
)
if
__name__
==
'__main__'
:
import
sys
tidy
=
CSSTidy
()
f
=
open
(
sys
.
argv
[
1
],
"r"
)
css
=
f
.
read
()
f
.
close
()
tidy
.
parse
(
css
)
tidy
.
Output
(
'file'
,
filename
=
"Stylesheet.min.css"
)
print
tidy
.
Output
()
#print tidy._import
\ No newline at end of file
compress/filters/csstidy_python/data.py
deleted
100644 → 0
View file @
c00984f9
# Various CSS Data for CSSTidy
#
# This file is part of CSSTidy.
#
# CSSTidy is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# CSSTidy is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with CSSTidy; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# @license http://opensource.org/licenses/gpl-license.php GNU Public License
# @package csstidy
# @author Florian Schmitz (floele at gmail dot com) 2005
AT_START
=
1
AT_END
=
2
SEL_START
=
3
SEL_END
=
4
PROPERTY
=
5
VALUE
=
6
COMMENT
=
7
DEFAULT_AT
=
41
# All whitespace allowed in CSS
#
# @global array whitespace
# @version 1.0
whitespace
=
frozenset
([
' '
,
"
\n
"
,
"
\t
"
,
"
\r
"
,
"
\x0B
"
])
# All CSS tokens used by csstidy
#
# @global string tokens
# @version 1.0
tokens
=
'/@}{;:=
\'
"(,
\\
!$
%
&)#+.<>?[]^`|~'
# All CSS units (CSS 3 units included)
#
# @see compress_numbers()
# @global array units
# @version 1.0
units
=
frozenset
([
'in'
,
'cm'
,
'mm'
,
'pt'
,
'pc'
,
'px'
,
'rem'
,
'em'
,
'
%
'
,
'ex'
,
'gd'
,
'vw'
,
'vh'
,
'vm'
,
'deg'
,
'grad'
,
'rad'
,
'ms'
,
's'
,
'khz'
,
'hz'
])
# Available at-rules
#
# @global array at_rules
# @version 1.0
at_rules
=
{
'page'
:
'is'
,
'font-face'
:
'is'
,
'charset'
:
'iv'
,
'import'
:
'iv'
,
'namespace'
:
'iv'
,
'media'
:
'at'
}
# Properties that need a value with unit
#
# @todo CSS3 properties
# @see compress_numbers()
# @global array unit_values
# @version 1.2
unit_values
=
frozenset
([
'background'
,
'background-position'
,
'border'
,
'border-top'
,
'border-right'
,
'border-bottom'
,
'border-left'
,
'border-width'
,
'border-top-width'
,
'border-right-width'
,
'border-left-width'
,
'border-bottom-width'
,
'bottom'
,
'border-spacing'
,
'font-size'
,
'height'
,
'left'
,
'margin'
,
'margin-top'
,
'margin-right'
,
'margin-bottom'
,
'margin-left'
,
'max-height'
,
'max-width'
,
'min-height'
,
'min-width'
,
'outline-width'
,
'padding'
,
'padding-top'
,
'padding-right'
,
'padding-bottom'
,
'padding-left'
,
'position'
,
'right'
,
'top'
,
'text-indent'
,
'letter-spacing'
,
'word-spacing'
,
'width'
])
# Properties that allow <color> as value
#
# @todo CSS3 properties
# @see compress_numbers()
# @global array color_values
# @version 1.0
color_values
=
frozenset
([
'background-color'
,
'border-color'
,
'border-top-color'
,
'border-right-color'
,
'border-bottom-color'
,
'border-left-color'
,
'color'
,
'outline-color'
])
# Default values for the background properties
#
# @todo Possibly property names will change during CSS3 development
# @global array background_prop_default
# @see dissolve_short_bg()
# @see merge_bg()
# @version 1.0
background_prop_default
=
{}
background_prop_default
[
'background-image'
]
=
'none'
background_prop_default
[
'background-size'
]
=
'auto'
background_prop_default
[
'background-repeat'
]
=
'repeat'
background_prop_default
[
'background-position'
]
=
'0 0'
background_prop_default
[
'background-attachment'
]
=
'scroll'
background_prop_default
[
'background-clip'
]
=
'border'
background_prop_default
[
'background-origin'
]
=
'padding'
background_prop_default
[
'background-color'
]
=
'transparent'
# A list of non-W3C color names which get replaced by their hex-codes
#
# @global array replace_colors
# @see cut_color()
# @version 1.0
replace_colors
=
{}
replace_colors
[
'aliceblue'
]
=
'#F0F8FF'
replace_colors
[
'antiquewhite'
]
=
'#FAEBD7'
replace_colors
[
'aquamarine'
]
=
'#7FFFD4'
replace_colors
[
'azure'
]
=
'#F0FFFF'
replace_colors
[
'beige'
]
=
'#F5F5DC'
replace_colors
[
'bisque'
]
=
'#FFE4C4'
replace_colors
[
'blanchedalmond'
]
=
'#FFEBCD'
replace_colors
[
'blueviolet'
]
=
'#8A2BE2'
replace_colors
[
'brown'
]
=
'#A52A2A'
replace_colors
[
'burlywood'
]
=
'#DEB887'
replace_colors
[
'cadetblue'
]
=
'#5F9EA0'
replace_colors
[
'chartreuse'
]
=
'#7FFF00'
replace_colors
[
'chocolate'
]
=
'#D2691E'
replace_colors
[
'coral'
]
=
'#FF7F50'
replace_colors
[
'cornflowerblue'
]
=
'#6495ED'
replace_colors
[
'cornsilk'
]
=
'#FFF8DC'
replace_colors
[
'crimson'
]
=
'#DC143C'
replace_colors
[
'cyan'
]
=
'#00FFFF'
replace_colors
[
'darkblue'
]
=
'#00008B'
replace_colors
[
'darkcyan'
]
=
'#008B8B'
replace_colors
[
'darkgoldenrod'
]
=
'#B8860B'
replace_colors
[
'darkgray'
]
=
'#A9A9A9'
replace_colors
[
'darkgreen'
]
=
'#006400'
replace_colors
[
'darkkhaki'
]
=
'#BDB76B'
replace_colors
[
'darkmagenta'
]
=
'#8B008B'
replace_colors
[
'darkolivegreen'
]
=
'#556B2F'
replace_colors
[
'darkorange'
]
=
'#FF8C00'
replace_colors
[
'darkorchid'
]
=
'#9932CC'
replace_colors
[
'darkred'
]
=
'#8B0000'
replace_colors
[
'darksalmon'
]
=
'#E9967A'
replace_colors
[
'darkseagreen'
]
=
'#8FBC8F'
replace_colors
[
'darkslateblue'
]
=
'#483D8B'
replace_colors
[
'darkslategray'
]
=
'#2F4F4F'
replace_colors
[
'darkturquoise'
]
=
'#00CED1'
replace_colors
[
'darkviolet'
]
=
'#9400D3'
replace_colors
[
'deeppink'
]
=
'#FF1493'
replace_colors
[
'deepskyblue'
]
=
'#00BFFF'
replace_colors
[
'dimgray'
]
=
'#696969'
replace_colors
[
'dodgerblue'
]
=
'#1E90FF'
replace_colors
[
'feldspar'
]
=
'#D19275'
replace_colors
[
'firebrick'
]
=
'#B22222'
replace_colors
[
'floralwhite'
]
=
'#FFFAF0'
replace_colors
[
'forestgreen'
]
=
'#228B22'
replace_colors
[
'gainsboro'
]
=
'#DCDCDC'
replace_colors
[
'ghostwhite'
]
=
'#F8F8FF'
replace_colors
[
'gold'
]
=
'#FFD700'
replace_colors
[
'goldenrod'
]
=
'#DAA520'
replace_colors
[
'greenyellow'
]
=
'#ADFF2F'
replace_colors
[
'honeydew'
]
=
'#F0FFF0'
replace_colors
[
'hotpink'
]
=
'#FF69B4'
replace_colors
[
'indianred'
]
=
'#CD5C5C'
replace_colors
[
'indigo'
]
=
'#4B0082'
replace_colors
[
'ivory'
]
=
'#FFFFF0'
replace_colors
[
'khaki'
]
=
'#F0E68C'
replace_colors
[
'lavender'
]
=
'#E6E6FA'
replace_colors
[
'lavenderblush'
]
=
'#FFF0F5'
replace_colors
[
'lawngreen'
]
=
'#7CFC00'
replace_colors
[
'lemonchiffon'
]
=
'#FFFACD'
replace_colors
[
'lightblue'
]
=
'#ADD8E6'
replace_colors
[
'lightcoral'
]
=
'#F08080'
replace_colors
[
'lightcyan'
]
=
'#E0FFFF'
replace_colors
[
'lightgoldenrodyellow'
]
=
'#FAFAD2'
replace_colors
[
'lightgrey'
]
=
'#D3D3D3'
replace_colors
[
'lightgreen'
]
=
'#90EE90'
replace_colors
[
'lightpink'
]
=
'#FFB6C1'
replace_colors
[
'lightsalmon'
]
=
'#FFA07A'
replace_colors
[
'lightseagreen'
]
=
'#20B2AA'
replace_colors
[
'lightskyblue'
]
=
'#87CEFA'
replace_colors
[
'lightslateblue'
]
=
'#8470FF'
replace_colors
[
'lightslategray'
]
=
'#778899'
replace_colors
[
'lightsteelblue'
]
=
'#B0C4DE'
replace_colors
[
'lightyellow'
]
=
'#FFFFE0'
replace_colors
[
'limegreen'
]
=
'#32CD32'
replace_colors
[
'linen'
]
=
'#FAF0E6'
replace_colors
[
'magenta'
]
=
'#FF00FF'
replace_colors
[
'mediumaquamarine'
]
=
'#66CDAA'
replace_colors
[
'mediumblue'
]
=
'#0000CD'
replace_colors
[
'mediumorchid'
]
=
'#BA55D3'
replace_colors
[
'mediumpurple'
]
=
'#9370D8'
replace_colors
[
'mediumseagreen'
]
=
'#3CB371'
replace_colors
[
'mediumslateblue'
]
=
'#7B68EE'
replace_colors
[
'mediumspringgreen'
]
=
'#00FA9A'
replace_colors
[
'mediumturquoise'
]
=
'#48D1CC'
replace_colors
[
'mediumvioletred'
]
=
'#C71585'
replace_colors
[
'midnightblue'
]
=
'#191970'
replace_colors
[
'mintcream'
]
=
'#F5FFFA'
replace_colors
[
'mistyrose'
]
=
'#FFE4E1'
replace_colors
[
'moccasin'
]
=
'#FFE4B5'
replace_colors
[
'navajowhite'
]
=
'#FFDEAD'
replace_colors
[
'oldlace'
]
=
'#FDF5E6'
replace_colors
[
'olivedrab'
]
=
'#6B8E23'
replace_colors
[
'orangered'
]
=
'#FF4500'
replace_colors
[
'orchid'
]
=
'#DA70D6'
replace_colors
[
'palegoldenrod'
]
=
'#EEE8AA'
replace_colors
[
'palegreen'
]
=
'#98FB98'
replace_colors
[
'paleturquoise'
]
=
'#AFEEEE'
replace_colors
[
'palevioletred'
]
=
'#D87093'
replace_colors
[
'papayawhip'
]
=
'#FFEFD5'
replace_colors
[
'peachpuff'
]
=
'#FFDAB9'
replace_colors
[
'peru'
]
=
'#CD853F'
replace_colors
[
'pink'
]
=
'#FFC0CB'
replace_colors
[
'plum'
]
=
'#DDA0DD'
replace_colors
[
'powderblue'
]
=
'#B0E0E6'
replace_colors
[
'rosybrown'
]
=
'#BC8F8F'
replace_colors
[
'royalblue'
]
=
'#4169E1'
replace_colors
[
'saddlebrown'
]
=
'#8B4513'
replace_colors
[
'salmon'
]
=
'#FA8072'
replace_colors
[
'sandybrown'
]
=
'#F4A460'
replace_colors
[
'seagreen'
]
=
'#2E8B57'
replace_colors
[
'seashell'
]
=
'#FFF5EE'
replace_colors
[
'sienna'
]
=
'#A0522D'
replace_colors
[
'skyblue'
]
=
'#87CEEB'
replace_colors
[
'slateblue'
]
=
'#6A5ACD'
replace_colors
[
'slategray'
]
=
'#708090'
replace_colors
[
'snow'
]
=
'#FFFAFA'
replace_colors
[
'springgreen'
]
=
'#00FF7F'
replace_colors
[
'steelblue'
]
=
'#4682B4'
replace_colors
[
'tan'
]
=
'#D2B48C'
replace_colors
[
'thistle'
]
=
'#D8BFD8'
replace_colors
[
'tomato'
]
=
'#FF6347'
replace_colors
[
'turquoise'
]
=
'#40E0D0'
replace_colors
[
'violet'
]
=
'#EE82EE'
replace_colors
[
'violetred'
]
=
'#D02090'
replace_colors
[
'wheat'
]
=
'#F5DEB3'
replace_colors
[
'whitesmoke'
]
=
'#F5F5F5'
replace_colors
[
'yellowgreen'
]
=
'#9ACD32'
#A list of optimized colors
optimize_colors
=
{}
optimize_colors
[
'black'
]
=
'#000'
optimize_colors
[
'fuchsia'
]
=
'#F0F'
optimize_colors
[
'white'
]
=
'#FFF'
optimize_colors
[
'yellow'
]
=
'#FF0'
optimize_colors
[
'cyan'
]
=
'#0FF'
optimize_colors
[
'magenta'
]
=
'#F0F'
optimize_colors
[
'lightslategray'
]
=
'#789'
optimize_colors
[
'#800000'
]
=
'maroon'
optimize_colors
[
'#FFA500'
]
=
'orange'
optimize_colors
[
'#808000'
]
=
'olive'
optimize_colors
[
'#800080'
]
=
'purple'
optimize_colors
[
'#008000'
]
=
'green'
optimize_colors
[
'#000080'
]
=
'navy'
optimize_colors
[
'#008080'
]
=
'teal'
optimize_colors
[
'#C0C0C0'
]
=
'silver'
optimize_colors
[
'#808080'
]
=
'gray'
optimize_colors
[
'#4B0082'
]
=
'indigo'
optimize_colors
[
'#FFD700'
]
=
'gold'
optimize_colors
[
'#A52A2A'
]
=
'brown'
optimize_colors
[
'#00FFFF'
]
=
'cyan'
optimize_colors
[
'#EE82EE'
]
=
'violet'
optimize_colors
[
'#DA70D6'
]
=
'orchid'
optimize_colors
[
'#FFE4C4'
]
=
'bisque'
optimize_colors
[
'#F0E68C'
]
=
'khaki'
optimize_colors
[
'#F5DEB3'
]
=
'wheat'
optimize_colors
[
'#FF7F50'
]
=
'coral'
optimize_colors
[
'#F5F5DC'
]
=
'beige'
optimize_colors
[
'#F0FFFF'
]
=
'azure'
optimize_colors
[
'#A0522D'
]
=
'sienna'
optimize_colors
[
'#CD853F'
]
=
'peru'
optimize_colors
[
'#FFFFF0'
]
=
'ivory'
optimize_colors
[
'#DDA0DD'
]
=
'plum'
optimize_colors
[
'#D2B48C'
]
=
'tan'
optimize_colors
[
'#FFC0CB'
]
=
'pink'
optimize_colors
[
'#FFFAFA'
]
=
'snow'
optimize_colors
[
'#FA8072'
]
=
'salmon'
optimize_colors
[
'#FF6347'
]
=
'tomato'
optimize_colors
[
'#FAF0E6'
]
=
'linen'
optimize_colors
[
'#F00'
]
=
'red'
# A list of all shorthand properties that are devided into four properties and/or have four subvalues
#
# @global array shorthands
# @todo Are there new ones in CSS3?
# @see dissolve_4value_shorthands()
# @see merge_4value_shorthands()
# @version 1.0
shorthands
=
{}
shorthands
[
'border-color'
]
=
[
'border-top-color'
,
'border-right-color'
,
'border-bottom-color'
,
'border-left-color'
]
shorthands
[
'border-style'
]
=
[
'border-top-style'
,
'border-right-style'
,
'border-bottom-style'
,
'border-left-style'
]
shorthands
[
'border-width'
]
=
[
'border-top-width'
,
'border-right-width'
,
'border-bottom-width'
,
'border-left-width'
]
shorthands
[
'margin'
]
=
[
'margin-top'
,
'margin-right'
,
'margin-bottom'
,
'margin-left'
]
shorthands
[
'padding'
]
=
[
'padding-top'
,
'padding-right'
,
'padding-bottom'
,
'padding-left'
]
shorthands
[
'-moz-border-radius'
]
=
0
# All CSS Properties. Needed for csstidy::property_is_next()
#
# @global array all_properties
# @todo Add CSS3 properties
# @version 1.0
# @see csstidy::property_is_next()
all_properties
=
{}
all_properties
[
'background'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'background-color'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'background-image'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'background-repeat'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'background-attachment'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'background-position'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'border'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'border-top'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'border-right'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'border-bottom'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'border-left'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'border-color'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'border-top-color'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'border-bottom-color'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'border-left-color'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'border-right-color'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'border-style'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'border-top-style'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'border-right-style'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'border-left-style'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'border-bottom-style'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'border-width'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'border-top-width'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'border-right-width'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'border-left-width'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'border-bottom-width'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'border-collapse'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'border-spacing'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'bottom'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'caption-side'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'content'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'clear'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'clip'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'color'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'counter-reset'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'counter-increment'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'cursor'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'empty-cells'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'display'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'direction'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'float'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'font'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'font-family'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'font-style'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'font-variant'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'font-weight'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'font-stretch'
]
=
'CSS2.0'
all_properties
[
'font-size-adjust'
]
=
'CSS2.0'
all_properties
[
'font-size'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'height'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'left'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'line-height'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'list-style'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'list-style-type'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'list-style-image'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'list-style-position'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'margin'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'margin-top'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'margin-right'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'margin-bottom'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'margin-left'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'marks'
]
=
'CSS1.0,CSS2.0'
all_properties
[
'marker-offset'
]
=
'CSS2.0'
all_properties
[
'max-height'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'max-width'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'min-height'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'min-width'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'overflow'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'orphans'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'outline'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'outline-width'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'outline-style'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'outline-color'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'padding'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'padding-top'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'padding-right'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'padding-bottom'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'padding-left'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'page-break-before'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'page-break-after'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'page-break-inside'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'page'
]
=
'CSS2.0'
all_properties
[
'position'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'quotes'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'right'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'size'
]
=
'CSS1.0,CSS2.0'
all_properties
[
'speak-header'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'table-layout'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'top'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'text-indent'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'text-align'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'text-decoration'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'text-shadow'
]
=
'CSS2.0'
all_properties
[
'letter-spacing'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'word-spacing'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'text-transform'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'white-space'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'unicode-bidi'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'vertical-align'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'visibility'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'width'
]
=
'CSS1.0,CSS2.0,CSS2.1'
all_properties
[
'widows'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'z-index'
]
=
'CSS1.0,CSS2.0,CSS2.1'
# Speech #
all_properties
[
'volume'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'speak'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'pause'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'pause-before'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'pause-after'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'cue'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'cue-before'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'cue-after'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'play-during'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'azimuth'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'elevation'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'speech-rate'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'voice-family'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'pitch'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'pitch-range'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'stress'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'richness'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'speak-punctuation'
]
=
'CSS2.0,CSS2.1'
all_properties
[
'speak-numeral'
]
=
'CSS2.0,CSS2.1'
\ No newline at end of file
compress/filters/csstidy_python/optimizer.py
deleted
100644 → 0
View file @
c00984f9
# CSSTidy - CSS Optimizer
#
# CSS Optimizer class
#
# This file is part of CSSTidy.
#
# CSSTidy is free software you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation either version 2 of the License, or
# (at your option) any later version.
#
# CSSTidy is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with CSSTidy if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# @license http://opensource.org/licenses/gpl-license.php GNU Public License
# @package csstidy
# @author Dj Gilcrease (digitalxero at gmail dot com) 2005-2006
import
data
from
tools
import
SortedDict
class
CSSOptimizer
(
object
):
def
__init__
(
self
,
parser
):
#raw_css is a dict
self
.
parser
=
parser
self
.
_optimized_css
=
SortedDict
#PUBLIC METHODS
def
optimize
(
self
,
raw_css
):
if
self
.
parser
.
getSetting
(
'preserve_css'
):
return
raw_css
self
.
_optimized_css
=
raw_css
if
self
.
parser
.
getSetting
(
'merge_selectors'
)
==
2
:
self
.
__merge_selectors
()
##OPTIMIZE##
for
media
,
css
in
self
.
_optimized_css
.
iteritems
():
for
selector
,
cssdata
in
css
.
iteritems
():
if
self
.
parser
.
getSetting
(
'optimise_shorthands'
)
>=
1
:
cssdata
=
self
.
__merge_4value_shorthands
(
cssdata
)
if
self
.
parser
.
getSetting
(
'optimise_shorthands'
)
>=
2
:
cssdata
=
self
.
__merge_bg
(
cssdata
)
for
item
,
value
in
cssdata
.
iteritems
():
value
=
self
.
__compress_numbers
(
item
,
value
)
value
=
self
.
__compress_important
(
value
)
if
item
in
data
.
color_values
and
self
.
parser
.
getSetting
(
'compress_colors'
):
old
=
value
[:]
value
=
self
.
__compress_color
(
value
)
if
old
!=
value
:
self
.
parser
.
log
(
'In "'
+
selector
+
'" Optimised '
+
item
+
': Changed '
+
old
+
' to '
+
value
,
'Information'
)
if
item
==
'font-weight'
and
self
.
parser
.
getSetting
(
'compress_font-weight'
):
if
value
==
'bold'
:
value
=
'700'
self
.
parser
.
log
(
'In "'
+
selector
+
'" Optimised font-weight: Changed "bold" to "700"'
,
'Information'
)
elif
value
==
'normal'
:
value
=
'400'
self
.
parser
.
log
(
'In "'
+
selector
+
'" Optimised font-weight: Changed "normal" to "400"'
,
'Information'
)
self
.
_optimized_css
[
media
][
selector
][
item
]
=
value
return
self
.
_optimized_css
#PRIVATE METHODS
def
__merge_bg
(
self
,
cssdata
):
"""
Merges all background properties
@cssdata (dict) is a dictionary of the selector properties
"""
#Max number of background images. CSS3 not yet fully implemented
img
=
1
clr
=
1
bg_img_list
=
[]
if
cssdata
.
has_key
(
'background-image'
):
img
=
len
(
cssdata
[
'background-image'
]
.
split
(
','
))
bg_img_list
=
self
.
parser
.
gvw_important
(
cssdata
[
'background-image'
])
.
split
(
','
)
elif
cssdata
.
has_key
(
'background-color'
):
clr
=
len
(
cssdata
[
'background-color'
]
.
split
(
','
))
number_of_values
=
max
(
img
,
clr
,
1
)
new_bg_value
=
''
important
=
''
for
i
in
xrange
(
number_of_values
):
for
bg_property
,
default_value
in
data
.
background_prop_default
.
iteritems
():
#Skip if property does not exist
if
not
cssdata
.
has_key
(
bg_property
):
continue
cur_value
=
cssdata
[
bg_property
]
#Skip some properties if there is no background image
if
(
len
(
bg_img_list
)
>
i
and
bg_img_list
[
i
]
==
'none'
)
and
bg_property
in
frozenset
([
'background-size'
,
'background-position'
,
'background-attachment'
,
'background-repeat'
]):
continue
#Remove !important
if
self
.
parser
.
is_important
(
cur_value
):
important
=
' !important'
cur_value
=
self
.
parser
.
gvw_important
(
cur_value
)
#Do not add default values
if
cur_value
==
default_value
:
continue
temp
=
cur_value
.
split
(
','
)
if
len
(
temp
)
>
i
:
if
bg_property
==
'background-size'
:
new_bg_value
+=
'('
+
temp
[
i
]
+
') '
else
:
new_bg_value
+=
temp
[
i
]
+
' '
new_bg_value
=
new_bg_value
.
strip
()
if
i
!=
(
number_of_values
-
1
):
new_bg_value
+=
','
#Delete all background-properties
for
bg_property
,
default_value
in
data
.
background_prop_default
.
iteritems
():
try
:
del
cssdata
[
bg_property
]
except
:
pass
#Add new background property
if
new_bg_value
!=
''
:
cssdata
[
'background'
]
=
new_bg_value
+
important
return
cssdata
def
__merge_4value_shorthands
(
self
,
cssdata
):
"""
Merges Shorthand properties again, the opposite of dissolve_4value_shorthands()
@cssdata (dict) is a dictionary of the selector properties
"""
for
key
,
value
in
data
.
shorthands
.
iteritems
():
important
=
''
if
value
!=
0
and
cssdata
.
has_key
(
value
[
0
])
and
cssdata
.
has_key
(
value
[
1
])
and
cssdata
.
has_key
(
value
[
2
])
and
cssdata
.
has_key
(
value
[
3
]):
cssdata
[
key
]
=
''
for
i
in
xrange
(
4
):
val
=
cssdata
[
value
[
i
]]
if
self
.
parser
.
is_important
(
val
):
important
=
'!important'
cssdata
[
key
]
+=
self
.
parser
.
gvw_important
(
val
)
+
' '
else
:
cssdata
[
key
]
+=
val
+
' '
del
cssdata
[
value
[
i
]]
if
cssdata
.
has_key
(
key
):
cssdata
[
key
]
=
self
.
__shorthand
(
cssdata
[
key
]
+
important
.
strip
())
return
cssdata
def
__merge_selectors
(
self
):
"""
Merges selectors with same properties. Example: a{color:red} b{color:red} . a,b{color:red}
Very basic and has at least one bug. Hopefully there is a replacement soon.
@selector_one (string) is the current selector
@value_one (dict) is a dictionary of the selector properties
Note: Currently is the elements of a selector are identical, but in a different order, they are not merged
"""
##OPTIMIZE##
##FIX##
raw_css
=
self
.
_optimized_css
.
copy
()
delete
=
[]
add
=
SortedDict
()
for
media
,
css
in
raw_css
.
iteritems
():
for
selector_one
,
value_one
in
css
.
iteritems
():
newsel
=
selector_one
for
selector_two
,
value_two
in
css
.
iteritems
():
if
selector_one
==
selector_two
:
#We need to skip self
continue
if
value_one
==
value_two
:
#Ok, we need to merge these two selectors
newsel
+=
', '
+
selector_two
delete
.
append
((
media
,
selector_two
))
if
not
add
.
has_key
(
media
):
add
[
media
]
=
SortedDict
()
add
[
media
][
newsel
]
=
value_one
delete
.
append
((
media
,
selector_one
))
for
item
in
delete
:
try
:
del
self
.
_optimized_css
[
item
[
0
]][
item
[
1
]]
except
:
#Must have already been deleted
continue
for
media
,
css
in
add
.
iteritems
():
self
.
_optimized_css
[
media
]
.
update
(
css
)
def
__shorthand
(
self
,
value
):
"""
Compresses shorthand values. Example: margin:1px 1px 1px 1px . margin:1px
@value (string)
"""
##FIX##
important
=
''
;
if
self
.
parser
.
is_important
(
value
):
value_list
=
self
.
parser
.
gvw_important
(
value
)
important
=
'!important'
else
:
value_list
=
value
ret
=
value
value_list
=
value_list
.
split
(
' '
)
if
len
(
value_list
)
==
4
:
if
value_list
[
0
]
==
value_list
[
1
]
and
value_list
[
0
]
==
value_list
[
2
]
and
value_list
[
0
]
==
value_list
[
3
]:
ret
=
value_list
[
0
]
+
important
elif
value_list
[
1
]
==
value_list
[
3
]
and
value_list
[
0
]
==
value_list
[
2
]:
ret
=
value_list
[
0
]
+
' '
+
value_list
[
1
]
+
important
elif
value_list
[
1
]
==
value_list
[
3
]:
ret
=
value_list
[
0
]
+
' '
+
value_list
[
1
]
+
' '
+
value_list
[
2
]
+
important
elif
len
(
value_list
)
==
3
:
if
value_list
[
0
]
==
value_list
[
1
]
and
value_list
[
0
]
==
value_list
[
2
]:
ret
=
value_list
[
0
]
+
important
elif
value_list
[
0
]
==
value_list
[
2
]:
return
value_list
[
0
]
+
' '
+
value_list
[
1
]
+
important
elif
len
(
value_list
)
==
2
:
if
value_list
[
0
]
==
value_list
[
1
]:
ret
=
value_list
[
0
]
+
important
if
ret
!=
value
:
self
.
parser
.
log
(
'Optimised shorthand notation: Changed "'
+
value
+
'" to "'
+
ret
+
'"'
,
'Information'
)
return
ret
def
__compress_important
(
self
,
value
):
"""
Removes unnecessary whitespace in ! important
@value (string)
"""
if
self
.
parser
.
is_important
(
value
):
value
=
self
.
parser
.
gvw_important
(
value
)
+
'!important'
return
value
def
__compress_numbers
(
self
,
prop
,
value
):
"""
Compresses numbers (ie. 1.0 becomes 1 or 1.100 becomes 1.1 )
@value (string) is the posible number to be compressed
"""
##FIX##
value
=
value
.
split
(
'/'
)
for
l
in
xrange
(
len
(
value
)):
#continue if no numeric value
if
not
(
len
(
value
[
l
])
>
0
and
(
value
[
l
][
0
]
.
isdigit
()
or
value
[
l
][
0
]
in
(
'+'
,
'-'
)
)):
continue
#Fix bad colors
if
prop
in
data
.
color_values
:
value
[
l
]
=
'#'
+
value
[
l
]
is_floatable
=
False
try
:
float
(
value
[
l
])
is_floatable
=
True
except
:
pass
if
is_floatable
and
float
(
value
[
l
])
==
0
:
value
[
l
]
=
'0'
elif
value
[
l
][
0
]
!=
'#'
:
unit_found
=
False
for
unit
in
data
.
units
:
pos
=
value
[
l
]
.
lower
()
.
find
(
unit
)
if
pos
!=
-
1
and
prop
not
in
data
.
shorthands
:
value
[
l
]
=
self
.
__remove_leading_zeros
(
float
(
value
[
l
][:
pos
]))
+
unit
unit_found
=
True
break
;
if
not
unit_found
and
prop
in
data
.
unit_values
and
prop
not
in
data
.
shorthands
:
value
[
l
]
=
self
.
__remove_leading_zeros
(
float
(
value
[
l
]))
+
'px'
elif
not
unit_found
and
prop
not
in
data
.
shorthands
:
value
[
l
]
=
self
.
__remove_leading_zeros
(
float
(
value
[
l
]))
if
len
(
value
)
>
1
:
return
'/'
.
join
(
value
)
return
value
[
0
]
def
__remove_leading_zeros
(
self
,
float_val
):
"""
Removes the leading zeros from a float value
@float_val (float)
@returns (string)
"""
#Remove leading zero
if
abs
(
float_val
)
<
1
:
if
float_val
<
0
:
float_val
=
'-'
.
str
(
float_val
)[
2
:]
else
:
float_val
=
str
(
float_val
)[
1
:]
return
str
(
float_val
)
def
__compress_color
(
self
,
color
):
"""
Color compression function. Converts all rgb() values to #-values and uses the short-form if possible. Also replaces 4 color names by #-values.
@color (string) the {posible} color to change
"""
#rgb(0,0,0) . #000000 (or #000 in this case later)
if
color
[:
4
]
.
lower
()
==
'rgb('
:
color_tmp
=
color
[
4
:(
len
(
color
)
-
5
)]
color_tmp
=
color_tmp
.
split
(
','
)
for
c
in
color_tmp
:
c
=
c
.
strip
()
if
c
[:
-
1
]
==
'
%
'
:
c
=
round
((
255
*
color_tmp
[
i
])
/
100
)
if
color_tmp
[
i
]
>
255
:
color_tmp
[
i
]
=
255
color
=
'#'
for
i
in
xrange
(
3
):
if
color_tmp
[
i
]
<
16
:
color
+=
'0'
+
str
(
hex
(
color_tmp
[
i
]))
.
replace
(
'0x'
,
''
)
else
:
color
+=
str
(
hex
(
color_tmp
[
i
]))
.
replace
(
'0x'
,
''
)
#Fix bad color names
if
data
.
replace_colors
.
has_key
(
color
.
lower
()):
color
=
data
.
replace_colors
[
color
.
lower
()]
#aabbcc . #abc
if
len
(
color
)
==
7
:
color_temp
=
color
.
lower
()
if
color_temp
[
0
]
==
'#'
and
color_temp
[
1
]
==
color_temp
[
2
]
and
color_temp
[
3
]
==
color_temp
[
4
]
and
color_temp
[
5
]
==
color_temp
[
6
]:
color
=
'#'
+
color
[
1
]
+
color
[
3
]
+
color
[
5
]
if
data
.
optimize_colors
.
has_key
(
color
.
lower
()):
color
=
data
.
optimize_colors
[
color
.
lower
()]
return
color
\ No newline at end of file
compress/filters/csstidy_python/output.py
deleted
100644 → 0
View file @
c00984f9
# CSSTidy - CSS Printer
#
# CSS Printer class
#
# This file is part of CSSTidy.
#
# CSSTidy is free software you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation either version 2 of the License, or
# (at your option) any later version.
#
# CSSTidy is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with CSSTidy if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# @license http://opensource.org/licenses/gpl-license.php GNU Public License
# @package csstidy
# @author Dj Gilcrease (digitalxero at gmail dot com) 2005-2006
import
data
class
CSSPrinter
(
object
):
def
__init__
(
self
,
parser
):
self
.
parser
=
parser
self
.
_css
=
{}
self
.
__renderMethods
=
{
'string'
:
self
.
__renderString
,
'file'
:
self
.
__renderFile
}
#PUBLIC METHODS
def
prepare
(
self
,
css
):
self
.
_css
=
css
def
render
(
self
,
output
=
"string"
,
*
args
,
**
kwargs
):
return
self
.
__renderMethods
[
output
](
*
args
,
**
kwargs
)
#PRIVATE METHODS
def
__renderString
(
self
,
*
args
,
**
kwargs
):
##OPTIMIZE##
template
=
self
.
parser
.
getSetting
(
'template'
)
ret
=
""
if
template
==
'highest_compression'
:
top_line_end
=
""
iner_line_end
=
""
bottom_line_end
=
""
indent
=
""
elif
template
==
'high_compression'
:
top_line_end
=
"
\n
"
iner_line_end
=
""
bottom_line_end
=
"
\n
"
indent
=
""
elif
template
==
'default'
:
top_line_end
=
"
\n
"
iner_line_end
=
"
\n
"
bottom_line_end
=
"
\n\n
"
indent
=
""
elif
template
==
'low_compression'
:
top_line_end
=
"
\n
"
iner_line_end
=
"
\n
"
bottom_line_end
=
"
\n\n
"
indent
=
" "
if
self
.
parser
.
getSetting
(
'timestamp'
):
ret
+=
'/# CSSTidy '
+
self
.
parser
.
version
+
': '
+
datetime
.
now
()
.
strftime
(
"
%
a,
%
d
%
b
%
Y
%
H:
%
M:
%
S +0000"
)
+
' #/'
+
top_line_end
for
item
in
self
.
parser
.
_import
:
ret
+=
'@import('
+
item
+
');'
+
top_line_end
for
item
in
self
.
parser
.
_charset
:
ret
+=
'@charset('
+
item
+
');'
+
top_line_end
for
item
in
self
.
parser
.
_namespace
:
ret
+=
'@namespace('
+
item
+
');'
+
top_line_end
for
media
,
css
in
self
.
_css
.
iteritems
():
for
selector
,
cssdata
in
css
.
iteritems
():
ret
+=
selector
+
'{'
+
top_line_end
for
item
,
value
in
cssdata
.
iteritems
():
ret
+=
indent
+
item
+
':'
+
value
+
';'
+
iner_line_end
ret
+=
'}'
+
bottom_line_end
return
ret
def
__renderFile
(
self
,
filename
=
None
,
*
args
,
**
kwargs
):
if
filename
is
None
:
return
self
.
__renderString
()
try
:
f
=
open
(
filename
,
"w"
)
f
.
write
(
self
.
__renderString
())
finally
:
f
.
close
()
\ No newline at end of file
compress/filters/csstidy_python/tools.py
deleted
100644 → 0
View file @
c00984f9
class
SortedDict
(
dict
):
"""
A dictionary that keeps its keys in the order in which they're inserted.
"""
def
__init__
(
self
,
data
=
None
):
if
data
is
None
:
data
=
{}
super
(
SortedDict
,
self
)
.
__init__
(
data
)
if
isinstance
(
data
,
dict
):
self
.
keyOrder
=
data
.
keys
()
else
:
self
.
keyOrder
=
[]
for
key
,
value
in
data
:
if
key
not
in
self
.
keyOrder
:
self
.
keyOrder
.
append
(
key
)
def
__deepcopy__
(
self
,
memo
):
from
copy
import
deepcopy
return
self
.
__class__
([(
key
,
deepcopy
(
value
,
memo
))
for
key
,
value
in
self
.
iteritems
()])
def
__setitem__
(
self
,
key
,
value
):
super
(
SortedDict
,
self
)
.
__setitem__
(
key
,
value
)
if
key
not
in
self
.
keyOrder
:
self
.
keyOrder
.
append
(
key
)
def
__delitem__
(
self
,
key
):
super
(
SortedDict
,
self
)
.
__delitem__
(
key
)
self
.
keyOrder
.
remove
(
key
)
def
__iter__
(
self
):
for
k
in
self
.
keyOrder
:
yield
k
def
pop
(
self
,
k
,
*
args
):
result
=
super
(
SortedDict
,
self
)
.
pop
(
k
,
*
args
)
try
:
self
.
keyOrder
.
remove
(
k
)
except
ValueError
:
# Key wasn't in the dictionary in the first place. No problem.
pass
return
result
def
popitem
(
self
):
result
=
super
(
SortedDict
,
self
)
.
popitem
()
self
.
keyOrder
.
remove
(
result
[
0
])
return
result
def
items
(
self
):
return
zip
(
self
.
keyOrder
,
self
.
values
())
def
iteritems
(
self
):
for
key
in
self
.
keyOrder
:
yield
key
,
super
(
SortedDict
,
self
)
.
__getitem__
(
key
)
def
keys
(
self
):
return
self
.
keyOrder
[:]
def
iterkeys
(
self
):
return
iter
(
self
.
keyOrder
)
def
values
(
self
):
return
[
super
(
SortedDict
,
self
)
.
__getitem__
(
k
)
for
k
in
self
.
keyOrder
]
def
itervalues
(
self
):
for
key
in
self
.
keyOrder
:
yield
super
(
SortedDict
,
self
)
.
__getitem__
(
key
)
def
update
(
self
,
dict_
):
for
k
,
v
in
dict_
.
items
():
self
.
__setitem__
(
k
,
v
)
def
setdefault
(
self
,
key
,
default
):
if
key
not
in
self
.
keyOrder
:
self
.
keyOrder
.
append
(
key
)
return
super
(
SortedDict
,
self
)
.
setdefault
(
key
,
default
)
def
value_for_index
(
self
,
index
):
"""Returns the value of the item at the given zero-based index."""
return
self
[
self
.
keyOrder
[
index
]]
def
insert
(
self
,
index
,
key
,
value
):
"""Inserts the key, value pair before the item with the given index."""
if
key
in
self
.
keyOrder
:
n
=
self
.
keyOrder
.
index
(
key
)
del
self
.
keyOrder
[
n
]
if
n
<
index
:
index
-=
1
self
.
keyOrder
.
insert
(
index
,
key
)
super
(
SortedDict
,
self
)
.
__setitem__
(
key
,
value
)
def
copy
(
self
):
"""Returns a copy of this object."""
# This way of initializing the copy means it works for subclasses, too.
obj
=
self
.
__class__
(
self
)
obj
.
keyOrder
=
self
.
keyOrder
[:]
return
obj
def
__repr__
(
self
):
"""
Replaces the normal dict.__repr__ with a version that returns the keys
in their sorted order.
"""
return
'{
%
s}'
%
', '
.
join
([
'
%
r:
%
r'
%
(
k
,
v
)
for
k
,
v
in
self
.
items
()])
def
clear
(
self
):
super
(
SortedDict
,
self
)
.
clear
()
self
.
keyOrder
=
[]
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment