void LatexTables::addHLine(QDocumentCursor &cur,const int numberOfLines,const bool remove){ QDocumentCursor c(cur); c.beginEditBlock(); QStringList tokens("\\\\"); QStringList hline("\\hline"); int ln=numberOfLines; while(ln!=0){ int result=findNextToken(c,tokens); if(result<0) break; if(remove){ QDocumentCursor c2(c); result=findNextToken(c,hline,true); if(c.selectedText().contains(QRegExp("^\\s*\\\\hline$"))){ c.removeSelectedText(); }else{ c=c2; } }else{ // don't add \hline if already present QString text=c.line().text(); int col=c.columnNumber(); int pos_hline=text.indexOf(" \\hline",col); if(pos_hline<0 || !text.mid(col,pos_hline-col).contains(QRegExp("^\\s*$"))){ c.insertText(" \\hline"); if(!c.atLineEnd()) c.insertText("\n"); } } ln--; } c.endEditBlock(); }
void LatexTables::removeRow(QDocumentCursor &c){ QDocumentCursor cur(c); const QStringList tokens("\\\\"); if(cur.hasSelection()){ if(cur.lineNumber()>cur.anchorLineNumber()||(cur.lineNumber()==cur.anchorLineNumber() && cur.columnNumber()>cur.anchorColumnNumber())){ cur.moveTo(cur.anchorLineNumber(),cur.anchorColumnNumber()); } } int result=findNextToken(cur,tokens,false,true); if(result==0) cur.movePosition(2,QDocumentCursor::Right); if(result==-2) cur.movePosition(1,QDocumentCursor::EndOfLine); bool breakLoop=false; while(!(breakLoop=(findNextToken(cur,tokens,true)==-1)) && c.isWithinSelection(cur) ){ } if(!breakLoop) { // check if end of cursor is at line end QDocumentCursor c2(cur.document(),cur.anchorLineNumber(),cur.anchorColumnNumber()); if(c2.atLineEnd()) { c2.movePosition(1,QDocumentCursor::Right); cur.moveTo(c2,QDocumentCursor::KeepAnchor); } // remove text cur.beginEditBlock(); cur.removeSelectedText(); if(cur.line().text().isEmpty()) cur.deleteChar(); // don't leave empty lines cur.endEditBlock(); } }
//get named integer positive value inline int getNamedValue(std::istream& inStream, const std::string& inName){ findNextToken(inStream); std::string token; std::getline(inStream, token, ' '); if(token != inName) fatalError(inName + " variable wanted."); int value = -1; findNextToken(inStream); inStream >> value; if(value < 0) fatalError( inName + " has wrong value."); return value; }
/* countTokens * Find all of the white space delimited or apostraphe contained * tokens within the given line * Notes: This function should be done. I am getting what I expect. */ int countTokens(char *line){ int tokens = 0; token_tag tk; tk.start = line; // Loop while tk.end actually points to something. tk = findNextToken(tk.start,line); while(*tk.start){ tk = findNextToken(tk.end,line); tokens++; } //printf("num_tokens: %d\n",tokens); return tokens; }
QString LatexTables::getTableText(QDocumentCursor &cur){ int result=findNextToken(cur,QStringList(),false,true); if(result!=-2) return QString(); QString line=cur.line().text(); int i=line.indexOf("\\begin"); if(i>=0) cur.setColumnNumber(i); result=findNextToken(cur,QStringList(),true,false); if(result!=-2) return QString(); line=cur.line().text(); QRegExp rx("\\\\end\\{.*\\}"); i=rx.indexIn(line); if(i>=0) cur.setColumnNumber(i+rx.cap(0).length(),QDocumentCursor::KeepAnchor); QString res=cur.selectedText(); return res; }
inline void checkAndEatHeader(std::istream& inStream){ int version = getNamedValue(inStream, "MD5Version"); if(version != MD5_SUPPORTED_VERSION){ fatalError("MD5 data has wrong version."); } //get 'commandline' string //we don't use it but it must be present findNextToken(inStream); std::string token; std::getline(inStream, token, ' '); if(token != "commandline") fatalError("MD5 data must contain 'commandline' variable in its header."); findNextToken(inStream); //find " character inStream.ignore(50, '"'); //ignore commanline data inStream.ignore(10000, '"'); }
void LatexTables::addRow(QDocumentCursor &c,const int numberOfColumns ){ QDocumentCursor cur(c); bool stopSearch=false; if(cur.columnNumber()>1){ cur.movePosition(2,QDocumentCursor::Left,QDocumentCursor::KeepAnchor); QString res=cur.selectedText(); if(res=="\\\\") stopSearch=true; cur.movePosition(2,QDocumentCursor::Right); } const QStringList tokens("\\\\"); int result=0; if(!stopSearch) result=findNextToken(cur,tokens); if(result==0 || result==-2){ //if last line before end, check whether the user was too lazy to put in a linebreak if(result==-2){ QDocumentCursor ch(cur); int res=findNextToken(ch,tokens,true,true); if(res==-2){ cur.movePosition(1,QDocumentCursor::Left); cur.insertText("\\\\\n"); }else{ ch.movePosition(2,QDocumentCursor::Right,QDocumentCursor::KeepAnchor); if(ch.selectedText().contains(QRegExp("^\\S+$"))){ cur.movePosition(1,QDocumentCursor::Left); cur.insertText("\\\\\n"); } } } // //result=findNextToken(cur,tokens); cur.beginEditBlock(); if(result>-2) cur.insertText("\n"); QString str("& "); QString outStr(" "); for(int i=1;i<numberOfColumns;i++){ outStr+=str; } cur.insertText(outStr); cur.insertText("\\\\"); if(!cur.atLineEnd()) cur.insertText("\n"); cur.endEditBlock(); } }
inline std::string getNamedString(std::istream& inStream, const std::string& inName){ findNextToken(inStream); std::string token; std::getline(inStream, token, ' '); if(token != inName) fatalError(inName + " variable wanted."); // '"' must be here eatChar(inStream, '"'); //read name std::string value; std::getline(inStream, value, '"'); return value; }
bool LatexTables::inTableEnv(QDocumentCursor &cur){ QDocumentCursor c(cur); int result=findNextToken(c,QStringList(),false,true); if(result!=-2) return false; if(c.lineNumber()==cur.lineNumber()) return false; QString line=c.line().text(); int pos=line.indexOf("\\begin"); if(pos>-1){ QStringList values; LatexParser::resolveCommandOptions(line,pos,values); QString env=values.takeFirst(); if(!env.startsWith("{")||!env.endsWith("}")) return -1; env=env.mid(1); env.chop(1); if(tabularNames.contains(env,Qt::CaseSensitive)||tabularNamesWithOneOption.contains(env,Qt::CaseSensitive)){ int result=findNextToken(c,QStringList()); if(result!=-2) return false; if(c.lineNumber()>cur.lineNumber()) return true; } } return false; }
int LatexTables::getNumberOfColumns(QDocumentCursor &cur){ QDocumentCursor c(cur); int result=findNextToken(c,QStringList(),false,true); if(result!=-2) return -1; QString line=c.line().text(); int pos=line.indexOf("\\begin"); if(pos>-1){ QStringList values; LatexParser::resolveCommandOptions(line,pos,values); return getNumberOfColumns(values); } return -1; }
int LatexTables::getColumn(QDocumentCursor &cur){ QDocumentCursor c(cur); QStringList tokens("\\\\"); int result=findNextToken(c,tokens,true,true); if(result==0) c.movePosition(2,QDocumentCursor::Right,QDocumentCursor::KeepAnchor); if(c.lineNumber()==cur.lineNumber() && c.selectedText().contains(QRegExp("^\\s*$"))){ c.movePosition(1,QDocumentCursor::EndOfLine,QDocumentCursor::KeepAnchor); QString zw=c.selectedText(); if(zw.contains(QRegExp("^\\s*$"))) return -1; } c.clearSelection(); tokens << "\\&" << "&"; int col=0; do{ result=findNextToken(c,tokens); if(c.lineNumber()>cur.lineNumber()|| (c.lineNumber()==cur.lineNumber() && c.columnNumber()>cur.columnNumber())) break; if(result==2) col++; }while(result>0); return col; }
int calculate(string s) { stack<string> tokens; int pos = 0; string token; while (findNextToken(s, token, pos)){ if (token == ")"){ int val = calSimple(tokens); tokens.pop(); // "(" ostringstream oss; oss << val; tokens.push(oss.str()); }else{ tokens.push(token); } } return calSimple(tokens); }
QString LatexTables::getDef(QDocumentCursor &cur){ QDocumentCursor c(cur); int result=findNextToken(c,QStringList(),false,true); if(result!=-2) return QString(); QString line=c.line().text(); QString opt; int pos=line.indexOf("\\begin"); if(pos>-1){ QStringList values; QList<int> starts; LatexParser::resolveCommandOptions(line,pos,values,&starts); QString env=values.takeFirst(); pos=starts.takeFirst(); if(!env.startsWith("{")||!env.endsWith("}")) return QString(); env=env.mid(1); env.chop(1); int numberOfOptions=-1; if(tabularNames.contains(env)) numberOfOptions=0; if(tabularNamesWithOneOption.contains(env)) numberOfOptions=1; if(numberOfOptions>=0){ while(!values.isEmpty()){ opt=values.takeFirst(); pos=starts.takeFirst(); if(opt.startsWith("[")&&opt.endsWith("]")) continue; if(numberOfOptions>0) { numberOfOptions--; continue; } if(!opt.startsWith("{")||!opt.endsWith("}")) return QString(); opt=opt.mid(1); opt.chop(1); cur.moveTo(c.line(),pos+1); cur.movePosition(opt.length(),QDocumentCursor::NextCharacter,QDocumentCursor::KeepAnchor); } } } return opt; }
void LatexTables::addColumn(QDocument *doc,const int lineNumber,const int afterColumn,QStringList *cutBuffer){ QDocumentCursor cur(doc); QStringList pasteBuffer; QStringList nTokens; nTokens << "\\\\" << "\\&" << "&"; if(cutBuffer) pasteBuffer=*cutBuffer; cur.beginEditBlock(); cur.moveTo(lineNumber,0); QString def=getDef(cur); //int result=findNextToken(cur,QStringList(),false,true); // move to \begin{...} if(def.isEmpty()) { cur.endEditBlock(); return; // begin not found } //add col in definition QStringList defs=splitColDef(def); QString addCol="l"; if(cutBuffer){ addCol=pasteBuffer.takeFirst(); } def.clear(); if(afterColumn==0) def=addCol; for(int i=0;i<defs.count();i++){ def.append(defs[i]); if(i+1==afterColumn || (i+1==defs.count()&&i+1<afterColumn)) def.append(addCol); } cur.insertText(def); //continue adding col cur.movePosition(2,QDocumentCursor::Right); QString line; bool breakLoop=false; int result=2; while(!breakLoop){ for(int col=0;col<afterColumn;col++){ do{ result=findNextToken(cur,nTokens); }while(result==1); breakLoop=(result<0); // end of tabular reached (eof or \end) if(result<1) break; //end of tabular line reached } if(result==-1) break; //if last line before end, check whether the user was too lazy to put in a linebreak if(result==-2){ QDocumentCursor ch(cur); QStringList tokens("\\\\"); int res=findNextToken(ch,tokens,true,true); if(res==0){ ch.movePosition(2,QDocumentCursor::Right,QDocumentCursor::KeepAnchor); if(ch.selectedText().contains(QRegExp("^\\S+$"))) break; } } // add element if(result==2){ if(pasteBuffer.isEmpty()) { cur.insertText(" &"); }else{ if(afterColumn==0){ QDocumentCursor ch(cur); int res=findNextToken(ch,nTokens); cur.insertText(pasteBuffer.takeFirst()); if(res!=0){ cur.insertText("&"); } }else{ cur.insertText(pasteBuffer.takeFirst()+"&"); } } } if(result<=0){ int count= result==0 ? 2 : 1; cur.movePosition(count,QDocumentCursor::Left); if(pasteBuffer.isEmpty()) { cur.insertText("& "); }else{ cur.insertText("&"+pasteBuffer.takeFirst()); } } const QStringList tokens("\\\\"); breakLoop=(findNextToken(cur,tokens)==-1); // go over \hline if present QString text=cur.line().text(); int col=cur.columnNumber(); text=text.mid(col); QRegExp rxHL("^(\\s*\\\\hline\\s*)"); int pos_hline=rxHL.indexIn(text); if(pos_hline>-1){ int l=rxHL.cap().length(); cur.movePosition(l,QDocumentCursor::Right); } if(cur.atLineEnd()) cur.movePosition(1,QDocumentCursor::Right); line=cur.line().text(); if(line.contains("\\end{")) breakLoop=true; } cur.endEditBlock(); }
void LatexTables::removeColumn(QDocument *doc,const int lineNumber,const int column,QStringList *cutBuffer){ QDocumentCursor cur(doc); //preparations for search QStringList nTokens; nTokens << "\\\\" << "\\&" << "&"; cur.moveTo(lineNumber,0); QString def=getDef(cur); //int result=findNextToken(cur,QStringList(),false,true); // move to \begin{...} if(def.isEmpty()) { return; // begin not found } cur.beginEditBlock(); //remove col in definition QStringList defs=splitColDef(def); def.clear(); for(int i=0;i<defs.count();i++){ if(i==column){ if(cutBuffer) cutBuffer->append(defs[i]); }else{ def.append(defs[i]); } } if(def.isEmpty()){ cur.removeSelectedText(); }else{ cur.insertText(def); } cur.movePosition(2,QDocumentCursor::Right); // remove column QString line; bool breakLoop=false; while(!breakLoop){ int result=2; int off=0; for(int col=0;col<column;col++){ if(off>0) off--; cur.clearSelection(); QDocumentCursor oldCur(cur); do{ result=findNextToken(cur,nTokens,true); }while(result==1); QString selText=cur.selectedText(); if(selText.startsWith("\\multicolumn")){ int add=getNumOfColsInMultiColumn(selText); if(off==0) off=add; if(off>1) cur=oldCur; } breakLoop=(result<0); // end of tabular reached (eof or \end) if(result<1) break; //end of tabular line reached } cur.clearSelection(); if(result==-1) break; // add element if(result>0 || off){ do{ result=findNextToken(cur,nTokens,true); }while(result==1); QString selText=cur.selectedText(); int add=0; if(selText.startsWith("\\multicolumn")){ add=getNumOfColsInMultiColumn(selText); } if(add>1) { //multicolumn handling QStringList values; LatexParser::resolveCommandOptions(selText,0,values); values.takeFirst(); values.prepend(QString("{%1}").arg(add-1)); cur.movePosition(1,QDocumentCursor::Left,QDocumentCursor::KeepAnchor); if(result==0) cur.movePosition(1,QDocumentCursor::Left,QDocumentCursor::KeepAnchor); cur.insertText("\\multicolumn"+values.join("")); }else{ //normal handling if(result==2 && column>0) { cur.movePosition(1,QDocumentCursor::Left,QDocumentCursor::KeepAnchor); } if(result==0) { cur.movePosition(2,QDocumentCursor::Left,QDocumentCursor::KeepAnchor); } QString zw=cur.selectedText(); if(cutBuffer){ if(column==0 && result!=0) zw.chop(1); cutBuffer->append(zw); } // detect elements which need to be kept like \hline QString keep; if(column==0){ QStringList elementsToKeep; elementsToKeep << "\\hline" << "\\endhead" << "\\endfoot" << "\\endfirsthead" << "\\endlastfoot"; for(int i=0;i<zw.length();i++){ if(zw.at(i)=='\n') { if(!keep.endsWith('\n')) keep += "\n"; } //commands if(zw.at(i)=='\\') { QRegExp rx("\\w+"); rx.indexIn(zw,i+1); QString cmd="\\"+rx.cap(); if(elementsToKeep.contains(cmd)){ keep += " " + cmd; } } } if(keep.length()==1) keep.clear();; } cur.removeSelectedText(); if(column>0) { cur.movePosition(1,QDocumentCursor::Left,QDocumentCursor::KeepAnchor); cur.removeSelectedText(); } cur.insertText(keep); } const QStringList tokens("\\\\"); breakLoop=(findNextToken(cur,tokens)==-1); } if(cur.atLineEnd()) cur.movePosition(1,QDocumentCursor::Right); line=cur.line().text(); if(line.contains("\\end{")) breakLoop=true; } cur.endEditBlock(); }