X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2FInsetRef.cpp;h=49cf630b78b6ed0b97d4ef8c5522586cc9a69da9;hb=6cffef87d26a9aad1ce3394095851f1b3056d61c;hp=e9b26953976a729bb4e2a2967859600f1d6fd865;hpb=3883b85f49054c109cb8a9a293721a5e41edb68d;p=lyx.git diff --git a/src/insets/InsetRef.cpp b/src/insets/InsetRef.cpp index e9b2695397..49cf630b78 100644 --- a/src/insets/InsetRef.cpp +++ b/src/insets/InsetRef.cpp @@ -20,10 +20,10 @@ #include "Language.h" #include "LaTeXFeatures.h" #include "LyX.h" -#include "OutputParams.h" #include "output_xhtml.h" #include "Paragraph.h" #include "ParIterator.h" +#include "PDFOptions.h" #include "xml.h" #include "texstream.h" #include "TocBackend.h" @@ -75,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_; } @@ -104,6 +105,13 @@ void InsetRef::changeTarget(docstring const & new_label) void InsetRef::doDispatch(Cursor & cur, FuncRequest & cmd) { + // Ctrl + click: go to label + if (cmd.action() == LFUN_MOUSE_RELEASE && cmd.modifier() == ControlModifier) { + lyx::dispatch(FuncRequest(LFUN_BOOKMARK_SAVE, "0")); + lyx::dispatch(FuncRequest(LFUN_LABEL_GOTO, getParam("reference"))); + return; + } + string const inset = cmd.getArg(0); string const arg = cmd.getArg(1); string pstring; @@ -114,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); @@ -124,12 +134,14 @@ void InsetRef::doDispatch(Cursor & cur, FuncRequest & cmd) return; } } + // otherwise not for us if (pstring.empty()) return InsetCommand::doDispatch(cur, cmd); bool const isSet = (getParam(pstring) == "true"); setParam(pstring, from_ascii(isSet ? "false" : "true")); + cur.forceBufferUpdate(); } @@ -162,21 +174,17 @@ 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); } -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. // @@ -192,7 +200,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"); @@ -209,19 +218,20 @@ 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; } // make sure the prefix is legal for a latex command - int const len = prefix.size(); - for (int i = 0; i < len; i++) { + size_t const len = prefix.size(); + for (size_t i = 0; i < len; i++) { char_type const c = prefix[i]; if (!isAlphaASCII(c)) { LYXERR0("Prefix `" << prefix << "' is invalid for LaTeX."); @@ -230,8 +240,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"); } @@ -250,24 +260,32 @@ 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{"; - 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 // 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; docstring prefix; + bool const use_caps = getParam("caps") == "true"; + bool const use_plural = getParam("plural") == "true"; + bool const use_refstyle = buffer().params().use_refstyle; docstring const fcmd = - getFormattedCmd(data, label, prefix, getParam("caps")); + getFormattedCmd(data, label, prefix, use_refstyle, use_caps); os << fcmd; - if (buffer().params().use_refstyle && getParam("plural") == "true") + if (use_refstyle && use_plural) os << "[s]"; os << '{' << label << '}'; } @@ -287,12 +305,11 @@ void InsetRef::latex(otexstream & os, OutputParams const & rp) const } } else { - // We don't want to output p_["name"], since that is only used - // in docbook. So we construct new params, without it, and use that. 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) @@ -305,7 +322,7 @@ int InsetRef::plaintext(odocstringstream & os, { docstring const str = getParam("reference"); os << '[' << str << ']'; - return 2 + str.size(); + return 2 + int(str.size()); } @@ -356,7 +373,7 @@ void InsetRef::docbook(XMLStream & xs, OutputParams const &) const } // No name, ask DocBook to generate one. - docstring attr = from_utf8("linkend=\"") + ref + from_utf8("\""); + docstring attr = from_utf8("linkend=\"") + xml::cleanID(ref) + from_utf8("\""); if (!role.empty()) attr += " role=\"" + role + "\""; xs << display_before; @@ -387,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... @@ -417,16 +434,18 @@ docstring InsetRef::xhtml(XMLStream & xs, OutputParams const & op) const void InsetRef::toString(odocstream & os) const { odocstringstream ods; - plaintext(ods, OutputParams(0)); + plaintext(ods, OutputParams(nullptr)); os << ods.str(); } void InsetRef::forOutliner(docstring & os, size_t const, bool const) const { - // There's no need for details in the TOC, and a long label - // will just get in the way. - os += '#'; + // It's hard to know what to do here. Should we show XREF in the TOC? + // Or should we just show that there is one? For now, we do the former. + odocstringstream ods; + plaintext(ods, OutputParams(nullptr)); + os += ods.str(); } @@ -458,6 +477,24 @@ 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"; + bool const isCaps = getParam("caps") == "true"; + if (isCaps) { + // up arrow (shift key) symbol + label += docstring(1, char_type(0x21E7)); + } + if (isPlural) + label += from_ascii("+"); + } + label += from_ascii(": "); break; } } @@ -508,7 +545,7 @@ void InsetRef::addToToc(DocIterator const & cpit, bool output_active, active_ = output_active; docstring const & label = getParam("reference"); if (buffer().insetLabel(label)) { - broken_ = !buffer().activeLabel(label); + broken_ = !buffer().activeLabel(label) && active_; setBroken(broken_); if (broken_ && output_active) { shared_ptr toc2 = backend.toc("brokenrefs"); @@ -522,7 +559,9 @@ void InsetRef::addToToc(DocIterator const & cpit, bool output_active, broken_ = true; setBroken(broken_); shared_ptr toc = backend.toc("label"); - toc->push_back(TocItem(cpit, 0, screenLabel(), output_active)); + if (TocBackend::findItem(*toc, 0, label) == toc->end()) + toc->push_back(TocItem(cpit, 0, label, output_active, true)); + toc->push_back(TocItem(cpit, 1, screenLabel(), output_active)); shared_ptr toc2 = backend.toc("brokenrefs"); toc2->push_back(TocItem(cpit, 0, screenLabel(), output_active)); } @@ -530,16 +569,18 @@ void InsetRef::addToToc(DocIterator const & cpit, bool output_active, void InsetRef::validate(LaTeXFeatures & features) const { - string const cmd = getCmdName(); + string const & cmd = getCmdName(); if (cmd == "vref" || cmd == "vpageref") features.require("varioref"); else if (cmd == "formatted") { 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")); @@ -577,14 +618,14 @@ bool InsetRef::forceLTR(OutputParams const & rp) const InsetRef::type_info const InsetRef::types[] = { - { "ref", N_("Standard"), N_("Ref: ")}, - { "eqref", N_("Equation"), N_("EqRef: ")}, - { "pageref", N_("Page Number"), N_("Page: ")}, - { "vpageref", N_("Textual Page Number"), N_("TextPage: ")}, - { "vref", N_("Standard+Textual Page"), N_("Ref+Text: ")}, - { "nameref", N_("Reference to Name"), N_("NameRef: ")}, - { "formatted", N_("Formatted"), N_("Format: ")}, - { "labelonly", N_("Label Only"), N_("Label: ")}, + { "ref", N_("Standard"), N_("Ref")}, + { "eqref", N_("Equation"), N_("EqRef")}, + { "pageref", N_("Page Number"), N_("Page")}, + { "vpageref", N_("Textual Page Number"), N_("TextPage")}, + { "vref", N_("Standard+Textual Page"), N_("Ref+Text")}, + { "nameref", N_("Reference to Name"), N_("NameRef")}, + { "formatted", N_("Formatted"), N_("Format")}, + { "labelonly", N_("Label Only"), N_("Label")}, { "", "", "" } };