1 // -*- C++ -*- 2 /** 3 * \file Counters.h 4 * This file is part of LyX, the document processor. 5 * Licence details can be found in the file COPYING. 6 * 7 * \author Lars Gullik Bjønnes 8 * \author Jean-Marc Lasgouttes 9 * \author John Levon 10 * \author Martin Vermeer 11 * 12 * Full author contact details are available in file CREDITS. 13 */ 14 15 #ifndef COUNTERS_H 16 #define COUNTERS_H 17 18 #include "OutputEnums.h" 19 20 #include "support/docstring.h" 21 22 #include <map> 23 #include <vector> 24 25 26 namespace lyx { 27 28 class Layout; 29 class Lexer; 30 31 /// This represents a single counter. 32 class Counter { 33 public: 34 /// 35 Counter(); 36 /// 37 Counter(docstring const & mc, docstring const & ls, 38 docstring const & lsa); 39 /// \return true on success 40 bool read(Lexer & lex); 41 /// 42 void set(int v); 43 /// 44 void addto(int v); 45 /// 46 int value() const; 47 /// 48 void step(); 49 /// 50 void reset(); 51 /// Returns the master counter of this counter. 52 docstring const & master() const; 53 /// Checks if the master counter is cnt, and if so removes 54 /// it. This is used when a counter is deleted. 55 /// \return whether we removed the master. 56 bool checkAndRemoveMaster(docstring const & cnt); 57 /// Returns a LaTeX-like string to format the counter. 58 /** This is similar to what one gets in LaTeX when using 59 * "\the<counter>". The \c in_appendix bool tells whether we 60 * want the version shown in an appendix. 61 */ 62 docstring const & labelString(bool in_appendix) const; 63 /// Similar, but used for formatted references in XHTML output. 64 /// E.g., for a section counter it might be "section \thesection" prettyFormat()65 docstring const & prettyFormat() const { return prettyformat_; } 66 67 /// Returns a map of LaTeX-like strings to format the counter. 68 /** For each language, the string is similar to what one gets 69 * in LaTeX when using "\the<counter>". The \c in_appendix 70 * bool tells whether we want the version shown in an 71 * appendix. This version does not contain any \\the<counter> 72 * expression. 73 */ 74 typedef std::map<std::string, docstring> StringMap; 75 StringMap & flatLabelStrings(bool in_appendix) const; 76 private: 77 /// 78 int value_; 79 /// This is actually one less than the initial value, since the 80 /// counter is always stepped before being used. 81 int initial_value_; 82 /// contains master counter name. 83 /** The master counter is the counter that, if stepped 84 * (incremented) zeroes this counter. E.g. "subsection"'s 85 * master is "section". 86 */ 87 docstring master_; 88 /// Contains a LaTeX-like string to format the counter. 89 docstring labelstring_; 90 /// The same as labelstring_, but in appendices. 91 docstring labelstringappendix_; 92 /// Similar, but used for formatted references in XHTML output 93 docstring prettyformat_; 94 /// Cache of the labelstring with \\the<counter> expressions expanded, 95 /// indexed by language 96 mutable StringMap flatlabelstring_; 97 /// Cache of the appendix labelstring with \\the<counter> expressions expanded, 98 /// indexed by language 99 mutable StringMap flatlabelstringappendix_; 100 }; 101 102 103 /// This is a class of (La)TeX type counters. 104 /// Every instantiation is an array of counters of type Counter. 105 class Counters { 106 public: 107 /// NOTE Do not call this in an attempt to clear the counters. 108 /// That will wipe out all the information we have about them 109 /// from the document class (e.g., which ones are defined). 110 /// Instead, call Counters::reset(). 111 Counters(); 112 /// Add new counter newc having masterc as its master, 113 /// ls as its label, and lsa as its appendix label. 114 void newCounter(docstring const & newc, 115 docstring const & masterc, 116 docstring const & ls, 117 docstring const & lsa); 118 /// Checks whether the given counter exists. 119 bool hasCounter(docstring const & c) const; 120 /// reads the counter name 121 /// \param makeNew whether to make a new counter if one 122 /// doesn't already exist 123 /// \return true on success 124 bool read(Lexer & lex, docstring const & name, bool makenew); 125 /// 126 void set(docstring const & ctr, int val); 127 /// 128 void addto(docstring const & ctr, int val); 129 /// 130 int value(docstring const & ctr) const; 131 /// Reset recursively all the counters that are slaves of the one named by \c ctr. 132 void resetSlaves(docstring const & ctr); 133 /// Increment by one master of counter named by \c ctr. 134 /// This also resets the counter named by \c ctr. 135 /// \param utype determines whether we track the counters. 136 void stepMaster(docstring const & ctr, UpdateType utype); 137 /// Increment by one counter named by \c ctr, and zeroes slave 138 /// counter(s) for which it is the master. 139 /// \param utype determines whether we track the counters. 140 void step(docstring const & ctr, UpdateType utype); 141 /// Reset all counters, and all the internal data structures 142 /// used for keeping track of their values. 143 void reset(); 144 /// Reset counters matched by match string. 145 void reset(docstring const & match); 146 /// Remove counter \p cnt. 147 bool remove(docstring const & cnt); 148 /// Copy counters whose name matches match from the &from to 149 /// the &to array of counters. Empty string matches all. 150 void copy(Counters & from, Counters & to, 151 docstring const & match = docstring()); 152 /** returns the expanded string representation of counter \c 153 * c. The \c lang code is used to translate the string. 154 */ 155 docstring theCounter(docstring const & c, 156 std::string const & lang) const; 157 /** Replace in \c format all the LaTeX-like macros that depend 158 * on counters. The \c lang code is used to translate the 159 * string. 160 */ 161 docstring counterLabel(docstring const & format, 162 std::string const & lang) const; 163 /// returns a formatted version of the counter, using the 164 /// format given by Counter::prettyFormat(). 165 docstring prettyCounter(docstring const & cntr, 166 std::string const & lang) const; 167 /// Are we in appendix? appendix()168 bool appendix() const { return appendix_; } 169 /// Set the state variable indicating whether we are in appendix. appendix(bool a)170 void appendix(bool a) { appendix_ = a; } 171 /// Returns the current enclosing float. current_float()172 std::string const & current_float() const { return current_float_; } 173 /// Sets the current enclosing float. current_float(std::string const & f)174 void current_float(std::string const & f) { current_float_ = f; } 175 /// Are we in a subfloat? isSubfloat()176 bool isSubfloat() const { return subfloat_; } 177 /// Set the state variable indicating whether we are in a subfloat. isSubfloat(bool s)178 void isSubfloat(bool s) { subfloat_ = s; } 179 /// Are we in a longtable? isLongtable()180 bool isLongtable() const { return longtable_; } 181 /// Set the state variable indicating whether we are in a longtable. isLongtable(bool s)182 void isLongtable(bool s) { longtable_ = s; } 183 184 /// \name refstepcounter 185 // @{ 186 /// The currently active counter, so far as references go. 187 /// We're trying to track \refstepcounter in LaTeX, more or less. 188 /// Note that this may be empty. 189 docstring currentCounter() const; 190 /// Called during updateBuffer() as we go through various paragraphs, 191 /// to track the layouts as we go through. 192 void setActiveLayout(Layout const & lay); 193 /// Also for updateBuffer(). 194 /// Call this when entering things like footnotes, where there is now 195 /// no "last layout" and we want to restore the "last layout" on exit. clearLastLayout()196 void clearLastLayout() { layout_stack_.push_back(0); } 197 /// Call this when exiting things like footnotes. restoreLastLayout()198 void restoreLastLayout() { layout_stack_.pop_back(); } 199 /// saveLastCounter()200 void saveLastCounter() 201 { counter_stack_.push_back(counter_stack_.back()); } 202 /// restoreLastCounter()203 void restoreLastCounter() { counter_stack_.pop_back(); } 204 // @} 205 private: 206 /** expands recursively any \\the<counter> macro in the 207 * labelstring of \c counter. The \c lang code is used to 208 * translate the string. 209 */ 210 docstring flattenLabelString(docstring const & counter, bool in_appendix, 211 std::string const &lang, 212 std::vector<docstring> & callers) const; 213 /// Returns the value of the counter according to the 214 /// numbering scheme numbertype. 215 /** Available numbering schemes are arabic (1, 2,...), roman 216 * (i, ii,...), Roman (I, II,...), alph (a, b,...), Alpha (A, 217 * B,...) and hebrew. 218 */ 219 docstring labelItem(docstring const & ctr, 220 docstring const & numbertype) const; 221 /// Used for managing the counter_stack_. 222 // @{ 223 void beginEnvironment(); 224 void endEnvironment(); 225 // @} 226 /// Maps counter (layout) names to actual counters. 227 typedef std::map<docstring, Counter> CounterList; 228 /// Instantiate. 229 CounterList counterList_; 230 /// Are we in an appendix? 231 bool appendix_; 232 /// The current enclosing float. 233 std::string current_float_; 234 /// Are we in a subfloat? 235 bool subfloat_; 236 /// Are we in a longtable? 237 bool longtable_; 238 /// Used to keep track of active counters. 239 std::vector<docstring> counter_stack_; 240 /// Same, but for last layout. 241 std::vector<Layout const *> layout_stack_; 242 }; 243 244 } // namespace lyx 245 246 #endif 247