void scContUnit::ForceRepaint( long offset1, long offset2 ) { scTextline* txl; scTextline* ntxl; scColumn* col; txl = GetFirstline(); if ( txl ) { col = txl->GetColumn(); /* search the lines of the paragraph until we find a line * containing the 'offset' */ for ( ; txl; txl = ntxl ) { if ( offset2 < txl->GetStartOffset( ) ) break; else if ( offset1 > txl->GetEndOffset( ) ) ; else if ( offset1 < txl->GetEndOffset( ) ) txl->Mark( scREPAINT ); ntxl = LNNext( txl ); if ( ntxl == NULL ) { /* hit the bottom of a column, check next column */ col = col->GetNext(); ntxl = NextColumn( col ); } if ( txl->IsLastLinePara( ) ) break; } } }
void WrapperDLL::Tool_NextColumn(void* self){ auto self_ = (Tool*)self; self_->NextColumn(); };
/* Process as much of the input HTML as possible. Construct new ** HtmlElement structures and appended them to the list. Return ** the number of characters actually processed. ** ** This routine may invoke a callback procedure which could delete ** the HTML widget. ** ** This routine is not reentrant for the same HTML widget. To ** prevent reentrancy (during a callback), the p->iCol field is ** set to a negative number. This is a flag to future invocations ** not to reentry this routine. The p->iCol field is restored ** before exiting, of course. */ static int Tokenize( HtmlWidget *p /* The HTML widget doing the parsing */ ){ char *z; /* The input HTML text */ int c; /* The next character of input */ int n; /* Number of characters processed so far */ int iCol; /* Column of input */ int i, j; /* Loop counters */ int h; /* Result from HtmlHash() */ int nByte; /* Space allocated for a single HtmlElement */ HtmlElement *pElem; /* A new HTML element */ int selfClose; /* True for content free elements. Ex: <br/> */ int argc; /* The number of arguments on a markup */ HtmlTokenMap *pMap; /* For searching the markup name hash table */ char *zBuf; /* For handing out buffer space */ # define mxARG 200 /* Maximum number of parameters in a single markup */ char *argv[mxARG]; /* Pointers to each markup argument. */ int arglen[mxARG]; /* Length of each markup argument */ iCol = p->iCol; n = p->nComplete; z = p->zText; if( iCol<0 ){ TestPoint(0); return n; } /* Prevents recursion */ p->iCol = -1; while( (c=z[n])!=0 ){ if( p->pScript ){ /* We are in the middle of <SCRIPT>...</SCRIPT>. Just look for ** the </SCRIPT> markup. (later:) Treat <STYLE>...</STYLE> the ** same way. */ HtmlScript *pScript = p->pScript; char *zEnd; int nEnd; if( pScript->markup.base.type==Html_SCRIPT ){ zEnd = "</script>"; nEnd = 9; }else{ zEnd = "</style>"; nEnd = 8; } if( pScript->zScript==0 ){ pScript->zScript = &z[n]; pScript->nScript = 0; } for(i=n+pScript->nScript; z[i]; i++){ if( z[i]=='<' && z[i+1]=='/' && strnicmp(&z[i],zEnd,nEnd)==0 ){ pScript->nScript = i - n; p->pScript = 0; n = i+nEnd; break; } } if( p->pScript ){ pScript->nScript = i - n; } continue; }else if( isspace(c) ){ /* White space */ for(i=0; (c=z[n+i])!=0 && isspace(c) && c!='\n' && c!='\r'; i++){} if( c=='\r' && z[n+i+1]=='\n' ){ i++; } pElem = HtmlAlloc( sizeof(HtmlSpaceElement) ); if( pElem==0 ){ goto incomplete; } pElem->base.type = Html_Space; if( c=='\n' || c=='\r' ){ pElem->base.flags = HTML_NewLine; pElem->base.count = 1; i++; iCol = 0; TestPoint(0); }else{ int iColStart = iCol; pElem->base.flags = 0; for(j=0; j<i; j++){ iCol = NextColumn(iCol, z[n+j]); TestPoint(0); } pElem->base.count = iCol - iColStart; } AppendElement(p,pElem); n += i; }else if( c!='<' || p->iPlaintext!=0 || (!isalpha(z[n+1]) && z[n+1]!='/' && z[n+1]!='!' && z[n+1]!='?') ){ /* Ordinary text */ for(i=1; (c=z[n+i])!=0 && !isspace(c) && c!='<'; i++){} if( c==0 ){ TestPoint(0); goto incomplete; } if( p->iPlaintext!=0 && z[n]=='<' ){ switch( p->iPlaintext ){ case Html_LISTING: if( i>=10 && strnicmp(&z[n],"</listing>",10)==0 ){ p->iPlaintext = 0; goto doMarkup; } break; case Html_XMP: if( i>=6 && strnicmp(&z[n],"</xmp>",6)==0 ){ p->iPlaintext = 0; goto doMarkup; } break; case Html_TEXTAREA: if( i>=11 && strnicmp(&z[n],"</textarea>",11)==0 ){ p->iPlaintext = 0; goto doMarkup; } break; default: break; } } nByte = sizeof(HtmlTextElement) + i; pElem = HtmlAlloc( nByte ); if( pElem==0 ){ goto incomplete; } memset(pElem,0,nByte); pElem->base.type = Html_Text; sprintf(pElem->text.zText,"%.*s",i,&z[n]); AppendElement(p,pElem); if( p->iPlaintext==0 || p->iPlaintext==Html_TEXTAREA ){ HtmlTranslateEscapes(pElem->text.zText); } pElem->base.count = strlen(pElem->text.zText); n += i; iCol += i; }else if( strncmp(&z[n],"<!--",4)==0 ){ /* An HTML comment. Just skip it. */ for(i=4; z[n+i]; i++){ if( z[n+i]=='-' && strncmp(&z[n+i],"-->",3)==0 ){ break; } } if( z[n+i]==0 ){ TestPoint(0); goto incomplete; } for(j=0; j<i+3; j++){ iCol = NextColumn(iCol, z[n+j]); } n += i + 3; }else{ /* Markup. ** ** First get the name of the markup */ doMarkup: argc = 1; argv[0] = &z[n+1]; for(i=1; (c=z[n+i])!=0 && !isspace(c) && c!='>' && (i<2 || c!='/'); i++){} arglen[0] = i - 1; if( c==0 ){ goto incomplete; } /* ** Now parse up the arguments */ while( isspace(z[n+i]) ){ i++; } while( (c=z[n+i])!=0 && c!='>' && (c!='/' || z[n+i+1]!='>') ){ if( argc>mxARG-3 ){ argc = mxARG-3; } argv[argc] = &z[n+i]; j = 0; while( (c=z[n+i+j])!=0 && !isspace(c) && c!='>' && c!='=' && (c!='/' || z[n+i+j+1]!='>') ){ j++; } arglen[argc] = j; if( c==0 ){ goto incomplete; } i += j; while( isspace(c) ){ i++; c = z[n+i]; } if( c==0 ){ goto incomplete; } argc++; if( c!='=' ){ argv[argc] = ""; arglen[argc] = 0; argc++; continue; } i++; c = z[n+i]; while( isspace(c) ){ i++; c = z[n+i]; } if( c==0 ){ goto incomplete; } if( c=='\'' || c=='"' ){ int cQuote = c; i++; argv[argc] = &z[n+i]; for(j=0; (c=z[n+i+j])!=0 && c!=cQuote; j++){} if( c==0 ){ goto incomplete; } arglen[argc] = j; i += j+1; TestPoint(0); }else{ argv[argc] = &z[n+i]; for(j=0; (c=z[n+i+j])!=0 && !isspace(c) && c!='>'; j++){} if( c==0 ){ goto incomplete; } arglen[argc] = j; i += j; } argc++; while( isspace(z[n+i]) ){ i++; } } if( c=='/' ){ i++; c = z[n+i]; selfClose = 1; }else{ selfClose = 0; } if( c==0 ){ goto incomplete; } for(j=0; j<i+1; j++){ iCol = NextColumn(iCol, z[n+j]); } n += i + 1; /* Lookup the markup name in the hash table */ if( !isInit ){ HtmlHashInit(); isInit = 1; } c = argv[0][arglen[0]]; argv[0][arglen[0]] = 0; h = HtmlHash(argv[0]); for(pMap = apMap[h]; pMap; pMap=pMap->pCollide){ if( stricmp(pMap->zName,argv[0])==0 ){ break; } TestPoint(0); } argv[0][arglen[0]] = c; if( pMap==0 ){ continue; } /* Ignore unknown markup */ makeMarkupEntry: /* Construct a HtmlMarkup entry for this markup. */ if( pMap->extra ){ nByte = pMap->extra; }else if( argc==1 ){ nByte = sizeof(HtmlBaseElement); }else{ nByte = sizeof(HtmlMarkupElement); } if( argc>1 ){ nByte += sizeof(char*) * argc; for(j=1; j<argc; j++){ nByte += arglen[j] + 1; } } pElem = HtmlAlloc( nByte ); if( pElem==0 ){ goto incomplete; } memset(pElem,0,nByte); pElem->base.type = pMap->type; pElem->base.count = argc - 1; if( argc>1 ){ if( pMap->extra ){ pElem->markup.argv = (char**)&((char*)pElem)[pMap->extra]; }else{ pElem->markup.argv = (char**)&((HtmlMarkupElement*)pElem)[1]; } zBuf = (char*)&pElem->markup.argv[argc]; for(j=1; j<argc; j++){ pElem->markup.argv[j-1] = zBuf; zBuf += arglen[j] + 1; sprintf(pElem->markup.argv[j-1],"%.*s",arglen[j],argv[j]); HtmlTranslateEscapes(pElem->markup.argv[j-1]); if( (j&1)==1 ){ ToLower(pElem->markup.argv[j-1]); } } pElem->markup.argv[argc-1] = 0; } /* The new markup has now be constructed in pElem. But before ** appending to the list, check to see if there is a special ** handler for this markup type. */ if( p->zHandler[pMap->type] ){ Tcl_DString str; Tcl_DStringInit(&str); Tcl_DStringAppend(&str, p->zHandler[pMap->type], -1); Tcl_DStringAppendElement(&str, pMap->zName); Tcl_DStringStartSublist(&str); for(j=0; j<argc-1; j++){ Tcl_DStringAppendElement(&str, pElem->markup.argv[j]); } Tcl_DStringEndSublist(&str); HtmlFree(pElem); HtmlLock(p); Tcl_GlobalEval(p->interp, Tcl_DStringValue(&str)); Tcl_DStringFree(&str); if( HtmlUnlock(p) ){ return 0; } /* Tricky, tricky. The callback might have caused the p->zText ** pointer to change, so renew our copy of that pointer. The ** callback might also have cleared or destroyed the widget. ** If so, abort this routine. */ z = p->zText; if( z==0 || p->tkwin==0 ){ n = 0; iCol = 0; goto incomplete; } continue; } /* No special handler for this markup. Just append it to the ** list of all tokens. */ AppendElement(p,pElem); switch( pMap->type ){ case Html_PLAINTEXT: case Html_LISTING: case Html_XMP: case Html_TEXTAREA: p->iPlaintext = pMap->type; break; case Html_STYLE: case Html_SCRIPT: p->pScript = (HtmlScript*)pElem; break; default: break; } /* If this is self-closing markup (ex: <br/> or <img/>) then ** synthesize a closing token. */ if( selfClose && argv[0][0]!='/' && strcmp(&pMap[1].zName[1],pMap->zName)==0 ){ selfClose = 0; pMap++; argc = 1; goto makeMarkupEntry; } } } incomplete: p->iCol = iCol; return n; }
void scSelection::MoveSelect( eSelectMove moveSelect ) { int setmax = 1; switch ( moveSelect ) { case ePrevChar: case eNextChar: case ePrevCharInPara: case eNextCharInPara: SLCCharacterMove( *this, moveSelect ); break; case ePrevWord: PrevWord( ); break; case eNextWord: NextWord( ); break; case ePrevSpellWord: PrevSpellWord( ); break; case eNextSpellWord: NextSpellWord( ); break; case eStartWord: StartWord( ); break; case eEndWord: EndWord( ); break; case ePrevEntireLine: PrevEntireLine(); break; case eNextEntireLine: NextEntireLine(); break; case ePrevLine: PrevLine(); setmax = 0; break; case eNextLine: NextLine(); setmax = 0; break; case eStartLine: StartLine(); break; case eEndLine: EndLine(); break; case ePrevPara: case eNextPara: case eFirstPara: case eLastPara: Para( moveSelect ); break; case eBeginPara: BeginPara(); break; case eEndPara: EndPara(); break; case ePrevEntireColumn: PrevColumn(); break; case eNextEntireColumn: NextColumn(); break; case eBeginColumn: StartColumn( ); break; case eEndColumn: EndColumn(); break; case eStartStream: fMark.SelectStartStream(); fPoint.SelectStartStream(); break; case eEndStream: fMark.SelectEndStream(); fPoint.SelectEndStream(); break; default: SCDebugBreak(); break; } fMark.UpdateInfo( setmax ); fPoint.UpdateInfo( setmax ); }