mirror of
https://git.lyx.org/repos/lyx.git
synced 2025-01-21 23:09:40 +00:00
New counter manipulation inset.
This inset allows counters to be set, reset, saved, restored, etc, both in the LyX GUI and in the output; optionally, the effect can be limited to the GUI. Of course, LaTeX provides means for doing all of these things, so they could previously be done with ERT, as far as the output is concerned. But there was no mechanism for manipulating counters in the GUI and none for other output formats.
This commit is contained in:
parent
db5021c42e
commit
684d27c0fb
167
src/Counters.cpp
167
src/Counters.cpp
@ -18,6 +18,7 @@
|
||||
#include "Lexer.h"
|
||||
|
||||
#include "support/convert.h"
|
||||
#include "support/counter_reps.h"
|
||||
#include "support/debug.h"
|
||||
#include "support/gettext.h"
|
||||
#include "support/lassert.h"
|
||||
@ -143,6 +144,18 @@ int Counter::value() const
|
||||
}
|
||||
|
||||
|
||||
void Counter::saveValue()
|
||||
{
|
||||
saved_value_ = value_;
|
||||
}
|
||||
|
||||
|
||||
void Counter::restoreValue()
|
||||
{
|
||||
value_ = saved_value_;
|
||||
}
|
||||
|
||||
|
||||
void Counter::step()
|
||||
{
|
||||
++value_;
|
||||
@ -265,6 +278,34 @@ int Counters::value(docstring const & ctr) const
|
||||
}
|
||||
|
||||
|
||||
void Counters::saveValue(docstring const & ctr) const
|
||||
{
|
||||
CounterList::const_iterator const cit = counterList_.find(ctr);
|
||||
if (cit == counterList_.end()) {
|
||||
lyxerr << "value: Counter does not exist: "
|
||||
<< to_utf8(ctr) << endl;
|
||||
return;
|
||||
}
|
||||
Counter const & cnt = cit->second;
|
||||
Counter & ccnt = const_cast<Counter &>(cnt);
|
||||
ccnt.saveValue();
|
||||
}
|
||||
|
||||
|
||||
void Counters::restoreValue(docstring const & ctr) const
|
||||
{
|
||||
CounterList::const_iterator const cit = counterList_.find(ctr);
|
||||
if (cit == counterList_.end()) {
|
||||
lyxerr << "value: Counter does not exist: "
|
||||
<< to_utf8(ctr) << endl;
|
||||
return;
|
||||
}
|
||||
Counter const & cnt = cit->second;
|
||||
Counter & ccnt = const_cast<Counter &>(cnt);
|
||||
ccnt.restoreValue();
|
||||
}
|
||||
|
||||
|
||||
void Counters::resetSlaves(docstring const & count)
|
||||
{
|
||||
for (auto & ctr : counterList_) {
|
||||
@ -357,124 +398,6 @@ void Counters::copy(Counters & from, Counters & to, docstring const & match)
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
char loweralphaCounter(int const n)
|
||||
{
|
||||
if (n < 1 || n > 26)
|
||||
return '?';
|
||||
return 'a' + n - 1;
|
||||
}
|
||||
|
||||
|
||||
char alphaCounter(int const n)
|
||||
{
|
||||
if (n < 1 || n > 26)
|
||||
return '?';
|
||||
return 'A' + n - 1;
|
||||
}
|
||||
|
||||
|
||||
char hebrewCounter(int const n)
|
||||
{
|
||||
static const char hebrew[22] = {
|
||||
'\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7', '\xe8',
|
||||
'\xe9', '\xeb', '\xec', '\xee', '\xf0', '\xf1', '\xf2', '\xf4', '\xf6',
|
||||
'\xf7', '\xf8', '\xf9', '\xfa'
|
||||
};
|
||||
|
||||
if (n < 1 || n > 22)
|
||||
return '?';
|
||||
return hebrew[n - 1];
|
||||
}
|
||||
|
||||
|
||||
// On the special cases, see http://mathworld.wolfram.com/RomanNumerals.html
|
||||
// and for a list of roman numerals up to and including 3999, see
|
||||
// http://www.research.att.com/~njas/sequences/a006968.txt. (Thanks to Joost
|
||||
// for this info.)
|
||||
docstring const romanCounter(int const n)
|
||||
{
|
||||
static char const * const ones[9] = {
|
||||
"I", "II", "III", "IV", "V",
|
||||
"VI", "VII", "VIII", "IX"
|
||||
};
|
||||
|
||||
static char const * const tens[9] = {
|
||||
"X", "XX", "XXX", "XL", "L",
|
||||
"LX", "LXX", "LXXX", "XC"
|
||||
};
|
||||
|
||||
static char const * const hunds[9] = {
|
||||
"C", "CC", "CCC", "CD", "D",
|
||||
"DC", "DCC", "DCCC", "CM"
|
||||
};
|
||||
|
||||
if (n >= 1000 || n < 1)
|
||||
return from_ascii("??");
|
||||
|
||||
int val = n;
|
||||
string roman;
|
||||
switch (n) {
|
||||
//special cases
|
||||
case 900:
|
||||
roman = "CM";
|
||||
break;
|
||||
case 400:
|
||||
roman = "CD";
|
||||
break;
|
||||
default:
|
||||
if (val >= 100) {
|
||||
int hundreds = val / 100;
|
||||
roman = hunds[hundreds - 1];
|
||||
val = val % 100;
|
||||
}
|
||||
if (val >= 10) {
|
||||
switch (val) {
|
||||
//special case
|
||||
case 90:
|
||||
roman = roman + "XC";
|
||||
val = 0; //skip next
|
||||
break;
|
||||
default:
|
||||
int tensnum = val / 10;
|
||||
roman = roman + tens[tensnum - 1];
|
||||
val = val % 10;
|
||||
} // end switch
|
||||
} // end tens
|
||||
if (val > 0)
|
||||
roman = roman + ones[val -1];
|
||||
}
|
||||
return from_ascii(roman);
|
||||
}
|
||||
|
||||
|
||||
docstring const lowerromanCounter(int const n)
|
||||
{
|
||||
return lowercase(romanCounter(n));
|
||||
}
|
||||
|
||||
|
||||
docstring const fnsymbolCounter(int const n)
|
||||
{
|
||||
switch(n) {
|
||||
case 1: return docstring(1, 0x002a); //*
|
||||
case 2: return docstring(1, 0x2020); // dagger
|
||||
case 3: return docstring(1, 0x2021); // double dagger
|
||||
case 4: return docstring(1, 0x00A7); // section sign
|
||||
case 5: return docstring(1, 0x00B6); // pilcrow sign
|
||||
case 6: return docstring(1, 0x2016); // vertical bar
|
||||
case 7: return docstring(2, 0x002a); // two *
|
||||
case 8: return docstring(2, 0x2020); // two daggers
|
||||
case 9: return docstring(2, 0x2021); // two double daggers
|
||||
default:
|
||||
return from_ascii("?");
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
docstring Counters::labelItem(docstring const & ctr,
|
||||
docstring const & numbertype) const
|
||||
{
|
||||
@ -687,4 +610,12 @@ void Counters::endEnvironment()
|
||||
}
|
||||
|
||||
|
||||
vector<docstring> Counters::listOfCounters() const {
|
||||
vector<docstring> ret;
|
||||
for(auto const & k : counterList_)
|
||||
ret.emplace_back(k.first);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
} // namespace lyx
|
||||
|
@ -45,6 +45,10 @@ public:
|
||||
///
|
||||
int value() const;
|
||||
///
|
||||
void saveValue();
|
||||
///
|
||||
void restoreValue();
|
||||
///
|
||||
void step();
|
||||
///
|
||||
void reset();
|
||||
@ -79,6 +83,8 @@ private:
|
||||
/// This is actually one less than the initial value, since the
|
||||
/// counter is always stepped before being used.
|
||||
int initial_value_;
|
||||
///
|
||||
int saved_value_;
|
||||
/// contains master counter name.
|
||||
/** The master counter is the counter that, if stepped
|
||||
* (incremented) zeroes this counter. E.g. "subsection"'s
|
||||
@ -128,6 +134,10 @@ public:
|
||||
void addto(docstring const & ctr, int val);
|
||||
///
|
||||
int value(docstring const & ctr) const;
|
||||
///
|
||||
void saveValue(docstring const & ctr) const;
|
||||
///
|
||||
void restoreValue(docstring const & ctr) const;
|
||||
/// Reset recursively all the counters that are slaves of the one named by \c ctr.
|
||||
void resetSlaves(docstring const & ctr);
|
||||
/// Increment by one master of counter named by \c ctr.
|
||||
@ -202,6 +212,8 @@ public:
|
||||
///
|
||||
void restoreLastCounter() { counter_stack_.pop_back(); }
|
||||
// @}
|
||||
///
|
||||
std::vector<docstring> listOfCounters() const;
|
||||
private:
|
||||
/** expands recursively any \\the<counter> macro in the
|
||||
* labelstring of \c counter. The \c lang code is used to
|
||||
|
@ -555,6 +555,7 @@ SOURCEFILESINSETS = \
|
||||
insets/InsetCollapsible.cpp \
|
||||
insets/InsetCommand.cpp \
|
||||
insets/InsetCommandParams.cpp \
|
||||
insets/InsetCounter.cpp \
|
||||
insets/InsetERT.cpp \
|
||||
insets/InsetExternal.cpp \
|
||||
insets/InsetFlex.cpp \
|
||||
@ -615,6 +616,7 @@ HEADERFILESINSETS = \
|
||||
insets/InsetCollapsible.h \
|
||||
insets/InsetCommand.h \
|
||||
insets/InsetCommandParams.h \
|
||||
insets/InsetCounter.h \
|
||||
insets/InsetERT.h \
|
||||
insets/InsetExternal.h \
|
||||
insets/InsetFlex.h \
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "insets/InsetBranch.h"
|
||||
#include "insets/InsetCaption.h"
|
||||
#include "insets/InsetCitation.h"
|
||||
#include "insets/InsetCounter.h"
|
||||
#include "insets/InsetFlex.h"
|
||||
#include "insets/InsetERT.h"
|
||||
#include "insets/InsetListings.h"
|
||||
@ -301,6 +302,12 @@ Inset * createInsetHelper(Buffer * buf, FuncRequest const & cmd)
|
||||
return new InsetCitation(buf, icp);
|
||||
}
|
||||
|
||||
case COUNTER_CODE: {
|
||||
InsetCommandParams icp(code);
|
||||
InsetCommand::string2params(to_utf8(cmd.argument()), icp);
|
||||
return new InsetCounter(buf, icp);
|
||||
}
|
||||
|
||||
case ERT_CODE: {
|
||||
return new InsetERT(buf,
|
||||
InsetERT::string2params(to_utf8(cmd.argument())));
|
||||
@ -551,6 +558,9 @@ Inset * readInset(Lexer & lex, Buffer * buf)
|
||||
case CITE_CODE:
|
||||
inset.reset(new InsetCitation(buf, inscmd));
|
||||
break;
|
||||
case COUNTER_CODE:
|
||||
inset.reset(new InsetCounter(buf, inscmd));
|
||||
break;
|
||||
case HYPERLINK_CODE:
|
||||
inset.reset(new InsetHyperlink(buf, inscmd));
|
||||
break;
|
||||
|
@ -74,6 +74,7 @@ static void build_translator()
|
||||
insetnames[TOC_CODE] = InsetName("toc");
|
||||
insetnames[QUOTE_CODE] = InsetName("quote");
|
||||
insetnames[REF_CODE] = InsetName("ref");
|
||||
insetnames[COUNTER_CODE] = InsetName("counter");
|
||||
insetnames[HYPERLINK_CODE] = InsetName("href");
|
||||
insetnames[SEPARATOR_CODE] = InsetName("separator");
|
||||
insetnames[ENDING_CODE] = InsetName("ending");
|
||||
|
@ -237,6 +237,8 @@ enum InsetCode {
|
||||
///
|
||||
MATH_CLASS_CODE,
|
||||
///
|
||||
COUNTER_CODE,
|
||||
///
|
||||
INSET_CODE_SIZE
|
||||
};
|
||||
|
||||
|
@ -346,7 +346,8 @@ bool decodeInsetParam(string const & name, string & data,
|
||||
case NOMENCL_PRINT_CODE:
|
||||
case REF_CODE:
|
||||
case TOC_CODE:
|
||||
case HYPERLINK_CODE: {
|
||||
case HYPERLINK_CODE:
|
||||
case COUNTER_CODE: {
|
||||
InsetCommandParams p(code);
|
||||
data = InsetCommand::params2string(p);
|
||||
break;
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "InsetBibitem.h"
|
||||
#include "InsetBibtex.h"
|
||||
#include "InsetCitation.h"
|
||||
#include "InsetCounter.h"
|
||||
#include "InsetFloatList.h"
|
||||
#include "InsetHyperlink.h"
|
||||
#include "InsetInclude.h"
|
||||
@ -63,6 +64,8 @@ static ParamInfo const & findInfo(InsetCode code, string const & cmdName)
|
||||
return InsetBibtex::findInfo(cmdName);
|
||||
case CITE_CODE:
|
||||
return InsetCitation::findInfo(cmdName);
|
||||
case COUNTER_CODE:
|
||||
return InsetCounter::findInfo(cmdName);
|
||||
case FLOAT_LIST_CODE:
|
||||
return InsetFloatList::findInfo(cmdName);
|
||||
case HYPERLINK_CODE:
|
||||
@ -201,6 +204,8 @@ string InsetCommandParams::getDefaultCmd(InsetCode code)
|
||||
return InsetBibtex::defaultCommand();
|
||||
case CITE_CODE:
|
||||
return InsetCitation::defaultCommand();
|
||||
case COUNTER_CODE:
|
||||
return InsetCounter::defaultCommand();
|
||||
case FLOAT_LIST_CODE:
|
||||
return InsetFloatList::defaultCommand();
|
||||
case HYPERLINK_CODE:
|
||||
@ -238,6 +243,8 @@ bool InsetCommandParams::isCompatibleCommand(InsetCode code, string const & s)
|
||||
return InsetBibtex::isCompatibleCommand(s);
|
||||
case CITE_CODE:
|
||||
return InsetCitation::isCompatibleCommand(s);
|
||||
case COUNTER_CODE:
|
||||
return InsetCounter::isCompatibleCommand(s);
|
||||
case FLOAT_LIST_CODE:
|
||||
return InsetFloatList::isCompatibleCommand(s);
|
||||
case HYPERLINK_CODE:
|
||||
@ -282,7 +289,7 @@ void InsetCommandParams::setCmdName(string const & name)
|
||||
|
||||
void InsetCommandParams::read(Lexer & lex)
|
||||
{
|
||||
Read(lex, 0);
|
||||
Read(lex, nullptr);
|
||||
}
|
||||
|
||||
|
||||
@ -356,7 +363,7 @@ void InsetCommandParams::Read(Lexer & lex, Buffer const * buffer)
|
||||
|
||||
void InsetCommandParams::write(ostream & os) const
|
||||
{
|
||||
Write(os, 0);
|
||||
Write(os, nullptr);
|
||||
}
|
||||
|
||||
|
||||
|
284
src/insets/InsetCounter.cpp
Normal file
284
src/insets/InsetCounter.cpp
Normal file
@ -0,0 +1,284 @@
|
||||
/**
|
||||
* \file InsetCounter.cpp
|
||||
* This file is part of LyX, the document processor.
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* \author Richard Kimberly Heck
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
*/
|
||||
#include <config.h>
|
||||
|
||||
#include "InsetCounter.h"
|
||||
|
||||
#include "Buffer.h"
|
||||
#include "BufferParams.h"
|
||||
#include "Counters.h"
|
||||
#include "LaTeXFeatures.h"
|
||||
#include "OutputParams.h"
|
||||
#include "output_xhtml.h"
|
||||
#include "sgml.h"
|
||||
#include "texstream.h"
|
||||
#include "TextClass.h"
|
||||
|
||||
#include "support/convert.h"
|
||||
#include "support/counter_reps.h"
|
||||
#include "support/docstream.h"
|
||||
#include "support/gettext.h"
|
||||
#include "support/lassert.h"
|
||||
#include "support/lstrings.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
/*
|
||||
#include "Cursor.h"
|
||||
#include "DispatchResult.h"
|
||||
#include "Language.h"
|
||||
#include "LyX.h"
|
||||
#include "ParIterator.h"
|
||||
#include "TocBackend.h"
|
||||
|
||||
#include "support/debug.h"
|
||||
#include "support/textutils.h"
|
||||
*/
|
||||
|
||||
using namespace lyx::support;
|
||||
using namespace std;
|
||||
|
||||
namespace lyx {
|
||||
|
||||
|
||||
InsetCounter::InsetCounter(Buffer * buf, InsetCommandParams const & p)
|
||||
: InsetCommand(buf, p)
|
||||
{}
|
||||
|
||||
|
||||
InsetCounter::InsetCounter(InsetCounter const & ir)
|
||||
: InsetCommand(ir)
|
||||
{}
|
||||
|
||||
|
||||
const map<string, string> InsetCounter::counterTable =
|
||||
{
|
||||
{"set", N_("Set")},
|
||||
{"addto", N_("Add To")},
|
||||
{"reset", N_("Reset")},
|
||||
{"save", N_("Save")},
|
||||
{"restore", N_("Restore")},
|
||||
{"value", N_("Value")}
|
||||
};
|
||||
|
||||
|
||||
bool InsetCounter::isCompatibleCommand(string const & s) {
|
||||
return counterTable.count(s);
|
||||
}
|
||||
|
||||
|
||||
ParamInfo const & InsetCounter::findInfo(string const & /* cmdName */)
|
||||
{
|
||||
static ParamInfo param_info_;
|
||||
if (param_info_.empty()) {
|
||||
param_info_.add("counter", ParamInfo::LYX_INTERNAL);
|
||||
param_info_.add("value", ParamInfo::LYX_INTERNAL);
|
||||
param_info_.add("vtype", ParamInfo::LYX_INTERNAL);
|
||||
param_info_.add("lyxonly", ParamInfo::LYX_INTERNAL);
|
||||
}
|
||||
return param_info_;
|
||||
}
|
||||
|
||||
|
||||
void InsetCounter::latex(otexstream & os, OutputParams const &) const
|
||||
{
|
||||
bool const lyxonly = lowercase(getParam("lyxonly")) == "true";
|
||||
if (lyxonly)
|
||||
return;
|
||||
|
||||
string const cmd = getCmdName();
|
||||
docstring cntr = getParam("counter");
|
||||
Counters & cnts = buffer().params().documentClass().counters();
|
||||
if (cmd == "set") {
|
||||
docstring const & val = getParam("value");
|
||||
os << "\\setcounter{" << cntr << "}{" << val << "}";
|
||||
} else if (cmd == "addto") {
|
||||
docstring const & val = getParam("value");
|
||||
os << "\\addtocounter{" << cntr << "}{" << val << "}";
|
||||
} else if (cmd == "reset") {
|
||||
os << "\\setcounter{" << cntr << "}{0}";
|
||||
} else if (cmd == "save") {
|
||||
cnts.saveValue(cntr);
|
||||
os << "\\setcounter{" << lyxSaveCounter()
|
||||
<< "}{\\value{" << cntr << "}}";
|
||||
} else if (cmd == "restore") {
|
||||
cnts.restoreValue(cntr);
|
||||
os << "\\setcounter{" << cntr
|
||||
<< "{\\value{" << lyxSaveCounter() << "}}";
|
||||
} else if (cmd == "value") {
|
||||
os << "\\value{" << cntr << "}";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void InsetCounter::toString(odocstream & os) const
|
||||
{
|
||||
os << "[Counter " << from_utf8(getCmdName()) << ": "
|
||||
<< getParam("counter") << "]";
|
||||
}
|
||||
|
||||
|
||||
int InsetCounter::plaintext(odocstringstream & os,
|
||||
OutputParams const &, size_t) const
|
||||
{
|
||||
toString(os);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void InsetCounter::trackCounters(string const & cmd) const
|
||||
{
|
||||
Counters & cnts = buffer().params().documentClass().counters();
|
||||
docstring cntr = getParam("counter");
|
||||
if (cmd == "set") {
|
||||
docstring const & val = getParam("value");
|
||||
cnts.set(cntr, convert<int>(val));
|
||||
} else if (cmd == "addto") {
|
||||
docstring const & val = getParam("value");
|
||||
cnts.addto(cntr, convert<int>(val));
|
||||
} else if (cmd == "reset") {
|
||||
cnts.reset(cntr);
|
||||
} else if (cmd == "save") {
|
||||
cnts.saveValue(cntr);
|
||||
} else if (cmd == "restore") {
|
||||
cnts.restoreValue(cntr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const map<string, string> InsetCounter::valueTable =
|
||||
{
|
||||
{"Roman", N_("Roman Uppercase")},
|
||||
{"roman", N_("Roman Lowercase")},
|
||||
{"Alpha", N_("Uppercase Letter")},
|
||||
{"alpha", N_("Lowercase Letter")},
|
||||
{"arabic", N_("Arabic Numeral")}
|
||||
};
|
||||
|
||||
|
||||
docstring InsetCounter::value() const {
|
||||
docstring const & cnt = getParam("counter");
|
||||
string const & vtype = getCmdName();
|
||||
int const val = buffer().params().documentClass().counters().value(cnt);
|
||||
if (vtype == "Roman")
|
||||
return romanCounter(val);
|
||||
if (vtype == "roman")
|
||||
return lowerromanCounter(val);
|
||||
if (vtype == "Alpha")
|
||||
return docstring(1, alphaCounter(val));
|
||||
if (vtype == "alpha")
|
||||
return docstring(1, loweralphaCounter(val));
|
||||
if (vtype == "arabic")
|
||||
return convert<docstring>(val);
|
||||
LATTEST(false);
|
||||
return empty_docstring();
|
||||
}
|
||||
|
||||
|
||||
int InsetCounter::docbook(odocstream & os, OutputParams const &) const
|
||||
{
|
||||
// Here, we need to track counter values ourselves,
|
||||
// since unlike in the LaTeX case, there is no external
|
||||
// mechanism for doing that.
|
||||
string const cmd = getCmdName();
|
||||
if (cmd == "value") {
|
||||
docstring cntr = getParam("counter");
|
||||
Counters & cnts = buffer().params().documentClass().counters();
|
||||
if (cnts.hasCounter(cntr))
|
||||
os << cnts.value(cntr);
|
||||
} else
|
||||
trackCounters(cmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
docstring InsetCounter::xhtml(XHTMLStream & xs, OutputParams const &) const
|
||||
{
|
||||
// Here, we need to track counter values ourselves,
|
||||
// since unlike in the LaTeX case, there is no external
|
||||
// mechanism for doing that.
|
||||
string const cmd = getCmdName();
|
||||
if (cmd == "value") {
|
||||
docstring cntr = getParam("counter");
|
||||
Counters & cnts = buffer().params().documentClass().counters();
|
||||
if (cnts.hasCounter(cntr))
|
||||
xs << cnts.value(cntr);
|
||||
} else
|
||||
trackCounters(cmd);
|
||||
|
||||
return docstring();
|
||||
}
|
||||
|
||||
|
||||
void InsetCounter::updateBuffer(ParIterator const &, UpdateType, bool const)
|
||||
{
|
||||
string const cmd = getCmdName();
|
||||
docstring cntr = getParam("counter");
|
||||
Counters & cnts = buffer().params().documentClass().counters();
|
||||
map<string, string>::const_iterator cit = counterTable.find(cmd);
|
||||
LASSERT(cit != counterTable.end(), return);
|
||||
string const label = cit->second;
|
||||
docstring const tlabel = translateIfPossible(from_ascii(label));
|
||||
|
||||
if (cmd == "set") {
|
||||
docstring const & val = getParam("value");
|
||||
cnts.set(cntr, convert<int>(val));
|
||||
screen_label_ = bformat(_("Counter: Set %1$s"), cntr);
|
||||
tooltip_ = bformat(_("Set value of counter %1$s to %2$s"), cntr, val);
|
||||
} else if (cmd == "addto") {
|
||||
docstring const & val = getParam("value");
|
||||
cnts.addto(cntr, convert<int>(val));
|
||||
screen_label_ = bformat(_("Counter: Add to %1$s"), cntr);
|
||||
tooltip_ = bformat(_("Add to value of counter %1$s"), cntr);
|
||||
} else if (cmd == "reset") {
|
||||
cnts.reset(cntr);
|
||||
screen_label_ = bformat(_("Counter: Reset %1$s"), cntr);
|
||||
tooltip_ = bformat(_("Reset value of counter %1$s"), cntr);
|
||||
} else if (cmd == "save") {
|
||||
cnts.saveValue(cntr);
|
||||
screen_label_ = bformat(_("Counter: Save %1$s"), cntr);
|
||||
tooltip_ = bformat(_("Save value of counter %1$s"), cntr);
|
||||
} else if (cmd == "restore") {
|
||||
cnts.restoreValue(cntr);
|
||||
screen_label_ = bformat(_("Counter: Restore %1$s"), cntr);
|
||||
tooltip_ = bformat(_("Restore value of counter %1$s"), cntr);
|
||||
} else if (cmd == "value") {
|
||||
screen_label_ = bformat(_("Counter: Value %1$s"), cntr);
|
||||
tooltip_ = bformat(_("Print value of counter %1$s"), cntr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
docstring InsetCounter::lyxSaveCounter() const
|
||||
{
|
||||
docstring cntr = getParam("counter");
|
||||
return from_ascii("LyXSave") + cntr;
|
||||
}
|
||||
|
||||
|
||||
void InsetCounter::validate(LaTeXFeatures & features) const
|
||||
{
|
||||
// create save counter if needed
|
||||
string const cmd = getCmdName();
|
||||
docstring const lyxonly = getParam("lyxonly");
|
||||
if ((cmd == "save" || cmd == "restore") && lyxonly != "true") {
|
||||
features.addPreambleSnippet(from_ascii("\\newcounter{") + lyxSaveCounter() + "}");
|
||||
}
|
||||
InsetCommand::validate(features);
|
||||
}
|
||||
|
||||
|
||||
string InsetCounter::contextMenuName() const
|
||||
{
|
||||
return "context-counter";
|
||||
}
|
||||
} // namespace lyx
|
99
src/insets/InsetCounter.h
Normal file
99
src/insets/InsetCounter.h
Normal file
@ -0,0 +1,99 @@
|
||||
// -*- C++ -*-
|
||||
/**
|
||||
* \file InsetCounter.h
|
||||
* This file is part of LyX, the document processor.
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* \author Richard Kimberly Heck
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
*/
|
||||
|
||||
#ifndef INSET_COUNTER_H
|
||||
#define INSET_COUNTER_H
|
||||
|
||||
#include "InsetCommand.h"
|
||||
|
||||
|
||||
namespace lyx {
|
||||
|
||||
///
|
||||
class InsetCounter : public InsetCommand {
|
||||
public:
|
||||
///
|
||||
InsetCounter(Buffer * buffer, InsetCommandParams const &);
|
||||
/// \name Public functions inherited from Inset class
|
||||
//@{
|
||||
///
|
||||
bool isLabeled() const { return true; }
|
||||
///
|
||||
docstring toolTip(BufferView const &, int, int) const
|
||||
{ return tooltip_; }
|
||||
///
|
||||
bool hasSettings() const { return true; }
|
||||
///
|
||||
InsetCode lyxCode() const { return COUNTER_CODE; }
|
||||
///
|
||||
void latex(otexstream &, OutputParams const &) const;
|
||||
///
|
||||
int plaintext(odocstringstream & ods, OutputParams const & op,
|
||||
size_t max_length = INT_MAX) const;
|
||||
///
|
||||
int docbook(odocstream &, OutputParams const &) const;
|
||||
///
|
||||
docstring xhtml(XHTMLStream &, OutputParams const &) const;
|
||||
///
|
||||
void toString(odocstream &) const;
|
||||
///
|
||||
void validate(LaTeXFeatures & features) const;
|
||||
///
|
||||
void updateBuffer(ParIterator const & it, UpdateType, bool const);
|
||||
///
|
||||
std::string contextMenuName() const;
|
||||
//@}
|
||||
|
||||
/// \name Static public methods obligated for InsetCommand derived classes
|
||||
//@{
|
||||
///
|
||||
static ParamInfo const & findInfo(std::string const &);
|
||||
///
|
||||
static std::string defaultCommand() { return "set"; }
|
||||
///
|
||||
static bool isCompatibleCommand(std::string const & s);
|
||||
//@}
|
||||
/// keys are commands, values are GUI strings
|
||||
static const std::map<std::string, std::string> counterTable;
|
||||
static const std::map<std::string, std::string> valueTable;
|
||||
|
||||
protected:
|
||||
///
|
||||
InsetCounter(InsetCounter const &);
|
||||
|
||||
private:
|
||||
/// \name Private functions inherited from Inset class
|
||||
//@{
|
||||
///
|
||||
Inset * clone() const { return new InsetCounter(*this); }
|
||||
//@}
|
||||
|
||||
/// \name Private functions inherited from InsetCommand class
|
||||
//@{
|
||||
///
|
||||
docstring screenLabel() const { return screen_label_; }
|
||||
//@}
|
||||
///
|
||||
docstring value() const;
|
||||
///
|
||||
docstring lyxSaveCounter() const;
|
||||
///
|
||||
void trackCounters(std::string const & cmd) const;
|
||||
///
|
||||
mutable docstring screen_label_;
|
||||
///
|
||||
mutable docstring tooltip_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace lyx
|
||||
|
||||
#endif // INSET_REF_H
|
@ -44,6 +44,8 @@ liblyxsupport_a_SOURCES = \
|
||||
convert.cpp \
|
||||
convert.h \
|
||||
copied_ptr.h \
|
||||
counter_reps.cpp \
|
||||
counter_reps.h \
|
||||
debug.cpp \
|
||||
debug.h \
|
||||
docstream.cpp \
|
||||
|
135
src/support/counter_reps.cpp
Normal file
135
src/support/counter_reps.cpp
Normal file
@ -0,0 +1,135 @@
|
||||
/**
|
||||
* \file convert.cpp
|
||||
* This file is part of LyX, the document processor.
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* \author André Pönitz
|
||||
* \author Lars Gullik Bjønnes
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "support/counter_reps.h"
|
||||
#include "support/docstring.h"
|
||||
#include "support/lstrings.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace lyx {
|
||||
|
||||
char loweralphaCounter(int const n)
|
||||
{
|
||||
if (n < 1 || n > 26)
|
||||
return '?';
|
||||
return 'a' + n - 1;
|
||||
}
|
||||
|
||||
|
||||
char alphaCounter(int const n)
|
||||
{
|
||||
if (n < 1 || n > 26)
|
||||
return '?';
|
||||
return 'A' + n - 1;
|
||||
}
|
||||
|
||||
|
||||
char hebrewCounter(int const n)
|
||||
{
|
||||
static const char hebrew[22] = {
|
||||
'\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7', '\xe8',
|
||||
'\xe9', '\xeb', '\xec', '\xee', '\xf0', '\xf1', '\xf2', '\xf4', '\xf6',
|
||||
'\xf7', '\xf8', '\xf9', '\xfa'
|
||||
};
|
||||
|
||||
if (n < 1 || n > 22)
|
||||
return '?';
|
||||
return hebrew[n - 1];
|
||||
}
|
||||
|
||||
|
||||
// On the special cases, see http://mathworld.wolfram.com/RomanNumerals.html
|
||||
// and for a list of roman numerals up to and including 3999, see
|
||||
// http://www.research.att.com/~njas/sequences/a006968.txt. (Thanks to Joost
|
||||
// for this info.)
|
||||
docstring const romanCounter(int const n)
|
||||
{
|
||||
static char const * const ones[9] = {
|
||||
"I", "II", "III", "IV", "V",
|
||||
"VI", "VII", "VIII", "IX"
|
||||
};
|
||||
|
||||
static char const * const tens[9] = {
|
||||
"X", "XX", "XXX", "XL", "L",
|
||||
"LX", "LXX", "LXXX", "XC"
|
||||
};
|
||||
|
||||
static char const * const hunds[9] = {
|
||||
"C", "CC", "CCC", "CD", "D",
|
||||
"DC", "DCC", "DCCC", "CM"
|
||||
};
|
||||
|
||||
if (n >= 1000 || n < 1)
|
||||
return from_ascii("??");
|
||||
|
||||
int val = n;
|
||||
string roman;
|
||||
switch (n) {
|
||||
//special cases
|
||||
case 900:
|
||||
roman = "CM";
|
||||
break;
|
||||
case 400:
|
||||
roman = "CD";
|
||||
break;
|
||||
default:
|
||||
if (val >= 100) {
|
||||
int hundreds = val / 100;
|
||||
roman = hunds[hundreds - 1];
|
||||
val = val % 100;
|
||||
}
|
||||
if (val >= 10) {
|
||||
switch (val) {
|
||||
//special case
|
||||
case 90:
|
||||
roman = roman + "XC";
|
||||
val = 0; //skip next
|
||||
break;
|
||||
default:
|
||||
int tensnum = val / 10;
|
||||
roman = roman + tens[tensnum - 1];
|
||||
val = val % 10;
|
||||
} // end switch
|
||||
} // end tens
|
||||
if (val > 0)
|
||||
roman = roman + ones[val -1];
|
||||
}
|
||||
return from_ascii(roman);
|
||||
}
|
||||
|
||||
|
||||
docstring const lowerromanCounter(int const n)
|
||||
{
|
||||
return support::lowercase(romanCounter(n));
|
||||
}
|
||||
|
||||
|
||||
docstring const fnsymbolCounter(int const n)
|
||||
{
|
||||
switch(n) {
|
||||
case 1: return docstring(1, 0x002a); //*
|
||||
case 2: return docstring(1, 0x2020); // dagger
|
||||
case 3: return docstring(1, 0x2021); // double dagger
|
||||
case 4: return docstring(1, 0x00A7); // section sign
|
||||
case 5: return docstring(1, 0x00B6); // pilcrow sign
|
||||
case 6: return docstring(1, 0x2016); // vertical bar
|
||||
case 7: return docstring(2, 0x002a); // two *
|
||||
case 8: return docstring(2, 0x2020); // two daggers
|
||||
case 9: return docstring(2, 0x2021); // two double daggers
|
||||
default:
|
||||
return from_ascii("?");
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace lyx
|
33
src/support/counter_reps.h
Normal file
33
src/support/counter_reps.h
Normal file
@ -0,0 +1,33 @@
|
||||
// -*- C++ -*-
|
||||
/**
|
||||
* \file counter_reps.h
|
||||
* This file is part of LyX, the document processor.
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* \author Lars Gullik Bjønnes
|
||||
* \author Richard Kimberly Heck (roman numerals)
|
||||
* \author Jean-Marc Lasgouttes
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
*
|
||||
* A collection of helper functions to convert counters to different
|
||||
* formats.
|
||||
*/
|
||||
|
||||
#ifndef COUNTER_REPS_H
|
||||
#define COUNTER_REPS_H
|
||||
|
||||
#include "support/strfwd.h"
|
||||
|
||||
namespace lyx {
|
||||
|
||||
char loweralphaCounter(int const n);
|
||||
char alphaCounter(int const n);
|
||||
char hebrewCounter(int const n);
|
||||
docstring const romanCounter(int const n);
|
||||
docstring const lowerromanCounter(int const n);
|
||||
docstring const fnsymbolCounter(int const n);
|
||||
|
||||
} // namespace lyx
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user