/* XML parser for help files - used for 10thkingdom.net Copyright (C) 2005 Mark Loeser This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include using namespace xercesc; class helpHandler : public DefaultHandler { private: std::ofstream _output; bool _service, _command, _name, _syntax, _li, _desc, _context, _sample, _heading, _body; void _clense(std::string&,bool=false,bool=false); public: helpHandler(std::string file) : _output(file.c_str()), _service(false), _command(false), _name(false), _syntax(false), _li(false), _desc(false), _context(false), _sample(false), _heading(false), _body(false) {} void startElement(const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname, const Attributes& attrs); void endElement(const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname); void characters(const XMLCh *const chars, const unsigned int length); void error(const SAXParseException&); void fatalError(const SAXParseException&); ~helpHandler() { _output.close(); } }; void helpHandler::startElement(const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname, const Attributes& attrs) { char *message = XMLString::transcode(localname); if(std::strcmp(message, "service") == 0) { _output << "--- \00210thKingdom "; _service = true; } else if(std::strcmp(message, "command") == 0) { _command = true; } else if(_command && std::strcmp(message, "name") == 0) { _name = true; } else if(_command && std::strcmp(message, "syntax") == 0) { _output << " \002SYNTAX:\002" << std::endl; _syntax = true; } else if(std::strcmp(message, "li") == 0) { _li = true; _output << " "; } else if(std::strcmp(message, "desc") == 0) { _desc = true; _output << " \002DESCRIPTION:\002" << std::endl; } else if(std::strcmp(message, "examples") == 0) { _output << " \002EXAMPLES:\002" << std::endl; } else if(std::strcmp(message, "context") == 0) { _context = true; } else if(std::strcmp(message, "sample") == 0) { _sample = true; } else if(std::strcmp(message, "heading") == 0) { _heading = true; } else if(std::strcmp(message, "body") == 0) { _body = true; } XMLString::release(&message); } void helpHandler::endElement(const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname) { char *message = XMLString::transcode(localname); if(std::strcmp(message,"help") == 0) { _output << std::endl << "--- \002End of Services Help\002 ---" << std::endl; } else if(std::strcmp(message, "command") == 0) { _command = false; } else if(std::strcmp(message, "syntax") == 0) { _syntax = false; _output << std::endl; } else if(std::strcmp(message, "li") == 0) { _li = false; _output << std::endl; } XMLString::release(&message); } void helpHandler::characters(const XMLCh *const chars, const unsigned int length) { char *message = XMLString::transcode(chars); std::string m = message; int x; if(_service) { _clense(m); if(m == "ChanServ") _output << "Channel "; _output << "Services Help\002 ---" << std::endl << std::endl; _service = false; } else if(_name) { _clense(m); _output << " === \002" << m << "\002 ===" << std::endl << std::endl; _name = false; } else if(_li && _syntax) { _clense(m,true); _output << m; } else if(_desc) { _clense(m,false,true); int x,curr; for(x=0, curr=0; curr < m.length(); ++curr) { if(m[curr] == '\n') { _output << " " << m.substr(x, curr-x+1); x = curr + 1; } } _output << " " << m.substr(x, curr-x+1) << std::endl << std::endl; _desc = false; } else if(_context) { _clense(m,false,true); int x,curr; for(x=0, curr=0; curr < m.length(); ++curr) { if(m[curr] == '\n') { _output << " " << m.substr(x, curr-x+1); x = curr + 1; } } _output << " " << m.substr(x, curr-x+1) << std::endl; _context = false; } else if(_sample) { _clense(m); _output << " " << m << std::endl; _sample = false; } else if(_heading) { _clense(m); _output << " \002" << m << ":\002" << std::endl; _heading = false; } else if(_body) { _clense(m,false,true); int x,curr; for(x=0, curr=0; curr < m.length(); ++curr) { if(m[curr] == '\n') { _output << " " << m.substr(x, curr-x+1); x = curr + 1; } } _output << " " << m.substr(x, curr-x+1) << std::endl << std::endl; _body = false; } XMLString::release(&message); } void helpHandler::error(const SAXParseException &exception) { char* message = XMLString::transcode(exception.getMessage()); std::cout << "Error: " << message << " at line: " << exception.getLineNumber() << std::endl; xercesc::XMLString::release(&message); throw exception; } void helpHandler::fatalError(const SAXParseException &exception) { char* message = XMLString::transcode(exception.getMessage()); std::cout << "Fatal Error: " << message << " at line: " << exception.getLineNumber() << std::endl; xercesc::XMLString::release(&message); throw exception; } void helpHandler::_clense(std::string &s, bool preserveEnd, bool preserveNL) { int y; for(y=0; y < s.length()-1 && std::isspace(s[y]); ++y); s = s.substr(y, s.length()-y); if(!preserveEnd) { for(y=s.length()-1; y > 0 && std::isspace(s[y]); --y); s = s.substr(0, y+1); } else { if(s[s.length()-1] == '\n') s = s.substr(0, s.length()-1); } for(int x=0; x < s.length()-1; ++x) { if(s[x] == '\t') { s.replace(x,1," "); while(std::isspace(s[x])) --x; } else if(preserveNL && s[x] == ' ' && s[x+1] == ' ') { s.erase(x,1); --x; } else if(!preserveNL && std::isspace(s[x]) && std::isspace(s[x+1])) { s.erase(x,1); --x; } else if(preserveNL && s[x] == '\n' && s[x+1] == ' ') { s.erase(x+1,1); } } }