summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfunvit <funvit@gmail.com>2013-10-01 01:50:19 +0400
committerfunvit <funvit@gmail.com>2013-10-01 01:50:19 +0400
commitc4bba84f2c77cd10b3d73802d26e6e1e5e684670 (patch)
tree9d157bb1d3a2360b9999fa3fc9d264e26b49ae13
parented2a59eea1058a3c7f6757070013c29ed85f0970 (diff)
downloadpyscss-c4bba84f2c77cd10b3d73802d26e6e1e5e684670.tar.gz
fonts_root, fonts_url
tests for font_files (inline_font_files) fixed font_files (works like 3.2)
-rw-r--r--scss/config.py2
-rw-r--r--scss/functions/compass/helpers.py98
-rw-r--r--scss/tests/files/fonts/bgrove.base64.txt1
-rw-r--r--scss/tests/files/fonts/bgrove.ttfbin0 -> 18744 bytes
-rw-r--r--scss/tests/functions/compass/test_helpers.py46
-rw-r--r--scss/tool.py8
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
new file mode 100644
index 0000000..9f2d056
--- /dev/null
+++ b/scss/tests/files/fonts/bgrove.ttf
Binary files differ
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: