1616
1717from six import string_types , text_type
1818
19- from _sass import (OUTPUT_STYLES , compile_dirname , compile_filename ,
20- compile_string )
19+ from _sass import (OUTPUT_STYLES , SOURCE_COMMENTS , compile_dirname ,
20+ compile_filename , compile_string )
2121
22- __all__ = 'MODES' , 'OUTPUT_STYLES' , 'CompileError' , 'and_join' , 'compile'
22+ __all__ = ('MODES' , 'OUTPUT_STYLES' , 'SOURCE_COMMENTS' , 'CompileError' ,
23+ 'and_join' , 'compile' )
2324__version__ = '0.4.0'
2425
2526
2627#: (:class:`collections.Mapping`) The dictionary of output styles.
2728#: Keys are output name strings, and values are flag integers.
2829OUTPUT_STYLES = OUTPUT_STYLES
2930
31+ #: (:class:`collections.Mapping`) The dictionary of source comments styles.
32+ #: Keys are mode names, and values are corresponding flag integers.
33+ #:
34+ #: .. versionadded:: 0.4.0
35+ SOURCE_COMMENTS = SOURCE_COMMENTS
36+
3037#: (:class:`collections.Set`) The set of keywords :func:`compile()` can take.
3138MODES = set (['string' , 'filename' , 'dirname' ])
3239
@@ -53,6 +60,11 @@ def compile(**kwargs):
5360 choose one of: ``'nested'`` (default), ``'expanded'``,
5461 ``'compact'``, ``'compressed'``
5562 :type output_style: :class:`str`
63+ :param source_comments: an optional source comments mode of the compiled
64+ result. choose one of ``'none'`` (default) or
65+ ``'line_numbers'``. ``'map'`` is unavailable for
66+ ``string``
67+ :type source_comments: :class:`str`
5668 :param include_paths: an optional list of paths to find ``@import``\ ed
5769 SASS/CSS source files
5870 :type include_paths: :class:`collections.Sequence`, :class:`str`
@@ -73,13 +85,28 @@ def compile(**kwargs):
7385 choose one of: ``'nested'`` (default), ``'expanded'``,
7486 ``'compact'``, ``'compressed'``
7587 :type output_style: :class:`str`
88+ :param source_comments: an optional source comments mode of the compiled
89+ result. choose one of ``'none'`` (default),
90+ ``'line_numbers'``, ``'map'``.
91+ if ``'map'`` is used it requires
92+ ``source_map_filename`` argument as well and
93+ returns a (compiled CSS string,
94+ source map string) pair instead of a string
95+ :type source_comments: :class:`str`
96+ :param source_map_filename: indicate the source map output filename.
97+ it's only available and required
98+ when ``source_comments`` is ``'map'``.
99+ note that it will ignore all other parts of
100+ the path except for its basename
101+ :type source_map_filename: :class:`str`
76102 :param include_paths: an optional list of paths to find ``@import``\ ed
77103 SASS/CSS source files
78104 :type include_paths: :class:`collections.Sequence`, :class:`str`
79105 :param image_path: an optional path to find images
80106 :type image_path: :class:`str`
81- :returns: the compiled CSS string
82- :rtype: :class:`str`
107+ :returns: the compiled CSS string, or a pair of the compiled CSS string
108+ and the source map string if ``source_comments='map'``
109+ :rtype: :class:`str`, :class:`tuple`
83110 :raises sass.CompileError: when it fails for any reason
84111 (for example the given SASS has broken syntax)
85112 :raises exceptions.IOError: when the ``filename`` doesn't exist or
@@ -101,6 +128,11 @@ def compile(**kwargs):
101128 choose one of: ``'nested'`` (default), ``'expanded'``,
102129 ``'compact'``, ``'compressed'``
103130 :type output_style: :class:`str`
131+ :param source_comments: an optional source comments mode of the compiled
132+ result. choose one of ``'none'`` (default) or
133+ ``'line_numbers'``. ``'map'`` is unavailable for
134+ ``dirname``
135+ :type source_comments: :class:`str`
104136 :param include_paths: an optional list of paths to find ``@import``\ ed
105137 SASS/CSS source files
106138 :type include_paths: :class:`collections.Sequence`, :class:`str`
@@ -109,6 +141,9 @@ def compile(**kwargs):
109141 :raises sass.CompileError: when it fails for any reason
110142 (for example the given SASS has broken syntax)
111143
144+ .. versionadded:: 0.4.0
145+ Added ``source_comments`` and ``source_map_filename`` parameters.
146+
112147 """
113148 modes = set ()
114149 for mode_name in MODES :
@@ -119,10 +154,7 @@ def compile(**kwargs):
119154 elif len (modes ) > 1 :
120155 raise TypeError (and_join (modes ) + ' are exclusive each other; '
121156 'cannot be used at a time' )
122- try :
123- output_style = kwargs .pop ('output_style' )
124- except KeyError :
125- output_style = 'nested'
157+ output_style = kwargs .pop ('output_style' , 'nested' )
126158 if not isinstance (output_style , string_types ):
127159 raise TypeError ('output_style must be a string, not ' +
128160 repr (output_style ))
@@ -131,7 +163,38 @@ def compile(**kwargs):
131163 except KeyError :
132164 raise CompileError ('{0} is unsupported output_style; choose one of {1}'
133165 '' .format (output_style , and_join (OUTPUT_STYLES )))
166+ source_comments = kwargs .pop ('source_comments' , 'none' )
167+ if not isinstance (source_comments , string_types ):
168+ raise TypeError ('source_comments must be a string, not ' +
169+ repr (source_comments ))
170+ if 'filename' not in modes and source_comments == 'map' :
171+ raise CompileError ('source_comments="map" is only available with '
172+ 'filename= keyword argument since it has to be '
173+ 'aware of it' )
174+ try :
175+ source_comments = SOURCE_COMMENTS [source_comments ]
176+ except KeyError :
177+ raise CompileError (
178+ '{0} is unsupported source_comments; choose one of '
179+ '{1}' .format (source_comments , and_join (SOURCE_COMMENTS ))
180+ )
134181 fs_encoding = sys .getfilesystemencoding () or sys .getdefaultencoding ()
182+ try :
183+ source_map_filename = kwargs .pop ('source_map_filename' ) or b''
184+ except KeyError :
185+ if source_comments == SOURCE_COMMENTS ['map' ]:
186+ raise TypeError ('source_comments="map" requires '
187+ 'source_map_filename argument' )
188+ source_map_filename = b''
189+ else :
190+ if source_comments != SOURCE_COMMENTS ['map' ]:
191+ raise TypeError ('source_map_filename is available only with '
192+ 'source_comments="map"' )
193+ elif not isinstance (source_map_filename , string_types ):
194+ raise TypeError ('source_map_filename must be a string, not ' +
195+ repr (source_map_filename ))
196+ if isinstance (source_map_filename , text_type ):
197+ source_map_filename = source_map_filename .encode (fs_encoding )
135198 try :
136199 include_paths = kwargs .pop ('include_paths' ) or b''
137200 except KeyError :
@@ -159,7 +222,11 @@ def compile(**kwargs):
159222 string = kwargs .pop ('string' )
160223 if isinstance (string , text_type ):
161224 string = string .encode ('utf-8' )
162- s , v = compile_string (string , output_style , include_paths , image_path )
225+ s , v = compile_string (string ,
226+ output_style , source_comments ,
227+ include_paths , image_path )
228+ if s :
229+ return v .decode ('utf-8' )
163230 elif 'filename' in modes :
164231 filename = kwargs .pop ('filename' )
165232 if not isinstance (filename , string_types ):
@@ -168,8 +235,16 @@ def compile(**kwargs):
168235 raise IOError ('{0!r} seems not a file' .format (filename ))
169236 elif isinstance (filename , text_type ):
170237 filename = filename .encode (fs_encoding )
171- s , v = compile_filename (filename ,
172- output_style , include_paths , image_path )
238+ s , v , source_map = compile_filename (
239+ filename ,
240+ output_style , source_comments ,
241+ include_paths , image_path , source_map_filename
242+ )
243+ if s :
244+ v = v .decode ('utf-8' )
245+ if source_map_filename :
246+ v = v , source_map .decode ('utf-8' )
247+ return v
173248 elif 'dirname' in modes :
174249 try :
175250 search_path , output_path = kwargs .pop ('dirname' )
@@ -182,11 +257,13 @@ def compile(**kwargs):
182257 if isinstance (output_path , text_type ):
183258 output_path = output_path .encode (fs_encoding )
184259 s , v = compile_dirname (search_path , output_path ,
185- output_style , include_paths , image_path )
260+ output_style , source_comments ,
261+ include_paths , image_path )
262+ if s :
263+ return
186264 else :
187265 raise TypeError ('something went wrong' )
188- if s :
189- return None if v is None else v .decode ('utf-8' )
266+ assert not s
190267 raise CompileError (v )
191268
192269
0 commit comments