Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug fixes #13

Merged
merged 3 commits into from
Mar 2, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 28 additions & 22 deletions Base64Fold.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,42 @@
class FoldBase64Command(sublime_plugin.TextCommand):
def run(self, edit, fold_all_uris):

# regular expression to search with
regexp = None
match_index = 0
region_filter = None

whitespace = r'(?:\\?\n|[\t ])+'
# Only fold Base64 code that has a valid length - ignoring whitespace
base64_filter = lambda region: len(re.sub(whitespace, '', self.view.substr(region))) % 4 == 0
if fold_all_uris:
# fold all URIs if the option is enabled
regexp = 'url\(([\'"])?[^,]+,(.+?)(?=\1?\))'
match_index = 2 # second group
region_filter = lambda region: region
else:
# fold just the base64 URIs otherwise
regexp = r'url\(([\'"])?[^;]+;([^,]+),([^\n\\]+?(?:\\\n[^\n\\]*?)*?)(?=\1?\))'
match_index = 3 # third group
base64_index = 2 # second group
self.fold_by_pattern(regexp, base64_index, match_index, base64_filter)

# fold the base64 URIs
base64 = r'[\w\d+/]{2,}'
# Base64 decodes each 4 encoded characters into 3 octects. The padding '='
# character might appear 1 or 2 times only at the end of the Base64 code,
# and only if there are fewer than 3 octects to be decoded. We don't need to
# match what (["');], etc) is after the code, as they are not being folded.
regexp = r'(base64),(' + base64 + r'(?:' + whitespace + base64 + r')*={0,2})'
match_index = 2 # second group
base64_index = 1 # first group

# Base64 decodes each 4 encoded characters into 3 octects. The padding '='
# character might appear 1 or 2 times only at the end of the Base64 code,
# and only if there are fewer than 3 octects to be decoded. We don't need to
# match what (["');], etc) is after the code, as they are not being folded.
regexp = '(?<=base64\,)[\w\d\+\/]{2,}={0,2}'
# Only fold Base64 code that has a valid length
region_filter = lambda region: region.size() % 4 == 0
self.fold_by_pattern(regexp, base64_index, match_index, base64_filter)

def fold_by_pattern(self, regexp, base64_index, match_index, base64_region_filter):
view_text = self.view.substr(sublime.Region(0, self.view.size()))

def get_region_from_group(match, group_index):
start = match.start(group_index)
end = start + len(match.group(group_index))
return sublime.Region(start, end)

pattern = re.compile(regexp)
for match in pattern.finditer(view_text):
start = match.start(match_index)
end = start + len(match.group(match_index))
region = sublime.Region(start, end)
if region_filter(region):
self.view.fold(region)
is_base64 = self.view.substr(get_region_from_group(match, base64_index)) == 'base64'
fold_region = get_region_from_group(match, match_index)
if not is_base64 or base64_region_filter(fold_region):
self.view.fold(fold_region)

class Base64Fold(sublime_plugin.EventListener):
def init_(self):
Expand Down
33 changes: 33 additions & 0 deletions test.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,42 @@ li {
list-style-image: url('data:image/svg+xml;utf8,<svg width="11px" height="11px" xmlns="http://www.w3.org/2000/svg"><path d="M6.56713392,6.3167819 ... Z" fill="red" stroke="black" stroke-width="1"></path></svg>');
}

/* multiline svg in utf8 */
li {
list-style-image: url('data:image/svg+xml;utf8,<svg width="11px" height="11px" xmlns="http://www.w3.org/2000/svg"><path d="M6.56713392,6.3167819 ... Z"\
fill="red" stroke="black" stroke-width="1"></path></svg>');
}

/* should not be folded, false positive if it is */
li {
list-style-image: rgba(0, 0, 0, .5);
}

/* multiline base64 with whitespace */
span {
padding-left: 20px;
background:white url('data:image/png;base64,iVBORw0KGgoAA\
AANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAA BlBMVEUAAAD///+l2Z/dAAAAM0l\
EQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6\
P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC') no-repeat scroll left top;
}
/* Backslashes at end of line - to continue character string
at new line. */

/* multiline base64 with whitespace, incorrect size */
span {
padding-left: 20px;
background:white url('data:image/png;base64,iVBORw0KGgoAA\
AANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAA BlBMVEUAAAD///+l2Z/dAAAAM0l\
EQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6\
P9/AFGGFyjOXZtQAAAAAElFTkSuQmCCk') no-repeat scroll left top;
}

/* multiline base64 with whitespace and no indentation */
span {
padding-left: 20px;
background:white url('data:image/png;base64,iVBORw0KGgoAA\
AANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAA BlBMVEUAAAD///+l2Z/dAAAAM0l\
EQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6\
P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC') no-repeat scroll left top;
}
24 changes: 24 additions & 0 deletions test.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<!-- base64 image data on a single line -->
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot" />

<!-- base64 image data on a single line, incorrect size -->
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJgggk==" alt="Not a red dot" />

<!-- base64 image data spanning multiple lines -->
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot" />

<!-- base64 image data spanning multiple lines, incorrect size -->
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
9TXL0Y4OHwAAAABJRU5ErkJgggk==" alt="Not a red dot" />

</body>
</html>