CSS-Sass
view release on metacpan or search on metacpan
libsass/util.cpp view on Meta::CPAN
} else if (
i == ' ' ||
i == '\r' ||
i == '\n' ||
i == ' '
) {
// only add one space
if (!ws) text += ' ';
ws = true;
} else {
ws = false;
text += i;
}
}
if (esc) text += '\\';
return text;
}
// find best quote_mark by detecting if the string contains any single
// or double quotes. When a single quote is found, we not we want a double
// quote as quote_mark. Otherwise we check if the string cotains any double
// quotes, which will trigger the use of single quotes as best quote_mark.
char detect_best_quotemark(const char* s, char qm)
{
// ensure valid fallback quote_mark
char quote_mark = qm && qm != '*' ? qm : '"';
while (*s) {
// force double quotes as soon
// as one single quote is found
if (*s == '\'') { return '"'; }
// a single does not force quote_mark
// maybe we see a double quote later
else if (*s == '"') { quote_mark = '\''; }
++ s;
}
return quote_mark;
}
string unquote(const string& s, char* qd)
{
// not enough room for quotes
// no possibility to unquote
if (s.length() < 2) return s;
char q;
bool skipped = false;
// this is no guarantee that the unquoting will work
// what about whitespace before/after the quote_mark?
if (*s.begin() == '"' && *s.rbegin() == '"') q = '"';
else if (*s.begin() == '\'' && *s.rbegin() == '\'') q = '\'';
else return s;
string unq;
unq.reserve(s.length()-2);
for (size_t i = 1, L = s.length() - 1; i < L; ++i) {
// implement the same strange ruby sass behavior
// an escape sequence can also mean a unicode char
if (s[i] == '\\' && !skipped) {
// remember
skipped = true;
// skip it
// ++ i;
// if (i == L) break;
// escape length
size_t len = 1;
// parse as many sequence chars as possible
// ToDo: Check if ruby aborts after possible max
while (i + len < L && s[i + len] && isxdigit(s[i + len])) ++ len;
// hex string?
if (len > 1) {
// convert the extracted hex string to code point value
// ToDo: Maybe we could do this without creating a substring
uint32_t cp = strtol(s.substr (i + 1, len - 1).c_str(), nullptr, 16);
// assert invalid code points
if (cp == 0) cp = 0xFFFD;
// replace bell character
// if (cp == 10) cp = 32;
// use a very simple approach to convert via utf8 lib
// maybe there is a more elegant way; maybe we shoud
// convert the whole output from string to a stream!?
// allocate memory for utf8 char and convert to utf8
unsigned char u[5] = {0,0,0,0,0}; utf8::append(cp, u);
for(size_t m = 0; u[m] && m < 5; m++) unq.push_back(u[m]);
// skip some more chars?
i += len - 1; skipped = false;
}
}
// check for unexpected delimiter
// be strict and throw error back
// else if (!skipped && q == s[i]) {
// // don't be that strict
// return s;
// // this basically always means an internal error and not users fault
// error("Unescaped delimiter in string to unquote found. [" + s + "]", ParserState("[UNQUOTE]"));
// }
else {
skipped = false;
unq.push_back(s[i]);
}
}
if (skipped) { return s; }
if (qd) *qd = q;
return unq;
( run in 0.475 second using v1.01-cache-2.11-cpan-39bf76dae61 )