int main(int argc, char** argv) { TestTreeBuilder treeBuilder; setlocale(LC_ALL, ""); /* Use system locale instead of default "C" */ if (argc != 2) { fprintf(stderr, "Usage: %s regex string\n", argv[0]); return 1; } FILE *f = fopen(argv[1], "r"); fseek(f, 0L, SEEK_END); size_t length = ftell(f); fseek(f, 0L, SEEK_SET); char *buffer = new char[length + 1]; buffer[length] = 0; fread(buffer, length, 1, f); fclose(f); length = remove_carriage_returns(buffer, length); { HTMLParser treeParser; treeParser.Parse(treeBuilder, buffer,length); } HTMLOutputterString outputter(cout); treeBuilder.AsHTML(outputter); cout << endl; return 0; }
void InfoView::UpdateAwayDisplay( BMessage* message ) { // away message if( message->HasString("away_message" ) ) { HTMLParser parse; styleList styles; BString origMsg = BString((char*)message->FindString("away_message")); // translate it into UTF-8 origMsg = ConvertToUTF8( origMsg, encoding ); // handle the away message variables client->ReplaceTagVars( origMsg ); // automatically link the web and mail addresses that weren't linked Linkify( origMsg ); // Now parse the bad boy and display the results awaymessage->SetText(""); awaymessage->ClearInsertStuff(); awaymessage->ResetFontToBase(); parse.Parse( const_cast<char*>(origMsg.String()) ); styles = parse.Styles(); awaymessage->SetViewColor( styles.bgColor.R(), styles.bgColor.G(), styles.bgColor.B() ); awaymessage->Invalidate(); awaymessage->AddStyledText( parse.ParsedString(), styles ); styles.Clear(); awaymessage->AddStatement(); } }
void HTMLFormControlElement::removedFromTree(bool deep) { // If the form and element are both in the same tree, preserve the connection to the form. // Otherwise, null out our form and remove ourselves from the form's list of elements. HTMLParser* parser = 0; if (Tokenizer* tokenizer = document()->tokenizer()) if (tokenizer->isHTMLTokenizer()) parser = static_cast<HTMLTokenizer*>(tokenizer)->htmlParser(); if (m_form && !(parser && parser->isHandlingResidualStyleAcrossBlocks()) && findRoot(this) != findRoot(m_form)) { m_form->removeFormElement(this); m_form = 0; } HTMLElement::removedFromTree(deep); }
int main( int argc, char * argv[] ) { ifstream file; if ( argc < 2 ) { cout << "Please supply a document to load\n"; return 1; } else { file.open( argv[ 1 ] ); } cout << "Loading document...\n"; string content; char ch; while ( file.get( ch ) ) { content += ch; } cout << "Document loaded. " << content.size() << " characters\n"; cout << "Parsing file...\n"; // Create a DOM document TDocumentShared document( new TDocument() ); document->setSmartPointer( document ); // Create a HTMLParser object HTMLParser htmlParser; htmlParser.setContent( content ); htmlParser.startParsing( document ); htmlParser.showDocument(); return 0; }
void VHTMLSyntax::SetLine( ICodeEditorDocument *inDocument, sLONG inLineNumber, bool inLoading ) { #if 0 VString source; inDocument->GetLine( inLineNumber, source ); HTMLParser parser; HTMLParser::State *state = NULL; HTMLParser::State *prevLineState = NULL; if (inLineNumber > 0) prevLineState = GetStateForLine( inDocument, inLineNumber - 1 ); ParsingCookie *cookie = new ParsingCookie( inDocument, inLineNumber ); parser.Parse( source, prevLineState, &state, this, (const void *)cookie ); SetStateForLine( inDocument, inLineNumber, state ); cookie->Release(); #else // Get the params for the current line so that we can set them up properly VLineSyntaxParams *currentLineParams = static_cast< VLineSyntaxParams * >( inDocument->GetLineSyntaxParams( inLineNumber ) ); if (!currentLineParams) { currentLineParams = new VLineSyntaxParams(); inDocument->AssignLineSyntaxParams( inLineNumber, currentLineParams ); } bool previousOpenCommentState = currentLineParams->IsOpenComment(); // We also want the params for the preceeding line, in case we're the continuation of // a comment. VLineSyntaxParams *previousLineParams = NULL; if (inLineNumber > 0) { previousLineParams = static_cast< VLineSyntaxParams * >( inDocument->GetLineSyntaxParams( inLineNumber - 1 ) ); } VString xstr; inDocument->GetLine(inLineNumber,xstr); inDocument->SetLineStyle(inLineNumber,0,xstr.GetLength(),0); //initiate the line char *lexinput = CreateUTF8String( xstr ); struct htmlLexeme *list = parseHTML( lexinput ); // If we used to be in comment continuation mode, the assumption is that we're still in // comment continuation mode. We'll switch this off if the comment ends though currentLineParams->CopyState( previousLineParams ); // We are going to keep track of which open and close tags we've seen on the line. This allows // us to determine which unmatched open and close tags exist so we can associate that data with // the line. As we find open tags, we'll push them onto the open tag list. As we find close tags, // we will scan the open tag list and *remove* any that match. If there's no match, then we'll add // the tag to the close list. std::vector< VString > openList, closeList; // Given the list of HTML tokens, let's walk over the list and try to make some sense // of them. Walk over the list one token at a time, and see if we can make sense of // what we've got. struct htmlLexeme *cur = list; while (cur) { // There are only three types of comments we need to worry about. Full comments, // open comments and close comments. We'll get a token representing any one of the // three. However, we need to pay special attention to multi-line comments, since // they won't lex out entirely correct. If the previous line was part of an open // comment, then we want to keep walking over the tokens, marking them as part of // the comment, until we run out of tokens, or we find a kCommentClose token. if (currentLineParams->IsOpenComment()) { if (kCommentClose == cur->fStyle) { // We found the end of the comment, so we can highlight it appropriately, // and go back to our regularly scheduled lexing inDocument->SetLineStyle( inLineNumber, cur->fOffset, cur->fOffset + cur->fLength, htmlcolorShadow[ comment_col ] ); // We're also done being a part of the comment continuation train currentLineParams->SetIsOpenComment( false ); } else { // This is just another part of the comment inDocument->SetLineStyle( inLineNumber, cur->fOffset, cur->fOffset + cur->fLength, htmlcolorShadow[ comment_col ] ); } // Advance cur = cur->fNext; continue; } if (kCompleteComment == cur->fStyle) { // A complete comment is the easiest of the three cases. Just highlight it inDocument->SetLineStyle( inLineNumber, cur->fOffset, cur->fOffset + cur->fLength, htmlcolorShadow[ comment_col ] ); } else if (kCommentOpen == cur->fStyle) { // An open comment must be the last token in the list xbox_assert( !cur->fNext ); // We want to highlight from here to the end of the line inDocument->SetLineStyle( inLineNumber, cur->fOffset, cur->fOffset + cur->fLength, htmlcolorShadow[ comment_col ] ); // We also want to flag that this line ends with an open comment currentLineParams->SetIsOpenComment( true ); } else if (kCommentClose == cur->fStyle) { // If we got a close comment token, then something's off. That means the user put in a close comment // token, but they never opened it. We're going to ignore that state, and flag this as being normal inDocument->SetLineStyle( inLineNumber, cur->fOffset, cur->fOffset + cur->fLength, htmlcolorShadow[ scommentend_col ] ); } else if (kString == cur->fStyle) { inDocument->SetLineStyle( inLineNumber, cur->fOffset, cur->fOffset + cur->fLength, htmlcolorShadow[ string_col ] ); } else if (kKeyword == cur->fStyle) { // Keywords a bit trickier than you might think because we need to be sure they're actually part of a // tag. If the user types something like: <b>This table rocks</b>, we only want to highlight the b in the // begin and end tag, and not the "table" in the user's text. To deal with this, we have an "in tag" flag // that basically turns keyword highlighting on and off. if (currentLineParams->IsProcessingTag()) { inDocument->SetLineStyle( inLineNumber, cur->fOffset, cur->fOffset + cur->fLength, htmlcolorShadow[ keyword_col ] ); // If we're processing an opening tag, then we want to push the keyword onto the tag stack. But if we're // processing a closing tag, then we want to pop the last keyword off the tag stack and try to match it up // to what we just processed. If they match, we're golden. If not, we just assume the user's mismatching // their tags because they're an idiot. VString tagName; xstr.GetSubString( cur->fOffset + 1, cur->fLength, tagName ); if (currentLineParams->IsProcessingStartTag()) { if (!IsTagWithoutClose( tagName )) { openList.push_back( tagName ); } currentLineParams->PushTag( tagName ); // Note that we are no longer processing the start of a tag. This allows us to handle attributes // separately from the tag itself. currentLineParams->SetIsProcessingStartTag( false ); } else { // Check to see if this closed tag is on the open list. If it is, we want to remove it from the // list. Otherwise, we want to add it to the close list. bool bAddToClose = true; for (std::vector< VString >::iterator iter = openList.begin(); bAddToClose && iter != openList.end();) { if (tagName.EqualTo( *iter, false )) { iter = openList.erase( iter ); bAddToClose = false; } else { ++iter; } } if (bAddToClose) closeList.push_back( tagName ); VString lastTag; currentLineParams->PopTag( lastTag ); if (!lastTag.EqualTo( tagName, false )) { // The tags don't match, so we're just going to ignore the issue // TODO: do something more sensible here } } } } else if (kNumber == cur->fStyle) { inDocument->SetLineStyle( inLineNumber, cur->fOffset, cur->fOffset + cur->fLength, htmlcolorShadow[ allnum_col ] ); } else if (kTagOpen == cur->fStyle || kEndTagOpen == cur->fStyle) { currentLineParams->SetIsProcessingTag( true ); currentLineParams->SetIsProcessingStartTag( kTagOpen == cur->fStyle ); } else if (kTagClose == cur->fStyle || kTagSelfClose == cur->fStyle) { currentLineParams->SetIsProcessingTag( false ); // If we just handled a self-closing tag (like <br />), then we want to pop it from the stack VString lastTag; currentLineParams->LastTag( lastTag ); if (kTagSelfClose == cur->fStyle || IsTagWithoutClose( lastTag )) { VString toss; currentLineParams->PopTag( toss ); // We also do not want to add it to our list of open tags for the line, since it's self-closed for (std::vector< VString >::iterator iter = openList.begin(); iter != openList.end(); ++iter) { if (lastTag.EqualTo( *iter, false )) { iter = openList.erase( iter ); break; } } } } cur = cur->fNext; } FreeLexemeList( list ); // Now that we have an open and a close list, we want to associate them with the line. for (std::vector< VString >::iterator iter = openList.begin(); iter != openList.end(); ++iter) { currentLineParams->AddUnmatchedOpenTag( *iter ); } for (std::vector< VString >::iterator iter = closeList.begin(); iter != closeList.end(); ++iter) { currentLineParams->AddUnmatchedCloseTag( *iter ); } // There are two cases we really need to care about. If the line now ends in // an open comment (and didn't used to), we want to colorize down the document. // Also, if the line no longer ends in an open comment (but used to), we want to // colorize down the document. In either case, we want to keep colorizing subsequent // lines until the comment is ended or the end of the document is reached. if ((!previousOpenCommentState && currentLineParams->IsOpenComment() || // Now ends with open comment, didn't used to previousOpenCommentState && !currentLineParams->IsOpenComment()) && // Used to end with an open comment, but no longer does inLineNumber + 1 < inDocument->GetNbLines()) { SetLine( inDocument, inLineNumber + 1, inLoading ); } #endif // old code }
void InfoView::UpdateDisplay( BMessage* message ) { time_t *membersince; char theTime[100], stemp[100]; BString origProfile; unsigned idletime; ssize_t size; bool away = false; // away? if( message->HasBool("away") && message->FindBool("away") ) away = true; // username if( message->HasString("userid") ) { BMessage* msg = new BMessage(BEAIM_UPDATE_NAME_FORMAT); msg->AddString("userid", message->FindString("userid")); Window()->PostMessage( msg ); char windowTitle[DISPLAY_NAME_MAX+35]; sprintf( windowTitle, "%s: %s", Language.get("IW_USER_INFO"), message->FindString("userid") ); if( away ) { strcat( windowTitle, " (" ); strcat( windowTitle, Language.get("STAT_AWAY") ); strcat( windowTitle, ")" ); } Window()->SetTitle( windowTitle ); } // user class if( message->HasString("userclass") ) { label2->SetText( message->FindString( "userclass" ) ); printf( "IW: userclass done.\n" ); fflush(stdout); } // member since if( message->HasData("membersince", B_TIME_TYPE) ) { message->FindData( "membersince", B_TIME_TYPE, (const void**)(&membersince), &size ); strftime( theTime, 100, "%B %e, %Y", localtime(membersince) ); label4->SetText( theTime ); } // onsince /*if( message->HasData("onsince", B_TIME_TYPE) ) { message->FindData( "onsince", B_TIME_TYPE, (const void**)(&onsince), &size ); MakeElapsedTimeString( *onsince, theTime ); label6->SetText( theTime ); }*/ // session length if( message->HasInt32("sessionlen") ) { MakeElapsedTimeString( message->FindInt32("sessionlen"), theTime ); label6->SetText( theTime ); } // warning level if( message->HasInt32("warninglevel") ) { sprintf( stemp, "%u%%", (unsigned)(message->FindInt32("warninglevel")) ); label8->SetText( stemp ); } // idle time if( message->HasInt32( "idletime" ) ) { idletime = (unsigned)message->FindInt32("idletime"); if( idletime ) { label9->SetText( (char*)LangWithSuffix("STAT_IDLE_TIME", ":") ); MakeElapsedTimeString( (idletime*60), stemp ); label10->SetText( stemp ); statNotIdle = false; } else { label10->SetText( Language.get("STAT_ACTIVE") ); } } // profile if( message->HasString("profile" ) ) origProfile = BString((char*)message->FindString("profile")); if( origProfile.Length() ) { HTMLParser parse; styleList styles; // first, convert it to UTF-8 origProfile = ConvertToUTF8( origProfile, encoding ); // handle the away message variables client->ReplaceTagVars( origProfile ); // automatically link the web and mail addresses that weren't linked Linkify( origProfile ); profile->SetText(""); profile->ClearInsertStuff(); profile->ResetFontToBase(); parse.Parse( const_cast<char*>(origProfile.String()) ); styles = parse.Styles(); profile->SetViewColor( styles.bgColor.R(), styles.bgColor.G(), styles.bgColor.B() ); profile->Invalidate(); profile->AddStyledText( parse.ParsedString(), styles ); styles.Clear(); profile->AddStatement(); } // put up a generic "no profile" message else profile->SetText( Language.get("IW_NO_PROFILE") ); BView::Invalidate(); }