mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-25 10:58:52 +00:00
Fix bug #11104. Activate refstyle support for InsetMathRef.
At the moment, there is no support for plurals and capitalization. A long comment explains why. Support could be added for that without a format change.
This commit is contained in:
parent
79a21be5c3
commit
cf07d4825f
@ -3993,6 +3993,40 @@ def revert_hrquotes(document):
|
||||
document.body[i] = "\\begin_inset Quotes ard"
|
||||
|
||||
|
||||
def convert_math_refs(document):
|
||||
i = 0
|
||||
while True:
|
||||
i = find_token(document.body, "\\begin_inset Formula", i)
|
||||
if i == -1:
|
||||
break
|
||||
j = find_end_of_inset(document.body, i)
|
||||
if j == -1:
|
||||
document.warning("Can't find end of inset at line %d of body!" % i)
|
||||
i += 1
|
||||
continue
|
||||
while i < j:
|
||||
document.body[i] = document.body[i].replace("\\prettyref", "\\formatted")
|
||||
i += 1
|
||||
|
||||
|
||||
def revert_math_refs(document):
|
||||
i = 0
|
||||
while True:
|
||||
i = find_token(document.body, "\\begin_inset Formula", i)
|
||||
if i == -1:
|
||||
break
|
||||
j = find_end_of_inset(document.body, i)
|
||||
if j == -1:
|
||||
document.warning("Can't find end of inset at line %d of body!" % i)
|
||||
i += 1
|
||||
continue
|
||||
while i < j:
|
||||
document.body[i] = document.body[i].replace("\\formatted", "\\prettyref")
|
||||
if "\\labelonly" in document.body[i]:
|
||||
document.body[i] = re.sub("\\\\labelonly{([^}]+?)}", "\\1", document.body[i])
|
||||
i += 1
|
||||
|
||||
|
||||
##
|
||||
# Conversion hub
|
||||
#
|
||||
@ -4054,10 +4088,12 @@ convert = [
|
||||
[597, [convert_libertinus_rm_fonts]],
|
||||
[598, []],
|
||||
[599, []],
|
||||
[600, []]
|
||||
[600, []],
|
||||
[601, [convert_math_refs]]
|
||||
]
|
||||
|
||||
revert = [[598, [revert_hrquotes]],
|
||||
revert = [[599, [revert_math_refs]],
|
||||
[598, [revert_hrquotes]],
|
||||
[598, [revert_nopagebreak]],
|
||||
[597, [revert_docbook_table_output]],
|
||||
[596, [revert_libertinus_rm_fonts,revert_libertinus_sftt_fonts]],
|
||||
|
@ -145,13 +145,14 @@ void GuiRef::enableView(bool enable)
|
||||
void GuiRef::enableBoxes()
|
||||
{
|
||||
QString const reftype =
|
||||
typeCO->itemData(typeCO->currentIndex()).toString();
|
||||
typeCO->itemData(typeCO->currentIndex()).toString();
|
||||
bool const isFormatted = (reftype == "formatted");
|
||||
bool const isLabelOnly = (reftype == "labelonly");
|
||||
bool const usingRefStyle = buffer().params().use_refstyle;
|
||||
pluralCB->setEnabled(isFormatted && usingRefStyle);
|
||||
capsCB->setEnabled(isFormatted && usingRefStyle);
|
||||
noprefixCB->setEnabled(isLabelOnly);
|
||||
bool const intext = bufferview()->cursor().inTexted();
|
||||
pluralCB->setEnabled(intext && isFormatted && usingRefStyle);
|
||||
capsCB->setEnabled(intext && isFormatted && usingRefStyle);
|
||||
noprefixCB->setEnabled(intext && isLabelOnly);
|
||||
}
|
||||
|
||||
|
||||
@ -324,11 +325,8 @@ void GuiRef::updateContents()
|
||||
typeCO->addItem(qt_("on page <page>"), "vpageref");
|
||||
typeCO->addItem(qt_("<reference> on page <page>"), "vref");
|
||||
typeCO->addItem(qt_("Textual reference"), "nameref");
|
||||
if (bufferview()->cursor().inTexted()) {
|
||||
typeCO->addItem(qt_("Formatted reference"), "formatted");
|
||||
typeCO->addItem(qt_("Label only"), "labelonly");
|
||||
} else
|
||||
typeCO->addItem(qt_("Formatted reference"), "prettyref");
|
||||
typeCO->addItem(qt_("Formatted reference"), "formatted");
|
||||
typeCO->addItem(qt_("Label only"), "labelonly");
|
||||
|
||||
referenceED->setText(toqstr(params_["reference"]));
|
||||
|
||||
|
@ -174,16 +174,6 @@ bool InsetRef::getStatus(Cursor & cur, FuncRequest const & cmd,
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
void capitalize(docstring & s) {
|
||||
char_type t = uppercase(s[0]);
|
||||
s[0] = t;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
// the ref argument is the label name we are referencing.
|
||||
// we expect ref to be in the form: pfx:suffix.
|
||||
//
|
||||
@ -199,7 +189,8 @@ void capitalize(docstring & s) {
|
||||
// label, thus: \prettyref{pfx:suffix}.
|
||||
//
|
||||
docstring InsetRef::getFormattedCmd(docstring const & ref,
|
||||
docstring & label, docstring & prefix, docstring const & caps) const
|
||||
docstring & label, docstring & prefix, bool use_refstyle,
|
||||
bool use_caps)
|
||||
{
|
||||
static docstring const defcmd = from_ascii("\\ref");
|
||||
static docstring const prtcmd = from_ascii("\\prettyref");
|
||||
@ -216,11 +207,12 @@ docstring InsetRef::getFormattedCmd(docstring const & ref,
|
||||
|
||||
if (prefix.empty()) {
|
||||
// we have ":xxxx"
|
||||
LYXERR0("Label `" << ref << "' contains nothign before `:'.");
|
||||
label = ref;
|
||||
return defcmd;
|
||||
}
|
||||
|
||||
if (!buffer().params().use_refstyle) {
|
||||
if (!use_refstyle) {
|
||||
// \prettyref uses the whole label
|
||||
label = ref;
|
||||
return prtcmd;
|
||||
@ -237,8 +229,8 @@ docstring InsetRef::getFormattedCmd(docstring const & ref,
|
||||
return defcmd;
|
||||
}
|
||||
}
|
||||
if (caps == "true") {
|
||||
capitalize(prefix);
|
||||
if (use_caps) {
|
||||
prefix = support::capitalize(prefix);
|
||||
}
|
||||
return from_ascii("\\") + prefix + from_ascii("ref");
|
||||
}
|
||||
@ -261,7 +253,7 @@ void InsetRef::latex(otexstream & os, OutputParams const & rp) const
|
||||
if (rp.inulemcmd > 0)
|
||||
os << "\\mbox{";
|
||||
|
||||
if (cmd == "eqref" && buffer().params().use_refstyle) {
|
||||
if (buffer().params().use_refstyle && cmd == "eqref") {
|
||||
// we advertise this as printing "(n)", so we'll do that, at least
|
||||
// for refstyle, since refstlye's own \eqref prints, by default,
|
||||
// "equation n". if one wants \eqref, one can get it by using a
|
||||
@ -271,10 +263,12 @@ void InsetRef::latex(otexstream & os, OutputParams const & rp) const
|
||||
else if (cmd == "formatted") {
|
||||
docstring label;
|
||||
docstring prefix;
|
||||
bool const use_caps = getParam("caps") == "true";
|
||||
bool const use_plural = getParam("plural") == "true";
|
||||
docstring const fcmd =
|
||||
getFormattedCmd(data, label, prefix, getParam("caps"));
|
||||
getFormattedCmd(data, label, prefix, use_caps);
|
||||
os << fcmd;
|
||||
if (buffer().params().use_refstyle && getParam("plural") == "true")
|
||||
if (buffer().params().use_refstyle && use_plural)
|
||||
os << "[s]";
|
||||
os << '{' << label << '}';
|
||||
}
|
||||
@ -542,9 +536,11 @@ void InsetRef::validate(LaTeXFeatures & features) const
|
||||
docstring const data = getEscapedLabel(features.runparams());
|
||||
docstring label;
|
||||
docstring prefix;
|
||||
bool const use_refstyle = buffer().params().use_refstyle;
|
||||
bool const use_caps = getParam("caps") == "true";
|
||||
docstring const fcmd =
|
||||
getFormattedCmd(data, label, prefix, getParam("caps"));
|
||||
if (buffer().params().use_refstyle) {
|
||||
getFormattedCmd(data, label, prefix, use_refstyle, use_caps);
|
||||
if (use_refstyle) {
|
||||
features.require("refstyle");
|
||||
if (prefix == "cha")
|
||||
features.addPreambleSnippet(from_ascii("\\let\\charef=\\chapref"));
|
||||
|
@ -90,6 +90,13 @@ public:
|
||||
//@}
|
||||
///
|
||||
bool outputActive() const { return active_; }
|
||||
/// \return the command for a formatted reference to ref
|
||||
/// \param label we're cross-referencing
|
||||
/// \param argument for reference command
|
||||
/// \param prefix of the label (before :)
|
||||
/// Also used by InsetMathRef
|
||||
static docstring getFormattedCmd(docstring const & ref, docstring & label,
|
||||
docstring & prefix, bool use_refstyle, bool use_caps = false);
|
||||
|
||||
protected:
|
||||
///
|
||||
@ -110,12 +117,6 @@ private:
|
||||
|
||||
/// \return the label with things that need to be escaped escaped
|
||||
docstring getEscapedLabel(OutputParams const &) const;
|
||||
/// \return the command for a formatted reference to ref
|
||||
/// \param label we're cross-referencing
|
||||
/// \param argument for reference command
|
||||
/// \param prefix of the label (before :)
|
||||
docstring getFormattedCmd(docstring const & ref, docstring & label,
|
||||
docstring & prefix, docstring const & caps) const;
|
||||
|
||||
///
|
||||
mutable docstring screen_label_;
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include "InsetMathRef.h"
|
||||
|
||||
#include "BufferParams.h"
|
||||
#include "BufferView.h"
|
||||
#include "Buffer.h"
|
||||
#include "Cursor.h"
|
||||
@ -21,14 +22,18 @@
|
||||
#include "LyX.h"
|
||||
#include "MathData.h"
|
||||
#include "MathFactory.h"
|
||||
#include "MathStream.h"
|
||||
#include "MathSupport.h"
|
||||
#include "ParIterator.h"
|
||||
#include "xml.h"
|
||||
|
||||
#include "insets/InsetCommand.h"
|
||||
#include "insets/InsetRef.h"
|
||||
|
||||
#include "support/debug.h"
|
||||
#include "support/gettext.h"
|
||||
#include "support/lstrings.h"
|
||||
#include "support/textutils.h"
|
||||
|
||||
#include <ostream>
|
||||
|
||||
@ -75,7 +80,9 @@ void InsetMathRef::doDispatch(Cursor & cur, FuncRequest & cmd)
|
||||
MathData ar;
|
||||
if (createInsetMath_fromDialogStr(cmd.argument(), ar)) {
|
||||
cur.recordUndo();
|
||||
Buffer & buf = buffer();
|
||||
*this = *ar[0].nucleus()->asRefInset();
|
||||
setBuffer(buf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -170,11 +177,24 @@ docstring const InsetMathRef::screenLabel() const
|
||||
|
||||
void InsetMathRef::validate(LaTeXFeatures & features) const
|
||||
{
|
||||
// This really should not happen here but does.
|
||||
if (!buffer_) {
|
||||
LYXERR0("Unassigned buffer_ in InsetMathRef::write!");
|
||||
LYXERR0("LaTeX output may be wrong!");
|
||||
}
|
||||
bool const use_refstyle =
|
||||
buffer_ && buffer().params().use_refstyle;
|
||||
|
||||
if (commandname() == "vref" || commandname() == "vpageref")
|
||||
features.require("varioref");
|
||||
else if (commandname() == "prettyref")
|
||||
features.require("prettyref");
|
||||
else if (commandname() == "eqref")
|
||||
else if (commandname() == "formatted") {
|
||||
if (use_refstyle)
|
||||
features.require("refstyle");
|
||||
else
|
||||
features.require("prettyref");
|
||||
}
|
||||
// if eqref is used with refstyle, we do our own output
|
||||
else if (commandname() == "eqref" && use_refstyle)
|
||||
features.require("amsmath");
|
||||
else if (commandname() == "nameref")
|
||||
features.require("nameref");
|
||||
@ -240,14 +260,99 @@ void InsetMathRef::changeTarget(docstring const & target)
|
||||
}
|
||||
|
||||
|
||||
void InsetMathRef::write(TeXMathStream & os) const
|
||||
{
|
||||
docstring const & cmd = commandname();
|
||||
// This should not happen, but of course it does
|
||||
if (!buffer_) {
|
||||
LYXERR0("Unassigned buffer_ in InsetMathRef::write!");
|
||||
LYXERR0("LaTeX output may be wrong!");
|
||||
}
|
||||
bool const use_refstyle =
|
||||
buffer_ && buffer().params().use_refstyle;
|
||||
bool special_case = cmd == "formatted" ||
|
||||
cmd == "labelonly" ||
|
||||
(cmd == "eqref" && use_refstyle);
|
||||
// are we writing to the LyX file or not in a special case?
|
||||
if (!os.latex() || !special_case) {
|
||||
// if so, then this is easy
|
||||
InsetMathCommand::write(os);
|
||||
return;
|
||||
}
|
||||
// we need to translate 'formatted' to prettyref or refstyle-type
|
||||
// commands and just output the label with labelonly
|
||||
// most of this is borrowed from InsetRef and should be kept in
|
||||
// sync with that.
|
||||
ModeSpecifier specifier(os, currentMode(), lockedMode(), asciiOnly());
|
||||
MathEnsurer ensurer(os, false);
|
||||
|
||||
if (use_refstyle && cmd == "eqref") {
|
||||
// we advertise this as printing "(n)", so we'll do that, at least
|
||||
// for refstyle, since refstlye's own \eqref prints, by default,
|
||||
// "equation n". if one wants \eqref, one can get it by using a
|
||||
// formatted label in this case.
|
||||
os << '(' << from_ascii("\\ref{") << cell(0) << from_ascii("})");
|
||||
}
|
||||
else if (cmd == "formatted") {
|
||||
if (!use_refstyle)
|
||||
os << "\\prettyref{" << cell(0) << "}";
|
||||
else {
|
||||
odocstringstream ods;
|
||||
// get the label we are referencing
|
||||
for (auto const & d : cell(0)) {
|
||||
ods << d;
|
||||
}
|
||||
docstring const ref = ods.str();
|
||||
|
||||
/*
|
||||
At the moment, the 'plural' and 'caps' options will
|
||||
not work here. The reason is that we handle these as
|
||||
'internal' LyX argumemts, but those are not handled by
|
||||
InsetCommandParams::getCommand, which is what is used
|
||||
in createInsetMath_fromDialogStr to interpret the data
|
||||
coming from the dialog.
|
||||
If this is fixed, then what follows will get the info
|
||||
we need.
|
||||
Fixing it, I think, would mean sub-classing
|
||||
InsetCommandParams to InsetRefParams, and the overriding
|
||||
getCommand.
|
||||
*******************************************************
|
||||
// reset
|
||||
ods.str(docstring());
|
||||
ods.clear();
|
||||
// get the options from the optional argument
|
||||
for (auto const & d : cell(1))
|
||||
ods << d;
|
||||
docstring const options = ods.str();
|
||||
bool const caps = support::contains(options, 'C');
|
||||
bool const plural = support::contains(options, 's');
|
||||
*/
|
||||
docstring label;
|
||||
docstring prefix;
|
||||
docstring const fcmd =
|
||||
InsetRef::getFormattedCmd(ref, label, prefix, true);
|
||||
os << fcmd;
|
||||
//if (plural)
|
||||
// os << "[s]";
|
||||
os << '{' << label << '}';
|
||||
}
|
||||
}
|
||||
else if (cmd == "labelonly") {
|
||||
// noprefix does not work here, for reasons given above.
|
||||
os << cell(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
InsetMathRef::ref_type_info InsetMathRef::types[] = {
|
||||
{ from_ascii("ref"), from_ascii(N_("Standard[[mathref]]")), from_ascii(N_("Ref: "))},
|
||||
{ from_ascii("eqref"), from_ascii(N_("Equation")), from_ascii(N_("EqRef: "))},
|
||||
{ from_ascii("pageref"), from_ascii(N_("Page Number")), from_ascii(N_("Page: "))},
|
||||
{ from_ascii("vpageref"), from_ascii(N_("Textual Page Number")), from_ascii(N_("TextPage: "))},
|
||||
{ from_ascii("vref"), from_ascii(N_("Standard+Textual Page")), from_ascii(N_("Ref+Text: "))},
|
||||
{ from_ascii("prettyref"), from_ascii(N_("PrettyRef")), from_ascii(N_("FormatRef: "))},
|
||||
{ from_ascii("formatted"), from_ascii(N_("PrettyRef")), from_ascii(N_("FormatRef: "))},
|
||||
{ from_ascii("nameref"), from_ascii(N_("Reference to Name")), from_ascii(N_("NameRef: "))},
|
||||
{ from_ascii("labelonly"), from_ascii(N_("Label Only")), from_ascii(N_("Label Only: "))},
|
||||
{ from_ascii(""), from_ascii(""), from_ascii("") }
|
||||
};
|
||||
|
||||
|
@ -29,7 +29,7 @@ public:
|
||||
///
|
||||
void updateBuffer(ParIterator const &, UpdateType, bool const deleted = false) override;
|
||||
///
|
||||
//void write(TeXMathStream & os) const override;
|
||||
void write(TeXMathStream & os) const override;
|
||||
///
|
||||
void infoize(odocstream & os) const override;
|
||||
///
|
||||
@ -62,10 +62,6 @@ public:
|
||||
};
|
||||
static ref_type_info types[];
|
||||
///
|
||||
static int getType(docstring const & name);
|
||||
///
|
||||
static docstring const & getName(int type);
|
||||
///
|
||||
docstring const getTarget() const;
|
||||
///
|
||||
InsetCode lyxCode() const override { return MATH_REF_CODE; }
|
||||
|
@ -1546,7 +1546,8 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
|
||||
|
||||
else if (t.cs() == "ref" || t.cs() == "eqref" || t.cs() == "prettyref"
|
||||
|| t.cs() == "nameref" || t.cs() == "pageref"
|
||||
|| t.cs() == "vpageref" || t.cs() == "vref") {
|
||||
|| t.cs() == "vpageref" || t.cs() == "vref"
|
||||
|| t.cs() == "formatted" || t.cs() == "labelonly") {
|
||||
cell->push_back(MathAtom(new InsetMathRef(buf, t.cs())));
|
||||
docstring const opt = parse_verbatim_option();
|
||||
docstring const ref = parse_verbatim_item();
|
||||
|
@ -543,6 +543,14 @@ docstring const uppercase(docstring const & a)
|
||||
}
|
||||
|
||||
|
||||
docstring capitalize(docstring const & s) {
|
||||
docstring ret = s;
|
||||
char_type t = uppercase(ret[0]);
|
||||
ret[0] = t;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
string const ascii_lowercase(string const & a)
|
||||
{
|
||||
string tmp(a);
|
||||
|
@ -181,6 +181,8 @@ docstring const token(docstring const & a, char_type delim, int n);
|
||||
int tokenPos(std::string const & a, char delim, std::string const & tok);
|
||||
int tokenPos(docstring const & a, char_type delim, docstring const & tok);
|
||||
|
||||
///
|
||||
docstring capitalize(docstring const & s);
|
||||
|
||||
/// Substitute all \a oldchar with \a newchar
|
||||
std::string const subst(std::string const & a, char oldchar, char newchar);
|
||||
|
@ -32,8 +32,8 @@ extern char const * const lyx_version_info;
|
||||
|
||||
// Do not remove the comment below, so we get merge conflict in
|
||||
// independent branches. Instead add your own.
|
||||
#define LYX_FORMAT_LYX 600 // spitz: hungarian quote style
|
||||
#define LYX_FORMAT_TEX2LYX 600
|
||||
#define LYX_FORMAT_LYX 601 // rkh: refstyle in math
|
||||
#define LYX_FORMAT_TEX2LYX 601
|
||||
|
||||
#if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX
|
||||
#ifndef _MSC_VER
|
||||
|
Loading…
Reference in New Issue
Block a user