Hi,
after I needed to explain several times lately why one should not use the
menu entries for sub/superscript in text and what to do instead, I finally
sat down and completed a fix for bug 3008 that I started years ago. It
implements a new inset for subscript and superscript in text mode, including
correct output for all backends. There are some other ideas discussed in
http://www.lyx.org/trac/ticket/3008, but the inset approach is the best one
IMO.
The attached patch has no known problems (the cursor position problem
mentioned in trac is fixed). May the patch go in at this stage (I don't know
how the current policy is)? The risk of breakage is close to zero. The only
code that is touched besides the new inset is the cursor positioning in
Text::dispatch() after inserting a new inset: If the inset is a text inset,
the inset is entered instead of positioning it behind the inset, since this
is consistent with ERT insets etc.
Georg
Index: development/scons/scons_manifest.py
===================================================================
--- development/scons/scons_manifest.py (revision 36398)
+++ development/scons/scons_manifest.py (working copy)
@@ -1057,6 +1057,7 @@ src_insets_header_files = Split('''
InsetPreview.h
InsetQuotes.h
InsetRef.h
+ InsetScript.h
InsetSpace.h
InsetSpecialChar.h
InsetTOC.h
@@ -1113,6 +1114,7 @@ src_insets_files = Split('''
InsetPreview.cpp
InsetQuotes.cpp
InsetRef.cpp
+ InsetScript.cpp
InsetSpace.cpp
InsetSpecialChar.cpp
InsetTOC.cpp
@@ -1499,6 +1501,8 @@ lib_images_files = Split('''
href-insert.png
hidetab.png
index-insert.png
+ inset-insert_script_script_subscript.png
+ inset-insert_script_script_superscript.png
info-insert_buffer_vcs-revision.png
label-insert.png
layout-document.png
Index: development/qmake/lyx.pro
===================================================================
--- development/qmake/lyx.pro (revision 36398)
+++ development/qmake/lyx.pro (working copy)
@@ -189,6 +189,7 @@ SOURCES += \
../../src/insets/InsetPhantom.cpp \
../../src/insets/InsetQuotes.cpp \
../../src/insets/InsetRef.cpp \
+../../src/insets/InsetScript.cpp \
../../src/insets/InsetSpace.cpp \
../../src/insets/InsetSpecialChar.cpp \
../../src/insets/InsetTabular.cpp \
@@ -531,6 +532,7 @@ HEADERS += \
../../src/insets/InsetQuotes.h \
../../src/insets/InsetPhantom.h \
../../src/insets/InsetRef.h \
+../../src/insets/InsetScript.h \
../../src/insets/InsetSpace.h \
../../src/insets/InsetSpecialChar.h \
../../src/insets/InsetTOC.h \
Index: src/LyXAction.cpp
===================================================================
--- src/LyXAction.cpp (revision 36398)
+++ src/LyXAction.cpp (working copy)
@@ -1594,7 +1594,7 @@ void LyXAction::init()
{ LFUN_MATH_SUBSCRIPT, "math-subscript", Noop, Math },
/*!
* \var lyx::FuncCode lyx::LFUN_MATH_SUPERSCRIPT
- * \li Action: Enters subscript expression in math expression.
+ * \li Action: Enters superscript expression in math expression.
* \li Syntax: math-superscript
* \li Origin: vermeer, 12 Dec 2001
* \endvar
@@ -2297,7 +2297,7 @@ void LyXAction::init()
* \li Action: Insert new inset (type given by the parameters).
* \li Syntax: inset-insert <INSET> <ARGS>
* \li Params: <INSET>: <bibitem|bibtex|cite|ert|listings|external|graphics|tabular|
- hyperlink|include|index|label|line|nomencl|vspace|ref|toc>\n
+ hyperlink|include|index|label|line|nomencl|vspace|ref|toc|script>\n
<ARGS>: depends on the given inset. Use "lyx -dbg action" to explore.
* \li Sample: inset-insert ref LatexCommand <Format> reference "<label name>"\end_inset \n
where <label name> is the name of the referenced label and
Index: src/insets/InsetScript.h
===================================================================
--- src/insets/InsetScript.h (revision 0)
+++ src/insets/InsetScript.h (revision 0)
@@ -0,0 +1,127 @@
+// -*- C++ -*-
+/**
+ * \file InsetScript.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Uwe Stöhr
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#ifndef INSET_SCRIPT_H
+#define INSET_SCRIPT_H
+
+#include "InsetText.h"
+
+
+namespace lyx {
+
+class InsetScriptParams
+{
+public:
+ enum Type {
+ Subscript,
+ Superscript
+ };
+ /// \c type defaults to Subscript
+ InsetScriptParams();
+ ///
+ void write(std::ostream & os) const;
+ ///
+ void read(Lexer & lex);
+ ///
+ int shift(FontInfo const & font) const;
+ ///
+ Type type;
+};
+
+
+/////////////////////////////////////////////////////////////////////////
+//
+// InsetScript
+//
+/////////////////////////////////////////////////////////////////////////
+
+/// The subscript and superscript inset
+class InsetScript : public InsetText
+{
+public:
+ ///
+ InsetScript(Buffer *, InsetScriptParams const & = InsetScriptParams());
+ ///
+ InsetScript(Buffer *, std::string const &);
+ ///
+ ~InsetScript();
+ ///
+ static std::string params2string(InsetScriptParams const &);
+ ///
+ static void string2params(std::string const &, InsetScriptParams &);
+ ///
+ InsetScriptParams const & params() const { return params_; }
+private:
+ ///
+ InsetCode lyxCode() const { return SCRIPT_CODE; }
+ ///
+ docstring name() const;
+ ///
+ DisplayType display() const;
+ ///
+ void metrics(MetricsInfo &, Dimension &) const;
+ ///
+ void draw(PainterInfo & pi, int x, int y) const;
+ ///
+ virtual void cursorPos(BufferView const & bv,
+ CursorSlice const & sl, bool boundary, int & x, int & y) const;
+ ///
+ void write(std::ostream &) const;
+ ///
+ void read(Lexer & lex);
+ ///
+ bool neverIndent() const { return true; }
+ ///
+ virtual bool forcePlainLayout(idx_type = 0) const { return true; }
+ ///
+ virtual bool allowMultiPar() const { return false; }
+ ///
+ virtual bool allowParagraphCustomization(idx_type = 0) const { return false; }
+ ///
+ virtual void validate(LaTeXFeatures &) const;
+ ///
+ int latex(odocstream &, OutputParams const &) const;
+ ///
+ int plaintext(odocstream &, OutputParams const &) const;
+ ///
+ int docbook(odocstream &, OutputParams const &) const;
+ ///
+ docstring xhtml(XHTMLStream &, OutputParams const &) const;
+ ///
+ void edit(Cursor & cur, bool front,
+ EntryDirection entry_from = ENTRY_DIRECTION_IGNORE);
+ ///
+ Inset * editXY(Cursor & cur, int x, int y);
+ ///
+ virtual bool insetAllowed(InsetCode code) const;
+ ///
+ bool getStatus(Cursor &, FuncRequest const &, FuncStatus &) const;
+ ///
+ void doDispatch(Cursor & cur, FuncRequest & cmd);
+ ///
+ docstring toolTip(BufferView const & bv, int x, int y) const;
+ ///
+ Inset * clone() const { return new InsetScript(*this); }
+ /// used by the constructors
+ void init();
+ ///
+ docstring contextMenu(BufferView const & bv, int x, int y) const;
+ ///
+ friend class InsetScriptParams;
+
+ ///
+ InsetScriptParams params_;
+};
+
+
+} // namespace lyx
+
+#endif
Property changes on: src/insets/InsetScript.h
___________________________________________________________________
Added: svn:eol-style
+ native
Index: src/insets/Inset.cpp
===================================================================
--- src/insets/Inset.cpp (revision 36398)
+++ src/insets/Inset.cpp (working copy)
@@ -115,6 +115,7 @@ static void build_translator()
insetnames[INFO_CODE] = InsetName("info", _("Info"));
insetnames[COLLAPSABLE_CODE] = InsetName("collapsable");
insetnames[NEWPAGE_CODE] = InsetName("newpage");
+ insetnames[SCRIPT_CODE] = InsetName("script");
insetnames[CELL_CODE] = InsetName("tablecell");
insetnames[MATH_AMSARRAY_CODE] = InsetName("mathamsarray");
insetnames[MATH_ARRAY_CODE] = InsetName("matharray");
Index: src/insets/InsetScript.cpp
===================================================================
--- src/insets/InsetScript.cpp (revision 0)
+++ src/insets/InsetScript.cpp (revision 0)
@@ -0,0 +1,413 @@
+/**
+ * \file InsetScript.cpp
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Uwe Stöhr
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#include <config.h>
+
+#include "InsetScript.h"
+
+#include "Buffer.h"
+#include "BufferParams.h"
+#include "BufferView.h"
+#include "Cursor.h"
+#include "Dimension.h"
+#include "DispatchResult.h"
+#include "Exporter.h"
+#include "FuncRequest.h"
+#include "FuncStatus.h"
+#include "LaTeXFeatures.h"
+#include "Lexer.h"
+#include "MetricsInfo.h"
+#include "OutputParams.h"
+#include "output_xhtml.h"
+#include "TextClass.h"
+#include "TextMetrics.h"
+
+#include "support/docstream.h"
+#include "support/gettext.h"
+#include "support/lstrings.h"
+#include "support/Translator.h"
+
+#include "frontends/Application.h"
+#include "frontends/FontMetrics.h"
+#include "frontends/Painter.h"
+
+#include <algorithm>
+
+using namespace std;
+
+namespace lyx {
+
+namespace {
+
+typedef Translator<string, InsetScriptParams::Type> ScriptTranslator;
+typedef Translator<docstring, InsetScriptParams::Type> ScriptTranslatorLoc;
+
+ScriptTranslator const init_scripttranslator()
+{
+ ScriptTranslator translator("subscript", InsetScriptParams::Subscript);
+ translator.addPair("superscript", InsetScriptParams::Superscript);
+ return translator;
+}
+
+
+ScriptTranslatorLoc const init_scripttranslator_loc()
+{
+ ScriptTranslatorLoc translator(_("Subscript"), InsetScriptParams::Subscript);
+ translator.addPair(_("Superscript"), InsetScriptParams::Superscript);
+ return translator;
+}
+
+
+ScriptTranslator const & scripttranslator()
+{
+ static ScriptTranslator translator = init_scripttranslator();
+ return translator;
+}
+
+
+ScriptTranslatorLoc const & scripttranslator_loc()
+{
+ static ScriptTranslatorLoc translator = init_scripttranslator_loc();
+ return translator;
+}
+
+} // anon
+
+
+InsetScriptParams::InsetScriptParams()
+ : type(Subscript)
+{}
+
+
+void InsetScriptParams::write(ostream & os) const
+{
+ string const label = scripttranslator().find(type);
+ os << "script " << label << "\n";
+}
+
+
+void InsetScriptParams::read(Lexer & lex)
+{
+ string label;
+ lex >> label;
+ if (lex)
+ type = scripttranslator().find(label);
+}
+
+
+int InsetScriptParams::shift(FontInfo const & font) const
+{
+ frontend::FontMetrics const & fm = theFontMetrics(font);
+ switch (type) {
+ case Subscript:
+ return fm.maxAscent() / 3;
+ case Superscript:
+ return -fm.maxAscent() / 2;
+ }
+ // shut up compiler
+ return 0;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+//
+// InsetScript
+//
+/////////////////////////////////////////////////////////////////////
+
+InsetScript::InsetScript(Buffer * buf, InsetScriptParams const & params)
+ : InsetText(buf), params_(params)
+{
+ setDrawFrame(false);
+}
+
+
+InsetScript::InsetScript(Buffer * buf, string const & label)
+ : InsetText(buf)
+{
+ setDrawFrame(false);
+ params_.type = scripttranslator().find(label);
+}
+
+
+InsetScript::~InsetScript()
+{
+}
+
+
+docstring InsetScript::name() const
+{
+ return from_ascii("script:" + scripttranslator().find(params_.type));
+}
+
+
+Inset::DisplayType InsetScript::display() const
+{
+ return Inline;
+}
+
+
+void InsetScript::metrics(MetricsInfo & mi, Dimension & dim) const
+{
+ int const shift = params_.shift(mi.base.font);
+ ScriptChanger dummy(mi.base);
+ InsetText::metrics(mi, dim);
+ dim.asc -= shift;
+ dim.des += shift;
+}
+
+
+void InsetScript::draw(PainterInfo & pi, int x, int y) const
+{
+ int const shift = params_.shift(pi.base.font);
+ ScriptChanger dummy(pi.base);
+ InsetText::draw(pi, x, y + shift);
+}
+
+
+void InsetScript::cursorPos(BufferView const & bv,
+ CursorSlice const & sl, bool boundary, int & x, int & y) const
+{
+ Font const font = bv.textMetrics(&text()).displayFont(sl.pit(), sl.pos());
+ int const shift = params_.shift(font.fontInfo());
+ InsetText::cursorPos(bv, sl, boundary, x, y);
+ y += shift;
+}
+
+
+void InsetScript::write(ostream & os) const
+{
+ params_.write(os);
+ text().write(os);
+}
+
+
+void InsetScript::read(Lexer & lex)
+{
+ params_.read(lex);
+ InsetText::read(lex);
+}
+
+
+void InsetScript::edit(Cursor & cur, bool front, EntryDirection entry_from)
+{
+ cur.push(*this);
+ InsetText::edit(cur, front, entry_from);
+}
+
+
+Inset * InsetScript::editXY(Cursor & cur, int x, int y)
+{
+ cur.push(*this);
+ return InsetText::editXY(cur, x, y);
+}
+
+void InsetScript::doDispatch(Cursor & cur, FuncRequest & cmd)
+{
+ switch (cmd.action()) {
+ case LFUN_INSET_MODIFY:
+ string2params(to_utf8(cmd.argument()), params_);
+ break;
+ default:
+ InsetText::doDispatch(cur, cmd);
+ break;
+ }
+}
+
+
+bool InsetScript::insetAllowed(InsetCode code) const
+{
+ switch (code) {
+ // code that is not allowed in a script
+ case SCRIPT_CODE:
+ case FLOAT_CODE:
+ case FOOT_CODE:
+ case NEWPAGE_CODE:
+ case MARGIN_CODE:
+ case MATHMACRO_CODE:
+ case TABULAR_CODE:
+ case WRAP_CODE:
+ return false;
+ default:
+ return InsetText::insetAllowed(code);
+ }
+}
+
+bool InsetScript::getStatus(Cursor & cur, FuncRequest const & cmd,
+ FuncStatus & flag) const
+{
+ switch (cmd.action()) {
+ case LFUN_BREAK_PARAGRAPH:
+ case LFUN_LAYOUT:
+ case LFUN_LAYOUT_PARAGRAPH:
+ flag.setEnabled(false);
+ return true;
+ break;
+ case LFUN_INSET_MODIFY:
+ flag.setEnabled(true);
+ return true;
+ case LFUN_INSET_INSERT:
+ if (cmd.getArg(0) == "script") {
+ flag.setEnabled(false);
+ return true;
+ }
+ // fall through
+ default:
+ return InsetText::getStatus(cur, cmd, flag);
+ }
+}
+
+
+docstring InsetScript::toolTip(BufferView const &, int, int) const
+{
+ OutputParams rp(&buffer().params().encoding());
+ odocstringstream ods;
+ InsetText::plaintext(ods, rp);
+ docstring content_tip = ods.str();
+ // shorten it if necessary
+ if (content_tip.size() > 200)
+ content_tip = content_tip.substr(0, 200) + "...";
+ docstring res = scripttranslator_loc().find(params_.type);
+ if (!content_tip.empty())
+ res += from_ascii(": ") + content_tip;
+ return res;
+}
+
+
+void InsetScript::validate(LaTeXFeatures & features) const
+{
+ if (params_.type == InsetScriptParams::Subscript)
+ features.require("subscript");
+ InsetText::validate(features);
+}
+
+
+int InsetScript::latex(odocstream & os, OutputParams const & runparams) const
+{
+ switch (params_.type) {
+ case InsetScriptParams::Subscript:
+ os << "\\textsubscript{";
+ break;
+ case InsetScriptParams::Superscript:
+ os << "\\textsuperscript{";
+ break;
+ }
+ int const i = InsetText::latex(os, runparams);
+ os << "}";
+
+ return i;
+}
+
+
+int InsetScript::plaintext(odocstream & os, OutputParams const & runparams) const
+{
+ odocstringstream oss;
+ InsetText::plaintext(oss, runparams);
+ docstring const text = oss.str();
+ switch (params_.type) {
+ case InsetScriptParams::Subscript:
+ if (text.size() == 1) {
+ char_type const c = support::subscript(text[0]);
+ if (c != text[0]) {
+ os.put(c);
+ return 0;
+ }
+ }
+ os << '[' << buffer().B_("subscript") << ':';
+ break;
+ case InsetScriptParams::Superscript:
+ if (text.size() == 1) {
+ char_type const c = support::superscript(text[0]);
+ if (c != text[0]) {
+ os.put(c);
+ return 0;
+ }
+ }
+ os << '[' << buffer().B_("superscript") << ':';
+ break;
+ }
+ InsetText::plaintext(os, runparams);
+ os << ']';
+
+ return PLAINTEXT_NEWLINE;
+}
+
+
+int InsetScript::docbook(odocstream & os, OutputParams const & runparams) const
+{
+ string cmdname;
+ switch (params_.type) {
+ case InsetScriptParams::Subscript:
+ cmdname = "subscript";
+ break;
+ case InsetScriptParams::Superscript:
+ cmdname = "superscript";
+ break;
+ }
+ os << '<' + cmdname + '>';
+ int const i = InsetText::docbook(os, runparams);
+ os << "</" + cmdname + '>';
+
+ return i;
+}
+
+
+docstring InsetScript::xhtml(XHTMLStream & xs, OutputParams const & runparams) const
+{
+ string cmdname;
+ switch (params_.type) {
+ case InsetScriptParams::Subscript:
+ cmdname = "sub";
+ break;
+ case InsetScriptParams::Superscript:
+ cmdname = "sup";
+ break;
+ }
+
+ xs << html::StartTag(cmdname);
+ docstring const ret = InsetText::xhtml(xs, runparams);
+ xs << html::EndTag(cmdname);
+ return ret;
+}
+
+
+docstring InsetScript::contextMenu(BufferView const &, int, int) const
+{
+ return from_ascii("context-script");
+}
+
+
+string InsetScript::params2string(InsetScriptParams const & params)
+{
+ ostringstream data;
+ data << "script ";
+ params.write(data);
+ return data.str();
+}
+
+
+void InsetScript::string2params(string const & in, InsetScriptParams & params)
+{
+ params = InsetScriptParams();
+
+ if (in.empty())
+ return;
+
+ istringstream data(in);
+ Lexer lex;
+ lex.setStream(data);
+ lex.setContext("InsetScript::string2params");
+ lex >> "script" >> "script";
+
+ params.read(lex);
+}
+
+
+} // namespace lyx
Property changes on: src/insets/InsetScript.cpp
___________________________________________________________________
Added: svn:eol-style
+ native
Index: src/insets/InsetCode.h
===================================================================
--- src/insets/InsetCode.h (revision 36398)
+++ src/insets/InsetCode.h (working copy)
@@ -115,6 +115,8 @@ enum InsetCode {
///
PHANTOM_CODE,
///
+ SCRIPT_CODE,
+ ///
MATH_AMSARRAY_CODE,
///
MATH_ARRAY_CODE,
Index: src/Makefile.am
===================================================================
--- src/Makefile.am (revision 36398)
+++ src/Makefile.am (working copy)
@@ -558,6 +558,7 @@ SOURCEFILESINSETS = \
insets/InsetPreview.cpp \
insets/InsetQuotes.cpp \
insets/InsetRef.cpp \
+ insets/InsetScript.cpp \
insets/InsetSpace.cpp \
insets/InsetSpecialChar.cpp \
insets/InsetTabular.cpp \
@@ -613,6 +614,7 @@ HEADERFILESINSETS = \
insets/InsetPhantom.h \
insets/InsetQuotes.h \
insets/InsetRef.h \
+ insets/InsetScript.h \
insets/InsetSpace.h \
insets/InsetSpecialChar.h \
insets/InsetTabular.h \
Index: src/support/lstrings.h
===================================================================
--- src/support/lstrings.h (revision 36398)
+++ src/support/lstrings.h (working copy)
@@ -101,6 +101,14 @@ docstring const lowercase(docstring cons
/// Does not depend on the locale.
docstring const uppercase(docstring const & s);
+/// Returns the superscript of \p c or \p c if no superscript exists.
+/// Does not depend on the locale.
+char_type superscript(char_type c);
+
+/// Returns the subscript of \p c or \p c if no subscript exists.
+/// Does not depend on the locale.
+char_type subscript(char_type c);
+
/// Does str start with c?
bool prefixIs(docstring const & str, char_type c);
Index: src/support/lstrings.cpp
===================================================================
--- src/support/lstrings.cpp (revision 36398)
+++ src/support/lstrings.cpp (working copy)
@@ -506,6 +506,132 @@ docstring const ascii_lowercase(docstrin
}
+char_type superscript(char_type c)
+{
+ switch (c) {
+ case '2': return 0x00b2;
+ case '3': return 0x00b3;
+ case '1': return 0x00b9;
+ case '0': return 0x2070;
+ case 'i': return 0x2071;
+ case '4': return 0x2074;
+ case '5': return 0x2075;
+ case '6': return 0x2076;
+ case '7': return 0x2077;
+ case '8': return 0x2078;
+ case '9': return 0x2079;
+ case '+': return 0x207a;
+ case '-': return 0x207b;
+ case '=': return 0x207c;
+ case '(': return 0x207d;
+ case ')': return 0x207e;
+ case 'n': return 0x207f;
+ case 'h': return 0x02b0;
+ case 0x0266: return 0x02b1; // LATIN SMALL LETTER H WITH HOOK
+ case 'j': return 0x02b2;
+ case 'r': return 0x02b3;
+ case 0x0279: return 0x02b4; // LATIN SMALL LETTER TURNED R
+ case 0x027b: return 0x02b5; // LATIN SMALL LETTER TURNED R WITH HOOK
+ case 0x0281: return 0x02b6; // LATIN SMALL LETTER CAPITAL INVERTED R
+ case 'w': return 0x02b7;
+ case 'y': return 0x02b8;
+// case 0x0294: return 0x02c0; // LATIN LETTER GLOTTAL STOP)
+// case 0x0295: return 0x02c1; // LATIN LETTER PHARYNGEAL VOICED FRICATIVE
+ // (= LATIN LETTER REVERSED GLOTTAL STOP)
+ case 'l': return 0x02e1;
+ case 's': return 0x02e2;
+ case 'x': return 0x02e3;
+// case 0x0295: return 0x02e4; // LATIN SMALL LETTER REVERSED GLOTTAL STOP
+ case 'A': return 0x1d2c;
+ case 0x00c6: return 0x1d2d; // LATIN CAPITAL LETTER AE
+ case 'B': return 0x1d2e;
+ case 'D': return 0x1d30;
+ case 'E': return 0x1d31;
+ case 'G': return 0x1d33;
+ case 'H': return 0x1d34;
+ case 'I': return 0x1d35;
+ case 'J': return 0x1d36;
+ case 'K': return 0x1d37;
+ case 'L': return 0x1d38;
+ case 'M': return 0x1d39;
+ case 'N': return 0x1d3a;
+ case 'O': return 0x1d3c;
+ case 'P': return 0x1d3e;
+ case 'R': return 0x1d3f;
+ case 'T': return 0x1d40;
+ case 'U': return 0x1d41;
+ case 'W': return 0x1d42;
+ case 'a': return 0x1d43;
+ case 0x0250: return 0x1d44; // LATIN SMALL LETTER TURNED A
+ case 0x0251: return 0x1d45; // LATIN SMALL LETTER ALPHA
+ case 'b': return 0x1d47;
+ case 'd': return 0x1d48;
+ case 'e': return 0x1d49;
+ case 0x0259: return 0x1d4a; // LATIN SMALL LETTER SCHWA
+ case 0x025b: return 0x1d4b; // LATIN SMALL LETTER OPEN E
+ case 0x1d08: return 0x1d4c; // LATIN SMALL LETTER TURNED OPEN E
+ case 'g': return 0x1d4d;
+ case 0x1d09: return 0x1d4e; // LATIN SMALL LETTER TURNED I
+ case 'k': return 0x1d4f;
+ case 'm': return 0x1d50;
+ case 0x014b: return 0x1d51; // LATIN SMALL LETTER ENG
+ case 'o': return 0x1d52;
+ case 0x0254: return 0x1d53; // LATIN SMALL LETTER OPEN O
+ case 0x1d16: return 0x1d54; // LATIN SMALL LETTER TOP HALF O
+ case 0x1d17: return 0x1d55; // LATIN SMALL LETTER BOTTOM HALF O
+ case 'p': return 0x1d56;
+ case 't': return 0x1d57;
+ case 'u': return 0x1d58;
+ case 0x1d1d: return 0x1d59; // LATIN SMALL LETTER SIDEWAYS U
+ case 0x1d1f: return 0x1d5a; // LATIN SMALL LETTER SIDEWAYS TURNED M
+ case 'v': return 0x1d5b;
+ case 0x03b2: return 0x1d5d; // GREEK SMALL LETTER BETA
+ case 0x03b3: return 0x1d5e; // GREEK SMALL LETTER GAMMA
+ case 0x03b4: return 0x1d5f; // GREEK SMALL LETTER DELTA
+ case 0x03c6: return 0x1d60; // GREEK SMALL LETTER PHI
+ case 0x03c7: return 0x1d61; // GREEK SMALL LETTER CHI
+ }
+ return c;
+}
+
+
+char_type subscript(char_type c)
+{
+ switch (c) {
+ case 'i': return 0x1d62;
+ case 'r': return 0x1d63;
+ case 'u': return 0x1d64;
+ case 'v': return 0x1d65;
+ case 0x03b2: return 0x1d66; // GREEK SMALL LETTER BETA
+ case 0x03b3: return 0x1d67; // GREEK SMALL LETTER GAMMA
+ case 0x03c1: return 0x1d68; // GREEK SMALL LETTER RHO
+ case 0x03c6: return 0x1d69; // GREEK SMALL LETTER PHI
+ case 0x03c7: return 0x1d6a; // GREEK SMALL LETTER CHI
+ case '0': return 0x2080;
+ case '1': return 0x2081;
+ case '2': return 0x2082;
+ case '3': return 0x2083;
+ case '4': return 0x2084;
+ case '5': return 0x2085;
+ case '6': return 0x2086;
+ case '7': return 0x2087;
+ case '8': return 0x2088;
+ case '9': return 0x2089;
+ case '+': return 0x208a;
+ case '-': return 0x208b;
+ case '=': return 0x208c;
+ case '(': return 0x208d;
+ case ')': return 0x208e;
+ case 'a': return 0x2090;
+ case 'e': return 0x2091;
+ case 'o': return 0x2092;
+ case 'x': return 0x2093;
+ case 0x0259: return 0x2093; // LATIN SMALL LETTER SCHWA
+ }
+ return c;
+}
+
+
bool prefixIs(docstring const & a, char_type c)
{
if (a.empty())
Index: src/factory.cpp
===================================================================
--- src/factory.cpp (revision 36398)
+++ src/factory.cpp (working copy)
@@ -49,6 +49,7 @@
#include "insets/InsetPhantom.h"
#include "insets/InsetPreview.h"
#include "insets/InsetRef.h"
+#include "insets/InsetScript.h"
#include "insets/InsetSpace.h"
#include "insets/InsetTabular.h"
#include "insets/InsetTOC.h"
@@ -310,6 +311,12 @@ Inset * createInsetHelper(Buffer * buf,
return new InsetRef(buf, icp);
}
+ case SCRIPT_CODE: {
+ InsetScriptParams isp;
+ InsetScript::string2params(to_utf8(cmd.argument()), isp);
+ return new InsetScript(buf, isp);
+ }
+
case SPACE_CODE: {
InsetSpaceParams isp;
InsetSpace::string2params(to_utf8(cmd.argument()), isp);
@@ -549,6 +556,8 @@ Inset * readInset(Lexer & lex, Buffer *
inset.reset(new InsetERT(buf));
} else if (tmptok == "listings") {
inset.reset(new InsetListings(buf));
+ } else if (tmptok == "script") {
+ inset.reset(new InsetScript(buf));
} else if (tmptok == "space") {
inset.reset(new InsetSpace);
} else if (tmptok == "Tabular") {
Index: src/LaTeXFeatures.cpp
===================================================================
--- src/LaTeXFeatures.cpp (revision 36398)
+++ src/LaTeXFeatures.cpp (working copy)
@@ -537,6 +537,7 @@ char const * simplefeatures[] = {
"framed",
"soul",
"textcomp",
+ "subscript",
"pmboxdraw",
"bbding",
"ifsym",
Index: src/Text3.cpp
===================================================================
--- src/Text3.cpp (revision 36398)
+++ src/Text3.cpp (working copy)
@@ -1073,7 +1073,10 @@ void Text::dispatch(Cursor & cur, FuncRe
if (cur.selection())
cutSelection(cur, true, false);
cur.insert(inset);
- cur.posForward();
+ if (inset->editable() && inset->asInsetText())
+ inset->edit(cur, true);
+ else
+ cur.posForward();
// trigger InstantPreview now
if (inset->lyxCode() == EXTERNAL_CODE) {
Index: src/Buffer.cpp
===================================================================
--- src/Buffer.cpp (revision 36398)
+++ src/Buffer.cpp (working copy)
@@ -128,7 +128,7 @@ namespace {
// Do not remove the comment below, so we get merge conflict in
// independent branches. Instead add your own.
-int const LYX_FORMAT = 407; // uwestoehr: support for multirow offset
+int const LYX_FORMAT = 408; // gb add script inset
typedef map<string, bool> DepClean;
typedef map<docstring, pair<InsetLabel const *, Buffer::References> > RefCache;
Index: lib/lyx2lyx/lyx_2_0.py
===================================================================
--- lib/lyx2lyx/lyx_2_0.py (revision 36398)
+++ lib/lyx2lyx/lyx_2_0.py (working copy)
@@ -2293,6 +2293,50 @@ def revert_multirowOffset(document):
begin_table = end_table
+def revert_script(document):
+ " Convert subscript/superscript inset to TeX code "
+ i = 0
+ foundsubscript = False
+ while 1:
+ i = find_token(document.body, '\\begin_inset script', i)
+ if i == -1:
+ break
+ z = find_end_of_inset(document.body, i)
+ if z == -1:
+ document.warning("Malformed LyX document: Can't find end of script inset.")
+ i += 1
+ continue
+ blay = find_token(document.body, "\\begin_layout", i, z)
+ if blay == -1:
+ document.warning("Malformed LyX document: Can't find layout in script inset.")
+ i = z
+ continue
+
+ if check_token(document.body[i], "\\begin_inset script subscript"):
+ subst = '\\textsubscript{'
+ foundsubscript = True
+ elif check_token(document.body[i], "\\begin_inset script superscript"):
+ subst = '\\textsuperscript{'
+ else:
+ document.warning("Malformed LyX document: Unknown type of script inset.")
+ i = z
+ continue
+ bend = find_end_of_layout(document.body, blay)
+ if bend == -1 or bend > z:
+ document.warning("Malformed LyX document: Can't find end of layout in script inset.")
+ i = z
+ continue
+ # remove the \end_layout \end_inset pair
+ document.body[bend:z + 1] = put_cmd_in_ert("}")
+ document.body[i:blay + 1] = put_cmd_in_ert(subst)
+ i += 1
+ # these classes provide a \textsubscript command:
+ # FIXME: Would be nice if we could use the information of the .layout file here
+ classes = ["memoir", "scrartcl", "scrbook", "scrlttr2", "scrreprt"]
+ if foundsubscript and find_token_exact(classes, document.textclass, 0) == -1:
+ add_to_preamble(document, ['\\usepackage{subscript}'])
+
+
##
# Conversion hub
#
@@ -2359,10 +2403,12 @@ convert = [[346, []],
[404, [convert_prettyref]],
[405, []],
[406, [convert_passthru]],
- [407, []]
+ [407, []],
+ [408, []]
]
-revert = [[406, [revert_multirowOffset]],
+revert = [[407, [revert_script]],
+ [406, [revert_multirowOffset]],
[405, [revert_passthru]],
[404, []],
[403, [revert_refstyle]],
Index: lib/unicodesymbols
===================================================================
--- lib/unicodesymbols (revision 36398)
+++ lib/unicodesymbols (working copy)
@@ -49,14 +49,14 @@
0x00af "\\textasciimacron" "textcomp" "" # MACRON
0x00b0 "\\textdegree" "textcomp" "force" # DEGREE SIGN # the force flag is only needed due to a bug in teTeX 3 / TeXLive 2005
0x00b1 "\\textpm" "textcomp" "force" "\pm" # ± PLUS-MINUS SIGN
-0x00b2 "\\texttwosuperior" "textcomp" "force" # ² SUPERSCRIPT TWO
-0x00b3 "\\textthreesuperior" "textcomp" "force" # ³ SUPERSCRIPT THREE
+0x00b2 "\\texttwosuperior" "textcomp" "force" "{{}^2}" "" # ² SUPERSCRIPT TWO
+0x00b3 "\\textthreesuperior" "textcomp" "force" "{{}^3}" "" # ³ SUPERSCRIPT THREE
0x00b4 "\\textasciiacute" "textcomp" "" # ACUTE ACCENT
0x00b5 "\\textmu" "textcomp" "force" # µ MICRO SIGN
0x00b6 "\\textparagraph" "textcomp" "" # PILCROW SIGN # not equal to \textpilcrow
0x00b7 "\\textperiodcentered" "" "" "\cdot" # MIDDLE DOT
0x00b8 "\\c\\ " "" "" # CEDILLA (command from latin1.def)
-0x00b9 "\\textonesuperior" "textcomp" "force" # ¹ SUPERSCRIPT ONE
+0x00b9 "\\textonesuperior" "textcomp" "force" "{{}^1}" "" # ¹ SUPERSCRIPT ONE
0x00ba "\\textordmasculine" "textcomp" "" # MASCULINE ORDINAL INDICATOR
0x00bb "\\guillemotright" "" "" # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0x00bc "\\textonequarter" "textcomp" "" # 1/4 FRACTION
@@ -958,7 +958,7 @@
0x1d2d "\\textsuperscript{\\AE}" "" "" # MODIFIER LETTER CAPITAL AE
0x1d2e "\\textsuperscript{B}" "" "" # MODIFIER LETTER CAPITAL B
#0x1d2f "" "" "" # MODIFIER LETTER CAPITAL BARRED B
-0x1d30 "\\textsuperscript{B}" "" "" # MODIFIER LETTER CAPITAL D
+0x1d30 "\\textsuperscript{D}" "" "" # MODIFIER LETTER CAPITAL D
0x1d31 "\\textsuperscript{E}" "" "" # MODIFIER LETTER CAPITAL E
#0x1d32 "" "" "" # MODIFIER LETTER CAPITAL REVERSED E
0x1d33 "\\textsuperscript{G}" "" "" # MODIFIER LETTER CAPITAL G
@@ -1008,15 +1008,15 @@
0x1d5f "\\textsuperscript{\\textgreek{d}}" "textgreek""" # MODIFIER LETTER SMALL DELTA
0x1d60 "\\textsuperscript{\\textgreek{f}}" "textgreek""" # MODIFIER LETTER SMALL GREEK PHI
0x1d61 "\\textsuperscript{\\textgreek{q}}" "textgreek""" # MODIFIER LETTER SMALL CHI
-#0x1d62 "" "" "" # LATIN SUBSCRIPT SMALL LETTER I
-#0x1d63 "" "" "" # LATIN SUBSCRIPT SMALL LETTER R
-#0x1d64 "" "" "" # LATIN SUBSCRIPT SMALL LETTER U
-#0x1d65 "" "" "" # LATIN SUBSCRIPT SMALL LETTER V
-#0x1d66 "" "" "" # GREEK SUBSCRIPT SMALL LETTER BETA
-#0x1d67 "" "" "" # GREEK SUBSCRIPT SMALL LETTER GAMMA
-#0x1d68 "" "" "" # GREEK SUBSCRIPT SMALL LETTER RHO
-#0x1d69 "" "" "" # GREEK SUBSCRIPT SMALL LETTER PHI
-#0x1d6a "" "" "" # GREEK SUBSCRIPT SMALL LETTER CHI
+0x1d62 "\\textsubscript{i}" "subscript" "" "{{}_i}" "" # LATIN SUBSCRIPT SMALL LETTER I
+0x1d63 "\\textsubscript{r}" "subscript" "" "{{}_r}" "" # LATIN SUBSCRIPT SMALL LETTER R
+0x1d64 "\\textsubscript{u}" "subscript" "" "{{}_u}" "" # LATIN SUBSCRIPT SMALL LETTER U
+0x1d65 "\\textsubscript{v}" "subscript" "" "{{}_v}" "" # LATIN SUBSCRIPT SMALL LETTER V
+0x1d66 "\\textsubscript{\\textgreek{b}}" "subscript" "" "{{}_\\beta}" "" # GREEK SUBSCRIPT SMALL LETTER BETA
+0x1d67 "\\textsubscript{\\textgreek{g}}" "subscript" "" "{{}_\\gamma}" "" # GREEK SUBSCRIPT SMALL LETTER GAMMA
+0x1d68 "\\textsubscript{\\textgreek{r}}" "subscript" "" "{{}_\\rho}" "" # GREEK SUBSCRIPT SMALL LETTER RHO
+0x1d69 "\\textsubscript{\\textgreek{f}}" "subscript" "" "{{}_\\phi}" "" # GREEK SUBSCRIPT SMALL LETTER PHI
+0x1d6a "\\textsubscript{\\textgreek{q}}" "subscript" "" "{{}_\\chi}" "" # GREEK SUBSCRIPT SMALL LETTER CHI
#0x1d6b "" "" "" # LATIN SMALL LETTER UE
#0x1d6c "" "" "" # LATIN SMALL LETTER B WITH MIDDLE TILDE
0x1d6d "\\textsuperimposetilde{d}" "tipa" "force" # LATIN SMALL LETTER D WITH MIDDLE TILDE
@@ -1575,6 +1575,42 @@
0x2049 "!?" "" "" # EXCLAMATION QUESTION MARK
0x2052 "\\textdiscount" "textcomp" "" # COMMERCIAL MINUS SIGN
0x205d "\\vdots" "" "" # TRICOLON # â VERTICAL ELLIPSIS
+#0x205e "" "" "" "" "" # VERTICAL FOUR DOTS
+0x205f "" "" "" "\\:" "" # MEDIUM MATHEMATICAL SPACE
+0x2070 "\\textsuperscript{0}" "" "" "{{}^0}" "" # SUPERSCRIPT ZERO
+0x2071 "\\textsuperscript{i}" "" "" "{{}^i}" "" # SUPERSCRIPT LATIN SMALL LETTER I
+0x2074 "\\textsuperscript{4}" "" "" "{{}^4}" "" # SUPERSCRIPT FOUR
+0x2075 "\\textsuperscript{5}" "" "" "{{}^5}" "" # SUPERSCRIPT FIVE
+0x2076 "\\textsuperscript{6}" "" "" "{{}^6}" "" # SUPERSCRIPT SIX
+0x2077 "\\textsuperscript{7}" "" "" "{{}^7}" "" # SUPERSCRIPT SEVEN
+0x2078 "\\textsuperscript{8}" "" "" "{{}^8}" "" # SUPERSCRIPT EIGHT
+0x2079 "\\textsuperscript{9}" "" "" "{{}^9}" "" # SUPERSCRIPT NINE
+0x207a "\\textsuperscript{+}" "" "" "{{}^+}" "" # SUPERSCRIPT PLUS SIGN
+0x207b "\\textsuperscript{-}" "" "" "{{}^-}" "" # SUPERSCRIPT MINUS
+0x207c "\\textsuperscript{=}" "" "" "{{}^=}" "" # SUPERSCRIPT EQUALS SIGN
+0x207d "\\textsuperscript{(}" "" "" "{{}^(}" "" # SUPERSCRIPT LEFT PARENTHESIS
+0x207e "\\textsuperscript{)}" "" "" "{{}^)}" "" # SUPERSCRIPT RIGHT PARENTHESIS
+0x207f "\\textsuperscript{n}" "" "" "{{}^n}" "" # SUPERSCRIPT LATIN SMALL LETTER N
+0x2080 "\\textsubscript{0}" "subscript" "" "{{}_0}" "" # SUBSCRIPT ZERO
+0x2081 "\\textsubscript{1}" "subscript" "" "{{}_1}" "" # SUBSCRIPT ONE
+0x2082 "\\textsubscript{2}" "subscript" "" "{{}_2}" "" # SUBSCRIPT TWO
+0x2083 "\\textsubscript{3}" "subscript" "" "{{}_3}" "" # SUBSCRIPT THREE
+0x2084 "\\textsubscript{4}" "subscript" "" "{{}_4}" "" # SUBSCRIPT FOUR
+0x2085 "\\textsubscript{5}" "subscript" "" "{{}_5}" "" # SUBSCRIPT FIVE
+0x2086 "\\textsubscript{6}" "subscript" "" "{{}_6}" "" # SUBSCRIPT SIX
+0x2087 "\\textsubscript{7}" "subscript" "" "{{}_7}" "" # SUBSCRIPT SEVEN
+0x2088 "\\textsubscript{8}" "subscript" "" "{{}_8}" "" # SUBSCRIPT EIGHT
+0x2089 "\\textsubscript{9}" "subscript" "" "{{}_9}" "" # SUBSCRIPT NINE
+0x208a "\\textsubscript{+}" "subscript" "" "{{}_+}" "" # SUBSCRIPT PLUS SIGN
+0x208b "\\textsubscript{-}" "subscript" "" "{{}_-}" "" # SUBSCRIPT MINUS
+0x208c "\\textsubscript{=}" "subscript" "" "{{}_=}" "" # SUBSCRIPT EQUALS SIGN
+0x208d "\\textsubscript{(}" "subscript" "" "{{}_(}" "" # SUBSCRIPT LEFT PARENTHESIS
+0x208e "\\textsubscript{)}" "subscript" "" "{{}_)}" "" # SUBSCRIPT RIGHT PARENTHESIS
+0x2090 "\\textsubscript{a}" "subscript" "" "{{}_a}" "" # LATIN SUBSCRIPT SMALL LETTER A
+0x2091 "\\textsubscript{e}" "subscript" "" "{{}_e}" "" # LATIN SUBSCRIPT SMALL LETTER E
+0x2092 "\\textsubscript{o}" "subscript" "" "{{}_o}" "" # LATIN SUBSCRIPT SMALL LETTER O
+0x2093 "\\textsubscript{x}" "subscript" "" "{{}_x}" "" # LATIN SUBSCRIPT SMALL LETTER X
+0x2094 "\\textsubscript{\\textschwa}" "subscript" "" "{{}_\\textschwa}" "tipa" # LATIN SUBSCRIPT SMALL LETTER SCHWA
#
# currency symbols
#
@@ -1620,7 +1656,7 @@
# Weierstrass elliptic function, actually this has the form of a
# lowercase calligraphic p, despite its name (Maybe use Zapf chancery?)
#0x2118 "" "" "" "\\mathscr{P}" "mathrsfs" # SCRIPT CAPITAL P
-0x2119 "" "" "" "\\mathbb{P}" "amssymb"# DOUBLE-STUCK CAPITAL P
+0x2119 "" "" "" "\\mathbb{P}" "amssymb" # DOUBLE-STUCK CAPITAL P
0x211a "" "" "" "\\mathbb{Q}" "amssymb" # DOUBLE-STUCK CAPITAL Q
0x211b "" "" "" "\\mathscr{R}" "mathrsfs" # SCRIPT CAPITAL R
0x211c "" "" "" "\\mathfrak{R}" "amssymb" # BLACK-LETTER CAPITAL R
Index: lib/layouts/scrlttr2.layout
===================================================================
--- lib/layouts/scrlttr2.layout (revision 36398)
+++ lib/layouts/scrlttr2.layout (working copy)
@@ -5,6 +5,8 @@
# Uwe Stöhr <uwesto...@web.de>, 2008/2/03.
Format 30
+Provides subscript 1
+
Style Standard
LatexName dummy
ParSep 0.4
Index: lib/layouts/scrclass.inc
===================================================================
--- lib/layouts/scrclass.inc (revision 36398)
+++ lib/layouts/scrclass.inc (working copy)
@@ -11,6 +11,7 @@ Format 30
SecNumDepth 2
TocDepth 2
DefaultStyle Standard
+Provides subscript 1
Style Standard
LatexName dummy
Index: lib/layouts/memoir.layout
===================================================================
--- lib/layouts/memoir.layout (revision 36398)
+++ lib/layouts/memoir.layout (working copy)
@@ -15,6 +15,7 @@ DefaultStyle Standard
PageStyle Headings
Provides makeidx 1
Provides framed 1
+Provides subscript 1
# Memoir has support for line spacing, but uses different names from
# what setspace.sty does.
Provides SetSpace 1
Index: lib/chkconfig.ltx
===================================================================
--- lib/chkconfig.ltx (revision 36398)
+++ lib/chkconfig.ltx (working copy)
@@ -297,6 +297,7 @@
\TestPackage{subfig}
\TestPackage{Sweave}
\TestPackage{textcomp}
+\TestPackage{subscript}
\TestPackage[turkmen.ldf]{turkmen}
\TestPackage{ulem}
\TestPackage{units}
Index: lib/images/inset-insert_script_script_superscript.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: lib/images/inset-insert_script_script_subscript.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: lib/doc/LaTeXConfig.lyx
===================================================================
--- lib/doc/LaTeXConfig.lyx (revision 36398)
+++ lib/doc/LaTeXConfig.lyx (working copy)
@@ -5209,6 +5209,34 @@ e., subfigures, subtables, etc.).
\end_layout
\begin_layout Subsection
+subscript
+\end_layout
+
+\begin_layout Description
+Found:
+\begin_inset Info
+type "package"
+arg "subscript"
+\end_inset
+
+
+\end_layout
+
+\begin_layout Description
+CTAN:
+\family typewriter
+macros/latex/contrib/fragments/subscript.sty
+\end_layout
+
+\begin_layout Description
+Notes: The package
+\family sans
+subscript
+\family default
+ is needed by LyX to output subscript text with some document classes.
+\end_layout
+
+\begin_layout Subsection
setspace
\end_layout
Index: lib/Makefile.am
===================================================================
--- lib/Makefile.am (revision 36398)
+++ lib/Makefile.am (working copy)
@@ -381,6 +381,8 @@ dist_images_DATA = \
images/hidetab.png \
images/index-insert.png \
images/info-insert_buffer_vcs-revision.png \
+ images/inset-insert_script_script_subscript.png \
+ images/inset-insert_script_script_superscript.png \
images/label-insert.png \
images/layout.png \
images/layout-document.png \
Index: lib/ui/stdmenus.inc
===================================================================
--- lib/ui/stdmenus.inc (revision 36398)
+++ lib/ui/stdmenus.inc (working copy)
@@ -385,8 +385,8 @@ Menuset
End
Menu "insert_formatting"
- Item "Superscript|S" "command-sequence math-mode on; math-superscript; math-insert \text;"
- Item "Subscript|u" "command-sequence math-mode on; math-subscript; math-insert \text;"
+ Item "Superscript|S" "inset-insert script script superscript"
+ Item "Subscript|u" "inset-insert script script subscript"
Separator
Item "Protected Space|P" "space-insert protected"
Item "Interword Space|w" "space-insert normal"