3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Asger Alstrup Nielsen
7 * \author Jean-Marc Lasgouttes
8 * \author Lars Gullik Bjønnes
9 * \author Jürgen Spitzmüller
11 * Full author contact details are available in file CREDITS.
16 #include "InsetSpace.h"
18 #include "BufferView.h"
20 #include "Dimension.h"
21 #include "FuncRequest.h"
22 #include "FuncStatus.h"
24 #include "LaTeXFeatures.h"
27 #include "MetricsInfo.h"
28 #include "OutputParams.h"
29 #include "output_xhtml.h"
31 #include "support/debug.h"
32 #include "support/docstream.h"
33 #include "support/gettext.h"
34 #include "support/lassert.h"
35 #include "support/lstrings.h"
37 #include "frontends/Application.h"
38 #include "frontends/FontMetrics.h"
39 #include "frontends/Painter.h"
46 InsetSpace::InsetSpace(InsetSpaceParams const & params)
47 : Inset(0), params_(params)
51 InsetSpaceParams::Kind InsetSpace::kind() const
57 GlueLength InsetSpace::length() const
59 return params_.length;
63 docstring InsetSpace::toolTip(BufferView const &, int, int) const
66 switch (params_.kind) {
67 case InsetSpaceParams::NORMAL:
68 message = _("Interword Space");
70 case InsetSpaceParams::PROTECTED:
71 message = _("Protected Space");
73 case InsetSpaceParams::VISIBLE:
74 message = _("Visible Space");
76 case InsetSpaceParams::THIN:
77 message = _("Thin Space");
79 case InsetSpaceParams::MEDIUM:
80 message = _("Medium Space");
82 case InsetSpaceParams::THICK:
83 message = _("Thick Space");
85 case InsetSpaceParams::QUAD:
86 message = _("Quad Space");
88 case InsetSpaceParams::QQUAD:
89 message = _("Double Quad Space");
91 case InsetSpaceParams::ENSPACE:
92 message = _("Enspace");
94 case InsetSpaceParams::ENSKIP:
95 message = _("Enskip");
97 case InsetSpaceParams::NEGTHIN:
98 message = _("Negative Thin Space");
100 case InsetSpaceParams::NEGMEDIUM:
101 message = _("Negative Medium Space");
103 case InsetSpaceParams::NEGTHICK:
104 message = _("Negative Thick Space");
106 case InsetSpaceParams::HFILL:
107 message = _("Horizontal Fill");
109 case InsetSpaceParams::HFILL_PROTECTED:
110 message = _("Protected Horizontal Fill");
112 case InsetSpaceParams::DOTFILL:
113 message = _("Horizontal Fill (Dots)");
115 case InsetSpaceParams::HRULEFILL:
116 message = _("Horizontal Fill (Rule)");
118 case InsetSpaceParams::LEFTARROWFILL:
119 message = _("Horizontal Fill (Left Arrow)");
121 case InsetSpaceParams::RIGHTARROWFILL:
122 message = _("Horizontal Fill (Right Arrow)");
124 case InsetSpaceParams::UPBRACEFILL:
125 message = _("Horizontal Fill (Up Brace)");
127 case InsetSpaceParams::DOWNBRACEFILL:
128 message = _("Horizontal Fill (Down Brace)");
130 case InsetSpaceParams::CUSTOM:
132 message = support::bformat(_("Horizontal Space (%1$s)"),
133 from_ascii(params_.length.asString()));
135 case InsetSpaceParams::CUSTOM_PROTECTED:
137 message = support::bformat(_("Protected Horizontal Space (%1$s)"),
138 from_ascii(params_.length.asString()));
145 void InsetSpace::doDispatch(Cursor & cur, FuncRequest & cmd)
147 switch (cmd.action()) {
149 case LFUN_INSET_MODIFY:
151 string2params(to_utf8(cmd.argument()), params_);
154 case LFUN_INSET_DIALOG_UPDATE:
155 cur.bv().updateDialog("space", params2string(params()));
159 Inset::doDispatch(cur, cmd);
165 bool InsetSpace::getStatus(Cursor & cur, FuncRequest const & cmd,
166 FuncStatus & status) const
168 switch (cmd.action()) {
170 case LFUN_INSET_MODIFY:
171 if (cmd.getArg(0) == "space") {
172 InsetSpaceParams params;
173 string2params(to_utf8(cmd.argument()), params);
174 status.setOnOff(params_.kind == params.kind);
175 status.setEnabled(true);
177 status.setEnabled(false);
180 case LFUN_INSET_DIALOG_UPDATE:
181 status.setEnabled(true);
184 return Inset::getStatus(cur, cmd, status);
190 int const arrow_size = 8;
194 void InsetSpace::metrics(MetricsInfo & mi, Dimension & dim) const
196 if (isStretchableSpace()) {
197 // The metrics for this kinds are calculated externally in
198 // \c TextMetrics::computeRowMetrics. Those are dummy value:
199 dim = Dimension(10, 10, 10);
203 frontend::FontMetrics const & fm = theFontMetrics(mi.base.font);
204 dim.asc = fm.maxAscent();
205 dim.des = fm.maxDescent();
207 switch (params_.kind) {
208 case InsetSpaceParams::THIN:
209 case InsetSpaceParams::NEGTHIN:
210 dim.wid = fm.width(char_type('M')) / 6;
212 case InsetSpaceParams::MEDIUM:
213 case InsetSpaceParams::NEGMEDIUM:
214 dim.wid = fm.width(char_type('M')) / 4;
216 case InsetSpaceParams::THICK:
217 case InsetSpaceParams::NEGTHICK:
218 dim.wid = fm.width(char_type('M')) / 2;
220 case InsetSpaceParams::PROTECTED:
221 case InsetSpaceParams::VISIBLE:
222 case InsetSpaceParams::NORMAL:
223 dim.wid = fm.width(char_type(' '));
225 case InsetSpaceParams::QUAD:
226 dim.wid = fm.width(char_type('M'));
228 case InsetSpaceParams::QQUAD:
229 dim.wid = 2 * fm.width(char_type('M'));
231 case InsetSpaceParams::ENSPACE:
232 case InsetSpaceParams::ENSKIP:
233 dim.wid = int(0.5 * fm.width(char_type('M')));
235 case InsetSpaceParams::CUSTOM:
236 case InsetSpaceParams::CUSTOM_PROTECTED: {
238 params_.length.len().inPixels(mi.base.textwidth,
239 fm.width(char_type('M')));
240 int const minw = (w < 0) ? 3 * arrow_size : 4;
241 dim.wid = max(minw, abs(w));
244 case InsetSpaceParams::HFILL:
245 case InsetSpaceParams::HFILL_PROTECTED:
246 case InsetSpaceParams::DOTFILL:
247 case InsetSpaceParams::HRULEFILL:
248 case InsetSpaceParams::LEFTARROWFILL:
249 case InsetSpaceParams::RIGHTARROWFILL:
250 case InsetSpaceParams::UPBRACEFILL:
251 case InsetSpaceParams::DOWNBRACEFILL:
255 // Cache the inset dimension.
256 setDimCache(mi, dim);
260 void InsetSpace::draw(PainterInfo & pi, int x, int y) const
262 Dimension const dim = dimension(*pi.base.bv);
264 if (isStretchableSpace() || params_.length.len().value() < 0) {
265 int const asc = theFontMetrics(pi.base.font).ascent('M');
266 int const desc = theFontMetrics(pi.base.font).descent('M');
267 // Pixel height divisible by 2 for prettier fill graphics:
268 int const oddheight = (asc ^ desc) & 1;
269 int const x0 = x + 1;
270 int const x1 = x + dim.wid - 2;
271 int const y0 = y + desc - 1;
272 int const y1 = y - asc + oddheight - 1;
273 int const y2 = (y0 + y1) / 2;
274 int xoffset = (y0 - y1) / 2;
276 // Two tests for very narrow insets
277 if (xoffset > x1 - x0
278 && (params_.kind == InsetSpaceParams::LEFTARROWFILL
279 || params_.kind == InsetSpaceParams::RIGHTARROWFILL))
281 if (xoffset * 6 > (x1 - x0)
282 && (params_.kind == InsetSpaceParams::UPBRACEFILL
283 || params_.kind == InsetSpaceParams::DOWNBRACEFILL))
284 xoffset = (x1 - x0) / 6;
286 int const x2 = x0 + xoffset;
287 int const x3 = x1 - xoffset;
288 int const xm = (x0 + x1) / 2;
289 int const xml = xm - xoffset;
290 int const xmr = xm + xoffset;
292 if (params_.kind == InsetSpaceParams::HFILL) {
293 pi.pain.line(x0, y1, x0, y0, Color_added_space);
294 pi.pain.line(x0, y2, x1, y2, Color_added_space,
295 frontend::Painter::line_onoffdash);
296 pi.pain.line(x1, y1, x1, y0, Color_added_space);
297 } else if (params_.kind == InsetSpaceParams::HFILL_PROTECTED) {
298 pi.pain.line(x0, y1, x0, y0, Color_latex);
299 pi.pain.line(x0, y2, x1, y2, Color_latex,
300 frontend::Painter::line_onoffdash);
301 pi.pain.line(x1, y1, x1, y0, Color_latex);
302 } else if (params_.kind == InsetSpaceParams::DOTFILL) {
303 pi.pain.line(x0, y1, x0, y0, Color_special);
304 pi.pain.line(x0, y0, x1, y0, Color_special,
305 frontend::Painter::line_onoffdash);
306 pi.pain.line(x1, y1, x1, y0, Color_special);
307 } else if (params_.kind == InsetSpaceParams::HRULEFILL) {
308 pi.pain.line(x0, y1, x0, y0, Color_special);
309 pi.pain.line(x0, y0, x1, y0, Color_special);
310 pi.pain.line(x1, y1, x1, y0, Color_special);
311 } else if (params_.kind == InsetSpaceParams::LEFTARROWFILL) {
312 pi.pain.line(x2, y1 + 1 , x0 + 1, y2, Color_special);
313 pi.pain.line(x0 + 1, y2 + 1 , x2, y0, Color_special);
314 pi.pain.line(x0, y2 , x1, y2, Color_special);
315 } else if (params_.kind == InsetSpaceParams::RIGHTARROWFILL) {
316 pi.pain.line(x3 + 1, y1 + 1 , x1, y2, Color_special);
317 pi.pain.line(x1, y2 + 1 , x3 + 1, y0, Color_special);
318 pi.pain.line(x0, y2 , x1, y2, Color_special);
319 } else if (params_.kind == InsetSpaceParams::UPBRACEFILL) {
320 pi.pain.line(x0 + 1, y1 + 1 , x2, y2, Color_special);
321 pi.pain.line(x2, y2 , xml, y2, Color_special);
322 pi.pain.line(xml + 1, y2 + 1 , xm, y0, Color_special);
323 pi.pain.line(xm + 1, y0 , xmr, y2 + 1, Color_special);
324 pi.pain.line(xmr, y2 , x3, y2, Color_special);
325 pi.pain.line(x3 + 1, y2 , x1, y1 + 1, Color_special);
326 } else if (params_.kind == InsetSpaceParams::DOWNBRACEFILL) {
327 pi.pain.line(x0 + 1, y0 , x2, y2 + 1, Color_special);
328 pi.pain.line(x2, y2 , xml, y2, Color_special);
329 pi.pain.line(xml + 1, y2 , xm, y1 + 1, Color_special);
330 pi.pain.line(xm + 1, y1 + 1 , xmr, y2, Color_special);
331 pi.pain.line(xmr, y2 , x3, y2, Color_special);
332 pi.pain.line(x3 + 1, y2 + 1 , x1, y0, Color_special);
333 } else if (params_.kind == InsetSpaceParams::CUSTOM) {
334 pi.pain.line(x0, y1 + 1 , x2 + 1, y2, Color_special);
335 pi.pain.line(x2 + 1, y2 + 1 , x0, y0, Color_special);
336 pi.pain.line(x1 + 1, y1 + 1 , x3, y2, Color_special);
337 pi.pain.line(x3, y2 + 1 , x1 + 1, y0, Color_special);
338 pi.pain.line(x2, y2 , x3, y2, Color_special);
339 } else if (params_.kind == InsetSpaceParams::CUSTOM_PROTECTED) {
340 pi.pain.line(x0, y1 + 1 , x2 + 1, y2, Color_latex);
341 pi.pain.line(x2 + 1, y2 + 1 , x0, y0, Color_latex);
342 pi.pain.line(x1 + 1, y1 + 1 , x3, y2, Color_latex);
343 pi.pain.line(x3, y2 + 1 , x1 + 1, y0, Color_latex);
344 pi.pain.line(x2, y2 , x3, y2, Color_latex);
349 int const w = dim.wid;
350 int const h = theFontMetrics(pi.base.font).ascent('x');
354 yp[0] = y - max(h / 4, 1);
355 if (params_.kind == InsetSpaceParams::NORMAL ||
356 params_.kind == InsetSpaceParams::PROTECTED ||
357 params_.kind == InsetSpaceParams::VISIBLE) {
358 xp[1] = x; yp[1] = y;
359 xp[2] = x + w; yp[2] = y;
361 xp[1] = x; yp[1] = y + max(h / 4, 1);
362 xp[2] = x + w; yp[2] = y + max(h / 4, 1);
365 yp[3] = y - max(h / 4, 1);
367 Color col = Color_special;
368 if (params_.kind == InsetSpaceParams::PROTECTED ||
369 params_.kind == InsetSpaceParams::ENSPACE ||
370 params_.kind == InsetSpaceParams::NEGTHIN ||
371 params_.kind == InsetSpaceParams::NEGMEDIUM ||
372 params_.kind == InsetSpaceParams::NEGTHICK ||
373 params_.kind == InsetSpaceParams::CUSTOM_PROTECTED)
375 else if (params_.kind == InsetSpaceParams::VISIBLE)
376 col = Color_foreground;
378 pi.pain.lines(xp, yp, 4, col);
382 void InsetSpaceParams::write(ostream & os) const
386 case InsetSpaceParams::NORMAL:
389 case InsetSpaceParams::PROTECTED:
392 case InsetSpaceParams::VISIBLE:
393 os << "\\textvisiblespace{}";
395 case InsetSpaceParams::THIN:
396 os << "\\thinspace{}";
398 case InsetSpaceParams::MEDIUM:
399 os << "\\medspace{}";
401 case InsetSpaceParams::THICK:
402 os << "\\thickspace{}";
404 case InsetSpaceParams::QUAD:
407 case InsetSpaceParams::QQUAD:
410 case InsetSpaceParams::ENSPACE:
413 case InsetSpaceParams::ENSKIP:
416 case InsetSpaceParams::NEGTHIN:
417 os << "\\negthinspace{}";
419 case InsetSpaceParams::NEGMEDIUM:
420 os << "\\negmedspace{}";
422 case InsetSpaceParams::NEGTHICK:
423 os << "\\negthickspace{}";
425 case InsetSpaceParams::HFILL:
428 case InsetSpaceParams::HFILL_PROTECTED:
429 os << "\\hspace*{\\fill}";
431 case InsetSpaceParams::DOTFILL:
434 case InsetSpaceParams::HRULEFILL:
435 os << "\\hrulefill{}";
437 case InsetSpaceParams::LEFTARROWFILL:
438 os << "\\leftarrowfill{}";
440 case InsetSpaceParams::RIGHTARROWFILL:
441 os << "\\rightarrowfill{}";
443 case InsetSpaceParams::UPBRACEFILL:
444 os << "\\upbracefill{}";
446 case InsetSpaceParams::DOWNBRACEFILL:
447 os << "\\downbracefill{}";
449 case InsetSpaceParams::CUSTOM:
452 case InsetSpaceParams::CUSTOM_PROTECTED:
457 if (!length.len().empty())
458 os << "\n\\length " << length.asString();
462 void InsetSpaceParams::read(Lexer & lex)
464 lex.setContext("InsetSpaceParams::read");
468 // The tests for math might be disabled after a file format change
469 if (command == "\\space{}")
470 kind = InsetSpaceParams::NORMAL;
471 else if (command == "~")
472 kind = InsetSpaceParams::PROTECTED;
473 else if (command == "\\textvisiblespace{}")
474 kind = InsetSpaceParams::VISIBLE;
475 else if (command == "\\thinspace{}")
476 kind = InsetSpaceParams::THIN;
477 else if (math && command == "\\medspace{}")
478 kind = InsetSpaceParams::MEDIUM;
479 else if (math && command == "\\thickspace{}")
480 kind = InsetSpaceParams::THICK;
481 else if (command == "\\quad{}")
482 kind = InsetSpaceParams::QUAD;
483 else if (command == "\\qquad{}")
484 kind = InsetSpaceParams::QQUAD;
485 else if (command == "\\enspace{}")
486 kind = InsetSpaceParams::ENSPACE;
487 else if (command == "\\enskip{}")
488 kind = InsetSpaceParams::ENSKIP;
489 else if (command == "\\negthinspace{}")
490 kind = InsetSpaceParams::NEGTHIN;
491 else if (command == "\\negmedspace{}")
492 kind = InsetSpaceParams::NEGMEDIUM;
493 else if (command == "\\negthickspace{}")
494 kind = InsetSpaceParams::NEGTHICK;
495 else if (command == "\\hfill{}")
496 kind = InsetSpaceParams::HFILL;
497 else if (command == "\\hspace*{\\fill}")
498 kind = InsetSpaceParams::HFILL_PROTECTED;
499 else if (command == "\\dotfill{}")
500 kind = InsetSpaceParams::DOTFILL;
501 else if (command == "\\hrulefill{}")
502 kind = InsetSpaceParams::HRULEFILL;
503 else if (command == "\\hspace{}")
504 kind = InsetSpaceParams::CUSTOM;
505 else if (command == "\\leftarrowfill{}")
506 kind = InsetSpaceParams::LEFTARROWFILL;
507 else if (command == "\\rightarrowfill{}")
508 kind = InsetSpaceParams::RIGHTARROWFILL;
509 else if (command == "\\upbracefill{}")
510 kind = InsetSpaceParams::UPBRACEFILL;
511 else if (command == "\\downbracefill{}")
512 kind = InsetSpaceParams::DOWNBRACEFILL;
513 else if (command == "\\hspace*{}")
514 kind = InsetSpaceParams::CUSTOM_PROTECTED;
516 lex.printError("InsetSpace: Unknown kind: `$$Token'");
518 if (lex.checkFor("\\length"))
523 void InsetSpace::write(ostream & os) const
530 void InsetSpace::read(Lexer & lex)
533 lex >> "\\end_inset";
537 void InsetSpace::latex(otexstream & os, OutputParams const & runparams) const
539 switch (params_.kind) {
540 case InsetSpaceParams::NORMAL:
541 os << (runparams.free_spacing ? " " : "\\ ");
543 case InsetSpaceParams::PROTECTED:
544 if (runparams.local_font &&
545 runparams.local_font->language()->lang() == "polutonikogreek")
546 // in babel's polutonikogreek, ~ is active
547 os << (runparams.free_spacing ? " " : "\\nobreakspace{}");
549 os << (runparams.free_spacing ? ' ' : '~');
551 case InsetSpaceParams::VISIBLE:
552 os << (runparams.free_spacing ? " " : "\\textvisiblespace{}");
554 case InsetSpaceParams::THIN:
555 os << (runparams.free_spacing ? " " : "\\,");
557 case InsetSpaceParams::MEDIUM:
558 os << (runparams.free_spacing ? " " : "\\:");
560 case InsetSpaceParams::THICK:
561 os << (runparams.free_spacing ? " " : "\\;");
563 case InsetSpaceParams::QUAD:
564 os << (runparams.free_spacing ? " " : "\\quad{}");
566 case InsetSpaceParams::QQUAD:
567 os << (runparams.free_spacing ? " " : "\\qquad{}");
569 case InsetSpaceParams::ENSPACE:
570 os << (runparams.free_spacing ? " " : "\\enspace{}");
572 case InsetSpaceParams::ENSKIP:
573 os << (runparams.free_spacing ? " " : "\\enskip{}");
575 case InsetSpaceParams::NEGTHIN:
576 os << (runparams.free_spacing ? " " : "\\negthinspace{}");
578 case InsetSpaceParams::NEGMEDIUM:
579 os << (runparams.free_spacing ? " " : "\\negmedspace{}");
581 case InsetSpaceParams::NEGTHICK:
582 os << (runparams.free_spacing ? " " : "\\negthickspace{}");
584 case InsetSpaceParams::HFILL:
585 os << (runparams.free_spacing ? " " : "\\hfill{}");
587 case InsetSpaceParams::HFILL_PROTECTED:
588 os << (runparams.free_spacing ? " " : "\\hspace*{\\fill}");
590 case InsetSpaceParams::DOTFILL:
591 os << (runparams.free_spacing ? " " : "\\dotfill{}");
593 case InsetSpaceParams::HRULEFILL:
594 os << (runparams.free_spacing ? " " : "\\hrulefill{}");
596 case InsetSpaceParams::LEFTARROWFILL:
597 os << (runparams.free_spacing ? " " : "\\leftarrowfill{}");
599 case InsetSpaceParams::RIGHTARROWFILL:
600 os << (runparams.free_spacing ? " " : "\\rightarrowfill{}");
602 case InsetSpaceParams::UPBRACEFILL:
603 os << (runparams.free_spacing ? " " : "\\upbracefill{}");
605 case InsetSpaceParams::DOWNBRACEFILL:
606 os << (runparams.free_spacing ? " " : "\\downbracefill{}");
608 case InsetSpaceParams::CUSTOM:
609 if (runparams.free_spacing)
612 os << "\\hspace{" << from_ascii(params_.length.asLatexString()) << "}";
614 case InsetSpaceParams::CUSTOM_PROTECTED:
615 if (runparams.free_spacing)
618 os << "\\hspace*{" << from_ascii(params_.length.asLatexString()) << "}";
624 int InsetSpace::plaintext(odocstringstream & os,
625 OutputParams const &, size_t) const
627 switch (params_.kind) {
628 case InsetSpaceParams::HFILL:
629 case InsetSpaceParams::HFILL_PROTECTED:
632 case InsetSpaceParams::DOTFILL:
635 case InsetSpaceParams::HRULEFILL:
638 case InsetSpaceParams::LEFTARROWFILL:
641 case InsetSpaceParams::RIGHTARROWFILL:
644 case InsetSpaceParams::UPBRACEFILL:
647 case InsetSpaceParams::DOWNBRACEFILL:
650 case InsetSpaceParams::VISIBLE:
653 case InsetSpaceParams::ENSKIP:
656 case InsetSpaceParams::ENSPACE:
657 os.put(0x2060); // WORD JOINER, makes the breakable en space unbreakable
659 os.put(0x2060); // WORD JOINER, makes the breakable en space unbreakable
661 case InsetSpaceParams::QUAD:
664 case InsetSpaceParams::QQUAD:
668 case InsetSpaceParams::THIN:
671 case InsetSpaceParams::MEDIUM:
672 os.put(0x200b); // ZERO WIDTH SPACE, makes the unbreakable medium space breakable
674 os.put(0x200b); // ZERO WIDTH SPACE, makes the unbreakable medium space breakable
676 case InsetSpaceParams::THICK:
677 os.put(0x200b); // ZERO WIDTH SPACE, makes the unbreakable thick space breakable
679 os.put(0x200b); // ZERO WIDTH SPACE, makes the unbreakable thick space breakable
681 case InsetSpaceParams::PROTECTED:
682 case InsetSpaceParams::CUSTOM_PROTECTED:
685 case InsetSpaceParams::NEGTHIN:
686 case InsetSpaceParams::NEGMEDIUM:
687 case InsetSpaceParams::NEGTHICK:
696 int InsetSpace::docbook(odocstream & os, OutputParams const &) const
698 switch (params_.kind) {
699 case InsetSpaceParams::NORMAL:
700 case InsetSpaceParams::QUAD:
701 case InsetSpaceParams::QQUAD:
702 case InsetSpaceParams::ENSKIP:
705 // FIXME For spaces and dashes look here:
706 // http://oreilly.com/catalog/docbook/book2/iso-pub.html
707 case InsetSpaceParams::PROTECTED:
709 case InsetSpaceParams::VISIBLE:
710 case InsetSpaceParams::ENSPACE:
712 case InsetSpaceParams::THIN:
713 case InsetSpaceParams::MEDIUM:
714 case InsetSpaceParams::THICK:
715 case InsetSpaceParams::NEGTHIN:
716 case InsetSpaceParams::NEGMEDIUM:
717 case InsetSpaceParams::NEGTHICK:
720 case InsetSpaceParams::HFILL:
721 case InsetSpaceParams::HFILL_PROTECTED:
724 case InsetSpaceParams::DOTFILL:
728 case InsetSpaceParams::HRULEFILL:
732 case InsetSpaceParams::LEFTARROWFILL:
733 case InsetSpaceParams::RIGHTARROWFILL:
734 case InsetSpaceParams::UPBRACEFILL:
735 case InsetSpaceParams::DOWNBRACEFILL:
736 case InsetSpaceParams::CUSTOM:
737 case InsetSpaceParams::CUSTOM_PROTECTED:
746 docstring InsetSpace::xhtml(XHTMLStream & xs, OutputParams const &) const
749 switch (params_.kind) {
750 case InsetSpaceParams::NORMAL:
753 case InsetSpaceParams::ENSKIP:
756 case InsetSpaceParams::ENSPACE:
757 output ="⁠ ⁠";
759 case InsetSpaceParams::QQUAD:
760 output ="  ";
762 case InsetSpaceParams::THICK:
765 case InsetSpaceParams::QUAD:
768 case InsetSpaceParams::MEDIUM:
771 case InsetSpaceParams::THIN:
774 case InsetSpaceParams::PROTECTED:
775 case InsetSpaceParams::NEGTHIN:
776 case InsetSpaceParams::NEGMEDIUM:
777 case InsetSpaceParams::NEGTHICK:
780 // no XHTML entity, only unicode code for space character exists
781 case InsetSpaceParams::VISIBLE:
784 case InsetSpaceParams::HFILL:
785 case InsetSpaceParams::HFILL_PROTECTED:
786 case InsetSpaceParams::DOTFILL:
787 case InsetSpaceParams::HRULEFILL:
788 case InsetSpaceParams::LEFTARROWFILL:
789 case InsetSpaceParams::RIGHTARROWFILL:
790 case InsetSpaceParams::UPBRACEFILL:
791 case InsetSpaceParams::DOWNBRACEFILL:
793 // Can we do anything with those in HTML?
795 case InsetSpaceParams::CUSTOM:
797 // Probably we could do some sort of blank span?
799 case InsetSpaceParams::CUSTOM_PROTECTED:
801 // Probably we could do some sort of blank span?
805 // don't escape the entities!
806 xs << XHTMLStream::ESCAPE_NONE << from_ascii(output);
811 void InsetSpace::validate(LaTeXFeatures & features) const
813 if (params_.kind == InsetSpaceParams::NEGMEDIUM ||
814 params_.kind == InsetSpaceParams::NEGTHICK)
815 features.require("amsmath");
819 void InsetSpace::toString(odocstream & os) const
821 odocstringstream ods;
822 plaintext(ods, OutputParams(0));
827 void InsetSpace::forToc(docstring & os, size_t) const
829 // There's no need to be cute here.
834 bool InsetSpace::isStretchableSpace() const
836 return params_.kind == InsetSpaceParams::HFILL
837 || params_.kind == InsetSpaceParams::HFILL_PROTECTED
838 || params_.kind == InsetSpaceParams::DOTFILL
839 || params_.kind == InsetSpaceParams::HRULEFILL
840 || params_.kind == InsetSpaceParams::LEFTARROWFILL
841 || params_.kind == InsetSpaceParams::RIGHTARROWFILL
842 || params_.kind == InsetSpaceParams::UPBRACEFILL
843 || params_.kind == InsetSpaceParams::DOWNBRACEFILL;
847 string InsetSpace::contextMenuName() const
849 return "context-space";
853 void InsetSpace::string2params(string const & in, InsetSpaceParams & params)
855 params = InsetSpaceParams();
859 istringstream data(in);
862 lex.setContext("InsetSpace::string2params");
864 string const name = lex.getString();
865 if (name == "mathspace")
869 // we can try to read this even if the name is wrong
870 LATTEST(name == "space");
873 // There are cases, such as when we are called via getStatus() from
874 // Dialog::canApply(), where we are just called with "space" rather
875 // than a full "space \type{}\n\\end_inset".
881 string InsetSpace::params2string(InsetSpaceParams const & params)
886 data << "space" << ' ';