@@ -163,42 +163,64 @@ namespace Sass {
163163 std::replace (str.begin (), str.end (), ' \n ' , ' ' );
164164 }
165165
166- // bell characters are replaced with spaces
167- // also eats spaces after line-feeds (ltrim)
166+ // 1. Removes whitespace after newlines.
167+ // 2. Replaces newlines with spaces.
168+ //
169+ // This method only considers LF and CRLF as newlines.
168170 std::string string_to_output (const std::string& str)
169171 {
170- std::string out (" " );
171- bool lf = false ;
172- for (auto i : str) {
173- if (i == ' \n ' ) {
174- out += ' ' ;
175- lf = true ;
176- } else if (!(lf && isspace (i))) {
177- out += i;
178- lf = false ;
172+ std::string result;
173+ result.reserve (str.size ());
174+ std::size_t pos = 0 ;
175+ while (true ) {
176+ const std::size_t newline = str.find_first_of (" \n\r " , pos);
177+ if (newline == std::string::npos) break ;
178+ result.append (str, pos, newline - pos);
179+ if (str[newline] == ' \r ' ) {
180+ if (str[newline + 1 ] == ' \n ' ) {
181+ pos = newline + 2 ;
182+ } else {
183+ // CR without LF: append as-is and continue.
184+ result += ' \r ' ;
185+ pos = newline + 1 ;
186+ continue ;
187+ }
188+ } else {
189+ pos = newline + 1 ;
190+ }
191+ result += ' ' ;
192+ const std::size_t non_space = str.find_first_not_of (" \f\n\r\t\v " , pos);
193+ if (non_space != std::string::npos) {
194+ pos = non_space;
179195 }
180196 }
181- return out;
197+ result.append (str, pos, std::string::npos);
198+ return result;
182199 }
183200
184201 std::string escape_string (const std::string& str)
185202 {
186- std::string out (" " );
187- for (auto i : str) {
188- if (i == ' \n ' ) {
189- out += " \\ n" ;
190- } else if (i == ' \r ' ) {
191- out += " \\ r" ;
192- } else if (i == ' \t ' ) {
193- out += " \\ t" ;
194- } else {
195- out += i;
203+ std::string out;
204+ out.reserve (str.size ());
205+ for (char c : str) {
206+ switch (c) {
207+ case ' \n ' :
208+ out.append (" \\ n" );
209+ break ;
210+ case ' \r ' :
211+ out.append (" \\ r" );
212+ break ;
213+ case ' \f ' :
214+ out.append (" \\ f" );
215+ break ;
216+ default :
217+ out += c;
196218 }
197219 }
198220 return out;
199221 }
200222
201- std::string comment_to_string (const std::string& text)
223+ std::string comment_to_compact_string (const std::string& text)
202224 {
203225 std::string str = " " ;
204226 size_t has = 0 ;
@@ -207,7 +229,6 @@ namespace Sass {
207229 for (auto i : text) {
208230 if (clean) {
209231 if (i == ' \n ' ) { has = 0 ; }
210- else if (i == ' \r ' ) { has = 0 ; }
211232 else if (i == ' \t ' ) { ++ has; }
212233 else if (i == ' ' ) { ++ has; }
213234 else if (i == ' *' ) {}
@@ -219,8 +240,6 @@ namespace Sass {
219240 }
220241 } else if (i == ' \n ' ) {
221242 clean = true ;
222- } else if (i == ' \r ' ) {
223- clean = true ;
224243 } else {
225244 str += i;
226245 }
@@ -508,33 +527,6 @@ namespace Sass {
508527 }
509528
510529 namespace Util {
511- using std::string;
512-
513- std::string rtrim (const std::string &str) {
514- std::string trimmed = str;
515- size_t pos_ws = trimmed.find_last_not_of (" \t\n\v\f\r " );
516- if (pos_ws != std::string::npos)
517- { trimmed.erase (pos_ws + 1 ); }
518- else { trimmed.clear (); }
519- return trimmed;
520- }
521-
522- std::string normalize_underscores (const std::string& str) {
523- std::string normalized = str;
524- for (size_t i = 0 , L = normalized.length (); i < L; ++i) {
525- if (normalized[i] == ' _' ) {
526- normalized[i] = ' -' ;
527- }
528- }
529- return normalized;
530- }
531-
532- std::string normalize_decimals (const std::string& str) {
533- std::string prefix = " 0" ;
534- std::string normalized = str;
535-
536- return normalized[0 ] == ' .' ? normalized.insert (0 , prefix) : normalized;
537- }
538530
539531 bool isPrintable (Ruleset* r, Sass_Output_Style style) {
540532 if (r == NULL ) {
0 commit comments