bool readCommaWhitespace() { if (reader >= 1) { bool ws = readWhitespace(); if (reader.is(',')) { ++ reader; } else { return ws; } readWhitespace(); return true; } return false; }
bool readCmd() { if (!readMoveTo()) { return false; } readWhitespace(); bool readNext = true; while(readNext) { readNext = readDrawTo(); if (readNext) { readWhitespace(); } } return true; }
bool readMoveTo() { if (reader >= 1) { readWhitespace(); bool relative = true; if (reader.is('M')) { relative = false; ++ reader; } else if (reader.is('m')) { relative = true; ++ reader; } else { return false; } readWhitespace(); return readMoveToArgs(relative); } return false; }
bool readCmdGroup() { readWhitespace(); while (!reader.empty()) { if (!readCmd()) { return false; } } return true; }
bool CssTokenizer::readUrl() { string urlchars = "!#$%&*-[]-~"; if (!lastReadEq('(')) return false; currentToken.add(lastRead); readChar(); while(readWhitespace()) {}; if (readString()) { if (lastReadEq(')')) { currentToken.add(lastRead); readChar(); return true; } else { throw new ParseException(&lastRead, "end of url (')')"); } } while (in != NULL) { if (readWhitespace() || lastReadEq(')')) { while (readWhitespace()) {}; if (lastReadEq(')')) { currentToken.add(lastRead); readChar(); return true; } else { throw new ParseException(&lastRead, "end of url (')')"); } } else if (in != NULL && urlchars.find(lastRead)) { currentToken.add(lastRead); readChar(); } else if (!readNonAscii() && !readEscape()) { throw new ParseException(&lastRead, "end of url (')')"); } } throw new ParseException(&lastRead, "end of url (')')"); return false; }
bool CssTokenizer::readUnicode () { if (!lastReadIsHex()) return false; // [0-9a-f]{1,6}(\r\n|[ \n\r\t\f])? for (int i=0; i < 6; i++) { currentToken.add(lastRead); readChar(); if (readWhitespace() || !lastReadIsHex()) break; } return true; }
Token *tokenize(Buffer *input) { Lexer *l; l->source = input; l->start = 0; l->pos = 0; l->head = NULL; l->tail = NULL; while (peek(l) != '\0') { l->start = l->pos; char c = next(l); switch(c) { case '(': addToken(l, TOKEN_LEFT_PAREN); break; case ')': addToken(l, TOKEN_RIGHT_PAREN); break; case '%': addToken(l, TOKEN_MOD); break; case '.': addToken(l, TOKEN_DOT); break; case '/': addToken(l, TOKEN_SLASH); break; case '*': addToken(l, TOKEN_STAR); break; case '=': addToken(l, TOKEN_EQ); break; case '-': addToken(l, TOKEN_MINUS); break; case '+': addToken(l, TOKEN_PLUS); break; case ' ': readWhitespace(l); break; case '"': readString(l); break; case '\n': addToken(l, TOKEN_LINE); break; default: if (isName(c)) { readName(l); } else if (isDigit(c)) { readNumber(c); } else { emitToken(l, TOKEN_ERROR); } break; } } lexer.start = lexer.pos; emitToken(l, TOKEN_EOF); return l->head; }
bool readDrawTo() { if (reader >= 1) { auto c = reader[0]; ++ reader; readWhitespace(); if (c == 'M' || c == 'm') { return readMoveToArgs(c == 'm'); } else if (c == 'Z' || c == 'z') { SP_PATH_LOG("Z"); if (_pathStarted) { _x = _sx; _y = _sy; _pathStarted = false; } path->closePath(); return true; } else if (c == 'L' || c == 'l') { return readLineToArgs(c == 'l'); } else if (c == 'H' || c == 'h') { return readHorizontalLineTo(c == 'h'); } else if (c == 'V' || c == 'v') { return readVerticalLineTo(c == 'v'); } else if (c == 'C' || c == 'c') { return readCubicBezier(c == 'c'); } else if (c == 'S' || c == 's') { return readCubicBezierShort(c == 's'); } else if (c == 'Q' || c == 'q') { return readQuadraticBezier(c == 'q'); } else if (c == 'T' || c == 't') { return readQuadraticBezierShort(c == 't'); } else if (c == 'A' || c == 'a') { return readEllipticalArc(c == 'a'); } } return false; }
Token::Type CssTokenizer::readNextToken(){ if (in == NULL) { currentToken.type = Token::EOS; return Token::EOS; } currentToken.clear(); switch (lastRead) { case '@': currentToken.type = Token::ATKEYWORD; currentToken.add(lastRead); readChar(); if (!readIdent()) { currentToken.type = Token::OTHER; } break; case '#': currentToken.type = Token::HASH; currentToken.add(lastRead); readChar(); if (!readName()) { throw new ParseException(&lastRead, "name following '#'"); } break; case '-': currentToken.add(lastRead); readChar(); if (readNum(true)) { currentToken.type = Token::NUMBER; readNumSuffix(); } else if (readIdent()) { currentToken.type = Token::IDENTIFIER; } else currentToken.type = Token::OTHER; break; case '~': currentToken.add(lastRead); readChar(); if (lastRead == '=') { currentToken.add(lastRead); readChar(); currentToken.type = Token::INCLUDES; } else currentToken.type = Token::OTHER; break; case '|': currentToken.add(lastRead); readChar(); if (lastRead == '=') { currentToken.add(lastRead); readChar(); currentToken.type = Token::DASHMATCH; } else currentToken.type = Token::OTHER; break; case '/': currentToken.add(lastRead); readChar(); if (readComment()) currentToken.type = Token::COMMENT; else currentToken.type = Token::OTHER; break; case ';': currentToken.type = Token::DELIMITER; currentToken.add(lastRead); readChar(); break; case ':': currentToken.type = Token::COLON; currentToken.add(lastRead); readChar(); break; case '{': currentToken.type = Token::BRACKET_OPEN; currentToken.add(lastRead); readChar(); break; case '}': currentToken.type = Token::BRACKET_CLOSED; currentToken.add(lastRead); readChar(); break; case '(': currentToken.type = Token::PAREN_OPEN; currentToken.add(lastRead); readChar(); break; case ')': currentToken.type = Token::PAREN_CLOSED; currentToken.add(lastRead); readChar(); break; case '[': currentToken.type = Token::BRACE_OPEN; currentToken.add(lastRead); readChar(); break; case ']': currentToken.type = Token::BRACE_CLOSED; currentToken.add(lastRead); readChar(); break; case '.': currentToken.add(lastRead); readChar(); if (readNum(false)) { currentToken.type = Token::NUMBER; readNumSuffix(); } break; default: if (readString()) currentToken.type = Token::STRING; else if (readNum(true)) { currentToken.type = Token::NUMBER; readNumSuffix(); } else if (readIdent()) { currentToken.type = Token::IDENTIFIER; if (currentToken.str == "url" && readUrl()) currentToken.type = Token::URL; else if (currentToken.str == "u" && lastReadEq('+')) { currentToken.add(lastRead); readChar(); currentToken.type = Token::UNICODE_RANGE; readUnicodeRange(); } } else if (readWhitespace()) { currentToken.type = Token::WHITESPACE; while (readWhitespace()) {}; } else { currentToken.add(lastRead); readChar(); } break; } return currentToken.type; }