mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-24 21:55:29 +00:00
Fix bug 5316 properly. The fix is to make the routine that reads a counter
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
This commit is contained in:
parent
2b234dad7d
commit
d841355b7e
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
///
|
||||
|
@ -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;
|
||||
|
@ -305,8 +305,6 @@ private:
|
||||
void readCharStyle(Lexer &, std::string const &);
|
||||
///
|
||||
void readFloat(Lexer &);
|
||||
///
|
||||
void readCounter(Lexer &);
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user