X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2FInsetSpace.cpp;h=90d171e2d40570c6330fd308565d115735d243f0;hb=3934f4a36f0402612206cfc0abe0b0b62166214b;hp=a7ada6dc47ed5bd4c585430ef6eb94905af6452c;hpb=11a0458d3f66bce83b90e23f1c85175a8ffcae45;p=lyx.git diff --git a/src/insets/InsetSpace.cpp b/src/insets/InsetSpace.cpp index a7ada6dc47..90d171e2d4 100644 --- a/src/insets/InsetSpace.cpp +++ b/src/insets/InsetSpace.cpp @@ -5,8 +5,8 @@ * * \author Asger Alstrup Nielsen * \author Jean-Marc Lasgouttes - * \author Lars Gullik Bjønnes - * \author Jürgen Spitzmüller + * \author Lars Gullik Bjønnes + * \author Jürgen Spitzmüller * * Full author contact details are available in file CREDITS. */ @@ -20,14 +20,18 @@ #include "Dimension.h" #include "FuncRequest.h" #include "FuncStatus.h" +#include "Language.h" +#include "LaTeXFeatures.h" #include "Length.h" #include "Lexer.h" #include "MetricsInfo.h" #include "OutputParams.h" +#include "output_xhtml.h" #include "support/debug.h" #include "support/docstream.h" #include "support/gettext.h" +#include "support/lassert.h" #include "support/lstrings.h" #include "frontends/Application.h" @@ -40,7 +44,7 @@ namespace lyx { InsetSpace::InsetSpace(InsetSpaceParams const & params) - : params_(params) + : Inset(0), params_(params) {} @@ -50,18 +54,12 @@ InsetSpaceParams::Kind InsetSpace::kind() const } -Length InsetSpace::length() const +GlueLength InsetSpace::length() const { return params_.length; } -InsetSpace::~InsetSpace() -{ - hideDialogs("space", this); -} - - docstring InsetSpace::toolTip(BufferView const &, int, int) const { docstring message; @@ -72,14 +70,23 @@ docstring InsetSpace::toolTip(BufferView const &, int, int) const case InsetSpaceParams::PROTECTED: message = _("Protected Space"); break; + case InsetSpaceParams::VISIBLE: + message = _("Visible Space"); + break; case InsetSpaceParams::THIN: message = _("Thin Space"); break; + case InsetSpaceParams::MEDIUM: + message = _("Medium Space"); + break; + case InsetSpaceParams::THICK: + message = _("Thick Space"); + break; case InsetSpaceParams::QUAD: message = _("Quad Space"); break; case InsetSpaceParams::QQUAD: - message = _("QQuad Space"); + message = _("Double Quad Space"); break; case InsetSpaceParams::ENSPACE: message = _("Enspace"); @@ -90,6 +97,12 @@ docstring InsetSpace::toolTip(BufferView const &, int, int) const case InsetSpaceParams::NEGTHIN: message = _("Negative Thin Space"); break; + case InsetSpaceParams::NEGMEDIUM: + message = _("Negative Medium Space"); + break; + case InsetSpaceParams::NEGTHICK: + message = _("Negative Thick Space"); + break; case InsetSpaceParams::HFILL: message = _("Horizontal Fill"); break; @@ -102,13 +115,27 @@ docstring InsetSpace::toolTip(BufferView const &, int, int) const case InsetSpaceParams::HRULEFILL: message = _("Horizontal Fill (Rule)"); break; + case InsetSpaceParams::LEFTARROWFILL: + message = _("Horizontal Fill (Left Arrow)"); + break; + case InsetSpaceParams::RIGHTARROWFILL: + message = _("Horizontal Fill (Right Arrow)"); + break; + case InsetSpaceParams::UPBRACEFILL: + message = _("Horizontal Fill (Up Brace)"); + break; + case InsetSpaceParams::DOWNBRACEFILL: + message = _("Horizontal Fill (Down Brace)"); + break; case InsetSpaceParams::CUSTOM: + // FIXME unicode message = support::bformat(_("Horizontal Space (%1$s)"), - params_.length.asDocstring()); + from_ascii(params_.length.asString())); break; case InsetSpaceParams::CUSTOM_PROTECTED: + // FIXME unicode message = support::bformat(_("Protected Horizontal Space (%1$s)"), - params_.length.asDocstring()); + from_ascii(params_.length.asString())); break; } return message; @@ -117,16 +144,15 @@ docstring InsetSpace::toolTip(BufferView const &, int, int) const void InsetSpace::doDispatch(Cursor & cur, FuncRequest & cmd) { - switch (cmd.action) { + switch (cmd.action()) { - case LFUN_INSET_MODIFY: { + case LFUN_INSET_MODIFY: + cur.recordUndo(); string2params(to_utf8(cmd.argument()), params_); break; - } - case LFUN_MOUSE_RELEASE: - if (!cur.selection() && cmd.button() == mouse_button::button1) - cur.bv().showDialog("space", params2string(params()), this); + case LFUN_INSET_DIALOG_UPDATE: + cur.bv().updateDialog("space", params2string(params())); break; default: @@ -139,16 +165,20 @@ void InsetSpace::doDispatch(Cursor & cur, FuncRequest & cmd) bool InsetSpace::getStatus(Cursor & cur, FuncRequest const & cmd, FuncStatus & status) const { - switch (cmd.action) { + switch (cmd.action()) { // we handle these case LFUN_INSET_MODIFY: if (cmd.getArg(0) == "space") { InsetSpaceParams params; string2params(to_utf8(cmd.argument()), params); status.setOnOff(params_.kind == params.kind); - } else { - status.enabled(true); - } + status.setEnabled(true); + } else + status.setEnabled(false); + return true; + + case LFUN_INSET_DIALOG_UPDATE: + status.setEnabled(true); return true; default: return Inset::getStatus(cur, cmd, status); @@ -156,9 +186,8 @@ bool InsetSpace::getStatus(Cursor & cur, FuncRequest const & cmd, } -void InsetSpace::edit(Cursor & cur, bool, EntryDirection) -{ - cur.bv().showDialog("space", params2string(params()), this); +namespace { +int const arrow_size = 8; } @@ -180,7 +209,16 @@ void InsetSpace::metrics(MetricsInfo & mi, Dimension & dim) const case InsetSpaceParams::NEGTHIN: dim.wid = fm.width(char_type('M')) / 6; break; + case InsetSpaceParams::MEDIUM: + case InsetSpaceParams::NEGMEDIUM: + dim.wid = fm.width(char_type('M')) / 4; + break; + case InsetSpaceParams::THICK: + case InsetSpaceParams::NEGTHICK: + dim.wid = fm.width(char_type('M')) / 2; + break; case InsetSpaceParams::PROTECTED: + case InsetSpaceParams::VISIBLE: case InsetSpaceParams::NORMAL: dim.wid = fm.width(char_type(' ')); break; @@ -195,13 +233,22 @@ void InsetSpace::metrics(MetricsInfo & mi, Dimension & dim) const dim.wid = int(0.5 * fm.width(char_type('M'))); break; case InsetSpaceParams::CUSTOM: - case InsetSpaceParams::CUSTOM_PROTECTED: - dim.wid = params_.length.inBP(); + case InsetSpaceParams::CUSTOM_PROTECTED: { + int const w = + params_.length.len().inPixels(mi.base.textwidth, + fm.width(char_type('M'))); + int const minw = (w < 0) ? 3 * arrow_size : 4; + dim.wid = max(minw, abs(w)); break; + } case InsetSpaceParams::HFILL: case InsetSpaceParams::HFILL_PROTECTED: case InsetSpaceParams::DOTFILL: case InsetSpaceParams::HRULEFILL: + case InsetSpaceParams::LEFTARROWFILL: + case InsetSpaceParams::RIGHTARROWFILL: + case InsetSpaceParams::UPBRACEFILL: + case InsetSpaceParams::DOWNBRACEFILL: // shut up compiler break; } @@ -214,34 +261,87 @@ void InsetSpace::draw(PainterInfo & pi, int x, int y) const { Dimension const dim = dimension(*pi.base.bv); - if (isStretchableSpace()) { + if (isStretchableSpace() || params_.length.len().value() < 0) { int const asc = theFontMetrics(pi.base.font).ascent('M'); int const desc = theFontMetrics(pi.base.font).descent('M'); + // Pixel height divisible by 2 for prettier fill graphics: + int const oddheight = (asc ^ desc) & 1; int const x0 = x + 1; int const x1 = x + dim.wid - 2; - int const y0 = y + desc; - int const y1 = y - asc; - int const y2 = y - asc / 2; + int const y0 = y + desc - 1; + int const y1 = y - asc + oddheight - 1; + int const y2 = (y0 + y1) / 2; + int xoffset = (y0 - y1) / 2; + + // Two tests for very narrow insets + if (xoffset > x1 - x0 + && (params_.kind == InsetSpaceParams::LEFTARROWFILL + || params_.kind == InsetSpaceParams::RIGHTARROWFILL)) + xoffset = x1 - x0; + if (xoffset * 6 > (x1 - x0) + && (params_.kind == InsetSpaceParams::UPBRACEFILL + || params_.kind == InsetSpaceParams::DOWNBRACEFILL)) + xoffset = (x1 - x0) / 6; + + int const x2 = x0 + xoffset; + int const x3 = x1 - xoffset; + int const xm = (x0 + x1) / 2; + int const xml = xm - xoffset; + int const xmr = xm + xoffset; if (params_.kind == InsetSpaceParams::HFILL) { pi.pain.line(x0, y1, x0, y0, Color_added_space); - pi.pain.line(x0, y2 , x1, y2, Color_added_space, + pi.pain.line(x0, y2, x1, y2, Color_added_space, frontend::Painter::line_onoffdash); pi.pain.line(x1, y1, x1, y0, Color_added_space); } else if (params_.kind == InsetSpaceParams::HFILL_PROTECTED) { pi.pain.line(x0, y1, x0, y0, Color_latex); - pi.pain.line(x0, y2 , x1, y2, Color_latex, + pi.pain.line(x0, y2, x1, y2, Color_latex, frontend::Painter::line_onoffdash); pi.pain.line(x1, y1, x1, y0, Color_latex); } else if (params_.kind == InsetSpaceParams::DOTFILL) { pi.pain.line(x0, y1, x0, y0, Color_special); - pi.pain.line(x0, y, x1, y, Color_special, + pi.pain.line(x0, y0, x1, y0, Color_special, frontend::Painter::line_onoffdash); pi.pain.line(x1, y1, x1, y0, Color_special); - } if (params_.kind == InsetSpaceParams::HRULEFILL) { + } else if (params_.kind == InsetSpaceParams::HRULEFILL) { pi.pain.line(x0, y1, x0, y0, Color_special); - pi.pain.line(x0, y, x1, y, Color_special); + pi.pain.line(x0, y0, x1, y0, Color_special); pi.pain.line(x1, y1, x1, y0, Color_special); + } else if (params_.kind == InsetSpaceParams::LEFTARROWFILL) { + pi.pain.line(x2, y1 + 1 , x0 + 1, y2, Color_special); + pi.pain.line(x0 + 1, y2 + 1 , x2, y0, Color_special); + pi.pain.line(x0, y2 , x1, y2, Color_special); + } else if (params_.kind == InsetSpaceParams::RIGHTARROWFILL) { + pi.pain.line(x3 + 1, y1 + 1 , x1, y2, Color_special); + pi.pain.line(x1, y2 + 1 , x3 + 1, y0, Color_special); + pi.pain.line(x0, y2 , x1, y2, Color_special); + } else if (params_.kind == InsetSpaceParams::UPBRACEFILL) { + pi.pain.line(x0 + 1, y1 + 1 , x2, y2, Color_special); + pi.pain.line(x2, y2 , xml, y2, Color_special); + pi.pain.line(xml + 1, y2 + 1 , xm, y0, Color_special); + pi.pain.line(xm + 1, y0 , xmr, y2 + 1, Color_special); + pi.pain.line(xmr, y2 , x3, y2, Color_special); + pi.pain.line(x3 + 1, y2 , x1, y1 + 1, Color_special); + } else if (params_.kind == InsetSpaceParams::DOWNBRACEFILL) { + pi.pain.line(x0 + 1, y0 , x2, y2 + 1, Color_special); + pi.pain.line(x2, y2 , xml, y2, Color_special); + pi.pain.line(xml + 1, y2 , xm, y1 + 1, Color_special); + pi.pain.line(xm + 1, y1 + 1 , xmr, y2, Color_special); + pi.pain.line(xmr, y2 , x3, y2, Color_special); + pi.pain.line(x3 + 1, y2 + 1 , x1, y0, Color_special); + } else if (params_.kind == InsetSpaceParams::CUSTOM) { + pi.pain.line(x0, y1 + 1 , x2 + 1, y2, Color_special); + pi.pain.line(x2 + 1, y2 + 1 , x0, y0, Color_special); + pi.pain.line(x1 + 1, y1 + 1 , x3, y2, Color_special); + pi.pain.line(x3, y2 + 1 , x1 + 1, y0, Color_special); + pi.pain.line(x2, y2 , x3, y2, Color_special); + } else if (params_.kind == InsetSpaceParams::CUSTOM_PROTECTED) { + pi.pain.line(x0, y1 + 1 , x2 + 1, y2, Color_latex); + pi.pain.line(x2 + 1, y2 + 1 , x0, y0, Color_latex); + pi.pain.line(x1 + 1, y1 + 1 , x3, y2, Color_latex); + pi.pain.line(x3, y2 + 1 , x1 + 1, y0, Color_latex); + pi.pain.line(x2, y2 , x3, y2, Color_latex); } return; } @@ -253,7 +353,8 @@ void InsetSpace::draw(PainterInfo & pi, int x, int y) const xp[0] = x; yp[0] = y - max(h / 4, 1); if (params_.kind == InsetSpaceParams::NORMAL || - params_.kind == InsetSpaceParams::PROTECTED) { + params_.kind == InsetSpaceParams::PROTECTED || + params_.kind == InsetSpaceParams::VISIBLE) { xp[1] = x; yp[1] = y; xp[2] = x + w; yp[2] = y; } else { @@ -263,13 +364,18 @@ void InsetSpace::draw(PainterInfo & pi, int x, int y) const xp[3] = x + w; yp[3] = y - max(h / 4, 1); + Color col = Color_special; if (params_.kind == InsetSpaceParams::PROTECTED || params_.kind == InsetSpaceParams::ENSPACE || params_.kind == InsetSpaceParams::NEGTHIN || + params_.kind == InsetSpaceParams::NEGMEDIUM || + params_.kind == InsetSpaceParams::NEGTHICK || params_.kind == InsetSpaceParams::CUSTOM_PROTECTED) - pi.pain.lines(xp, yp, 4, Color_latex); - else - pi.pain.lines(xp, yp, 4, Color_special); + col = Color_latex; + else if (params_.kind == InsetSpaceParams::VISIBLE) + col = Color_foreground; + + pi.pain.lines(xp, yp, 4, col); } @@ -283,9 +389,18 @@ void InsetSpaceParams::write(ostream & os) const case InsetSpaceParams::PROTECTED: os << "~"; break; + case InsetSpaceParams::VISIBLE: + os << "\\textvisiblespace{}"; + break; case InsetSpaceParams::THIN: os << "\\thinspace{}"; break; + case InsetSpaceParams::MEDIUM: + os << "\\medspace{}"; + break; + case InsetSpaceParams::THICK: + os << "\\thickspace{}"; + break; case InsetSpaceParams::QUAD: os << "\\quad{}"; break; @@ -301,6 +416,12 @@ void InsetSpaceParams::write(ostream & os) const case InsetSpaceParams::NEGTHIN: os << "\\negthinspace{}"; break; + case InsetSpaceParams::NEGMEDIUM: + os << "\\negmedspace{}"; + break; + case InsetSpaceParams::NEGTHICK: + os << "\\negthickspace{}"; + break; case InsetSpaceParams::HFILL: os << "\\hfill{}"; break; @@ -313,6 +434,18 @@ void InsetSpaceParams::write(ostream & os) const case InsetSpaceParams::HRULEFILL: os << "\\hrulefill{}"; break; + case InsetSpaceParams::LEFTARROWFILL: + os << "\\leftarrowfill{}"; + break; + case InsetSpaceParams::RIGHTARROWFILL: + os << "\\rightarrowfill{}"; + break; + case InsetSpaceParams::UPBRACEFILL: + os << "\\upbracefill{}"; + break; + case InsetSpaceParams::DOWNBRACEFILL: + os << "\\downbracefill{}"; + break; case InsetSpaceParams::CUSTOM: os << "\\hspace{}"; break; @@ -321,22 +454,30 @@ void InsetSpaceParams::write(ostream & os) const break; } - if (!length.empty()) + if (!length.len().empty()) os << "\n\\length " << length.asString(); } void InsetSpaceParams::read(Lexer & lex) { - lex.next(); - string const command = lex.getString(); + lex.setContext("InsetSpaceParams::read"); + string command; + lex >> command; + // The tests for math might be disabled after a file format change if (command == "\\space{}") kind = InsetSpaceParams::NORMAL; else if (command == "~") kind = InsetSpaceParams::PROTECTED; + else if (command == "\\textvisiblespace{}") + kind = InsetSpaceParams::VISIBLE; else if (command == "\\thinspace{}") kind = InsetSpaceParams::THIN; + else if (math && command == "\\medspace{}") + kind = InsetSpaceParams::MEDIUM; + else if (math && command == "\\thickspace{}") + kind = InsetSpaceParams::THICK; else if (command == "\\quad{}") kind = InsetSpaceParams::QUAD; else if (command == "\\qquad{}") @@ -347,6 +488,10 @@ void InsetSpaceParams::read(Lexer & lex) kind = InsetSpaceParams::ENSKIP; else if (command == "\\negthinspace{}") kind = InsetSpaceParams::NEGTHIN; + else if (command == "\\negmedspace{}") + kind = InsetSpaceParams::NEGMEDIUM; + else if (command == "\\negthickspace{}") + kind = InsetSpaceParams::NEGTHICK; else if (command == "\\hfill{}") kind = InsetSpaceParams::HFILL; else if (command == "\\hspace*{\\fill}") @@ -357,32 +502,27 @@ void InsetSpaceParams::read(Lexer & lex) kind = InsetSpaceParams::HRULEFILL; else if (command == "\\hspace{}") kind = InsetSpaceParams::CUSTOM; + else if (command == "\\leftarrowfill{}") + kind = InsetSpaceParams::LEFTARROWFILL; + else if (command == "\\rightarrowfill{}") + kind = InsetSpaceParams::RIGHTARROWFILL; + else if (command == "\\upbracefill{}") + kind = InsetSpaceParams::UPBRACEFILL; + else if (command == "\\downbracefill{}") + kind = InsetSpaceParams::DOWNBRACEFILL; else if (command == "\\hspace*{}") kind = InsetSpaceParams::CUSTOM_PROTECTED; else lex.printError("InsetSpace: Unknown kind: `$$Token'"); - - string token; - lex >> token; - if (token == "\\length") { - lex.next(); - string const len = lex.getString(); - length = Length(len); - lex.next(); - token = lex.getString(); - } - if (!lex) - return; - if (token != "\\end_inset") - lex.printError("Missing \\end_inset at this point. " - "Read: `$$Token'"); + if (lex.checkFor("\\length")) + lex >> length; } void InsetSpace::write(ostream & os) const { - os << "Space "; + os << "space "; params_.write(os); } @@ -390,21 +530,36 @@ void InsetSpace::write(ostream & os) const void InsetSpace::read(Lexer & lex) { params_.read(lex); + lex >> "\\end_inset"; } -int InsetSpace::latex(odocstream & os, OutputParams const & runparams) const +void InsetSpace::latex(otexstream & os, OutputParams const & runparams) const { switch (params_.kind) { case InsetSpaceParams::NORMAL: os << (runparams.free_spacing ? " " : "\\ "); break; case InsetSpaceParams::PROTECTED: - os << (runparams.free_spacing ? ' ' : '~'); + if (runparams.local_font && + runparams.local_font->language()->lang() == "polutonikogreek") + // in babel's polutonikogreek, ~ is active + os << (runparams.free_spacing ? " " : "\\nobreakspace{}"); + else + os << (runparams.free_spacing ? ' ' : '~'); + break; + case InsetSpaceParams::VISIBLE: + os << (runparams.free_spacing ? " " : "\\textvisiblespace{}"); break; case InsetSpaceParams::THIN: os << (runparams.free_spacing ? " " : "\\,"); break; + case InsetSpaceParams::MEDIUM: + os << (runparams.free_spacing ? " " : "\\:"); + break; + case InsetSpaceParams::THICK: + os << (runparams.free_spacing ? " " : "\\;"); + break; case InsetSpaceParams::QUAD: os << (runparams.free_spacing ? " " : "\\quad{}"); break; @@ -420,6 +575,12 @@ int InsetSpace::latex(odocstream & os, OutputParams const & runparams) const case InsetSpaceParams::NEGTHIN: os << (runparams.free_spacing ? " " : "\\negthinspace{}"); break; + case InsetSpaceParams::NEGMEDIUM: + os << (runparams.free_spacing ? " " : "\\negmedspace{}"); + break; + case InsetSpaceParams::NEGTHICK: + os << (runparams.free_spacing ? " " : "\\negthickspace{}"); + break; case InsetSpaceParams::HFILL: os << (runparams.free_spacing ? " " : "\\hfill{}"); break; @@ -432,6 +593,18 @@ int InsetSpace::latex(odocstream & os, OutputParams const & runparams) const case InsetSpaceParams::HRULEFILL: os << (runparams.free_spacing ? " " : "\\hrulefill{}"); break; + case InsetSpaceParams::LEFTARROWFILL: + os << (runparams.free_spacing ? " " : "\\leftarrowfill{}"); + break; + case InsetSpaceParams::RIGHTARROWFILL: + os << (runparams.free_spacing ? " " : "\\rightarrowfill{}"); + break; + case InsetSpaceParams::UPBRACEFILL: + os << (runparams.free_spacing ? " " : "\\upbracefill{}"); + break; + case InsetSpaceParams::DOWNBRACEFILL: + os << (runparams.free_spacing ? " " : "\\downbracefill{}"); + break; case InsetSpaceParams::CUSTOM: if (runparams.free_spacing) os << " "; @@ -445,7 +618,6 @@ int InsetSpace::latex(odocstream & os, OutputParams const & runparams) const os << "\\hspace*{" << from_ascii(params_.length.asLatexString()) << "}"; break; } - return 0; } @@ -462,6 +634,53 @@ int InsetSpace::plaintext(odocstream & os, OutputParams const &) const case InsetSpaceParams::HRULEFILL: os << "_____"; return 5; + case InsetSpaceParams::LEFTARROWFILL: + os << "<----"; + return 5; + case InsetSpaceParams::RIGHTARROWFILL: + os << "---->"; + return 5; + case InsetSpaceParams::UPBRACEFILL: + os << "\\-v-/"; + return 5; + case InsetSpaceParams::DOWNBRACEFILL: + os << "/-^-\\"; + return 5; + case InsetSpaceParams::VISIBLE: + os.put(0x2423); + return 1; + case InsetSpaceParams::ENSKIP: + os.put(0x2002); + return 1; + case InsetSpaceParams::ENSPACE: + os.put(0x2060); // WORD JOINER, makes the breakable en space unbreakable + os.put(0x2002); + os.put(0x2060); // WORD JOINER, makes the breakable en space unbreakable + return 3; + case InsetSpaceParams::QUAD: + os.put(0x2003); + return 1; + case InsetSpaceParams::QQUAD: + os.put(0x2003); + os.put(0x2003); + return 2; + case InsetSpaceParams::THIN: + os.put(0x2009); + return 1; + case InsetSpaceParams::MEDIUM: + os.put(0x2005); + return 1; + case InsetSpaceParams::THICK: + os.put(0x2004); + return 1; + case InsetSpaceParams::PROTECTED: + case InsetSpaceParams::CUSTOM_PROTECTED: + os.put(0x00a0); + return 1; + case InsetSpaceParams::NEGTHIN: + case InsetSpaceParams::NEGMEDIUM: + case InsetSpaceParams::NEGTHICK: + return 0; default: os << ' '; return 1; @@ -478,48 +697,149 @@ int InsetSpace::docbook(odocstream & os, OutputParams const &) const case InsetSpaceParams::ENSKIP: os << " "; break; + // FIXME For spaces and dashes look here: + // http://oreilly.com/catalog/docbook/book2/iso-pub.html case InsetSpaceParams::PROTECTED: + // FIXME ␣ ? + case InsetSpaceParams::VISIBLE: case InsetSpaceParams::ENSPACE: + // FIXME   ? case InsetSpaceParams::THIN: + case InsetSpaceParams::MEDIUM: + case InsetSpaceParams::THICK: case InsetSpaceParams::NEGTHIN: + case InsetSpaceParams::NEGMEDIUM: + case InsetSpaceParams::NEGTHICK: os << " "; break; case InsetSpaceParams::HFILL: case InsetSpaceParams::HFILL_PROTECTED: os << '\n'; + break; case InsetSpaceParams::DOTFILL: // FIXME os << '\n'; + break; case InsetSpaceParams::HRULEFILL: // FIXME os << '\n'; + break; + case InsetSpaceParams::LEFTARROWFILL: + case InsetSpaceParams::RIGHTARROWFILL: + case InsetSpaceParams::UPBRACEFILL: + case InsetSpaceParams::DOWNBRACEFILL: case InsetSpaceParams::CUSTOM: case InsetSpaceParams::CUSTOM_PROTECTED: // FIXME os << '\n'; + break; } return 0; } -void InsetSpace::textString(odocstream & os) const +docstring InsetSpace::xhtml(XHTMLStream & xs, OutputParams const &) const +{ + string output; + switch (params_.kind) { + case InsetSpaceParams::NORMAL: + output = " "; + break; + case InsetSpaceParams::ENSKIP: + output =" "; + break; + case InsetSpaceParams::ENSPACE: + output ="⁠ ⁠"; + break; + case InsetSpaceParams::QQUAD: + output ="  "; + break; + case InsetSpaceParams::THICK: + output =" "; + break; + case InsetSpaceParams::QUAD: + output =" "; + break; + case InsetSpaceParams::MEDIUM: + output =" "; + break; + case InsetSpaceParams::THIN: + output =" "; + break; + case InsetSpaceParams::PROTECTED: + case InsetSpaceParams::NEGTHIN: + case InsetSpaceParams::NEGMEDIUM: + case InsetSpaceParams::NEGTHICK: + output =" "; + break; + // no XHTML entity, only unicode code for space character exists + case InsetSpaceParams::VISIBLE: + output ="␣"; + break; + case InsetSpaceParams::HFILL: + case InsetSpaceParams::HFILL_PROTECTED: + case InsetSpaceParams::DOTFILL: + case InsetSpaceParams::HRULEFILL: + case InsetSpaceParams::LEFTARROWFILL: + case InsetSpaceParams::RIGHTARROWFILL: + case InsetSpaceParams::UPBRACEFILL: + case InsetSpaceParams::DOWNBRACEFILL: + // FIXME XHTML + // Can we do anything with those in HTML? + break; + case InsetSpaceParams::CUSTOM: + // FIXME XHTML + // Probably we could do some sort of blank span? + break; + case InsetSpaceParams::CUSTOM_PROTECTED: + // FIXME XHTML + // Probably we could do some sort of blank span? + output =" "; + break; + } + // don't escape the entities! + xs << XHTMLStream::ESCAPE_NONE << from_ascii(output); + return docstring(); +} + + +void InsetSpace::validate(LaTeXFeatures & features) const +{ + if (params_.kind == InsetSpaceParams::NEGMEDIUM || + params_.kind == InsetSpaceParams::NEGTHICK) + features.require("amsmath"); +} + + +void InsetSpace::toString(odocstream & os) const { plaintext(os, OutputParams(0)); } +void InsetSpace::forToc(docstring & os, size_t) const +{ + // There's no need to be cute here. + os += " "; +} + + bool InsetSpace::isStretchableSpace() const { - return (params_.kind == InsetSpaceParams::HFILL || - params_.kind == InsetSpaceParams::HFILL_PROTECTED || - params_.kind == InsetSpaceParams::DOTFILL || - params_.kind == InsetSpaceParams::HRULEFILL); + return params_.kind == InsetSpaceParams::HFILL + || params_.kind == InsetSpaceParams::HFILL_PROTECTED + || params_.kind == InsetSpaceParams::DOTFILL + || params_.kind == InsetSpaceParams::HRULEFILL + || params_.kind == InsetSpaceParams::LEFTARROWFILL + || params_.kind == InsetSpaceParams::RIGHTARROWFILL + || params_.kind == InsetSpaceParams::UPBRACEFILL + || params_.kind == InsetSpaceParams::DOWNBRACEFILL; } -docstring InsetSpace::contextMenu(BufferView const &, int, int) const +string InsetSpace::contextMenuName() const { - return from_ascii("context-space"); + return "context-space"; } @@ -532,21 +852,29 @@ void InsetSpace::string2params(string const & in, InsetSpaceParams & params) istringstream data(in); Lexer lex; lex.setStream(data); - - string name; - lex >> name; - if (!lex || name != "space") { - LYXERR0("Expected arg 1 to be \"space\" in " << in); - return; + lex.setContext("InsetSpace::string2params"); + lex.next(); + string const name = lex.getString(); + if (name == "mathspace") + params.math = true; + else { + params.math = false; + LASSERT(name == "space", /**/); } - params.read(lex); + // There are cases, such as when we are called via getStatus() from + // Dialog::canApply(), where we are just called with "space" rather + // than a full "space \type{}\n\\end_inset". + if (lex.isOK()) + params.read(lex); } string InsetSpace::params2string(InsetSpaceParams const & params) { ostringstream data; + if (params.math) + data << "math"; data << "space" << ' '; params.write(data); return data.str();