void VSpanTextParser::GenerateSpanText( const VTreeTextStyle& inStyles, const VString& inPlainText, VString& outTaggedText, VTextStyle* inDefaultStyle) { sLONG begin, end; bool vhasForecolore, vistransparent; VString fontName, defaultfontName; sLONG vbold,vitalic,vunderline, vstrikeout, vdefaultbold,vdefaultitalic,vdefaultunderline,vdefaultstrikeout; Real fontSize, defaultfontSize; RGBAColor vforecolor, vdefaultforecolor, vbackcolor, vdefaultbackcolor; justificationStyle justification, defaultjustification; VTextStyle* uniformStyle = inStyles.GetData(); justification = defaultjustification = JST_Left; uniformStyle->GetRange(begin, end); fontName = uniformStyle->GetFontName(); fontSize = uniformStyle->GetFontSize(); vbold = uniformStyle->GetBold(); vitalic = uniformStyle->GetItalic(); vunderline = uniformStyle->GetUnderline(); vstrikeout = uniformStyle->GetStrikeout(); vhasForecolore = uniformStyle->GetHasForeColor(); vistransparent = uniformStyle->GetTransparent(); vforecolor = uniformStyle->GetColor(); vbackcolor = uniformStyle->GetBackGroundColor(); justification = uniformStyle->GetJustification(); VTreeTextStyle* parenttree = inStyles.GetParent(); bool hasDefaultForeColor = false; bool hasDefaultBackColor = false; if(inDefaultStyle) { defaultfontName = inDefaultStyle->GetFontName(); defaultfontSize = inDefaultStyle->GetFontSize(); defaultjustification = inDefaultStyle->GetJustification(); vdefaultbold = inDefaultStyle->GetBold(); vdefaultitalic = inDefaultStyle->GetItalic(); vdefaultunderline = inDefaultStyle->GetUnderline(); vdefaultstrikeout = inDefaultStyle->GetStrikeout(); hasDefaultForeColor = inDefaultStyle->GetHasForeColor(); hasDefaultBackColor = !inDefaultStyle->GetTransparent(); vdefaultforecolor = inDefaultStyle->GetColor(); vdefaultbackcolor = inDefaultStyle->GetBackGroundColor(); } else { defaultfontName = ""; defaultfontSize = -1; vdefaultbold = 0; vdefaultitalic = 0; vdefaultunderline = 0; vdefaultstrikeout = 0; defaultjustification = JST_Notset; } //as we inherit styles from parent, -1 or default value should be assumed equal (otherwise comparison would trigger a useless tag) if (vdefaultbold < 0) vdefaultbold = 0; if (vdefaultitalic < 0) vdefaultitalic = 0; if (vdefaultunderline < 0) vdefaultunderline = 0; if (vdefaultstrikeout < 0) vdefaultstrikeout = 0; if (defaultjustification < 0) defaultjustification = JST_Default; bool addfontag, addfonsizetag, addboldtag, additalictag, addunderlinetag, addstrikeouttag, addforecolortag, addbackcolortag, addjustificationtag; addfontag = addfonsizetag = addboldtag = additalictag = addunderlinetag = addstrikeouttag = addforecolortag = addbackcolortag = addjustificationtag = false; //we pass inherited default style to children to avoid to redefine style already defined by parent node: //so current inDefaultStyle always inherits parent styles VTextStyle *defaultStyleInherit = inStyles.GetChildCount() > 0 ? new VTextStyle( inDefaultStyle) : NULL; if( fontName.GetLength() > 0 && fontName != defaultfontName) { addfontag = true; if (defaultStyleInherit) defaultStyleInherit->SetFontName( fontName); } if( fontSize != -1 && fontSize != defaultfontSize) { addfonsizetag = true; if (defaultStyleInherit) defaultStyleInherit->SetFontSize( fontSize); } if( justification != JST_Notset && justification != defaultjustification) { addjustificationtag = true; if (defaultStyleInherit) defaultStyleInherit->SetJustification( justification); } if( vbold != UNDEFINED_STYLE && vbold != vdefaultbold) { addboldtag = true; if (defaultStyleInherit) defaultStyleInherit->SetBold( vbold); } if( vitalic != UNDEFINED_STYLE && vitalic != vdefaultitalic) { additalictag = true; if (defaultStyleInherit) defaultStyleInherit->SetItalic( vitalic); } if( vunderline != UNDEFINED_STYLE && vunderline != vdefaultunderline) { addunderlinetag = true; if (defaultStyleInherit) defaultStyleInherit->SetUnderline( vunderline); } if( vstrikeout != UNDEFINED_STYLE && vstrikeout != vdefaultstrikeout) { addstrikeouttag = true; if (defaultStyleInherit) defaultStyleInherit->SetStrikeout( vstrikeout); } if( vhasForecolore && ((!hasDefaultForeColor) || vforecolor != vdefaultforecolor)) { addforecolortag = true; if (defaultStyleInherit) { defaultStyleInherit->SetHasForeColor( vhasForecolore); defaultStyleInherit->SetColor( vforecolor); } } if( !vistransparent && ((!hasDefaultBackColor) || vbackcolor != vdefaultbackcolor)) { addbackcolortag = true; if (defaultStyleInherit) { defaultStyleInherit->SetTransparent( false); defaultStyleInherit->SetBackGroundColor( vbackcolor); } } bool addtag = addfontag || addfonsizetag || addboldtag || additalictag || addunderlinetag || addstrikeouttag || addforecolortag || addbackcolortag || addjustificationtag; bool isInitialEmpty = outTaggedText.IsEmpty(); if(addtag) { bool addcoma = false; outTaggedText += "<SPAN STYLE=\""; if(addfontag) { outTaggedText += MS_FONT_NAME; outTaggedText += ":'"; outTaggedText += fontName + "'"; addcoma = true; } if(addfonsizetag) { VString strFontSize; //we need to convert from 72dpi font size to the desired dpi (screen dpi for v12 compatibility) #if VERSIONWIN strFontSize.FromReal(floor(fontSize*72.0f/VSpanTextParser::Get()->GetDPI()+0.5f)); #else strFontSize.FromReal(fontSize); #endif if(addcoma) outTaggedText+=";"; outTaggedText += MS_FONT_SIZE ; outTaggedText += ":"; outTaggedText += strFontSize; outTaggedText += "pt"; addcoma = true; } if(addjustificationtag) { VString value; JustificationToString(justification,value); if(addcoma) outTaggedText+=";"; outTaggedText += MS_JUSTIFICATION; outTaggedText += ":"; outTaggedText += value; addcoma = true; } if(addboldtag) { VString value; if(addcoma) outTaggedText+=";"; vbold ? value = "bold" : value = "normal"; outTaggedText += MS_BOLD ; outTaggedText += ":" + value; addcoma = true; } if(additalictag) { VString value; if(addcoma) outTaggedText+=";"; vitalic ? value = "italic" : value = "normal"; outTaggedText += MS_ITALIC ; outTaggedText += ":"+ value; addcoma = true; } if(addunderlinetag && addstrikeouttag) { VString value; if(addcoma) outTaggedText+=";"; if(!vunderline && !vstrikeout) value = "none"; if(vunderline && vstrikeout) value = "underline line-through"; else if(vunderline) value = "underline"; else if(vstrikeout) value = "line-through"; outTaggedText += MS_UNDERLINE ; outTaggedText += ":"+ value; addcoma = true; } else { if(addunderlinetag) { VString value; if(addcoma) outTaggedText+=";"; vunderline ? value = "underline" : value = "none"; outTaggedText += MS_UNDERLINE ; outTaggedText += ":"+ value; addcoma = true; } if(addstrikeouttag) { VString value; if(addcoma) outTaggedText+=";"; vstrikeout ? value = "line-through" : value = "none"; outTaggedText += MS_UNDERLINE ; outTaggedText += ":"+ value; addcoma = true; } } if(addforecolortag) { VString value; if(addcoma) outTaggedText+=";"; ColorToValue(vforecolor,value); outTaggedText += MS_COLOR; outTaggedText += ":"+ value; addcoma = true; } if(addbackcolortag) { VString value; if(addcoma) outTaggedText+=";"; ColorToValue(vbackcolor,value); outTaggedText += MS_BACKGROUND; outTaggedText += ":"+ value; addcoma = true; } outTaggedText +="\">"; } VString text; VString tmp; sLONG count = inStyles.GetChildCount(); //prevent assert in GetSubString if (end > inPlainText.GetLength()) end = inPlainText.GetLength(); if (begin > inPlainText.GetLength()) begin = inPlainText.GetLength(); if(count == 0) { if(end>begin) { inPlainText.GetSubString(begin+1, end-begin, text); ToXMLCompatibleText(text, tmp); outTaggedText += tmp; } } else { sLONG start = begin; for(sLONG i = 1; i <= count; i++) { VTreeTextStyle* child = inStyles.GetNthChild(i); sLONG b,e; child->GetData()->GetRange(b,e); //prevent assert in GetSubString if (e > inPlainText.GetLength()) e = inPlainText.GetLength(); if (b > inPlainText.GetLength()) b = inPlainText.GetLength(); //if(start < b-1) if(start < b) { inPlainText.GetSubString(start+1, b-start, text); ToXMLCompatibleText(text, tmp); outTaggedText += tmp; } GenerateSpanText(*child, inPlainText, outTaggedText, defaultStyleInherit); start = e; } if(start < end) { inPlainText.GetSubString(start+1, end-start, text); ToXMLCompatibleText(text, tmp); outTaggedText += tmp; } } if (addtag) outTaggedText +="</SPAN>"; //JQ 24/12/2012: ensure tagged text is bracketed with SPAN tag else if (isInitialEmpty) { if (!outTaggedText.BeginsWith(CVSTR("<SPAN"), true)) outTaggedText = CVSTR("<SPAN>")+outTaggedText+CVSTR("</SPAN>"); } if (defaultStyleInherit) delete defaultStyleInherit; }
void VHTMLSyntax::GetSuggestions( ICodeEditorDocument* inDocument, sLONG inLineNumber, sLONG inPos, ITipInfoArray *outSuggestions, sLONG& outStartOffset, bool inAll ) { // Get the text for the line up to the point of insertion, and we'll lex that to see if we can come up // with some rational suggestions for the user. VString xstr; inDocument->GetLine( inLineNumber, xstr ); xstr.Truncate( inPos ); char *lexinput = CreateUTF8String( xstr ); struct htmlLexeme *list = parseHTML( lexinput ); // Gin up some line params for tracking state information VLineSyntaxParams *currentLineParams = currentLineParams = new VLineSyntaxParams(); if (inLineNumber > 0) { // We're starting where we left off on the previous line currentLineParams->CopyState( static_cast< VLineSyntaxParams * >( inDocument->GetLineSyntaxParams( inLineNumber - 1 ) ) ); } // 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. This is going to be awfully similar to the way we do things in the // SetLine method, except that we're not actually updating the line state for the current // line. Instead, we're working on a copy of the existing information. struct htmlLexeme *cur = list; int lastTokenProcessed = 0; while (cur) { if (kKeyword == cur->fStyle) { lastTokenProcessed = 3; // 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()) { // 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()) { 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 { 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 (kTagOpen == cur->fStyle || kEndTagOpen == cur->fStyle) { lastTokenProcessed = (kTagOpen == cur->fStyle) ? 1 : 2; currentLineParams->SetIsProcessingTag( true ); currentLineParams->SetIsProcessingStartTag( kTagOpen == cur->fStyle ); } else if (kTagClose == cur->fStyle || kTagSelfClose == cur->fStyle) { lastTokenProcessed = 0; currentLineParams->SetIsProcessingTag( false ); // If we just handled a self-closing tag (like <br />), then we want to pop it from the stack // TODO: some tags can't have matching pairs, like <br>, so even if it's not self-closing, we want // to pop it off the tag stack. Handle that here if (kTagSelfClose == cur->fStyle) { VString toss; currentLineParams->PopTag( toss ); } } else { lastTokenProcessed = 0; } cur = cur->fNext; } if (lastTokenProcessed == 1) { // We processed a tag opener, but no keyword for the tag. So let's make a bunch of suggestions! } else if (lastTokenProcessed == 2) { // We processed a tag closer, but no keyword for the tag. Grab the last opened tag from the list // and suggest it as the closer VString suggestion; currentLineParams->LastTag( suggestion ); outSuggestions->AddTip( new VCodeEditorTipInfo( inDocument, suggestion, htmlcolorShadow[ keyword_col ] ) ); } delete currentLineParams; FreeLexemeList( list ); }
/** parse span text element or XHTML fragment @param inTaggedText tagged text to parse (span element text only if inParseSpanOnly == true, XHTML fragment otherwise) @param outStyles parsed styles @param outPlainText parsed plain text @param inParseSpanOnly true (default): only <span> element(s) with CSS styles are parsed false: all XHTML text fragment is parsed (parse also mandatory HTML text styles) */ void VSpanTextParser::ParseSpanText( const VString& inTaggedText, VTreeTextStyle*& outStyles, VString& outPlainText, bool inParseSpanOnly) { outPlainText = ""; if(outStyles) outStyles->Release(); outStyles = NULL; if (inTaggedText.IsEmpty()) return; //fixed ACI0076343: for compatibility with older bases which do not have support for multistyle var or field // we need to convert to xml text the text which is not bracketed with SPAN // otherwise parser would fail VString vtext; sLONG posStartSPAN = 1; //pos of first SPAN tag sLONG posEndSPAN = inTaggedText.GetLength()+1; //pos of character following ending SPAN tag if (inParseSpanOnly) { //search for opening SPAN tag posStartSPAN = inTaggedText.Find("<SPAN", 1, false); if (!posStartSPAN) { //convert full text to xml inTaggedText.GetXMLString( vtext, XSO_Default); vtext = VString("<SPAN>")+vtext+"</SPAN>"; } else { VString before, after; if (posStartSPAN > 1) { //convert to XML text preceeding first SPAN VString temp; inTaggedText.GetSubString( 1, posStartSPAN-1, temp); temp.GetXMLString( before, XSO_Default); } //search for ending SPAN tag const UniChar *c = inTaggedText.GetCPointer()+inTaggedText.GetLength()-1; sLONG pos = inTaggedText.GetLength()-1; VString spanEndTag = "</SPAN>"; VString spanEndTag2 = "</span>"; do { while (pos >= 0 && *c != '>') { pos--; if (pos >= 0) c--; } if (pos >= 0) { if (memcmp( (void*)(c+1-spanEndTag.GetLength()), spanEndTag.GetCPointer(), spanEndTag.GetLength()*sizeof(UniChar)) == 0 || memcmp( (void*)(c+1-spanEndTag2.GetLength()), spanEndTag2.GetCPointer(), spanEndTag2.GetLength()*sizeof(UniChar)) == 0) { posEndSPAN = pos+2; break; } else { pos--; if (pos >= 0) c--; } } } while (pos >= 0); if (posEndSPAN <= inTaggedText.GetLength()) { //convert to XML text following ending SPAN tag VString temp; inTaggedText.GetSubString( posEndSPAN, inTaggedText.GetLength()-posEndSPAN+1, temp); temp.GetXMLString( after, XSO_Default); } if (!before.IsEmpty() || !after.IsEmpty()) { inTaggedText.GetSubString( posStartSPAN, posEndSPAN-posStartSPAN, vtext); vtext = VString("<SPAN>")+before+vtext+after+"</SPAN>"; } else vtext = VString("<SPAN>")+inTaggedText+"</SPAN>"; } } else vtext = inTaggedText; vtext.ExchangeAll(0x0B,0x0D);//[MI] le 28/12/2010 ACI0069253 #if VERSIONWIN vtext.ConvertCarriageReturns(eCRM_CR); //important here on Windows before parsing because styles are assumed to use one character size for line ending on any platform //and so pair of 0x0D 0x0A should be treated as a single 0x0D character #endif VTaggedTextSAXHandler vsaxhandler(outStyles, &outPlainText, inParseSpanOnly); VXMLParser vSAXParser; vSAXParser.Parse(vtext, &vsaxhandler, XML_ValidateNever); #if VERSIONWIN outPlainText.ConvertCarriageReturns(eCRM_CR); //we need to convert to CR (on any platform but Linux here) because xerces parser has converted all line endings to LF (cf W3C XML line ending uniformization while parsing) #elif VERSIONMAC outPlainText.ConvertCarriageReturns(eCRM_CR); //we need to convert to CR (on any platform but Linux here) because xerces parser has converted all line endings to LF (cf W3C XML line ending uniformization while parsing) #endif }
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 }