/*************************************************************************** codegenerator.h - description ------------------- copyright : (C) 2007-2021 by Andre Simon email : a.simon@mailbox.org ***************************************************************************/ /* This file is part of ANSIFilter. ANSIFilter 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 3 of the License, or (at your option) any later version. ANSIFilter 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 ANSIFilter. If not, see . */ #ifndef CODEPARSER_H #define CODEPARSER_H #include #include #include #include #include // Avoid problems with isspace and UTF-8 characters, use iswspace instead //#include #include #include "elementstyle.h" #include "enums.h" #include "stringtools.h" /// The ansifilter namespace contains all classes and data structures needed for parsing input data. namespace ansifilter { /** TheDraw output information of individual characters*/ struct TDChar { unsigned char c; ElementStyle style; }; class StyleInfo { public: /// Constructor StyleInfo() : fgColor ( "" ), bgColor ( "" ), isBold (false),isItalic (false),isConcealed (false), isBlink (false), isUnderLine (false) { } /// Constructor StyleInfo ( const string& fgc, const string& bgc, bool b, bool i, bool c, bool blink, bool ul ) : fgColor ( fgc ), bgColor ( bgc ),isBold ( b ), isItalic ( i ), isConcealed ( c ), isBlink (blink), isUnderLine (ul) { } /// Copy Constructor StyleInfo ( const StyleInfo& other ) { fgColor = other.fgColor; bgColor = other.bgColor; isItalic = other.isItalic; isBold = other.isBold; isConcealed=other.isConcealed; isBlink = other.isBlink; isUnderLine = other.isUnderLine; } /// Operator overloading StyleInfo& operator= ( const StyleInfo & other ) { fgColor = other.fgColor; bgColor = other.bgColor; isItalic = other.isItalic; isBold = other.isBold; isConcealed=other.isConcealed; isBlink = other.isBlink; isUnderLine = other.isUnderLine; return *this; } bool operator==(const StyleInfo& r) { return this->fgColor==r.fgColor && this->bgColor==r.bgColor && this->isBold==r.isBold && this->isItalic==r.isItalic && this->isConcealed==r.isConcealed && this->isBlink==r.isBlink && this->isUnderLine==r.isUnderLine; } ~StyleInfo() { } string fgColor; ///< foreground color string bgColor; ///< background color bool isBold, isItalic, isConcealed, isBlink, isUnderLine; ///< style properties }; /** \brief Base class for escape sequence parsing. The virtual class provides escape sequence parsing functionality.
The derived classes have to define the output format.
Codegenerator is a singleton class. * @author Andre Simon */ class CodeGenerator { public: virtual ~CodeGenerator(); /** Get appropriate Codegenerator instance \param type Output file type (TEXT, PANGO, HTML, RTF, LATEX, TEX) */ static CodeGenerator* getInstance(OutputType type); /** Delete Codegenerator instance (this is intended for SWIG integration, in normal C++ code the result should be saved in an auto_ptr) \param CodeGenerator* CodeGenerator instance */ static void deleteInstance(CodeGenerator* inst) { if (inst) delete inst; } /** Generates output file \param inFileName Path of input file (if empty use stdin) \param outFileName Path of output file (if empty use stdout) \return ParseError */ ParseError generateFile(const string &inFileName, const string &outFileName); /** Generates output string from input string \param input input code string \return formatted output code */ string generateString(const string &input); /** Generates output string from input file \param inFileName file path \return formatted output code */ string generateStringFromFile(const string &inFileName); /** Generates output file from input string \param sourceStr input string \param outFileName output file path \param title document title \return formatted output code */ ParseError generateFileFromString (const string &sourceStr, const string &outFileName, const string &title); /** Generate a stylesheet with the styles found in the document \param outPath Output path \return true if successful */ virtual bool printDynamicStyleFile ( const string &outPath ); /** Overrides default colours by user defined values; resets palette to default if mapPath is empty \param mapPath path of map file \return true if parsing was successful */ bool setColorMap(const string& mapPath); /** tell parser to omit document header and footer \param flag true if output should be fragmented */ void setFragmentCode(bool flag); /** \return fragment flag */ bool getFragmentCode(); /** tell parser to use this font as base font \param s the font name, e.g. "Courier New" */ void setFont(const string& s); /** \return base font */ const string getFont() const ; /** tell parser to use this size as base font size \param s the font size, e.g. "12" */ void setFontSize(const string& s); /** \return base font size*/ const string getFontSize(); /** Set encloding \param encodingName encoding name */ void setEncoding(const string& encodingName); /** \param title Document title */ void setTitle(const string & title); /** \return Document title */ string getTitle(); /** \param path style sheet path*/ void setStyleSheet(const string & path); /** \param b set to true if text formatting should be stripped */ void setPlainOutput(bool b) { ignoreFormatting=b; } /** \param b set to true if HTML anchors should be added to line numbers */ void setAddAnchors(bool b, bool self=false) { addAnchors=b; addFunnyAnchors=self; } /** \param b set to true if the input stream is not closed after reaching EOF */ void setContinueReading(bool b) { readAfterEOF=b; } /** \param b set to true if the output should not be terminated with EOL*/ void setOmitTrailingCR(bool b) { omitTrailingCR=b; } /** \param b set to true if the output should not contain a version info comment*/ void setOmitVersionInfo(bool b) { omitVersionInfo=b; } /** \return plain outputting flag */ bool getPlainOutput() { return ignoreFormatting; } /** \return continue reading from input stream flag */ bool getContinueReading() { return readAfterEOF; } /** \param lineWrappingStyle wrapping style \param lineLength maximum length per wrapped text line */ void setPreformatting ( WrapMode lineWrappingStyle,unsigned int lineLength); /** \param b set to true if line numbers should be added */ void setShowLineNumbers(bool flag); /** \param b set to true if line numbers of wrapped lines should be omitted */ void setWrapNoNumbers(bool flag); /** \param b set to true if input is ASCII art codepage 437 file */ void setParseCodePage437(bool flag); /** \param b set to true if input is an ASCII art BIN file*/ void setParseAsciiBin(bool flag); /** \param b set to true if input is an Tundra art BIN file*/ void setParseAsciiTundra(bool flag); /** \param b set to true if K clear sequences should be ignored*/ void setIgnoreClearSeq(bool flag); /** \param b set to true if CSI sequences should be ignored*/ void setIgnoreCSISeq(bool flag); /** \param b set dimensions of ASCII art virtual console */ void setAsciiArtSize(int width, int height); /** tell parser to use dynamic stylesheets derived from the document's formatting \param flag true */ void setApplyDynStyles(bool flag); /** Set SVG dimensions \param w page width \param h page height */ void setSVGSize ( const string& w, const string& h ); protected: /** \param type Output type */ CodeGenerator(ansifilter::OutputType type); CodeGenerator() {} /** \param c Character to be masked \return Escape sequence of output format */ virtual string maskCharacter(unsigned char c) = 0; /** \param c Character to be masked \return Codepage 437 escape sequence of output format */ virtual string maskCP437Character(unsigned char c) { return maskCharacter(c); } /** \param uri URI * \param txt Description \return returns link formatting sequence */ virtual string getHyperlink(string uri, string txt) { return txt+"["+uri+"]"; } /** Tag for inserting line feeds*/ string newLineTag; /** SVG document dimensions */ string width, height; /** file input*/ istream *in; /** file output*/ ostream *out; /** line buffer*/ ostringstream lineBuf; bool tagIsOpen; ///< a reminder to close an open tag string styleCommentOpen, ///< open comment delimiter styleCommentClose; ///< close comment delimiter /** Encoding name */ string encoding; /** Encoding name */ string docTitle; string spacer; /** Test if header and footer should be omitted */ bool fragmentOutput; /** The base font to use */ string font ; /** The base font size to use */ string fontSize ; /** Style sheet path */ string styleSheetPath; /** Width of line numbers */ unsigned int lineNumberWidth; /** Current line number */ unsigned int lineNumber; bool showLineNumbers, ///< show line numbers numberWrappedLines, ///< also show number of wrapped lines numberCurrentLine, ///< output number of current line addAnchors, ///< add HTML anchor to line number addFunnyAnchors, ///< add HTML links to themselves applyDynStyles; ///< insert dynamic style references instead of inline styles bool omitVersionInfo; ///< do not print version info comment bool parseCP437; ///< treat input as CP437 file bool parseAsciiBin; ///< treat input as BIN or XBIN file bool parseAsciiTundra; ///< treat input as Tundra file /** Processes input data */ void processInput(); virtual void insertLineNumber (); /** \return true id encoding is defined */ bool encodingDefined() { return StringTools::lowerCase(encoding)!="none"; } /** convert a rgb triple to HTML color notation @param rgb RGB input values @return HTML color string */ string rgb2html(unsigned char* rgb); string rgb2html(int r, int g, int b); /// 16 basic colors static unsigned char workingPalette[16][3]; static unsigned char defaultPalette[16][3]; ElementStyle elementStyle; vector documentStyles; private: CodeGenerator(const CodeGenerator&) {} CodeGenerator& operator=(CodeGenerator&) { return *this; } /** parses string to extract ANSI sequence information @param line text line @param begin starting position within line @param end ending position within line @return true if sequence was recognized */ bool parseSGRParameters(const string& line, size_t begin, size_t end); /** parses Codepage 437 sequence information @param line text line @param begin starting position within line @param end ending position within line */ void parseCodePage437Seq(string line, size_t begin, size_t end); /** Prints document footer @return footer */ virtual string getFooter() = 0; /** Prints document body*/ virtual void printBody() = 0; /** Prints document header @return header */ virtual string getHeader() = 0; /** Resets parser to origin state, call this after every file conversion */ void reset(); /** Output format type*/ OutputType outputType; virtual string getOpenTag() = 0; ///< returns opening formatting sequence virtual string getCloseTag() = 0; ///< returns closing formatting sequence bool ignoreFormatting; ///< ignore color and font face information bool readAfterEOF; ///< continue reading after EOF occoured bool omitTrailingCR; ///< do not print EOL at the end of output bool ignClearSeq; ///< ignore clear sequence ESC K bool ignCSISeq; ///< ignore CSIs (may interfere with UTF-8 input) TDChar* termBuffer; int curX, curY, memX, memY, maxY; ///< cursor position for Codepage 437 sequences int asciiArtWidth; ///< virtual console column count int asciiArtHeight; ///< virtual console line count unsigned int lineWrapLen; ///< max line length before wrapping ElementStyle memStyle; /** clear line buffer */ void printNewLine(bool eof=false); /** convert an xterm color value (0-253) to 3 unsigned chars rgb @param color xterm color @param rgb RGB output values */ void xterm2rgb(unsigned char color, unsigned char* rgb); /**Print content of virtual terminal buffer. Deletes buffer. */ void printTermBuffer(); /**Parses BIN ASCII art file */ void parseBinFile(); /**Parses XBIN ASCII art file */ void parseXBinFile(); /**Parses Tundra ASCII art file */ void parseTundraFile(); /**allocate virtual terminal buffer */ void allocateTermBuffer(); /** @return true if stream begins with XBIN id */ bool streamIsXBIN(); /** @return true if stream begins with Tundra id */ bool streamIsTundra(); /// the 6 value iterations in the xterm color cube static const unsigned char valuerange[] ; }; } #endif