]> git.lyx.org Git - lyx.git/commitdiff
Fix bug 5316 properly. The fix is to make the routine that reads a counter
authorRichard Heck <rgheck@comcast.net>
Mon, 6 Oct 2008 14:37:28 +0000 (14:37 +0000)
committerRichard Heck <rgheck@comcast.net>
Mon, 6 Oct 2008 14:37:28 +0000 (14:37 +0000)
update an existing counter rather than overwrite it.

This turns out to be more complicated than it might seem. There are two
large parts to the patch. One moves the counter read routine out of TextClass
and into the Counter and Counters classes. The other changes the syntax of
counters from:
Counter
Name whatever
....
to:
Counter whatever
....
This allows us to get the name of the counter right away, so we can decide
whether it is an old one or a new one. So the layout format had to be
changed (again), with corresponding layout2layout code.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@26779 a592a061-630c-0410-9148-cb99ea01b6c8

lib/scripts/layout2layout.py
src/Counters.cpp
src/Counters.h
src/TextClass.cpp
src/TextClass.h

index 3d27398ecce1bef0f71f24d0b1f041f6d4a66dd8..f42a508a6c9c5cc31065c80e274dc212e290122e 100644 (file)
@@ -33,7 +33,10 @@ import os, re, string, sys
 # Incremented to format 9, 5 October 2008 by rgh
 # ForcePlain and CustomPars tags added to InsetLayout
 
-currentFormat = 9
+# Incremented to format 10, 6 October 2008 by rgh
+# Change format of counters
+
+currentFormat = 10
 
 
 def usage(prog_name):
@@ -87,6 +90,8 @@ def concatenate_label(old, new):
 def convert(lines):
     " Convert to new format."
     re_Comment = re.compile(r'^(\s*)#')
+    re_Counter = re.compile(r'\s*Counter\s*')
+    re_Name = re.compile(r'\s*Name\s+(\S+)\s*')
     re_Empty = re.compile(r'^(\s*)$')
     re_Format = re.compile(r'^(\s*)(Format)(\s+)(\S+)', re.IGNORECASE)
     re_Preamble = re.compile(r'^(\s*)Preamble', re.IGNORECASE)
@@ -175,6 +180,27 @@ def convert(lines):
                 i += 1
             continue
 
+        if format == 9:
+            match = re_Counter.match(lines[i])
+            if match:
+                counterline = i
+                i += 1
+                while i < len(lines):
+                    namem = re_Name.match(lines[i])
+                    if namem:
+                        name = namem.group(1)
+                        lines.pop(i)
+                        lines[counterline] = "Counter %s" % name
+                        # we don't need to increment i
+                        continue
+                    endem = re_End.match(lines[i])
+                    if endem:
+                        i += 1
+                        break
+                    i += 1
+            i += 1
+            continue
+
         # These just involved new features, not any changes to old ones
         if format >= 5 and format <= 8:
           i += 1
index 1cc78431c7da93dab570387cc69d88c5aba0cabc..cf4bfeed43f644412e9ff11710c7ece07a940d0e 100644 (file)
@@ -15,6 +15,8 @@
 
 #include "Counters.h"
 
+#include "Lexer.h"
+
 #include "support/convert.h"
 #include "support/debug.h"
 #include "support/lstrings.h"
@@ -43,6 +45,63 @@ Counter::Counter(docstring const & mc, docstring const & ls,
 }
 
 
+bool Counter::read(Lexer & lex)
+{
+       enum {
+               CT_WITHIN = 1,
+               CT_LABELSTRING,
+               CT_LABELSTRING_APPENDIX,
+               CT_END
+       };
+
+       LexerKeyword counterTags[] = {
+               { "end", CT_END },
+               { "labelstring", CT_LABELSTRING },
+               { "labelstringappendix", CT_LABELSTRING_APPENDIX },
+               { "within", CT_WITHIN }
+       };
+
+       lex.pushTable(counterTags);
+
+       bool getout = false;
+       while (!getout && lex.isOK()) {
+               int le = lex.lex();
+               switch (le) {
+                       case Lexer::LEX_UNDEF:
+                               lex.printError("Unknown counter tag `$$Token'");
+                               continue;
+                       default: 
+                               break;
+               }
+               switch (le) {
+                       case CT_WITHIN:
+                               lex.next();
+                               master_ = lex.getDocString();
+                               if (master_ == "none")
+                                       master_.erase();
+                               break;
+                       case CT_LABELSTRING:
+                               lex.next();
+                               labelstring_ = lex.getDocString();
+                               labelstringappendix_ = labelstring_;
+                               break;
+                       case CT_LABELSTRING_APPENDIX:
+                               lex.next();
+                               labelstringappendix_ = lex.getDocString();
+                               break;
+                       case CT_END:
+                               getout = true;
+                               break;
+               }
+       }
+
+       // Here if have a full counter if getout == true
+       if (!getout)
+               LYXERR0("No End tag found for counter!");
+       lex.popTable();
+       return getout;
+}
+
 void Counter::set(int v)
 {
        value_ = v;
@@ -112,6 +171,23 @@ bool Counters::hasCounter(docstring const & c) const
 }
 
 
+bool Counters::read(Lexer & lex, docstring const & name)
+{
+       if (hasCounter(name)) {
+               LYXERR(Debug::TCLASS, "Reading existing counter " << to_utf8(name));
+               return counterList[name].read(lex);
+       }
+       LYXERR(Debug::TCLASS, "Reading new counter " << to_utf8(name));
+       Counter cnt;
+       bool success = cnt.read(lex);
+       if (success)
+               counterList[name] = cnt;
+       else
+               LYXERR0("Error reading counter `" << name << "'!");
+       return success;
+}
+
+
 void Counters::set(docstring const & ctr, int const val)
 {
        CounterList::iterator const it = counterList.find(ctr);
index 721e4e307d1d23a86a798ab29a67ea4529cdf8ad..538dcd479215a89a5b885e16f3d303aab9094cc7 100644 (file)
@@ -23,6 +23,8 @@
 
 namespace lyx {
 
+class Lexer;
+
 /// This represents a single counter.
 class Counter {
 public:
@@ -31,6 +33,8 @@ public:
        ///
        Counter(docstring const & mc, docstring const & ls, 
                docstring const & lsa);
+       /// \return true on success
+       bool read(Lexer & lex);
        ///
        void set(int v);
        ///
@@ -75,8 +79,6 @@ class Counters {
 public:
        ///
        Counters() : appendix_(false), subfloat_(false) {}
-       /// Add a new counter to array.
-       void newCounter(docstring const & newc);
        /// Add new counter newc having masterc as its master, 
        /// ls as its label, and lsa as its appendix label.
        void newCounter(docstring const & newc,
@@ -85,6 +87,9 @@ public:
                        docstring const & lsa);
        /// Checks whether the given counter exists.
        bool hasCounter(docstring const & c) const;
+       /// reads the counter name
+       /// \return true on success
+       bool read(Lexer & lex, docstring const & name);
        ///
        void set(docstring const & ctr, int val);
        ///
index acf41f505494e14924f52ff8a0f21cade35e74b8..63719188f23d1ada91fc7f323b9e18c2f5992c01 100644 (file)
@@ -61,7 +61,7 @@ private:
 };
 
 
-int const FORMAT = 9;
+int const FORMAT = 10;
 
 
 bool layout2layout(FileName const & filename, FileName const & tempfile)
@@ -520,7 +520,23 @@ TextClass::ReturnValues TextClass::read(Lexer & lexrc, ReadType rt)
                        break;
 
                case TC_COUNTER:
-                       readCounter(lexrc);
+                       if (lexrc.next()) {
+                               docstring const name = lexrc.getDocString();
+                               if (name.empty()) {
+                                       string s = "Could not read name for counter: `$$Token' "
+                                                       + lexrc.getString() + " is probably not valid UTF-8!";
+                                       lexrc.printError(s.c_str());
+                                       Counter c;
+                                       // Since we couldn't read the name, we just scan the rest
+                                       // and discard it.
+                                       c.read(lexrc);
+                               } else
+                                       error = !counters_.read(lexrc, name);
+                       }
+                       else {
+                               lexrc.printError("No name given for style: `$$Token'.");
+                               error = true;
+                       }
                        break;
 
                case TC_TITLELATEXTYPE:
@@ -825,79 +841,6 @@ void TextClass::readFloat(Lexer & lexrc)
 }
 
 
-void TextClass::readCounter(Lexer & lexrc)
-{
-       enum {
-               CT_NAME = 1,
-               CT_WITHIN,
-               CT_LABELSTRING,
-               CT_LABELSTRING_APPENDIX,
-               CT_END
-       };
-
-       LexerKeyword counterTags[] = {
-               { "end", CT_END },
-               { "labelstring", CT_LABELSTRING },
-               { "labelstringappendix", CT_LABELSTRING_APPENDIX },
-               { "name", CT_NAME },
-               { "within", CT_WITHIN }
-       };
-
-       lexrc.pushTable(counterTags);
-
-       docstring name;
-       docstring within;
-       docstring labelstring;
-       docstring labelstring_appendix;
-
-       bool getout = false;
-       while (!getout && lexrc.isOK()) {
-               int le = lexrc.lex();
-               switch (le) {
-               case Lexer::LEX_UNDEF:
-                       lexrc.printError("Unknown counter tag `$$Token'");
-                       continue;
-               default: break;
-               }
-               switch (le) {
-               case CT_NAME:
-                       lexrc.next();
-                       name = lexrc.getDocString();
-                       if (counters_.hasCounter(name))
-                               LYXERR(Debug::TCLASS, "Reading existing counter " << to_utf8(name));
-                       else
-                               LYXERR(Debug::TCLASS, "Reading new counter " << to_utf8(name));
-                       break;
-               case CT_WITHIN:
-                       lexrc.next();
-                       within = lexrc.getDocString();
-                       if (within == "none")
-                               within.erase();
-                       break;
-               case CT_LABELSTRING:
-                       lexrc.next();
-                       labelstring = lexrc.getDocString();
-                       labelstring_appendix = labelstring;
-                       break;
-               case CT_LABELSTRING_APPENDIX:
-                       lexrc.next();
-                       labelstring_appendix = lexrc.getDocString();
-                       break;
-               case CT_END:
-                       getout = true;
-                       break;
-               }
-       }
-
-       // Here if have a full counter if getout == true
-       if (getout)
-               counters_.newCounter(name, within, 
-                                     labelstring, labelstring_appendix);
-
-       lexrc.popTable();
-}
-
-
 bool TextClass::hasLayout(docstring const & n) const
 {
        docstring const name = n.empty() ? defaultLayoutName() : n;
index 36630238aed0abe171fb0cf7c1ce9d1898c6dec3..fd2b50bb9f0292d456f5cb4d4118d690b57ae535 100644 (file)
@@ -305,8 +305,6 @@ private:
        void readCharStyle(Lexer &, std::string const &);
        ///
        void readFloat(Lexer &);
-       ///
-       void readCounter(Lexer &);
 };