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"
30 #include "texstream.h"
32 #include "support/debug.h"
33 #include "support/docstream.h"
34 #include "support/gettext.h"
35 #include "support/lassert.h"
36 #include "support/lstrings.h"
38 #include "frontends/Application.h"
39 #include "frontends/FontMetrics.h"
40 #include "frontends/Painter.h"
47 InsetSpace::InsetSpace(InsetSpaceParams const & params)
48 : Inset(0), params_(params)
52 InsetSpaceParams::Kind InsetSpace::kind() const
58 GlueLength InsetSpace::length() const
60 return params_.length;
64 docstring InsetSpace::toolTip(BufferView const &, int, int) const
67 switch (params_.kind) {
68 case InsetSpaceParams::NORMAL:
69 message = _("Interword Space");
71 case InsetSpaceParams::PROTECTED:
72 message = _("Protected Space");
74 case InsetSpaceParams::VISIBLE:
75 message = _("Visible Space");
77 case InsetSpaceParams::THIN:
78 message = _("Thin Space");
80 case InsetSpaceParams::MEDIUM:
81 message = _("Medium Space");
83 case InsetSpaceParams::THICK:
84 message = _("Thick Space");
86 case InsetSpaceParams::QUAD:
87 message = _("Quad Space");
89 case InsetSpaceParams::QQUAD:
90 message = _("Double Quad Space");
92 case InsetSpaceParams::ENSPACE:
93 message = _("Enspace");
95 case InsetSpaceParams::ENSKIP:
96 message = _("Enskip");
98 case InsetSpaceParams::NEGTHIN:
99 message = _("Negative Thin Space");
101 case InsetSpaceParams::NEGMEDIUM:
102 message = _("Negative Medium Space");
104 case InsetSpaceParams::NEGTHICK:
105 message = _("Negative Thick Space");
107 case InsetSpaceParams::HFILL:
108 message = _("Horizontal Fill");
110 case InsetSpaceParams::HFILL_PROTECTED:
111 message = _("Protected Horizontal Fill");
113 case InsetSpaceParams::DOTFILL:
114 message = _("Horizontal Fill (Dots)");
116 case InsetSpaceParams::HRULEFILL:
117 message = _("Horizontal Fill (Rule)");
119 case InsetSpaceParams::LEFTARROWFILL:
120 message = _("Horizontal Fill (Left Arrow)");
122 case InsetSpaceParams::RIGHTARROWFILL:
123 message = _("Horizontal Fill (Right Arrow)");
125 case InsetSpaceParams::UPBRACEFILL:
126 message = _("Horizontal Fill (Up Brace)");
128 case InsetSpaceParams::DOWNBRACEFILL:
129 message = _("Horizontal Fill (Down Brace)");
131 case InsetSpaceParams::CUSTOM:
133 message = support::bformat(_("Horizontal Space (%1$s)"),
134 from_ascii(params_.length.asString()));
136 case InsetSpaceParams::CUSTOM_PROTECTED:
138 message = support::bformat(_("Protected Horizontal Space (%1$s)"),
139 from_ascii(params_.length.asString()));
146 void InsetSpace::doDispatch(Cursor & cur, FuncRequest & cmd)
148 switch (cmd.action()) {
150 case LFUN_INSET_MODIFY: {
152 string arg = to_utf8(cmd.argument());
153 if (arg == "space \\hspace{}")
154 arg += params_.length.len().empty()
155 ? " \\length 1" + string(stringFromUnit(Length::defaultUnit()))
156 : " \\length " + params_.length.asString();
157 string2params(arg, params_);
161 case LFUN_INSET_DIALOG_UPDATE:
162 cur.bv().updateDialog("space", params2string(params()));
166 Inset::doDispatch(cur, cmd);
172 bool InsetSpace::getStatus(Cursor & cur, FuncRequest const & cmd,
173 FuncStatus & status) const
175 switch (cmd.action()) {
177 case LFUN_INSET_MODIFY:
178 if (cmd.getArg(0) == "space") {
179 InsetSpaceParams params;
180 string2params(to_utf8(cmd.argument()), params);
181 status.setOnOff(params_.kind == params.kind);
182 status.setEnabled(true);
184 status.setEnabled(false);
187 case LFUN_INSET_DIALOG_UPDATE:
188 status.setEnabled(true);
191 return Inset::getStatus(cur, cmd, status);
197 int const arrow_size = 8;
201 void InsetSpace::metrics(MetricsInfo & mi, Dimension & dim) const
204 // The width for hfills is calculated externally in
205 // TextMetrics::computeRowMetrics. The value of 5 is the
206 // minimal value when the hfill is not active.
207 dim = Dimension(5, 10, 10);
211 frontend::FontMetrics const & fm = theFontMetrics(mi.base.font);
212 dim.asc = fm.maxAscent();
213 dim.des = fm.maxDescent();
214 int const em = fm.em();
216 switch (params_.kind) {
217 case InsetSpaceParams::THIN:
218 case InsetSpaceParams::NEGTHIN:
221 case InsetSpaceParams::MEDIUM:
222 case InsetSpaceParams::NEGMEDIUM:
225 case InsetSpaceParams::THICK:
226 case InsetSpaceParams::NEGTHICK:
229 case InsetSpaceParams::PROTECTED:
230 case InsetSpaceParams::VISIBLE:
231 case InsetSpaceParams::NORMAL:
232 dim.wid = fm.width(char_type(' '));
234 case InsetSpaceParams::QUAD:
237 case InsetSpaceParams::QQUAD:
240 case InsetSpaceParams::ENSPACE:
241 case InsetSpaceParams::ENSKIP:
242 dim.wid = int(0.5 * em);
244 case InsetSpaceParams::CUSTOM:
245 case InsetSpaceParams::CUSTOM_PROTECTED: {
247 params_.length.len().inPixels(mi.base);
248 int const minw = (w < 0) ? 3 * arrow_size : 4;
249 dim.wid = max(minw, abs(w));
252 case InsetSpaceParams::HFILL:
253 case InsetSpaceParams::HFILL_PROTECTED:
254 case InsetSpaceParams::DOTFILL:
255 case InsetSpaceParams::HRULEFILL:
256 case InsetSpaceParams::LEFTARROWFILL:
257 case InsetSpaceParams::RIGHTARROWFILL:
258 case InsetSpaceParams::UPBRACEFILL:
259 case InsetSpaceParams::DOWNBRACEFILL:
263 // Cache the inset dimension.
264 setDimCache(mi, dim);
268 void InsetSpace::draw(PainterInfo & pi, int x, int y) const
270 Dimension const dim = dimension(*pi.base.bv);
272 if (isHfill() || params_.length.len().value() < 0) {
273 int const asc = theFontMetrics(pi.base.font).ascent('M');
274 int const desc = theFontMetrics(pi.base.font).descent('M');
275 // Pixel height divisible by 2 for prettier fill graphics:
276 int const oddheight = (asc ^ desc) & 1;
277 int const x0 = x + 1;
278 int const x1 = x + dim.wid - 2;
279 int const y0 = y + desc - 1;
280 int const y1 = y - asc + oddheight - 1;
281 int const y2 = (y0 + y1) / 2;
282 int xoffset = (y0 - y1) / 2;
284 // Two tests for very narrow insets
285 if (xoffset > x1 - x0
286 && (params_.kind == InsetSpaceParams::LEFTARROWFILL
287 || params_.kind == InsetSpaceParams::RIGHTARROWFILL))
289 if (xoffset * 6 > (x1 - x0)
290 && (params_.kind == InsetSpaceParams::UPBRACEFILL
291 || params_.kind == InsetSpaceParams::DOWNBRACEFILL))
292 xoffset = (x1 - x0) / 6;
294 int const x2 = x0 + xoffset;
295 int const x3 = x1 - xoffset;
296 int const xm = (x0 + x1) / 2;
297 int const xml = xm - xoffset;
298 int const xmr = xm + xoffset;
300 if (params_.kind == InsetSpaceParams::HFILL) {
301 pi.pain.line(x0, y1, x0, y0, Color_added_space);
302 pi.pain.line(x0, y2, x1, y2, Color_added_space,
303 frontend::Painter::line_onoffdash);
304 pi.pain.line(x1, y1, x1, y0, Color_added_space);
305 } else if (params_.kind == InsetSpaceParams::HFILL_PROTECTED) {
306 pi.pain.line(x0, y1, x0, y0, Color_latex);
307 pi.pain.line(x0, y2, x1, y2, Color_latex,
308 frontend::Painter::line_onoffdash);
309 pi.pain.line(x1, y1, x1, y0, Color_latex);
310 } else if (params_.kind == InsetSpaceParams::DOTFILL) {
311 pi.pain.line(x0, y1, x0, y0, Color_special);
312 pi.pain.line(x0, y0, x1, y0, Color_special,
313 frontend::Painter::line_onoffdash);
314 pi.pain.line(x1, y1, x1, y0, Color_special);
315 } else if (params_.kind == InsetSpaceParams::HRULEFILL) {
316 pi.pain.line(x0, y1, x0, y0, Color_special);
317 pi.pain.line(x0, y0, x1, y0, Color_special);
318 pi.pain.line(x1, y1, x1, y0, Color_special);
319 } else if (params_.kind == InsetSpaceParams::LEFTARROWFILL) {
320 pi.pain.line(x2, y1 + 1 , x0 + 1, y2, Color_special);
321 pi.pain.line(x0 + 1, y2 + 1 , x2, y0, Color_special);
322 pi.pain.line(x0, y2 , x1, y2, Color_special);
323 } else if (params_.kind == InsetSpaceParams::RIGHTARROWFILL) {
324 pi.pain.line(x3 + 1, y1 + 1 , x1, y2, Color_special);
325 pi.pain.line(x1, y2 + 1 , x3 + 1, y0, Color_special);
326 pi.pain.line(x0, y2 , x1, y2, Color_special);
327 } else if (params_.kind == InsetSpaceParams::UPBRACEFILL) {
328 pi.pain.line(x0 + 1, y1 + 1 , x2, y2, Color_special);
329 pi.pain.line(x2, y2 , xml, y2, Color_special);
330 pi.pain.line(xml + 1, y2 + 1 , xm, y0, Color_special);
331 pi.pain.line(xm + 1, y0 , xmr, y2 + 1, Color_special);
332 pi.pain.line(xmr, y2 , x3, y2, Color_special);
333 pi.pain.line(x3 + 1, y2 , x1, y1 + 1, Color_special);
334 } else if (params_.kind == InsetSpaceParams::DOWNBRACEFILL) {
335 pi.pain.line(x0 + 1, y0 , x2, y2 + 1, Color_special);
336 pi.pain.line(x2, y2 , xml, y2, Color_special);
337 pi.pain.line(xml + 1, y2 , xm, y1 + 1, Color_special);
338 pi.pain.line(xm + 1, y1 + 1 , xmr, y2, Color_special);
339 pi.pain.line(xmr, y2 , x3, y2, Color_special);
340 pi.pain.line(x3 + 1, y2 + 1 , x1, y0, Color_special);
341 } else if (params_.kind == InsetSpaceParams::CUSTOM) {
342 pi.pain.line(x0, y1 + 1 , x2 + 1, y2, Color_special);
343 pi.pain.line(x2 + 1, y2 + 1 , x0, y0, Color_special);
344 pi.pain.line(x1 + 1, y1 + 1 , x3, y2, Color_special);
345 pi.pain.line(x3, y2 + 1 , x1 + 1, y0, Color_special);
346 pi.pain.line(x2, y2 , x3, y2, Color_special);
347 } else if (params_.kind == InsetSpaceParams::CUSTOM_PROTECTED) {
348 pi.pain.line(x0, y1 + 1 , x2 + 1, y2, Color_latex);
349 pi.pain.line(x2 + 1, y2 + 1 , x0, y0, Color_latex);
350 pi.pain.line(x1 + 1, y1 + 1 , x3, y2, Color_latex);
351 pi.pain.line(x3, y2 + 1 , x1 + 1, y0, Color_latex);
352 pi.pain.line(x2, y2 , x3, y2, Color_latex);
357 int const w = dim.wid;
358 int const h = theFontMetrics(pi.base.font).ascent('x');
362 yp[0] = y - max(h / 4, 1);
363 if (params_.kind == InsetSpaceParams::NORMAL ||
364 params_.kind == InsetSpaceParams::PROTECTED ||
365 params_.kind == InsetSpaceParams::VISIBLE) {
366 xp[1] = x; yp[1] = y;
367 xp[2] = x + w; yp[2] = y;
369 xp[1] = x; yp[1] = y + max(h / 4, 1);
370 xp[2] = x + w; yp[2] = y + max(h / 4, 1);
373 yp[3] = y - max(h / 4, 1);
375 Color col = Color_special;
376 if (params_.kind == InsetSpaceParams::PROTECTED ||
377 params_.kind == InsetSpaceParams::ENSPACE ||
378 params_.kind == InsetSpaceParams::NEGTHIN ||
379 params_.kind == InsetSpaceParams::NEGMEDIUM ||
380 params_.kind == InsetSpaceParams::NEGTHICK ||
381 params_.kind == InsetSpaceParams::CUSTOM_PROTECTED)
383 else if (params_.kind == InsetSpaceParams::VISIBLE)
384 col = Color_foreground;
386 pi.pain.lines(xp, yp, 4, col);
390 void InsetSpaceParams::write(ostream & os) const
393 case InsetSpaceParams::NORMAL:
396 case InsetSpaceParams::PROTECTED:
399 case InsetSpaceParams::VISIBLE:
400 os << "\\textvisiblespace{}";
402 case InsetSpaceParams::THIN:
403 os << "\\thinspace{}";
405 case InsetSpaceParams::MEDIUM:
406 os << "\\medspace{}";
408 case InsetSpaceParams::THICK:
409 os << "\\thickspace{}";
411 case InsetSpaceParams::QUAD:
414 case InsetSpaceParams::QQUAD:
417 case InsetSpaceParams::ENSPACE:
420 case InsetSpaceParams::ENSKIP:
423 case InsetSpaceParams::NEGTHIN:
424 os << "\\negthinspace{}";
426 case InsetSpaceParams::NEGMEDIUM:
427 os << "\\negmedspace{}";
429 case InsetSpaceParams::NEGTHICK:
430 os << "\\negthickspace{}";
432 case InsetSpaceParams::HFILL:
435 case InsetSpaceParams::HFILL_PROTECTED:
436 os << "\\hspace*{\\fill}";
438 case InsetSpaceParams::DOTFILL:
441 case InsetSpaceParams::HRULEFILL:
442 os << "\\hrulefill{}";
444 case InsetSpaceParams::LEFTARROWFILL:
445 os << "\\leftarrowfill{}";
447 case InsetSpaceParams::RIGHTARROWFILL:
448 os << "\\rightarrowfill{}";
450 case InsetSpaceParams::UPBRACEFILL:
451 os << "\\upbracefill{}";
453 case InsetSpaceParams::DOWNBRACEFILL:
454 os << "\\downbracefill{}";
456 case InsetSpaceParams::CUSTOM:
459 case InsetSpaceParams::CUSTOM_PROTECTED:
464 if (!length.len().empty())
465 os << "\n\\length " << length.asString();
469 void InsetSpaceParams::read(Lexer & lex)
471 lex.setContext("InsetSpaceParams::read");
475 // The tests for math might be disabled after a file format change
476 if (command == "\\space{}")
477 kind = InsetSpaceParams::NORMAL;
478 else if (command == "~")
479 kind = InsetSpaceParams::PROTECTED;
480 else if (command == "\\textvisiblespace{}")
481 kind = InsetSpaceParams::VISIBLE;
482 else if (command == "\\thinspace{}")
483 kind = InsetSpaceParams::THIN;
484 else if (math && command == "\\medspace{}")
485 kind = InsetSpaceParams::MEDIUM;
486 else if (math && command == "\\thickspace{}")
487 kind = InsetSpaceParams::THICK;
488 else if (command == "\\quad{}")
489 kind = InsetSpaceParams::QUAD;
490 else if (command == "\\qquad{}")
491 kind = InsetSpaceParams::QQUAD;
492 else if (command == "\\enspace{}")
493 kind = InsetSpaceParams::ENSPACE;
494 else if (command == "\\enskip{}")
495 kind = InsetSpaceParams::ENSKIP;
496 else if (command == "\\negthinspace{}")
497 kind = InsetSpaceParams::NEGTHIN;
498 else if (command == "\\negmedspace{}")
499 kind = InsetSpaceParams::NEGMEDIUM;
500 else if (command == "\\negthickspace{}")
501 kind = InsetSpaceParams::NEGTHICK;
502 else if (command == "\\hfill{}")
503 kind = InsetSpaceParams::HFILL;
504 else if (command == "\\hspace*{\\fill}")
505 kind = InsetSpaceParams::HFILL_PROTECTED;
506 else if (command == "\\dotfill{}")
507 kind = InsetSpaceParams::DOTFILL;
508 else if (command == "\\hrulefill{}")
509 kind = InsetSpaceParams::HRULEFILL;
510 else if (command == "\\hspace{}")
511 kind = InsetSpaceParams::CUSTOM;
512 else if (command == "\\leftarrowfill{}")
513 kind = InsetSpaceParams::LEFTARROWFILL;
514 else if (command == "\\rightarrowfill{}")
515 kind = InsetSpaceParams::RIGHTARROWFILL;
516 else if (command == "\\upbracefill{}")
517 kind = InsetSpaceParams::UPBRACEFILL;
518 else if (command == "\\downbracefill{}")
519 kind = InsetSpaceParams::DOWNBRACEFILL;
520 else if (command == "\\hspace*{}")
521 kind = InsetSpaceParams::CUSTOM_PROTECTED;
523 lex.printError("InsetSpace: Unknown kind: `$$Token'");
525 if (lex.checkFor("\\length"))
530 void InsetSpace::write(ostream & os) const
537 void InsetSpace::read(Lexer & lex)
540 lex >> "\\end_inset";
544 void InsetSpace::latex(otexstream & os, OutputParams const & runparams) const
546 switch (params_.kind) {
547 case InsetSpaceParams::NORMAL:
548 os << (runparams.free_spacing ? " " : "\\ ");
550 case InsetSpaceParams::PROTECTED:
551 if (runparams.local_font &&
552 runparams.local_font->language()->lang() == "polutonikogreek")
553 // in babel's polutonikogreek, ~ is active
554 os << (runparams.free_spacing ? " " : "\\nobreakspace{}");
556 os << (runparams.free_spacing ? ' ' : '~');
558 case InsetSpaceParams::VISIBLE:
559 os << (runparams.free_spacing ? " " : "\\textvisiblespace{}");
561 case InsetSpaceParams::THIN:
562 os << (runparams.free_spacing ? " " : "\\,");
564 case InsetSpaceParams::MEDIUM:
565 os << (runparams.free_spacing ? " " : "\\:");
567 case InsetSpaceParams::THICK:
568 os << (runparams.free_spacing ? " " : "\\;");
570 case InsetSpaceParams::QUAD:
571 os << (runparams.free_spacing ? " " : "\\quad{}");
573 case InsetSpaceParams::QQUAD:
574 os << (runparams.free_spacing ? " " : "\\qquad{}");
576 case InsetSpaceParams::ENSPACE:
577 os << (runparams.free_spacing ? " " : "\\enspace{}");
579 case InsetSpaceParams::ENSKIP:
580 os << (runparams.free_spacing ? " " : "\\enskip{}");
582 case InsetSpaceParams::NEGTHIN:
583 os << (runparams.free_spacing ? " " : "\\negthinspace{}");
585 case InsetSpaceParams::NEGMEDIUM:
586 os << (runparams.free_spacing ? " " : "\\negmedspace{}");
588 case InsetSpaceParams::NEGTHICK:
589 os << (runparams.free_spacing ? " " : "\\negthickspace{}");
591 case InsetSpaceParams::HFILL:
592 os << (runparams.free_spacing ? " " : "\\hfill{}");
594 case InsetSpaceParams::HFILL_PROTECTED:
595 os << (runparams.free_spacing ? " " : "\\hspace*{\\fill}");
597 case InsetSpaceParams::DOTFILL:
598 os << (runparams.free_spacing ? " " : "\\dotfill{}");
600 case InsetSpaceParams::HRULEFILL:
601 os << (runparams.free_spacing ? " " : "\\hrulefill{}");
603 case InsetSpaceParams::LEFTARROWFILL:
604 os << (runparams.free_spacing ? " " : "\\leftarrowfill{}");
606 case InsetSpaceParams::RIGHTARROWFILL:
607 os << (runparams.free_spacing ? " " : "\\rightarrowfill{}");
609 case InsetSpaceParams::UPBRACEFILL:
610 os << (runparams.free_spacing ? " " : "\\upbracefill{}");
612 case InsetSpaceParams::DOWNBRACEFILL:
613 os << (runparams.free_spacing ? " " : "\\downbracefill{}");
615 case InsetSpaceParams::CUSTOM:
616 if (runparams.free_spacing)
619 os << "\\hspace{" << from_ascii(params_.length.asLatexString()) << "}";
621 case InsetSpaceParams::CUSTOM_PROTECTED:
622 if (runparams.free_spacing)
625 os << "\\hspace*{" << from_ascii(params_.length.asLatexString()) << "}";
631 int InsetSpace::plaintext(odocstringstream & os,
632 OutputParams const &, size_t) const
634 switch (params_.kind) {
635 case InsetSpaceParams::HFILL:
636 case InsetSpaceParams::HFILL_PROTECTED:
639 case InsetSpaceParams::DOTFILL:
642 case InsetSpaceParams::HRULEFILL:
645 case InsetSpaceParams::LEFTARROWFILL:
648 case InsetSpaceParams::RIGHTARROWFILL:
651 case InsetSpaceParams::UPBRACEFILL:
654 case InsetSpaceParams::DOWNBRACEFILL:
657 case InsetSpaceParams::VISIBLE:
660 case InsetSpaceParams::ENSKIP:
663 case InsetSpaceParams::ENSPACE:
664 os.put(0x2060); // WORD JOINER, makes the breakable en space unbreakable
666 os.put(0x2060); // WORD JOINER, makes the breakable en space unbreakable
668 case InsetSpaceParams::QUAD:
671 case InsetSpaceParams::QQUAD:
675 case InsetSpaceParams::THIN:
678 case InsetSpaceParams::MEDIUM:
679 os.put(0x200b); // ZERO WIDTH SPACE, makes the unbreakable medium space breakable
681 os.put(0x200b); // ZERO WIDTH SPACE, makes the unbreakable medium space breakable
683 case InsetSpaceParams::THICK:
684 os.put(0x200b); // ZERO WIDTH SPACE, makes the unbreakable thick space breakable
686 os.put(0x200b); // ZERO WIDTH SPACE, makes the unbreakable thick space breakable
688 case InsetSpaceParams::PROTECTED:
689 case InsetSpaceParams::CUSTOM_PROTECTED:
692 case InsetSpaceParams::NEGTHIN:
693 case InsetSpaceParams::NEGMEDIUM:
694 case InsetSpaceParams::NEGTHICK:
703 int InsetSpace::docbook(odocstream & os, OutputParams const &) const
705 switch (params_.kind) {
706 case InsetSpaceParams::NORMAL:
709 case InsetSpaceParams::QUAD:
712 case InsetSpaceParams::QQUAD:
713 os << "  ";
715 case InsetSpaceParams::ENSKIP:
718 case InsetSpaceParams::PROTECTED:
721 case InsetSpaceParams::VISIBLE:
724 case InsetSpaceParams::ENSPACE:
725 os << "⁠ ⁠";
727 case InsetSpaceParams::THIN:
730 case InsetSpaceParams::MEDIUM:
733 case InsetSpaceParams::THICK:
736 case InsetSpaceParams::NEGTHIN:
737 case InsetSpaceParams::NEGMEDIUM:
738 case InsetSpaceParams::NEGTHICK:
742 case InsetSpaceParams::HFILL:
743 case InsetSpaceParams::HFILL_PROTECTED:
746 case InsetSpaceParams::DOTFILL:
750 case InsetSpaceParams::HRULEFILL:
754 case InsetSpaceParams::LEFTARROWFILL:
755 case InsetSpaceParams::RIGHTARROWFILL:
756 case InsetSpaceParams::UPBRACEFILL:
757 case InsetSpaceParams::DOWNBRACEFILL:
758 case InsetSpaceParams::CUSTOM:
759 case InsetSpaceParams::CUSTOM_PROTECTED:
768 docstring InsetSpace::xhtml(XHTMLStream & xs, OutputParams const &) const
771 switch (params_.kind) {
772 case InsetSpaceParams::NORMAL:
775 case InsetSpaceParams::ENSKIP:
778 case InsetSpaceParams::ENSPACE:
779 output ="⁠ ⁠";
781 case InsetSpaceParams::QQUAD:
782 output ="  ";
784 case InsetSpaceParams::THICK:
787 case InsetSpaceParams::QUAD:
790 case InsetSpaceParams::MEDIUM:
793 case InsetSpaceParams::THIN:
796 case InsetSpaceParams::PROTECTED:
797 case InsetSpaceParams::NEGTHIN:
798 case InsetSpaceParams::NEGMEDIUM:
799 case InsetSpaceParams::NEGTHICK:
802 // no XHTML entity, only unicode code for space character exists
803 case InsetSpaceParams::VISIBLE:
806 case InsetSpaceParams::HFILL:
807 case InsetSpaceParams::HFILL_PROTECTED:
808 case InsetSpaceParams::DOTFILL:
809 case InsetSpaceParams::HRULEFILL:
810 case InsetSpaceParams::LEFTARROWFILL:
811 case InsetSpaceParams::RIGHTARROWFILL:
812 case InsetSpaceParams::UPBRACEFILL:
813 case InsetSpaceParams::DOWNBRACEFILL:
815 // Can we do anything with those in HTML?
817 case InsetSpaceParams::CUSTOM:
819 // Probably we could do some sort of blank span?
821 case InsetSpaceParams::CUSTOM_PROTECTED:
823 // Probably we could do some sort of blank span?
827 // don't escape the entities!
828 xs << XHTMLStream::ESCAPE_NONE << from_ascii(output);
833 void InsetSpace::validate(LaTeXFeatures & features) const
835 if (params_.kind == InsetSpaceParams::NEGMEDIUM ||
836 params_.kind == InsetSpaceParams::NEGTHICK)
837 features.require("amsmath");
841 void InsetSpace::toString(odocstream & os) const
843 odocstringstream ods;
844 plaintext(ods, OutputParams(0));
849 void InsetSpace::forOutliner(docstring & os, size_t const, bool const) const
851 // There's no need to be cute here.
856 bool InsetSpace::isHfill() const
858 return params_.kind == InsetSpaceParams::HFILL
859 || params_.kind == InsetSpaceParams::HFILL_PROTECTED
860 || params_.kind == InsetSpaceParams::DOTFILL
861 || params_.kind == InsetSpaceParams::HRULEFILL
862 || params_.kind == InsetSpaceParams::LEFTARROWFILL
863 || params_.kind == InsetSpaceParams::RIGHTARROWFILL
864 || params_.kind == InsetSpaceParams::UPBRACEFILL
865 || params_.kind == InsetSpaceParams::DOWNBRACEFILL;
869 string InsetSpace::contextMenuName() const
871 return "context-space";
875 void InsetSpace::string2params(string const & in, InsetSpaceParams & params)
877 params = InsetSpaceParams();
881 istringstream data(in);
884 lex.setContext("InsetSpace::string2params");
886 string const name = lex.getString();
887 if (name == "mathspace")
891 // we can try to read this even if the name is wrong
892 LATTEST(name == "space");
895 // There are cases, such as when we are called via getStatus() from
896 // Dialog::canApply(), where we are just called with "space" rather
897 // than a full "space \type{}\n\\end_inset".
903 string InsetSpace::params2string(InsetSpaceParams const & params)
908 data << "space" << ' ';