static lString16 decodeText(lString8 text) { if (text.empty()) return lString16::empty_str; lString8 buf; bool lastControl = false; for (int i=0; i<text.length(); i++) { char ch = buf[i]; if (lastControl) { switch (ch) { case 'r': buf.append(1, '\r'); break; case 'n': buf.append(1, '\n'); break; case 't': buf.append(1, '\t'); break; default: buf.append(1, ch); break; } lastControl = false; continue; } if (ch == '\\') { lastControl = true; continue; } buf.append(1, ch); } return Utf8ToUnicode(buf); }
bool pop() { if (level_==0) { return true; } prefix_ = prefix_.substr(0,prefix_.length()-1); level_--; update_candidates(); return false; }
/// extract @import filename from beginning of CSS bool LVProcessStyleSheetImport( const char * &str, lString8 & import_file ) { const char * p = str; import_file.clear(); skip_spaces( p ); if ( *p !='@' ) return false; p++; if (strncmp(p, "import", 6) != 0) return false; p+=6; skip_spaces( p ); bool in_url = false; char quote_ch = 0; if ( !strncmp(p, "url", 3) ) { p+=3; skip_spaces( p ); if ( *p != '(' ) return false; p++; skip_spaces( p ); in_url = true; } if ( *p == '\'' || *p=='\"' ) quote_ch = *p++; while (*p) { if ( quote_ch && *p==quote_ch ) { p++; break; } if ( !quote_ch ) { if ( in_url && *p==')' ) { break; } if ( *p==' ' || *p=='\t' || *p=='\r' || *p=='\n' ) break; } import_file << *p++; } skip_spaces( p ); if ( in_url ) { if ( *p!=')' ) return false; p++; } if ( import_file.empty() ) return false; str = p; return true; }
void onQuotedText(lString8 & token) { //CRLog::trace("state==%d: \"%s\"", _state, token.c_str()); if (_state == 11 || _state == 13) { if (!token.empty()) { _url = LVCombinePaths(_basePath, Utf8ToUnicode(token)); } _state = 2; } else if (_state == 5) { if (!token.empty()) { _face = token; } _state = 2; } token.clear(); }
void parse(lString16 basePath, const lString8 & css) { _state = 0; _basePath = basePath; lString8 token; char insideQuotes = 0; for (int i=0; i<css.length(); i++) { char ch = css[i]; if (insideQuotes || _state == 13) { if (ch == insideQuotes || (_state == 13 && ch == ')')) { onQuotedText(token); insideQuotes = 0; if (_state == 13) onToken(ch); } else { if (_state == 13 && token.empty() && (ch == '\'' || ch=='\"')) { insideQuotes = ch; } else if (ch != ' ' || _state != 13) token << ch; } continue; } if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') { onToken(token); } else if (ch == '@' || ch=='-' || ch=='_' || ch=='.' || ch>='a' && ch <='z' || ch>='A' && ch <='Z' || ch>='0' && ch <='9') { token << ch; } else if (ch == ':' || ch=='{' || ch == '}' || ch=='(' || ch == ')' || ch == ';') { onToken(token); onToken(ch); } else if (ch == '\'' || ch == '\"') { onToken(token); insideQuotes = ch; } } }
void onToken(char token) { // 4,5: font-family: // 6,7: font-weight: // 8,9: font-style: //10,11: src: // 10 11 12 13 // src : url ( //CRLog::trace("state==%d: %c ", _state, token); switch (token) { case ':': if (_state < 2) { _state = 0; } else if (_state == 4 || _state == 6 || _state == 8 || _state == 10) { _state++; } else if (_state != 3) { _state = 2; } break; case ';': if (_state < 2) { _state = 0; } else if (_state != 3) { _state = 2; } break; case '{': if (_state == 1) { _state = 2; // inside @font { _face.clear(); _italic = false; _bold = false; _url.clear(); } else _state = 3; // inside other { break; case '}': if (_state == 2) { if (!_url.empty()) { // CRLog::trace("@font { face: %s; bold: %s; italic: %s; url: %s", _face.c_str(), _bold ? "yes" : "no", // _italic ? "yes" : "no", LCSTR(_url)); _fontList.add(_url, _face, _bold, _italic); } } _state = 0; break; case '(': if (_state == 12) { _state = 13; } else { if (_state > 3) _state = 2; } break; } }
bool push_button(int key) { crtrace trace("selector::push(): "); lString8 old_prefix = prefix_; prefix_.append(1,static_cast<char>(key)); if(update_candidates()) { level_++; return true; } prefix_ = old_prefix; return false; }
void onToken(lString8 & token) { if (token.empty()) return; lString8 t = token; token.clear(); //CRLog::trace("state==%d: %s", _state, t.c_str()); if (t == "@font-face") { if (_state == 0) _state = 1; // right after @font return; } if (_state == 1) _state = 0; if (_state == 2) { if (t == "font-family") _state = 4; else if (t == "font-weight") _state = 6; else if (t == "font-style") _state = 8; else if (t == "src") _state = 10; } else if (_state == 5) { _face = t; _state = 2; } else if (_state == 7) { if (t == "bold") _bold = true; _state = 2; } else if (_state == 9) { if (t == "italic") _italic = true; _state = 2; } else if (_state == 11) { if (t == "url") _state = 12; else _state = 2; } }
/// load stylesheet from file, with processing of import bool LVLoadStylesheetFile( lString16 pathName, lString8 & css ) { LVStreamRef file = LVOpenFileStream( pathName.c_str(), LVOM_READ ); if ( file.isNull() ) return false; lString8 txt = UnicodeToUtf8( LVReadTextFile( file ) ); lString8 txt2; const char * s = txt.c_str(); lString8 import_file; if ( LVProcessStyleSheetImport( s, import_file ) ) { lString16 importFilename = LVMakeRelativeFilename( pathName, Utf8ToUnicode(import_file) ); //lString8 ifn = UnicodeToLocal(importFilename); //const char * ifns = ifn.c_str(); if ( !importFilename.empty() ) { LVStreamRef file2 = LVOpenFileStream( importFilename.c_str(), LVOM_READ ); if ( !file2.isNull() ) txt2 = UnicodeToUtf8( LVReadTextFile( file2 ) ); } } if ( !txt2.empty() ) txt2 << "\r\n"; css = txt2 + s; return !css.empty(); }
bool matchEncoded( const lString8 & prefix ) { if ( prefix.empty() ) return false; return encoded.startsWith( prefix ); }
static void addInfoSection( lString8 & buf, lString8 data, const char * caption ) { if ( !data.empty() ) buf << "<tr><td colspan=\"2\" style=\"font-weight: bold; text-align: center\">" << caption << "</td></tr>" << data; }