/* a basic c(++) code to rtf converter John Donoghue, 1999. uses singleton patterns This code is released under the GPL licencing agreement. See www.gnu.org for the current licence. FIX: return and default werenot showing as keywords */ #include #include #include #define NORMALSTYLE "\\plain\\cf0\\fs20 " #define BROWNSTYLE "\\plain\\cf1\\fs20 " #define GREENSTYLE "\\plain\\cf2\\fs20 " #define GREYITALICSTYLE "\\plain\\cf3\\i\\fs20 " #define BLUESTYLE "\\plain\\cf4\\fs20 " #define BOLDSTYLE "\\plain\\cf0\\b\\fs20 " #define MAX_BUFF 2048 /* check if the character is withing a array of chars */ bool IsIn(char c,char *check,int size) { for(int i=0;i=MAX_BUFF) // flush if full flushBuffer(); statebuff[currpos]=c; currpos++; //} lastchar2=lastchar; lastchar=c; } char killLastChar() { if(currpos==0) return 0; currpos--; return statebuff[currpos]; } virtual CState *addChar(CState *curr,char c); }; int CState::currpos=0; //Style CState::currstyle=NORMAL; char CState::lastchar=0; char CState::lastchar2=0; char CState::statebuff[MAX_BUFF]; class InitState : public CState { private: InitState() {} public: static CState *getState(CState *curr) { static InitState state; // write out the required stuff std::cout<<"{\\rtf1\\ansi\\ansicpg1252\\deff0\n"; std::cout<<"{\\fonttbl\n"; std::cout<<"{\\f0\\fnil\\fcharset0\\fprq0\\fttruetype Courier;}}\n"; std::cout<<"{\\colortbl\n"; std::cout<<"\\red0\\green0\\blue0;\\red200\\green60\\blue60;"; std::cout<<"\\red0\\green160\\blue0;\\red120\\green40\\blue40;"; std::cout<<"\\red0\\green0\\blue255;\\red100\\green0\\blue100;}\n"; std::cout<<"\\f0\\fs20\n"; return (CState *)&state; } virtual CState *addChar(CState *curr,char c); }; class EndState : public CState { private: EndState() {} public: static CState *getState(CState *curr) { // write out the required stuff if(curr) curr->flushBuffer(); std::cout<<"}\n"; return (CState *)NULL; } // always end with NULL state virtual CState *addChar(CState *curr,char c) { return NULL; } }; class NewLineState : public CState { private: NewLineState() {} public: static CState *getState(CState *curr) { static NewLineState state; if(curr!=&state) { //cerr<<"** newline state **\n"; if(curr) curr->flushBuffer(); } // write out the required stuff return (CState *)&state; } // always end with NULL state virtual CState *addChar(CState *curr,char c); }; class NormalState : public CState { private: NormalState() {} public: static CState *getState(CState *curr) { static NormalState state; if(curr!=&state) { //cerr<<"** normal state **\n"; if(curr) curr->flushBuffer(); std::cout<flushBuffer(); std::cout<flushBuffer(); std::cout<flushBuffer(); std::cout<flushBuffer(); std::cout<flushBuffer(); std::cout<flushBuffer(); std::cout<addChar(currstate,c); return true; } }; int main() { char c; CtoRTF formatter; std::cin.get(c); while(!std::cin.eof()) { //std::cout<addChar(curr,c); } CState *InitState::addChar(CState *curr,char c) { // we are in init state - got to newline state since we start // on a new line CState *temp=NewLineState::getState(curr); return temp->addChar(curr,c); } CState *NewLineState::addChar(CState *curr,char c) { // we are in newline state // if c is not a newline or space char - go into normal mode if(c=='#') { // a leading # - preprocessor command? CState *temp=PreState::getState(curr); return temp->addChar(temp,c); } else if(!IsSpace(c)) { CState *temp=NormalState::getState(curr); return temp->addChar(curr,c); } else putChar(c); return this; } CState *NormalState::addChar(CState *curr,char c) { if(c=='*' && getLastChar()=='/') // start of block comment { killLastChar(); // remove last char from the buff curr=BlockCommentState::getState(curr); curr=curr->addChar(curr,'/'); curr=curr->addChar(curr,'*'); return curr; } else if(c=='/' && getLastChar()=='/') // start of line comment { killLastChar(); // remove last char from the buff curr=LineCommentState::getState(curr); curr=curr->addChar(curr,'/'); curr=curr->addChar(curr,'/'); return curr; } else if(c=='\"') // start of string comment { curr=StringState::getState(curr); curr->putChar('\"'); return curr; } else if(c=='\'') // start of string comment { curr=QuoteState::getState(curr); curr->putChar('\''); return curr; } else if((c>='0' && c<='9') && IsDelim(getLastChar())) // start of number { //cerr<<"add a number\n"; curr=NumberState::getState(curr); curr=curr->addChar(curr,c); return curr; } else if(c=='\n' || c=='\r') { putChar(c); curr=NewLineState::getState(curr); return curr; } else putChar(c); return this; } CState *LineCommentState::addChar(CState *curr,char c) { // end of line - end of comment putChar(c); if(c=='\n' || c=='\r') { curr=NewLineState::getState(curr); return curr; } return (CState *)this; } CState *BlockCommentState::addChar(CState *curr,char c) { // end of comment block putChar(c); if(c=='/' && get2ndLastChar()=='*') { curr=NormalState::getState(curr); return curr; } return (CState *)this; } CState *StringState::addChar(CState *curr,char c) { // end of comment block if(c=='\"' && getLastChar()!=0) { // if we have \\" //if((getLastChar()!='\\') || // (getLastChar()=='\\' && get2ndLastChar()!='\\')) //{ putChar(c); curr=NormalState::getState(curr); return curr; //} } putChar(c); return (CState *)this; } CState *QuoteState::addChar(CState *curr,char c) { if(c=='\'' && getLastChar()!=0 && (getLastChar()!='\\' || (getLastChar()=='\\' && get2ndLastChar()=='\\'))) { putChar(c); curr=NormalState::getState(curr); return curr; } putChar(c); return (CState *)this; } CState *NumberState::addChar(CState *curr,char c) { if(!IsNumber(c)) { curr=NormalState::getState(curr); curr->addChar(curr,c); return curr; } putChar(c); return (CState *)this; } CState *PreState::addChar(CState *curr,char c) { // end of line - pre-processsor stuff? putChar(c); if(c=='\n' || c=='\r') { curr=NewLineState::getState(curr); return curr; } return (CState *)this; } void NormalState::flushBuffer() { bool bold=false; char c; if(currpos>0) { int i,x; statebuff[currpos]='\0'; for(i=0;i0 && (i==0 || IsDelim(statebuff[i-1]))) { // a reserved word found int n; if(!bold) std::cout<0) { int i; for(i=0;i