diff --git a/lib/scripts/layout2layout.py b/lib/scripts/layout2layout.py index 7d3cca7be8..611639412a 100644 --- a/lib/scripts/layout2layout.py +++ b/lib/scripts/layout2layout.py @@ -11,7 +11,7 @@ # This script will update a .layout file to current format # The latest layout format is also defined in src/TextClass.cpp -currentFormat = 103 +currentFormat = 104 # Incremented to format 4, 6 April 2007, lasgouttes @@ -348,6 +348,9 @@ currentFormat = 103 # Incremented to format 103, 27 July 2023 by rikiheck # Allow e.g. \roman{section} in PrettyFormat +# Incremented to format 104, 28 July 2023 by rikiheck +# RefFormat for counters and PrettyFormat for floats + # Do not forget to document format change in Customization # Manual (section "Declaring a new text class"). @@ -595,7 +598,7 @@ def convert(lines, end_format): i += 1 continue - if 101 <= format <= 102: + if 101 <= format <= 103: # nothing to do. i += 1 continue diff --git a/src/Counters.cpp b/src/Counters.cpp index 1a9c6af637..9376ef0aac 100644 --- a/src/Counters.cpp +++ b/src/Counters.cpp @@ -61,6 +61,7 @@ bool Counter::read(Lexer & lex) CT_INITIALVALUE, CT_GUINAME, CT_LATEXNAME, + CT_REFFORMAT, CT_END }; @@ -72,6 +73,7 @@ bool Counter::read(Lexer & lex) { "labelstringappendix", CT_LABELSTRING_APPENDIX }, { "latexname", CT_LATEXNAME }, { "prettyformat", CT_PRETTYFORMAT }, + { "refformat", CT_REFFORMAT }, { "within", CT_WITHIN } }; @@ -110,6 +112,15 @@ bool Counter::read(Lexer & lex) lex.next(); prettyformat_ = lex.getDocString(); break; + case CT_REFFORMAT: { + lex.next(); + docstring const key = lex.getDocString(); + lex.next(); + docstring const value = lex.getDocString(); + ref_formats_[key] = value; + LYXERR0("refformat: " << key << " => " << value); + break; + } case CT_LABELSTRING: lex.next(); labelstring_ = lex.getDocString(); @@ -131,11 +142,12 @@ bool Counter::read(Lexer & lex) getout = true; break; } - if (prettyformat_ == "") { // fall back on GuiName if PrettyFormat is empty - if (guiname_ == "") + // fall back on GuiName if PrettyFormat is empty + if (prettyformat_.empty()) { + if (guiname_.empty()) prettyformat_ = from_ascii("##"); else - prettyformat_ = "## (" + guiname_ + " counter)"; + prettyformat_ = "## (" + guiname_ + ")"; } } @@ -189,6 +201,15 @@ void Counter::reset() } +docstring const & Counter::refFormat(docstring const & prefix) const +{ + map::const_iterator it = ref_formats_.find(prefix); + if (it == ref_formats_.end()) + return prettyformat_; + return it->second; +} + + docstring const & Counter::parent() const { return parent_; @@ -601,6 +622,23 @@ docstring Counters::counterLabel(docstring const & format, } +docstring Counters::formattedCounter(docstring const & name, + docstring const & prex, string const & lang) const +{ + CounterList::const_iterator it = counterList_.find(name); + if (it == counterList_.end()) + return from_ascii("#"); + Counter const & ctr = it->second; + + docstring const value = theCounter(name, lang); + docstring const & format = + translateIfPossible(counterLabel(ctr.refFormat(prex), lang), lang); + if (format.empty()) + return value; + return subst(format, from_ascii("##"), value); +} + + docstring Counters::prettyCounter(docstring const & name, string const & lang) const { diff --git a/src/Counters.h b/src/Counters.h index 41ee930583..5be4aca197 100644 --- a/src/Counters.h +++ b/src/Counters.h @@ -69,6 +69,8 @@ public: /// E.g., for a section counter it might be "section \thesection" docstring const & prettyFormat() const { return prettyformat_; } /// + docstring const & refFormat(docstring const & prefix) const; + /// docstring const & guiName() const { return guiname_; } /// docstring const & latexName() const { return latexname_; } @@ -103,6 +105,8 @@ private: /// Similar, but used for formatted references in XHTML output docstring prettyformat_; /// + std::map ref_formats_; + /// docstring guiname_; /// The name used for the counter in LaTeX docstring latexname_; @@ -183,6 +187,11 @@ public: /// format given by Counter::prettyFormat(). docstring prettyCounter(docstring const & cntr, std::string const & lang) const; + /// returns a formatted version of the counter, using the + /// format given by Counter::prettyFormat(). + docstring formattedCounter(docstring const & cntr, + docstring const & prefix, + std::string const & lang) const; /// docstring const & guiName(docstring const & cntr) const; /// diff --git a/src/TextClass.cpp b/src/TextClass.cpp index a9688d3b13..f6ec875167 100644 --- a/src/TextClass.cpp +++ b/src/TextClass.cpp @@ -59,7 +59,7 @@ namespace lyx { // You should also run the development/tools/updatelayouts.py script, // to update the format of all of our layout files. // -int const LAYOUT_FORMAT = 103; // rkh: allow counter specs in PrettyFormat +int const LAYOUT_FORMAT = 104; // rkh: RefFormat for counters // Layout format for the current lyx file format. Controls which format is @@ -1412,6 +1412,7 @@ bool TextClass::readFloat(Lexer & lexrc) FT_ALLOWS_SIDEWAYS, FT_ALLOWS_WIDE, FT_REQUIRES, + FT_PRETTYFORMAT, FT_END }; @@ -1435,6 +1436,7 @@ bool TextClass::readFloat(Lexer & lexrc) { "listname", FT_LISTNAME }, { "numberwithin", FT_WITHIN }, { "placement", FT_PLACEMENT }, + { "prettyformat", FT_PRETTYFORMAT }, { "refprefix", FT_REFPREFIX }, { "requires", FT_REQUIRES }, { "style", FT_STYLE }, @@ -1463,6 +1465,7 @@ bool TextClass::readFloat(Lexer & lexrc) string type; string within; string required; + docstring prettyformat; bool usesfloat = true; bool ispredefined = false; bool allowswide = true; @@ -1566,6 +1569,10 @@ bool TextClass::readFloat(Lexer & lexrc) lexrc.next(); htmltag = lexrc.getString(); break; + case FT_PRETTYFORMAT: + lexrc.next(); + prettyformat = lexrc.getDocString(); + break; case FT_DOCBOOKATTR: lexrc.next(); docbookattr = lexrc.getString(); @@ -1624,13 +1631,13 @@ bool TextClass::readFloat(Lexer & lexrc) // each float has its own counter counters_.newCounter(from_ascii(type), from_ascii(within), docstring(), docstring(), - bformat(_("%1$s ##"), _(name)), + prettyformat.empty() ? bformat(_("%1$s ##"), _(name)) : prettyformat, bformat(_("%1$s (Float)"), _(name))); // also define sub-float counters docstring const subtype = "sub-" + from_ascii(type); counters_.newCounter(subtype, from_ascii(type), "\\alph{" + subtype + "}", docstring(), - bformat(_("Sub-%1$s ##"), _(name)), + prettyformat.empty() ? bformat(_("Sub-%1$s ##"), _(name)) : prettyformat, bformat(_("Sub-%1$s (Float)"), _(name))); } return getout; diff --git a/src/frontends/qt/GuiRef.cpp b/src/frontends/qt/GuiRef.cpp index fbf68247f8..6a2446a5a6 100644 --- a/src/frontends/qt/GuiRef.cpp +++ b/src/frontends/qt/GuiRef.cpp @@ -452,12 +452,10 @@ void GuiRef::redoRefs() QStringList refsCategories; // Do we have a prefix-less label at all? bool noprefix = false; - vector>::const_iterator iter; - for (auto const & ref : refs_) { + for (auto const & theref : refs_) { // first: plain label name, second: gui name, third: pretty name - QString const lab = toqstr(get<0>(ref)); - refsNames.append({lab, toqstr(get<1>(ref)), - toqstr(get<2>(*iter))}); + QString const lab = toqstr(get<0>(theref)); + refsNames.append({lab, toqstr(get<1>(theref)), toqstr(get<2>(theref))}); if (groupCB->isChecked()) { if (lab.contains(":")) { QString const pref = lab.split(':')[0]; diff --git a/src/insets/InsetLabel.cpp b/src/insets/InsetLabel.cpp index 1f0a0459ac..1ca8ea08ae 100644 --- a/src/insets/InsetLabel.cpp +++ b/src/insets/InsetLabel.cpp @@ -193,15 +193,24 @@ void InsetLabel::updateBuffer(ParIterator const & it, UpdateType, bool const /*d if (active_counter_ != from_ascii("equation")) { counter_value_ = cnts.theCounter(active_counter_, lang->code()); pretty_counter_ = cnts.prettyCounter(active_counter_, lang->code()); + docstring prex; + split(label, prex, ':'); + if (prex == label) { + // No prefix found + formatted_counter_ = pretty_counter_; + } else + formatted_counter_ = cnts.formattedCounter(active_counter_, prex, lang->code()); } else { // For equations, the counter value and pretty counter // value will be set by the parent InsetMathHull. counter_value_ = from_ascii("#"); pretty_counter_ = from_ascii(""); + formatted_counter_ = from_ascii(""); } } else { counter_value_ = from_ascii("#"); pretty_counter_ = from_ascii("#"); + formatted_counter_ = from_ascii("#"); } } @@ -215,10 +224,10 @@ void InsetLabel::addToToc(DocIterator const & cpit, bool output_active, if (buffer().insetLabel(label, true) != this) output_active = false; - // We put both active and inactive labels to the outliner + // We put both active and inactive labels to the outliner shared_ptr toc = backend.toc("label"); TocItem toc_item = TocItem(cpit, 0, screen_label_, output_active); - toc_item.prettyStr(pretty_counter_); + toc_item.prettyStr(formatted_counter_); toc->push_back(toc_item); // The refs get assigned only to the active label. If no active one exists, // assign the (BROKEN) refs to the first inactive one. diff --git a/src/insets/InsetLabel.h b/src/insets/InsetLabel.h index 5cd4a88ddc..886b9c6d8a 100644 --- a/src/insets/InsetLabel.h +++ b/src/insets/InsetLabel.h @@ -30,6 +30,8 @@ public: /// docstring const & prettyCounter() const { return pretty_counter_; } /// + docstring const & formattedCounter() const { return formatted_counter_; } + /// void setPrettyCounter(docstring pc) { pretty_counter_ = pc; } /// int rowFlags() const override { return CanBreakBefore | CanBreakAfter; } @@ -109,6 +111,8 @@ private: docstring counter_value_; /// docstring pretty_counter_; + /// + docstring formatted_counter_; }; diff --git a/src/insets/InsetRef.cpp b/src/insets/InsetRef.cpp index 4473bd7ad6..7c7a7a57e1 100644 --- a/src/insets/InsetRef.cpp +++ b/src/insets/InsetRef.cpp @@ -404,7 +404,7 @@ docstring InsetRef::xhtml(XMLStream & xs, OutputParams const & op) const else if (cmd == "eqref") display_string = '(' + value + ')'; else if (cmd == "formatted") { - display_string = il->prettyCounter(); + display_string = il->formattedCounter(); if (buffer().params().use_refstyle && getParam("caps") == "true") capitalize(display_string); // it is hard to see what to do about plurals...