1 // -*- C++ -*- 2 /** 3 * \file texstream.h 4 * This file is part of LyX, the document processor. 5 * Licence details can be found in the file COPYING. 6 * 7 * \author Enrico Forestieri 8 * 9 * Full author contact details are available in file CREDITS. 10 */ 11 12 #ifndef LYX_TEXSTREAM_H 13 #define LYX_TEXSTREAM_H 14 15 #include "support/docstream.h" 16 #include "support/unique_ptr.h" 17 18 namespace lyx { 19 20 class TexRow; 21 struct TexString; 22 23 24 /** Wrapper class for odocstream. 25 This class is used to automatically count the lines of the exported latex 26 code. 27 */ 28 29 class otexrowstream { 30 public: 31 /// 32 explicit otexrowstream(odocstream & os); 33 /// defaulted 34 ~otexrowstream(); 35 /// os()36 odocstream & os() { return os_; } 37 /// texrow()38 TexRow & texrow() { return *texrow_; } 39 /// 40 unique_ptr<TexRow> releaseTexRow(); 41 /// 42 void put(char_type const & c); 43 /// 44 void append(TexString ts); 45 private: 46 /// 47 odocstream & os_; 48 /// 49 unique_ptr<TexRow> texrow_; 50 }; 51 52 /// 53 otexrowstream & operator<<(otexrowstream &, odocstream_manip); 54 /// 55 otexrowstream & operator<<(otexrowstream &, TexString); 56 /// 57 otexrowstream & operator<<(otexrowstream &, docstring const &); 58 /// 59 otexrowstream & operator<<(otexrowstream &, std::string const &); 60 /// 61 otexrowstream & operator<<(otexrowstream &, char const *); 62 /// 63 otexrowstream & operator<<(otexrowstream &, char); 64 /// 65 template <typename Type> 66 otexrowstream & operator<<(otexrowstream & ots, Type value); 67 68 69 /** Subclass for otexrowstream. 70 This class is used to ensure that no blank lines may be inadvertently output. 71 To this end, use the special variables "breakln" and "safebreakln" as if 72 they were iomanip's to ensure that the next output will start at the 73 beginning of a line. Using "breakln", a '\n' char will be output if needed, 74 while using "safebreakln", "%\n" will be output if needed. 75 The class also records the last output character and can tell whether 76 a paragraph break was just output. 77 */ 78 79 class otexstream : public otexrowstream { 80 public: 81 /// otexstream(odocstream & os)82 explicit otexstream(odocstream & os) 83 : otexrowstream(os), canbreakline_(false), 84 protectspace_(false), terminate_command_(false), 85 parbreak_(true), blankline_(true), lastchar_(0) {} 86 /// 87 void put(char_type const & c); 88 /// 89 void append(TexString ts); 90 /// canBreakLine(bool breakline)91 void canBreakLine(bool breakline) { canbreakline_ = breakline; } 92 /// canBreakLine()93 bool canBreakLine() const { return canbreakline_; } 94 /// protectSpace(bool protectspace)95 void protectSpace(bool protectspace) { protectspace_ = protectspace; } 96 /// protectSpace()97 bool protectSpace() const { return protectspace_; } 98 /// terminateCommand(bool terminate)99 void terminateCommand(bool terminate) { terminate_command_ = terminate; } 100 /// terminateCommand()101 bool terminateCommand() const { return terminate_command_; } 102 /// lastChar(char_type const & c)103 void lastChar(char_type const & c) 104 { 105 parbreak_ = (!canbreakline_ && c == '\n'); 106 blankline_ = ((!canbreakline_ && c == ' ') || c == '\n'); 107 canbreakline_ = (c != '\n'); 108 lastchar_ = c; 109 } 110 /// lastChar()111 char_type lastChar() const { return lastchar_; } 112 /// afterParbreak()113 bool afterParbreak() const { return parbreak_; } 114 /// blankLine()115 bool blankLine() const { return blankline_; } 116 private: 117 /// 118 bool canbreakline_; 119 /// 120 bool protectspace_; 121 /// 122 bool terminate_command_; 123 /// 124 bool parbreak_; 125 /// 126 bool blankline_; 127 /// 128 char_type lastchar_; 129 }; 130 131 132 /// because we need to pass ods_ to the base class 133 struct otexstringstream_helper { odocstringstream ods_; }; 134 135 /// otexstringstream : a odocstringstream with tex/row correspondence 136 class otexstringstream : otexstringstream_helper, public otexstream { 137 public: otexstringstream()138 otexstringstream() : otexstringstream_helper(), otexstream(ods_) {} 139 /// str()140 docstring str() const { return ods_.str(); } 141 /// 142 size_t length(); 143 /// empty()144 bool empty() { return 0 == length(); } 145 /// move-returns the contents and reset the texstream 146 TexString release(); 147 }; 148 149 150 /// Helper structs for breaking a line 151 struct BreakLine { 152 char n; 153 }; 154 155 struct SafeBreakLine { 156 char n; 157 }; 158 159 /// Helper structs for terminating a command 160 struct TerminateCommand { 161 char n; 162 }; 163 164 extern BreakLine breakln; 165 extern SafeBreakLine safebreakln; 166 extern TerminateCommand termcmd; 167 168 /// 169 otexstream & operator<<(otexstream &, BreakLine); 170 /// 171 otexstream & operator<<(otexstream &, SafeBreakLine); 172 /// 173 otexstream & operator<<(otexstream &, TerminateCommand); 174 /// 175 otexstream & operator<<(otexstream &, odocstream_manip); 176 /// 177 otexstream & operator<<(otexstream &, TexString); 178 /// 179 otexstream & operator<<(otexstream &, docstring const &); 180 /// 181 otexstream & operator<<(otexstream &, std::string const &); 182 /// 183 otexstream & operator<<(otexstream &, char const *); 184 /// 185 otexstream & operator<<(otexstream &, char); 186 /// 187 template <typename Type> 188 otexstream & operator<<(otexstream & ots, Type value); 189 190 191 } // namespace lyx 192 193 #endif 194