[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