diff options
author | funvit <funvit@gmail.com> | 2013-10-01 01:50:19 +0400 |
---|---|---|
committer | funvit <funvit@gmail.com> | 2013-10-01 01:50:19 +0400 |
commit | c4bba84f2c77cd10b3d73802d26e6e1e5e684670 (patch) | |
tree | 9d157bb1d3a2360b9999fa3fc9d264e26b49ae13 /scss | |
parent | ed2a59eea1058a3c7f6757070013c29ed85f0970 (diff) | |
download | pyscss-c4bba84f2c77cd10b3d73802d26e6e1e5e684670.tar.gz |
fonts_root, fonts_url
tests for font_files (inline_font_files)
fixed font_files (works like 3.2)
Diffstat (limited to 'scss')
-rw-r--r-- | scss/config.py | 2 | ||||
-rw-r--r-- | scss/functions/compass/helpers.py | 98 | ||||
-rw-r--r-- | scss/tests/files/fonts/bgrove.base64.txt | 1 | ||||
-rw-r--r-- | scss/tests/files/fonts/bgrove.ttf | bin | 0 -> 18744 bytes | |||
-rw-r--r-- | scss/tests/functions/compass/test_helpers.py | 46 | ||||
-rw-r--r-- | scss/tool.py | 8 |
6 files changed, 109 insertions, 46 deletions
diff --git a/scss/config.py b/scss/config.py index 60d8bc5..734c8a9 100644 --- a/scss/config.py +++ b/scss/config.py @@ -14,6 +14,8 @@ CACHE_ROOT = None # Urls for the static and assets: STATIC_URL = 'static/' ASSETS_URL = 'static/assets/' +FONTS_ROOT = STATIC_ROOT +FONTS_URL = STATIC_URL VERBOSITY = True STYLE = 'nested' FATAL_UNDEFINED = True diff --git a/scss/functions/compass/helpers.py b/scss/functions/compass/helpers.py index db98cec..15d4e47 100644 --- a/scss/functions/compass/helpers.py +++ b/scss/functions/compass/helpers.py @@ -20,12 +20,22 @@ from scss import config from scss.functions.library import FunctionLibrary from scss.types import Boolean, List, Null, Number, String from scss.util import escape, to_str +import re log = logging.getLogger(__name__) COMPASS_HELPERS_LIBRARY = FunctionLibrary() register = COMPASS_HELPERS_LIBRARY.register +FONT_TYPES = { + 'woff': 'woff', + 'otf': 'opentype', + 'opentype': 'opentype', + 'ttf': 'truetype', + 'truetype': 'truetype', + 'svg': 'svg', + 'eot': 'embedded-opentype' +} def add_cache_buster(url, mtime): fragment = url.split('#') @@ -488,73 +498,73 @@ COMPASS_HELPERS_LIBRARY.add(Number.wrap_python_function(math.tan), 'tan', 1) def _font_url(path, only_path=False, cache_buster=True, inline=False): filepath = String.unquoted(path).value - path = None - if callable(config.STATIC_ROOT): + file = None + if callable(config.FONTS_ROOT): try: - _file, _storage = list(config.STATIC_ROOT(filepath))[0] + _file, _storage = list(config.FONTS_ROOT(filepath))[0] d_obj = _storage.modified_time(_file) filetime = int(time.mktime(d_obj.timetuple())) if inline: - path = _storage.open(_file) + file = _storage.open(_file) except: filetime = 'NA' else: - _path = os.path.join(config.STATIC_ROOT, filepath.strip('/')) + _path = os.path.join(config.FONTS_ROOT, filepath.strip('/')) if os.path.exists(_path): filetime = int(os.path.getmtime(_path)) if inline: - path = open(_path, 'rb') + file = open(_path, 'rb') else: filetime = 'NA' - BASE_URL = config.STATIC_URL - - if path and inline: - mime_type = mimetypes.guess_type(filepath)[0] - url = 'data:' + mime_type + ';base64,' + base64.b64encode(path.read()) + BASE_URL = config.FONTS_URL + + if file and inline: +# mime_type = mimetypes.guess_type(filepath)[0] + font_type = None + if re.match(r'^([^?]+)[.](.*)([?].*)?$', path.value): + font_type = String.unquoted(re.match(r'^([^?]+)[.](.*)([?].*)?$', path.value).groups()[1]).value + + if not FONT_TYPES.get(font_type): + raise Exception('Could not determine font type for "%s"' % path.value) + + url = 'data:font/' + FONT_TYPES.get(font_type) + ';base64,' + base64.b64encode(file.read()) + file.close() else: - url = '%s%s' % (BASE_URL, filepath) - if cache_buster: + url = '%s/%s' % (BASE_URL.rstrip('/'), filepath.lstrip('/')) + if cache_buster and filetime != 'NA': url = add_cache_buster(url, filetime) if not only_path: - url = 'url("%s")' % escape(url) + url = 'url(%s)' % escape(url) return String.unquoted(url) def _font_files(args, inline): - args = List.from_maybe_starargs(args) - n = 0 - params = [[], []] - for arg in args: - if isinstance(arg, List): - if len(arg) == 2: - if n % 2 == 1: - params[1].append(None) - n += 1 - params[0].append(arg[0]) - params[1].append(arg[1]) - n += 2 - else: - for arg2 in arg: - params[n % 2].append(arg2) - n += 1 - else: - params[n % 2].append(arg) - n += 1 - len0 = len(params[0]) - len1 = len(params[1]) - if len1 < len0: - params[1] += [None] * (len0 - len1) - elif len0 < len1: - params[0] += [None] * (len1 - len0) + if args == (): + return String.unquoted("") + fonts = [] - for font, format in zip(params[0], params[1]): - if format: - fonts.append('%s format("%s")' % (_font_url(font, inline=inline), String.unquoted(format).value)) + args_len = len(args) + skip_next = False + for index in xrange(len(args)): + arg = args[index] + if not skip_next: + font_type = args[index + 1] if args_len > (index +1) else None + if font_type and FONT_TYPES.has_key(font_type.value): + skip_next = True + else: + if re.match(r'^([^?]+)[.](.*)([?].*)?$', arg.value): + font_type = String.unquoted(re.match(r'^([^?]+)[.](.*)([?].*)?$', arg.value).groups()[1]) + + if FONT_TYPES.has_key(font_type.value): + fonts.append(String.unquoted('%s format("%s")' % (_font_url(arg, inline=inline), String.unquoted(FONT_TYPES[font_type.value]).value))) + else: + raise Exception('Could not determine font type for "%s"' % arg.value) else: - fonts.append(_font_url(font, inline=inline)) - return List(fonts) + skip_next = False + return List(fonts, separator=',') + @register('font-url', 1) @register('font-url', 2) diff --git a/scss/tests/files/fonts/bgrove.base64.txt b/scss/tests/files/fonts/bgrove.base64.txt new file mode 100644 index 0000000..56d0b5e --- /dev/null +++ b/scss/tests/files/fonts/bgrove.base64.txt @@ -0,0 +1 @@ +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
\ No newline at end of file diff --git a/scss/tests/files/fonts/bgrove.ttf b/scss/tests/files/fonts/bgrove.ttf Binary files differnew file mode 100644 index 0000000..9f2d056 --- /dev/null +++ b/scss/tests/files/fonts/bgrove.ttf diff --git a/scss/tests/functions/compass/test_helpers.py b/scss/tests/functions/compass/test_helpers.py index 0d52956..7453ac3 100644 --- a/scss/tests/functions/compass/test_helpers.py +++ b/scss/tests/functions/compass/test_helpers.py @@ -16,6 +16,9 @@ from scss.rule import Namespace import pytest +from scss import config +import os +from _pytest.monkeypatch import monkeypatch xfail = pytest.mark.xfail # TODO many of these tests could also stand to test for failure cases @@ -145,14 +148,53 @@ def test_pow(calc): ## Fonts - # font-url +def test_font_url(calc): + assert calc('font-url("/some_path.woff")').render() == ('url(%(static_url)ssome_path.woff)' % {'static_url': config.STATIC_URL}) + assert calc('font-url("/some_path.woff") format("woff")').render() == ('url(%(static_url)ssome_path.woff) format("woff")' % {'static_url': config.STATIC_URL}) + # font-files +def test_font_files(calc): + """ + @author: funvit + @note: adapted from compass / test / units / sass_extensions_test.rb + """ + assert '' == calc('font-files()').render() + assert ('url(%(static_url)sfont/name.woff) format("woff"), url(%(static_url)sfonts/name.ttf) format("truetype"), url(%(static_url)sfonts/name.svg#fontpath) format("svg")' % {'static_url': config.STATIC_URL}) == calc('font-files("/font/name.woff", woff, "/fonts/name.ttf", truetype, "/fonts/name.svg#fontpath", svg)').render() + + assert ('url(%(static_url)sfont/with/right_ext.woff) format("woff")' % {'static_url': config.STATIC_URL}) == calc('font_files("/font/with/right_ext.woff")').render() + assert ('url(%(static_url)sfont/with/wrong_ext.woff) format("svg")' % {'static_url': config.STATIC_URL}) == calc('font_files("/font/with/wrong_ext.woff", "svg")').render() + assert ('url(%(static_url)sfont/with/no_ext) format("opentype")' % {'static_url': config.STATIC_URL}) == calc('font_files("/font/with/no_ext", "otf")').render() + assert ('url(%(static_url)sfont/with/weird.ext) format("truetype")' % {'static_url': config.STATIC_URL}) == calc('font_files("/font/with/weird.ext", "truetype")').render() + + assert ('url(%(static_url)sfont/with/right_ext.woff) format("woff"), url(%(static_url)sfont/with/right_ext_also.otf) format("opentype")' % {'static_url': config.STATIC_URL}) == calc('font_files("/font/with/right_ext.woff", "/font/with/right_ext_also.otf")').render() + assert ('url(%(static_url)sfont/with/wrong_ext.woff) format("truetype"), url(%(static_url)sfont/with/right_ext.otf) format("opentype")' % {'static_url': config.STATIC_URL}) == calc('font_files("/font/with/wrong_ext.woff", "ttf", "/font/with/right_ext.otf")').render() + # inline-font-files - +def test_inline_font_files(calc): + """ + @author: funvit + @note: adapted from compass / test / units / sass_extensions_test.rb + """ +# def mockreturn(path): +# return os.path.join(config.PROJECT_ROOT, 'tests/files/fonts', path.strip('/')) + + monkeypatch().setattr(config, 'FONTS_ROOT', os.path.join(config.PROJECT_ROOT, 'tests/files/fonts')) + + f = open(os.path.join(config.PROJECT_ROOT, 'tests/files/fonts/bgrove.base64.txt'), 'r') + font_base64 = ''.join((f.readlines())) + f.close() + assert 'url(data:font/truetype;base64,%s) format("truetype")' % font_base64 == calc('inline_font_files("/bgrove.ttf", truetype)').render() ## External stylesheets # stylesheet-url + + +# for debugging uncomment next lines +#if __name__=='__main__': +# test_font_url(calc()) +# test_font_files(calc()) +# test_inline_font_files(calc())
\ No newline at end of file diff --git a/scss/tool.py b/scss/tool.py index 7e4aef0..84d211b 100644 --- a/scss/tool.py +++ b/scss/tool.py @@ -73,6 +73,10 @@ def main(): help="Assets root path (Sprite images will be created here)") paths_group.add_option("-a", "--assets-url", metavar="URL", dest="assets_url", help="URL to reach the files in your assets_root") + paths_group.add_option("-F", "--fonts-root", metavar="PATH", dest="fonts_root", + help="Fonts root path (Where fonts are located)") + paths_group.add_option("-f", "--fonts-url", metavar="PATH", dest="fonts_url", + help="URL to reach the fonts in your fonts_root") paths_group.add_option("--cache-root", metavar="PATH", dest="cache_root", help="Cache root path (Cache files will be created here)") parser.add_option_group(paths_group) @@ -91,6 +95,10 @@ def main(): config.STATIC_ROOT = options.static_root if options.assets_root is not None: config.ASSETS_ROOT = options.assets_root + if options.fonts_root is not None: + config.FONTS_ROOT = options.fonts_root + if options.fonts_url is not None: + config.FONTS_URL = options.fonts_url if options.cache_root is not None: config.CACHE_ROOT = options.cache_root if options.load_paths is not None: |