diff --git a/development/FORMAT b/development/FORMAT index 3c464f339f..d03a6b4547 100644 --- a/development/FORMAT +++ b/development/FORMAT @@ -7,6 +7,11 @@ changes happened in particular if possible. A good example would be ----------------------- +2017-01-28 Jürgen Spitzmüller + * Format incremented to 532: literal command inset parameter. + With this, inset command params with ParamInfo::HANDLING_LATEXIFY + can be passed to LaTeX either verbatim or latexified. + 2017-01-21 Jürgen Spitzmüller * Format incremented to 531: Support for qualified citation lists. \begin_inset CommandInset citation diff --git a/lib/lyx2lyx/lyx_2_3.py b/lib/lyx2lyx/lyx_2_3.py index 044bc755f1..23bdda8e0b 100644 --- a/lib/lyx2lyx/lyx_2_3.py +++ b/lib/lyx2lyx/lyx_2_3.py @@ -1547,6 +1547,54 @@ def revert_qualicites(document): i += 1 +command_insets = ["bibitem", "citation", "href", "index_print", "nomenclature"] +def convert_literalparam(document): + " Add param literal " + + # These already had some sort of latexify method + latexified_insets = ["href", "index_print", "nomenclature"] + + for inset in command_insets: + i = 0 + while True: + i = find_token(document.body, '\\begin_inset CommandInset %s' % inset, i) + if i == -1: + break + j = find_end_of_inset(document.body, i) + if j == -1: + document.warning("Malformed LyX document: Can't find end of %s inset at line %d" % (inset, i)) + i += 1 + continue + while i < j and document.body[i].strip() != '': + i += 1 + if inset in latexified_insets: + document.body.insert(i, "literal \"false\"") + else: + document.body.insert(i, "literal \"true\"") + + + +def revert_literalparam(document): + " Remove param literal " + + for inset in command_insets: + i = 0 + while True: + i = find_token(document.body, '\\begin_inset CommandInset %s' % inset, i) + if i == -1: + break + j = find_end_of_inset(document.body, i) + if j == -1: + document.warning("Malformed LyX document: Can't find end of %s inset at line %d" % (inset, i)) + i += 1 + continue + k = find_token(document.body, 'literal', i, j) + if k == -1: + i += 1 + continue + del document.body[k] + + ## # Conversion hub # @@ -1575,10 +1623,12 @@ convert = [ [528, []], [529, []], [530, []], - [531, []] + [531, []], + [532, [convert_literalparam]] ] revert = [ + [531, [revert_literalparam]], [530, [revert_qualicites]], [529, [revert_bibpackopts]], [528, [revert_citekeyonly]], diff --git a/src/BufferParams.cpp b/src/BufferParams.cpp index 2736c26977..e044d4e45a 100644 --- a/src/BufferParams.cpp +++ b/src/BufferParams.cpp @@ -1961,20 +1961,7 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, IndicesList::const_iterator iit = indiceslist().begin(); IndicesList::const_iterator iend = indiceslist().end(); for (; iit != iend; ++iit) { - pair indexname_latex = - features.runparams().encoding->latexString(iit->index(), - features.runparams().dryrun); - if (!indexname_latex.second.empty()) { - // issue a warning about omitted characters - // FIXME: should be passed to the error dialog - frontend::Alert::warning(_("Uncodable characters"), - bformat(_("The following characters that are used in an index name are not\n" - "representable in the current encoding and therefore have been omitted:\n%1$s."), - indexname_latex.second)); - } - os << "\\newindex["; - os << indexname_latex.first; - os << "]{"; + os << "\\newindex{"; os << escape(iit->shortcut()); os << "}\n"; } diff --git a/src/frontends/qt4/GuiBibitem.cpp b/src/frontends/qt4/GuiBibitem.cpp index 052be00f36..b29f8a8704 100644 --- a/src/frontends/qt4/GuiBibitem.cpp +++ b/src/frontends/qt4/GuiBibitem.cpp @@ -32,6 +32,8 @@ GuiBibitem::GuiBibitem(QWidget * parent) : InsetParamsWidget(parent) this, SIGNAL(changed())); connect(labelED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); + connect(literalCB, SIGNAL(clicked()), + this, SIGNAL(changed())); } @@ -41,6 +43,7 @@ void GuiBibitem::paramsToDialog(Inset const * inset) InsetCommandParams const & params = ic->params(); keyED->setText(toqstr(params["key"])); labelED->setText(toqstr(params["label"])); + literalCB->setChecked(params["literal"] == "true"); } @@ -49,6 +52,8 @@ docstring GuiBibitem::dialogToParams() const InsetCommandParams params(insetCode()); params["key"] = qstring_to_ucs4(keyED->text()); params["label"] = qstring_to_ucs4(labelED->text()); + params["literal"] = literalCB->isChecked() + ? from_ascii("true") : from_ascii("false"); return from_utf8(InsetCommand::params2string(params)); } diff --git a/src/frontends/qt4/GuiCitation.cpp b/src/frontends/qt4/GuiCitation.cpp index 2178dd1101..826a814cd6 100644 --- a/src/frontends/qt4/GuiCitation.cpp +++ b/src/frontends/qt4/GuiCitation.cpp @@ -127,6 +127,8 @@ GuiCitation::GuiCitation(GuiView & lv) this, SLOT(on_citationStyleCO_currentIndexChanged(int))); connect(starredCB, SIGNAL(clicked()), this, SLOT(updateStyles())); + connect(literalCB, SIGNAL(clicked()), + this, SLOT(changed())); connect(forceuppercaseCB, SIGNAL(clicked()), this, SLOT(updateStyles())); connect(textBeforeED, SIGNAL(textChanged(QString)), @@ -585,6 +587,7 @@ void GuiCitation::applyParams(int const choice, bool full, bool force, params_["pretextlist"] = getStringFromVector(getPreTexts(), from_ascii("\t")); params_["posttextlist"] = getStringFromVector(getPostTexts(), from_ascii("\t")); } + params_["literal"] = literalCB->isChecked() ? from_ascii("true") : from_ascii("false"); dispatchParams(); } @@ -726,6 +729,7 @@ void GuiCitation::init() documentBuffer().params().fullAuthorList()); textBeforeED->setText(toqstr(params_["before"])); textAfterED->setText(toqstr(params_["after"])); + literalCB->setChecked(params_["literal"] == "true"); setPreTexts(getVectorFromString(params_["pretextlist"], from_ascii("\t"))); setPostTexts(getVectorFromString(params_["posttextlist"], from_ascii("\t"))); diff --git a/src/frontends/qt4/GuiHyperlink.cpp b/src/frontends/qt4/GuiHyperlink.cpp index 3111d193c4..4bf50a094a 100644 --- a/src/frontends/qt4/GuiHyperlink.cpp +++ b/src/frontends/qt4/GuiHyperlink.cpp @@ -40,6 +40,8 @@ GuiHyperlink::GuiHyperlink(QWidget * parent) : InsetParamsWidget(parent) this, SIGNAL(changed())); connect(nameED, SIGNAL(textChanged(const QString &)), this, SIGNAL(changed())); + connect(literalCB, SIGNAL(clicked()), + this, SIGNAL(changed())); connect(webRB, SIGNAL(clicked()), this, SIGNAL(changed())); connect(emailRB, SIGNAL(clicked()), @@ -58,6 +60,7 @@ void GuiHyperlink::paramsToDialog(Inset const * inset) targetED->setText(toqstr(params["target"])); nameED->setText(toqstr(params["name"])); + literalCB->setChecked(params["literal"] == "true"); docstring const & type = params["type"]; if (type.empty()) webRB->setChecked(true); @@ -75,6 +78,7 @@ bool GuiHyperlink::initialiseParams(std::string const & data) return false; targetED->setText(toqstr(params["target"])); nameED->setText(toqstr(params["name"])); + literalCB->setChecked(params["literal"] == "true"); if (params["type"] == from_utf8("mailto:")) emailRB->setChecked(true); else if (params["type"] == from_utf8("file:")) @@ -97,6 +101,8 @@ docstring GuiHyperlink::dialogToParams() const params["type"] = from_utf8("mailto:"); else if (fileRB->isChecked()) params["type"] = from_utf8("file:"); + params["literal"] = literalCB->isChecked() + ? from_ascii("true") : from_ascii("false"); params.setCmdName("href"); return from_utf8(InsetHyperlink::params2string(params)); } diff --git a/src/frontends/qt4/GuiNomenclature.cpp b/src/frontends/qt4/GuiNomenclature.cpp index 0a52bd1403..3afad18a83 100644 --- a/src/frontends/qt4/GuiNomenclature.cpp +++ b/src/frontends/qt4/GuiNomenclature.cpp @@ -29,6 +29,8 @@ GuiNomenclature::GuiNomenclature(QWidget * parent) : InsetParamsWidget(parent) this, SIGNAL(changed())); connect(descriptionTE, SIGNAL(textChanged()), this, SIGNAL(changed())); + connect(literalCB, SIGNAL(clicked()), + this, SIGNAL(changed())); setFocusProxy(descriptionTE); } @@ -41,6 +43,7 @@ void GuiNomenclature::paramsToDialog(Inset const * inset) prefixED->setText(toqstr(params["prefix"])); symbolED->setText(toqstr(params["symbol"])); + literalCB->setChecked(params["literal"] == "true"); QString description = toqstr(params["description"]); description.replace("\\\\","\n"); descriptionTE->setPlainText(description); @@ -56,6 +59,8 @@ docstring GuiNomenclature::dialogToParams() const QString description = descriptionTE->toPlainText(); description.replace('\n',"\\\\"); params["description"] = qstring_to_ucs4(description); + params["literal"] = literalCB->isChecked() + ? from_ascii("true") : from_ascii("false"); return from_utf8(InsetNomencl::params2string(params)); } diff --git a/src/frontends/qt4/GuiPrintindex.cpp b/src/frontends/qt4/GuiPrintindex.cpp index c667584aab..be8c0cd9b6 100644 --- a/src/frontends/qt4/GuiPrintindex.cpp +++ b/src/frontends/qt4/GuiPrintindex.cpp @@ -43,6 +43,7 @@ GuiPrintindex::GuiPrintindex(GuiView & lv) connect(cancelPB, SIGNAL(clicked()), this, SLOT(slotClose())); connect(indicesCO, SIGNAL(activated(int)), this, SLOT(change_adaptor())); connect(subindexCB, SIGNAL(clicked()), this, SLOT(change_adaptor())); + connect(literalCB, SIGNAL(clicked()), this, SLOT(change_adaptor())); bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy); bc().setOK(okPB); @@ -78,6 +79,7 @@ void GuiPrintindex::updateContents() int const pos = indicesCO->findData(toqstr(cur_index)); indicesCO->setCurrentIndex(pos); subindexCB->setChecked(params_.getCmdName() == "printsubindex"); + literalCB->setChecked(params_["literal"] == "true"); } @@ -95,6 +97,8 @@ void GuiPrintindex::applyView() params_["type"] = docstring(); else params_["type"] = qstring_to_ucs4(index); + params_["literal"] = literalCB->isChecked() + ? from_ascii("true") : from_ascii("false"); } @@ -105,6 +109,7 @@ void GuiPrintindex::paramsToDialog(InsetCommandParams const & /*icp*/) indicesCO->findData(toqstr(params_["type"])); subindexCB->setChecked(params_.getCmdName() == "printsubindex"); indicesCO->setCurrentIndex(pos); + literalCB->setChecked(params_["literal"] == "true"); bc().setValid(isValid()); } diff --git a/src/frontends/qt4/ui/BibitemUi.ui b/src/frontends/qt4/ui/BibitemUi.ui index 0dfc146bc3..559a199887 100644 --- a/src/frontends/qt4/ui/BibitemUi.ui +++ b/src/frontends/qt4/ui/BibitemUi.ui @@ -1,3 +1,4 @@ + BibitemUi @@ -5,71 +6,90 @@ 0 0 - 211 - 74 + 218 + 121 - - - 9 - - - 6 - - - - - - 0 - 0 - - - - The bibliography key - - - - - - - - 0 - 0 - - - - The label as it appears in the document - - - - - - - The label as it appears in the document - - - &Label: - - - labelED - - - + - - - The bibliography key - - - &Key: - - - keyED - - + + + + + The bibliography key + + + Ke&y: + + + keyED + + + + + + + The label as it appears in the document + + + &Label: + + + labelED + + + + + + + + + + + + + + + + + + + 0 + 0 + + + + The bibliography key + + + + + + + + 0 + 0 + + + + The label as it appears in the document + + + + + + + Pass content of the `Label' field literally to LaTeX. Check this if you want to enter LaTeX code. + + + Li&teral + + + + diff --git a/src/frontends/qt4/ui/CitationUi.ui b/src/frontends/qt4/ui/CitationUi.ui index 6b43968a1a..cdd5189305 100644 --- a/src/frontends/qt4/ui/CitationUi.ui +++ b/src/frontends/qt4/ui/CitationUi.ui @@ -359,6 +359,16 @@ 0 + + + + Pass content of `Text before' and `Text after' fields literally to LaTeX. Check this if you want to enter LaTeX code. + + + Li&teral + + + diff --git a/src/frontends/qt4/ui/HyperlinkUi.ui b/src/frontends/qt4/ui/HyperlinkUi.ui index c423e16250..5bbf954a4b 100644 --- a/src/frontends/qt4/ui/HyperlinkUi.ui +++ b/src/frontends/qt4/ui/HyperlinkUi.ui @@ -1,3 +1,4 @@ + HyperlinkUi @@ -5,55 +6,101 @@ 0 0 - 343 - 130 + 290 + 188 - - - - URL - - - &Target: - - - targetED - - - - - - - URL - - + + + + + + + + URL + + + &Target: + + + targetED + + + + + + + Name associated with the URL + + + &Name: + + + nameED + + + + + + + + + + + + + + + + + + URL + + + + + + + Name associated with the URL + + + + + + + + + Pass content of the `Name' field literally to LaTeX. Check this if you want to enter LaTeX code. + + + Li&teral + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + - - - Name associated with the URL - - - &Name: - - - nameED - - - - - - - Name associated with the URL - - - - Specify the link target @@ -65,7 +112,16 @@ 6 - + + 9 + + + 9 + + + 9 + + 9 @@ -87,7 +143,7 @@ Link to an email address - &Email + E&mail @@ -97,14 +153,14 @@ Link to a file - &File + Fi&le - + Qt::Horizontal diff --git a/src/frontends/qt4/ui/NomenclUi.ui b/src/frontends/qt4/ui/NomenclUi.ui index c7431d09b9..9baff247d6 100644 --- a/src/frontends/qt4/ui/NomenclUi.ui +++ b/src/frontends/qt4/ui/NomenclUi.ui @@ -1,3 +1,4 @@ + NomenclUi @@ -6,46 +7,17 @@ 0 0 254 - 172 + 222 Nomenclature - - - 9 - - - 6 - - - - - - - - Sort &as: - - - prefixED - - - - - - - &Description: - - - descriptionTE - - - + - &Symbol: + Sy&mbol: symbolED @@ -59,6 +31,16 @@ + + + + Des&cription: + + + descriptionTE + + + @@ -66,6 +48,29 @@ + + + + Sort &as: + + + prefixED + + + + + + + + + + Pass content of the `Symbol' and `Description' fields literally to LaTeX. Check this if you want to enter LaTeX code. + + + Li&teral + + + diff --git a/src/frontends/qt4/ui/PrintindexUi.ui b/src/frontends/qt4/ui/PrintindexUi.ui index ea49cbf434..74fa0a8a84 100644 --- a/src/frontends/qt4/ui/PrintindexUi.ui +++ b/src/frontends/qt4/ui/PrintindexUi.ui @@ -1,97 +1,119 @@ - + + PrintindexUi - - + + 0 0 - 262 - 130 + 287 + 148 - + - + true - - - 9 - - - 6 - - - - - &Cancel - - - true - - - - - - - &OK - - - false - - - - - - - Qt::Horizontal - - - - 78 - 29 - - - - - - - - Check if this index should be part (e.g., a section) of the former one. - - - &Subindex - - - - - - - 0 - - + + + + 6 + + 0 + + + 0 + + + 0 + + + 0 + - - - A&vailable indexes: + + + Avai&lable indexes: - + indicesCO - - + + Select the index that shall be printed at this place of the document. + + + + + + Check if this index should be part (e.g., a section) of the former one. + + + &Subindex + + + + + + + Pass index names literally to LaTeX. Check this if you want to use LaTeX code in index names. + + + Li&teral + + + + + + + + + + + Qt::Horizontal + + + + 78 + 29 + + + + + + + + &OK + + + false + + + + + + + &Cancel + + + true + + + + + @@ -100,7 +122,7 @@ cancelPB - qt_i18n.h + qt_i18n.h diff --git a/src/insets/InsetBibitem.cpp b/src/insets/InsetBibitem.cpp index d0a28e73fe..18a261a3e0 100644 --- a/src/insets/InsetBibitem.cpp +++ b/src/insets/InsetBibitem.cpp @@ -108,6 +108,7 @@ ParamInfo const & InsetBibitem::findInfo(string const & /* cmdName */) ParamInfo::HANDLING_LATEXIFY); param_info_.add("key", ParamInfo::LATEX_REQUIRED, ParamInfo::HANDLING_ESCAPE); + param_info_.add("literal", ParamInfo::LYX_INTERNAL); } return param_info_; } @@ -129,54 +130,24 @@ void InsetBibitem::doDispatch(Cursor & cur, FuncRequest & cmd) docstring const & old_key = params()["key"]; docstring const & old_label = params()["label"]; + docstring const & old_literal = params()["literal"]; docstring label = p["label"]; - - // definitions for escaping - static docstring const backslash = from_ascii("\\"); - static docstring const lbrace = from_ascii("{"); - static docstring const rbrace = from_ascii("}"); - static char_type const chars_escape[6] = { - '&', '_', '$', '%', '#', '^'}; - static char_type const brackets_escape[2] = {'[', ']'}; - - if (!label.empty()) { - int previous; - // The characters in chars_name[] need to be changed to a command when - // they are in the name field. - for (int k = 0; k < 6; k++) - for (size_t i = 0, pos; - (pos = label.find(chars_escape[k], i)) != string::npos; - i = pos + 2) { - if (pos == 0) - previous = 0; - else - previous = pos - 1; - // only if not already escaped - if (label[previous] != '\\') - label.replace(pos, 1, backslash + chars_escape[k] + lbrace + rbrace); - } - // The characters '[' and ']' need to be put into braces - for (int k = 0; k < 2; k++) - for (size_t i = 0, pos; - (pos = label.find(brackets_escape[k], i)) != string::npos; - i = pos + 2) { - if (pos == 0) - previous = 0; - else - previous = pos - 1; - // only if not already escaped - if (label[previous] != '{') - label.replace(pos, 1, lbrace + brackets_escape[k] + rbrace); - } - } + docstring literal = p["literal"]; if (old_label != label) { p["label"] = label; cur.forceBufferUpdate(); buffer().invalidateBibinfoCache(); } - setParam("label", p["label"]); + + if (old_literal != literal) { + p["literal"] = literal; + cur.forceBufferUpdate(); + buffer().invalidateBibinfoCache(); + } + setParam("literal", p["literal"]); + if (p["key"] != old_key) { updateCommand(p["key"]); cur.bv().buffer().changeRefsIfUnique(old_key, params()["key"]); @@ -301,9 +272,8 @@ docstring bibitemWidest(Buffer const & buffer, OutputParams const & runparams) } if (!lbl.empty()) { - pair latex_lbl = - runparams.encoding->latexString(lbl, runparams.dryrun); - return latex_lbl.first; + InsetCommandParams p(BIBITEM_CODE); + return p.prepareCommand(runparams, lbl, ParamInfo::HANDLING_LATEXIFY); } return from_ascii("99"); diff --git a/src/insets/InsetCitation.cpp b/src/insets/InsetCitation.cpp index 6f238f964d..b16077ffd9 100644 --- a/src/insets/InsetCitation.cpp +++ b/src/insets/InsetCitation.cpp @@ -66,11 +66,16 @@ ParamInfo const & InsetCitation::findInfo(string const & /* cmdName */) // we have to allow both here. InsetCitation takes care that // LaTeX output is nevertheless correct. if (param_info_.empty()) { - param_info_.add("after", ParamInfo::LATEX_OPTIONAL); - param_info_.add("before", ParamInfo::LATEX_OPTIONAL); + param_info_.add("after", ParamInfo::LATEX_OPTIONAL, + ParamInfo::HANDLING_LATEXIFY); + param_info_.add("before", ParamInfo::LATEX_OPTIONAL, + ParamInfo::HANDLING_LATEXIFY); param_info_.add("key", ParamInfo::LATEX_REQUIRED); - param_info_.add("pretextlist", ParamInfo::LATEX_OPTIONAL); - param_info_.add("posttextlist", ParamInfo::LATEX_OPTIONAL); + param_info_.add("pretextlist", ParamInfo::LATEX_OPTIONAL, + ParamInfo::HANDLING_LATEXIFY); + param_info_.add("posttextlist", ParamInfo::LATEX_OPTIONAL, + ParamInfo::HANDLING_LATEXIFY); + param_info_.add("literal", ParamInfo::LYX_INTERNAL); } return param_info_; } @@ -568,8 +573,10 @@ void InsetCitation::latex(otexstream & os, OutputParams const & runparams) const if (qualified) os << "s"; - docstring before = getParam("before"); - docstring after = getParam("after"); + docstring before = params().prepareCommand(runparams, getParam("before"), + param_info_["before"].handling()); + docstring after = params().prepareCommand(runparams, getParam("after"), + param_info_["after"].handling()); if (!before.empty() && cs.textBefore) { if (qualified) os << '(' << protectArgument(before, '(', ')') @@ -592,8 +599,10 @@ void InsetCitation::latex(otexstream & os, OutputParams const & runparams) const map pres = getQualifiedLists(getParam("pretextlist")); map posts = getQualifiedLists(getParam("posttextlist")); for (docstring const & k: keys) { - docstring bef = pres[k]; - docstring aft = posts[k]; + docstring bef = params().prepareCommand(runparams, pres[k], + param_info_["pretextlist"].handling()); + docstring aft = params().prepareCommand(runparams, posts[k], + param_info_["posttextlist"].handling()); if (!bef.empty()) os << '[' << protectArgument(bef) << "][" << protectArgument(aft) << ']'; diff --git a/src/insets/InsetCitation.h b/src/insets/InsetCitation.h index 57b0b3da9e..992a85ee21 100644 --- a/src/insets/InsetCitation.h +++ b/src/insets/InsetCitation.h @@ -64,8 +64,6 @@ public: /// void forOutliner(docstring &, size_t const, bool const) const; /// - void validate(LaTeXFeatures &) const {} - /// void updateBuffer(ParIterator const & it, UpdateType); /// void addToToc(DocIterator const & di, bool output_active, diff --git a/src/insets/InsetCommand.cpp b/src/insets/InsetCommand.cpp index 879d9a35e0..2e24d4d4e1 100644 --- a/src/insets/InsetCommand.cpp +++ b/src/insets/InsetCommand.cpp @@ -14,6 +14,7 @@ #include "InsetCommand.h" #include "Buffer.h" +#include "BufferEncodings.h" #include "BufferView.h" #include "Cursor.h" #include "DispatchResult.h" @@ -157,6 +158,25 @@ int InsetCommand::docbook(odocstream &, OutputParams const &) const } +void InsetCommand::validate(LaTeXFeatures & features) const +{ + if (params()["literal"] == "true") + return; + + ParamInfo::const_iterator it = params().info().begin(); + ParamInfo::const_iterator end = params().info().end(); + for (; it != end; ++it) { + if (it->handling() == ParamInfo::HANDLING_LATEXIFY) { + docstring const text = params()[it->name()]; + // Validate the contents (if we LaTeXify, specific + // macros might require packages) + for (pos_type i = 0; i < int(text.size()) ; ++i) + BufferEncodings::validate(text[i], features); + } + } +} + + void InsetCommand::doDispatch(Cursor & cur, FuncRequest & cmd) { switch (cmd.action()) { diff --git a/src/insets/InsetCommand.h b/src/insets/InsetCommand.h index ba7a945339..0514e09ffe 100644 --- a/src/insets/InsetCommand.h +++ b/src/insets/InsetCommand.h @@ -87,6 +87,8 @@ public: /// int docbook(odocstream &, OutputParams const & runparams) const; /// + void validate(LaTeXFeatures & features) const; + /// bool setMouseHover(BufferView const * bv, bool mouse_hover) const; /// bool clickable(BufferView const &, int, int) const { return hasSettings(); } diff --git a/src/insets/InsetCommandParams.cpp b/src/insets/InsetCommandParams.cpp index 79e3bd795b..5ea28ff3fc 100644 --- a/src/insets/InsetCommandParams.cpp +++ b/src/insets/InsetCommandParams.cpp @@ -422,20 +422,50 @@ docstring InsetCommandParams::prepareCommand(OutputParams const & runparams, docstring const & command, ParamInfo::ParamHandling handling) const { + if (handling == ParamInfo::HANDLING_LATEXIFY) + if ((*this)["literal"] == "true") + handling = ParamInfo::HANDLING_NONE; docstring result; switch (handling) { case ParamInfo::HANDLING_LATEXIFY: { + // First handle backslash + result = subst(command, from_ascii("\\"), from_ascii("\\textbackslash{}")); + // Then get LaTeX macros pair command_latexed = - runparams.encoding->latexString(command, runparams.dryrun); + runparams.encoding->latexString(result, runparams.dryrun); result = command_latexed.first; if (!command_latexed.second.empty()) { - // issue a warning about omitted characters + // Issue a warning about omitted characters // FIXME: should be passed to the error dialog frontend::Alert::warning(_("Uncodable characters"), bformat(_("The following characters that are used in the inset %1$s are not\n" "representable in the current encoding and therefore have been omitted:\n%2$s."), from_utf8(insetType()), command_latexed.second)); } + // Now escape special commands + static docstring const backslash = from_ascii("\\"); + static char_type const chars_escape[6] = { + '&', '_', '$', '%', '#', '^'}; + + if (!result.empty()) { + int previous; + // The characters in chars_name[] need to be changed to a command when + // they are LaTeXified. + for (int k = 0; k < 6; k++) + for (size_t i = 0, pos; + (pos = result.find(chars_escape[k], i)) != string::npos; + i = pos + 2) { + //(Only) \\^ needs to be terminated + docstring const term = (k == 5) ? from_ascii("{}") : docstring(); + if (pos == 0) + previous = 0; + else + previous = pos - 1; + // only if not already escaped + if (result[previous] != '\\') + result.replace(pos, 1, backslash + chars_escape[k] + term); + } + } break; } case ParamInfo::HANDLING_ESCAPE: @@ -470,10 +500,10 @@ docstring InsetCommandParams::getCommand(OutputParams const & runparams) const break; } case ParamInfo::LATEX_OPTIONAL: { - docstring const data = + docstring data = prepareCommand(runparams, (*this)[name], it->handling()); if (!data.empty()) { - s += '[' + data + ']'; + s += '[' + protectArgument(data) + ']'; noparam = false; } else if (writeEmptyOptional(it)) { s += "[]"; diff --git a/src/insets/InsetHyperlink.cpp b/src/insets/InsetHyperlink.cpp index 3160c0b001..8405c48440 100644 --- a/src/insets/InsetHyperlink.cpp +++ b/src/insets/InsetHyperlink.cpp @@ -48,9 +48,11 @@ ParamInfo const & InsetHyperlink::findInfo(string const & /* cmdName */) { static ParamInfo param_info_; if (param_info_.empty()) { - param_info_.add("name", ParamInfo::LATEX_OPTIONAL); + param_info_.add("name", ParamInfo::LATEX_OPTIONAL, + ParamInfo::HANDLING_LATEXIFY); param_info_.add("target", ParamInfo::LATEX_REQUIRED); param_info_.add("type", ParamInfo::LATEX_REQUIRED); + param_info_.add("literal", ParamInfo::LYX_INTERNAL); } return param_info_; } @@ -119,11 +121,7 @@ void InsetHyperlink::latex(otexstream & os, { docstring url = getParam("target"); docstring name = getParam("name"); - static docstring const backslash = from_ascii("\\"); - static docstring const braces = from_ascii("{}"); static char_type const chars_url[2] = {'%', '#'}; - static char_type const chars_name[6] = { - '&', '_', '$', '%', '#', '^'}; // For the case there is no name given, the target is set as name. // Do this before !url.empty() and !name.empty() to handle characters @@ -151,7 +149,7 @@ void InsetHyperlink::latex(otexstream & os, for (size_t i = 0, pos; (pos = url.find(chars_url[k], i)) != string::npos; i = pos + 2) - url.replace(pos, 1, backslash + chars_url[k]); + url.replace(pos, 1, from_ascii("\\") + chars_url[k]); // add "http://" when the type is web (type = empty) // and no "://" or "run:" is given @@ -163,46 +161,19 @@ void InsetHyperlink::latex(otexstream & os, } // end if (!url.empty()) - // The characters in chars_name[] need to be changed to a command when - // they are in the name field. if (!name.empty()) { - // handle the "\" character, but only when the following character - // is not also a "\", because "\\" is valid code - docstring const textbackslash = from_ascii("\\textbackslash{}"); - for (size_t i = 0, pos; - (pos = name.find('\\', i)) != string::npos; - i = pos + 2) { - if (name[pos + 1] != '\\') - name.replace(pos, 1, textbackslash); - } - // The characters in chars_name[] need to be changed to a command - // when they are in the name field. - // Therefore the treatment of "\" must be the first thing - for (int k = 0; k < 6; k++) - for (size_t i = 0, pos; - (pos = name.find(chars_name[k], i)) != string::npos; - i = pos + 2) - name.replace(pos, 1, backslash + chars_name[k] + braces); - + name = params().prepareCommand(runparams, getParam("name"), + ParamInfo::HANDLING_LATEXIFY); // replace the tilde by the \sim character as suggested in the // LaTeX FAQ for URLs - docstring const sim = from_ascii("$\\sim$"); - for (size_t i = 0, pos; - (pos = name.find('~', i)) != string::npos; - i = pos + 1) - name.replace(pos, 1, sim); - pair name_latexed = - runparams.encoding->latexString(name, runparams.dryrun); - name = name_latexed.first; - if (!name_latexed.second.empty() && !runparams.silent) { - // issue a warning about omitted characters - // FIXME: should be passed to the error dialog - frontend::Alert::warning(_("Uncodable characters"), - bformat(_("The following characters that are used in the href inset are not\n" - "representable in the current encoding and therefore have been omitted:\n%1$s."), - name_latexed.second)); + if (getParam("literal") != from_ascii("true")) { + docstring const sim = from_ascii("$\\sim$"); + for (size_t i = 0, pos; + (pos = name.find('~', i)) != string::npos; + i = pos + 1) + name.replace(pos, 1, sim); } - } // end if (!name.empty()) + } if (runparams.moving_arg) os << "\\protect"; @@ -287,6 +258,7 @@ docstring InsetHyperlink::toolTip(BufferView const & /*bv*/, int /*x*/, int /*y* void InsetHyperlink::validate(LaTeXFeatures & features) const { features.require("hyperref"); + InsetCommand::validate(features); } diff --git a/src/insets/InsetIndex.cpp b/src/insets/InsetIndex.cpp index d5d487f78e..38472f0bdc 100644 --- a/src/insets/InsetIndex.cpp +++ b/src/insets/InsetIndex.cpp @@ -436,8 +436,10 @@ ParamInfo const & InsetPrintIndex::findInfo(string const & /* cmdName */) static ParamInfo param_info_; if (param_info_.empty()) { param_info_.add("type", ParamInfo::LATEX_OPTIONAL, - ParamInfo::HANDLING_ESCAPE); - param_info_.add("name", ParamInfo::LATEX_REQUIRED); + ParamInfo::HANDLING_ESCAPE); + param_info_.add("name", ParamInfo::LATEX_OPTIONAL, + ParamInfo::HANDLING_LATEXIFY); + param_info_.add("literal", ParamInfo::LYX_INTERNAL); } return param_info_; } @@ -560,6 +562,15 @@ bool InsetPrintIndex::getStatus(Cursor & cur, FuncRequest const & cmd, } +void InsetPrintIndex::updateBuffer(ParIterator const &, UpdateType) +{ + Index const * index = + buffer().masterParams().indiceslist().findShortcut(getParam("type")); + if (index) + setParam("name", index->index()); +} + + void InsetPrintIndex::latex(otexstream & os, OutputParams const & runparams_in) const { if (!buffer().masterBuffer()->params().use_indices) { @@ -577,6 +588,7 @@ void InsetPrintIndex::validate(LaTeXFeatures & features) const features.require("makeidx"); if (buffer().masterBuffer()->params().use_indices) features.require("splitidx"); + InsetCommand::validate(features); } diff --git a/src/insets/InsetIndex.h b/src/insets/InsetIndex.h index 80d8149bc4..3ee17509dc 100644 --- a/src/insets/InsetIndex.h +++ b/src/insets/InsetIndex.h @@ -111,6 +111,8 @@ public: /// bool getStatus(Cursor &, FuncRequest const &, FuncStatus &) const; /// + void updateBuffer(ParIterator const & it, UpdateType); + /// std::string contextMenuName() const; /// Updates needed features for this inset. void validate(LaTeXFeatures & features) const; diff --git a/src/insets/InsetNomencl.cpp b/src/insets/InsetNomencl.cpp index 1613542db3..c8904e67e0 100644 --- a/src/insets/InsetNomencl.cpp +++ b/src/insets/InsetNomencl.cpp @@ -68,6 +68,7 @@ ParamInfo const & InsetNomencl::findInfo(string const & /* cmdName */) ParamInfo::HANDLING_LATEXIFY); param_info_.add("description", ParamInfo::LATEX_REQUIRED, ParamInfo::HANDLING_LATEXIFY); + param_info_.add("literal", ParamInfo::LYX_INTERNAL); } return param_info_; } @@ -134,6 +135,7 @@ int InsetNomencl::docbookGlossary(odocstream & os) const void InsetNomencl::validate(LaTeXFeatures & features) const { features.require("nomencl"); + InsetCommand::validate(features); } diff --git a/src/tex2lyx/text.cpp b/src/tex2lyx/text.cpp index b6f5f1799d..b3cbc46c66 100644 --- a/src/tex2lyx/text.cpp +++ b/src/tex2lyx/text.cpp @@ -1682,8 +1682,8 @@ void parse_environment(Parser & p, ostream & os, bool outer, p.skip_spaces(true); os << "btprint " << '"' << "btPrintAll" << '"' << "\n"; } - os << "bibfiles " << '"' << bibfile << '"' << "\n"; - os << "options " << '"' << bibstyle << '"' << "\n"; + os << "bibfiles " << '"' << bibfile << "\"\n" + << "options " << '"' << bibstyle << "\"\n"; parse_text_in_inset(p, os, FLAG_END, outer, parent_context); end_inset(os); p.skip_spaces(); @@ -2760,7 +2760,8 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, } else { begin_command_inset(os, "bibitem", "bibitem"); os << "label \"" << label << "\"\n" - "key \"" << key << "\"\n"; + << "key \"" << key << "\"\n" + << "literal \"true\"\n"; end_inset(os); } } @@ -3439,6 +3440,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, os << "target \"" << target << "\"\n"; if (type == "mailto:" || type == "file:") os << "type \"" << type << "\"\n"; + os << "literal \"true\"\n"; end_inset(os); skip_spaces_braces(p); } @@ -3585,7 +3587,8 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, os << "before " << '"' << before << '"' << "\n"; os << "key \"" << convert_command_inset_arg(p.verbatim_item()) - << "\"\n"; + << "\"\n" + << "literal \"true\"\n"; end_inset(os); // Need to set the cite engine if natbib is loaded by // the document class directly @@ -3637,9 +3640,10 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, before.erase(before.length() - 1, 1); } begin_command_inset(os, "citation", command); - os << "after " << '"' << after << '"' << "\n"; - os << "before " << '"' << before << '"' << "\n"; - os << "key " << '"' << citation << '"' << "\n"; + os << "after " << '"' << after << "\"\n" + << "before " << '"' << before << "\"\n" + << "key " << '"' << citation << "\"\n" + << "literal \"true\"\n"; end_inset(os); // Need to set the cite engine if jurabib is loaded by // the document class directly @@ -3656,8 +3660,9 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, // the BibTeX inset if (key != "*") { begin_command_inset(os, "citation", t.cs()); - os << "after " << '"' << after << '"' << "\n"; - os << "key " << '"' << key << '"' << "\n"; + os << "after " << '"' << after << "\"\n" + << "key " << '"' << key << "\"\n" + << "literal \"true\"\n"; end_inset(os); } else if (t.cs() == "nocite") btprint = key; @@ -3687,7 +3692,8 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, << convert_command_inset_arg(p.verbatim_item()); os << "\"\ndescription \"" << convert_command_inset_arg(p.verbatim_item()) - << "\"\n"; + << "\"\n" + << "literal \"true\"\n"; end_inset(os); preamble.registerAutomaticallyLoadedPackage("nomencl"); } @@ -3717,6 +3723,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer, os << "type \"idx\"\n"; else os << "type \"" << indexname << "\"\n"; + os << "literal \"true\"\n"; } end_inset(os); skip_spaces_braces(p); diff --git a/src/version.h b/src/version.h index a0a611d20a..4056e9ddee 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 531 // spitz: qualified citation lists -#define LYX_FORMAT_TEX2LYX 531 +#define LYX_FORMAT_LYX 532 // gb/spitz add literal command inset parameter +#define LYX_FORMAT_TEX2LYX 532 #if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX #ifndef _MSC_VER