[LyX/master] Fix bug #11410.
Richard Kimberly Heck
rikiheck at lyx.org
Sun Dec 4 22:39:50 UTC 2022
commit d4f2460ac4707aa4d9302c6257fc2511fa0dc54f
Author: Richard Kimberly Heck <rikiheck at lyx.org>
Date: Sun Dec 4 18:33:58 2022 -0500
Fix bug #11410.
Main part of patch from Daniel, adapted by me.
I also added the lyx2lyx code.
---
lib/lyx2lyx/lyx_2_4.py | 81 ++++++++++++++++++++++++++++++++++++-
lib/ui/stdcontext.inc | 1 +
src/frontends/qt/GuiRef.cpp | 9 ++++
src/frontends/qt/ui/RefUi.ui | 7 +++
src/insets/InsetCommandParams.cpp | 4 +-
src/insets/InsetCommandParams.h | 2 +-
src/insets/InsetRef.cpp | 26 +++++++++++-
src/tex2lyx/TODO.txt | 2 +-
src/version.h | 4 +-
9 files changed, 127 insertions(+), 9 deletions(-)
diff --git a/lib/lyx2lyx/lyx_2_4.py b/lib/lyx2lyx/lyx_2_4.py
index 5c0507a..e10475b 100644
--- a/lib/lyx2lyx/lyx_2_4.py
+++ b/lib/lyx2lyx/lyx_2_4.py
@@ -4550,6 +4550,81 @@ def revert_index_macros(document):
document.body[pl:pl+1] = document.body[pl:pl] + sortkey + put_cmd_in_ert("@")
+def revert_starred_refs(document):
+ i = find_token(document.header, "\\use_hyperref true", 0)
+ use_hyperref = (i != -1)
+ i = 0
+ in_inset = False
+ cmd = ref = ""
+ plural = caps = noprefix = nolink = False
+ nolinkline = -1
+ while True:
+ if not in_inset:
+ i = find_token(document.body, "\\begin_inset CommandInset ref", i)
+ if i == -1:
+ break
+ start = i
+ end = find_end_of_inset(document.body, i)
+ if end == -1:
+ document.warning("Malformed LyX document: Can't find end of inset at line %d" % i)
+ i += 1
+ continue
+ # If we are not using hyperref, then we just need to delete the line
+ if not use_hyperref:
+ i = find_token(document.body, "nolink", i, e)
+ if i == -1:
+ continue
+ del document.body[i]
+ i = e - 1
+ continue
+ # If we are using hyperref, then we'll need to do more.
+ in_inset = True
+ i += 1
+ continue
+ # so we are in an InsetRef
+ if i == end:
+ in_inset = False
+ # If nolink is False, just remove that line
+ if nolink == False or cmd == "formatted":
+ # document.warning("Skipping " + cmd + " " + ref)
+ if nolinkline != -1:
+ del document.body[nolinkline]
+ continue
+ # We need to construct a new command and put it in ERT
+ newcmd = "\\" + cmd + "*{" + ref + "}"
+ # document.warning(newcmd)
+ newlines = put_cmd_in_ert(newcmd)
+ document.body[start:end+1] = newlines
+ i += len(newlines) - (end - start) + 1
+ # reset variables
+ cmd = ref = ""
+ plural = caps = noprefix = nolink = False
+ nolinkline = -1
+ continue
+ l = document.body[i]
+ if l.startswith("LatexCommand"):
+ cmd = l[13:]
+ elif l.startswith("reference"):
+ ref = l[11:-1]
+ elif l.startswith("caps"):
+ tmp = l[6:-1]
+ caps = (tmp == "true")
+ elif l.startswith("plural"):
+ tmp = l[8:-1]
+ plural = (tmp == "true")
+ elif l.startswith("noprefix"):
+ tmp = l[10:-1]
+ noprefix = (tmp == "true")
+ elif l.startswith("nolink"):
+ tmp = l[8:-1]
+ nolink = (tmp == "true")
+ nolinkline = i
+ i += 1
+
+
+
+
+
##
# Conversion hub
#
@@ -4622,10 +4697,12 @@ convert = [
[608, []],
[609, []],
[610, []],
- [611, []]
+ [611, []],
+ [612, []]
]
-revert = [[610, []],
+revert = [[611, [revert_starred_refs]],
+ [610, []],
[609, [revert_index_macros]],
[608, [revert_document_metadata]],
[607, [revert_docbook_mathml_prefix]],
diff --git a/lib/ui/stdcontext.inc b/lib/ui/stdcontext.inc
index 210e555..0b0d32f 100644
--- a/lib/ui/stdcontext.inc
+++ b/lib/ui/stdcontext.inc
@@ -124,6 +124,7 @@ Menuset
OptItem "Plural|a" "inset-modify ref toggle-plural"
OptItem "Capitalize|C" "inset-modify ref toggle-caps"
OptItem "No Prefix" "inset-modify ref toggle-noprefix"
+ OptItem "No Hyperlink" "inset-modify ref toggle-nolink"
Separator
Item "Settings...|S" "inset-settings"
End
diff --git a/src/frontends/qt/GuiRef.cpp b/src/frontends/qt/GuiRef.cpp
index eff0917..d5a551e 100644
--- a/src/frontends/qt/GuiRef.cpp
+++ b/src/frontends/qt/GuiRef.cpp
@@ -22,6 +22,7 @@
#include "Cursor.h"
#include "FancyLineEdit.h"
#include "FuncRequest.h"
+#include "PDFOptions.h"
#include "qt_helpers.h"
@@ -109,6 +110,8 @@ GuiRef::GuiRef(GuiView & lv)
this, SLOT(changed_adaptor()));
connect(noprefixCB, SIGNAL(clicked()),
this, SLOT(changed_adaptor()));
+ connect(nolinkCB, SIGNAL(clicked()),
+ this, SLOT(changed_adaptor()));
enableBoxes();
@@ -142,9 +145,12 @@ void GuiRef::enableBoxes()
bool const isLabelOnly = (reftype == "labelonly");
bool const usingRefStyle = buffer().params().use_refstyle;
bool const intext = bufferview()->cursor().inTexted();
+ bool const hyper_on = buffer().params().pdfoptions().use_hyperref;
pluralCB->setEnabled(intext && isFormatted && usingRefStyle);
capsCB->setEnabled(intext && isFormatted && usingRefStyle);
noprefixCB->setEnabled(intext && isLabelOnly);
+ // disabling of hyperlinks not supported by formatted references
+ nolinkCB->setEnabled(hyper_on && intext && !isFormatted && !isLabelOnly);
}
@@ -338,6 +344,7 @@ void GuiRef::updateContents()
pluralCB->setChecked(params_["plural"] == "true");
capsCB->setChecked(params_["caps"] == "true");
noprefixCB->setChecked(params_["noprefix"] == "true");
+ nolinkCB->setChecked(params_["nolink"] == "true");
// insert buffer list
bufferCO->clear();
@@ -380,6 +387,8 @@ void GuiRef::applyView()
from_ascii("true") : from_ascii("false");
params_["noprefix"] = noprefixCB->isChecked() ?
from_ascii("true") : from_ascii("false");
+ params_["nolink"] = nolinkCB->isChecked() ?
+ from_ascii("true") : from_ascii("false");
restored_buffer_ = bufferCO->currentIndex();
}
diff --git a/src/frontends/qt/ui/RefUi.ui b/src/frontends/qt/ui/RefUi.ui
index 0f4a7d3..a8391e0 100644
--- a/src/frontends/qt/ui/RefUi.ui
+++ b/src/frontends/qt/ui/RefUi.ui
@@ -335,6 +335,13 @@
</widget>
</item>
<item>
+ <widget class="QCheckBox" name="nolinkCB">
+ <property name="text">
+ <string>No Hyperlink</string>
+ </property>
+ </widget>
+ </item>
+ <item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
diff --git a/src/insets/InsetCommandParams.cpp b/src/insets/InsetCommandParams.cpp
index bff358f..94b9a2c 100644
--- a/src/insets/InsetCommandParams.cpp
+++ b/src/insets/InsetCommandParams.cpp
@@ -553,9 +553,11 @@ docstring InsetCommandParams::prepareCommand(OutputParams const & runparams,
}
-docstring InsetCommandParams::getCommand(OutputParams const & runparams) const
+docstring InsetCommandParams::getCommand(OutputParams const & runparams, bool starred) const
{
docstring s = '\\' + from_ascii(cmdName_);
+ if (starred)
+ s += from_utf8("*");
bool noparam = true;
ParamInfo::const_iterator it = info_.begin();
ParamInfo::const_iterator end = info_.end();
diff --git a/src/insets/InsetCommandParams.h b/src/insets/InsetCommandParams.h
index 7ed182a..134b46a 100644
--- a/src/insets/InsetCommandParams.h
+++ b/src/insets/InsetCommandParams.h
@@ -136,7 +136,7 @@ public:
///
void Write(std::ostream & os, Buffer const * buf) const;
/// Build the complete LaTeX command
- docstring getCommand(OutputParams const &) const;
+ docstring getCommand(OutputParams const &, bool starred = false) const;
/// Return the command name
std::string const & getCmdName() const { return cmdName_; }
/// Set the name to \p n. This must be a known name. All parameters
diff --git a/src/insets/InsetRef.cpp b/src/insets/InsetRef.cpp
index eab3e69..ed193f7 100644
--- a/src/insets/InsetRef.cpp
+++ b/src/insets/InsetRef.cpp
@@ -23,6 +23,7 @@
#include "output_xhtml.h"
#include "Paragraph.h"
#include "ParIterator.h"
+#include "PDFOptions.h"
#include "xml.h"
#include "texstream.h"
#include "TocBackend.h"
@@ -74,6 +75,7 @@ ParamInfo const & InsetRef::findInfo(string const & /* cmdName */)
param_info_.add("plural", ParamInfo::LYX_INTERNAL);
param_info_.add("caps", ParamInfo::LYX_INTERNAL);
param_info_.add("noprefix", ParamInfo::LYX_INTERNAL);
+ param_info_.add("nolink", ParamInfo::LYX_INTERNAL);
}
return param_info_;
}
@@ -120,6 +122,8 @@ void InsetRef::doDispatch(Cursor & cur, FuncRequest & cmd)
pstring = "caps";
else if (arg == "toggle-noprefix")
pstring = "noprefix";
+ else if (arg == "toggle-nolink")
+ pstring = "nolink";
else if (arg == "changetarget") {
string const oldtarget = cmd.getArg(2);
string const newtarget = cmd.getArg(3);
@@ -170,6 +174,12 @@ bool InsetRef::getStatus(Cursor & cur, FuncRequest const & cmd,
status.setOnOff(isSet);
return true;
}
+ if (arg == "toggle-nolink") {
+ status.setEnabled(params().getCmdName() != "formatted" && params().getCmdName() != "labelonly");
+ bool const isSet = (getParam("nolink") == "true");
+ status.setOnOff(isSet);
+ return true;
+ }
// otherwise not for us
return InsetCommand::getStatus(cur, cmd, status);
}
@@ -250,6 +260,7 @@ void InsetRef::latex(otexstream & os, OutputParams const & rp) const
{
string const & cmd = getCmdName();
docstring const & data = getEscapedLabel(rp);
+ bool const hyper_on = buffer().params().pdfoptions().use_hyperref;
if (rp.inulemcmd > 0)
os << "\\mbox{";
@@ -259,7 +270,11 @@ void InsetRef::latex(otexstream & os, OutputParams const & rp) const
// 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{") << data << from_ascii("})");
+ bool const use_nolink = hyper_on && getParam("nolink") == "true";
+ os << '(' << from_ascii("\\ref") +
+ // no hyperlink version?
+ (use_nolink ? from_utf8("*") : from_utf8("")) +
+ from_ascii("{") << data << from_ascii("})");
}
else if (cmd == "formatted") {
docstring label;
@@ -291,9 +306,10 @@ void InsetRef::latex(otexstream & os, OutputParams const & rp) const
}
else {
InsetCommandParams p(REF_CODE, cmd);
+ bool const use_nolink = hyper_on && getParam("nolink") == "true";
docstring const ref = getParam("reference");
p["reference"] = ref;
- os << p.getCommand(rp);
+ os << p.getCommand(rp, use_nolink);
}
if (rp.inulemcmd > 0)
@@ -461,6 +477,12 @@ void InsetRef::updateBuffer(ParIterator const & it, UpdateType, bool const /*del
for (int i = 0; !types[i].latex_name.empty(); ++i) {
if (cmd == types[i].latex_name) {
label = _(types[i].short_gui_name);
+ // indicate no hyperlink (starred)
+ if (cmd != "formatted" && cmd != "labelonly") {
+ bool const isNoLink = getParam("nolink") == "true";
+ if (isNoLink)
+ label += from_ascii("*");
+ }
// indicate plural and caps
if (cmd == "formatted") {
bool const isPlural = getParam("plural") == "true";
diff --git a/src/tex2lyx/TODO.txt b/src/tex2lyx/TODO.txt
index 3c6693e..001d6cf 100644
--- a/src/tex2lyx/TODO.txt
+++ b/src/tex2lyx/TODO.txt
@@ -34,7 +34,7 @@ Format LaTeX feature LyX feature
443 unicode-math.sty InsetMath*
453 automatic stmaryrd loading \use_package stmaryrd
457 automatic stackrel loading \use_package stackrel
-
+612 starred reference commands
General
diff --git a/src/version.h b/src/version.h
index bfcd986..a643509 100644
--- a/src/version.h
+++ b/src/version.h
@@ -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 611 // Yuriy Skalko: semantic linefeeds
-#define LYX_FORMAT_TEX2LYX 611
+#define LYX_FORMAT_LYX 612 // RKH & DR: Starred cross-references
+#define LYX_FORMAT_TEX2LYX 612
#if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX
#ifndef _MSC_VER
More information about the lyx-cvs
mailing list