#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 "texstream.h"
+#include "xml.h"
#include "support/debug.h"
#include "support/docstream.h"
#include "support/gettext.h"
#include "support/lassert.h"
+#include "support/Length.h"
#include "support/lstrings.h"
#include "frontends/Application.h"
InsetSpace::InsetSpace(InsetSpaceParams const & params)
- : Inset(0), params_(params)
+ : Inset(nullptr), params_(params)
{}
}
+int InsetSpace::rowFlags() const
+{
+ switch (params_.kind) {
+ case InsetSpaceParams::PROTECTED:
+ case InsetSpaceParams::CUSTOM_PROTECTED:
+ case InsetSpaceParams::HFILL_PROTECTED:
+ case InsetSpaceParams::THIN:
+ case InsetSpaceParams::NEGTHIN:
+ case InsetSpaceParams::MEDIUM:
+ case InsetSpaceParams::NEGMEDIUM:
+ case InsetSpaceParams::THICK:
+ case InsetSpaceParams::NEGTHICK:
+ case InsetSpaceParams::ENSPACE:
+ case InsetSpaceParams::VISIBLE:
+ // no break after these
+ return Inline;
+ case InsetSpaceParams::NORMAL:
+ case InsetSpaceParams::QUAD:
+ case InsetSpaceParams::QQUAD:
+ case InsetSpaceParams::ENSKIP:
+ case InsetSpaceParams::CUSTOM:
+ case InsetSpaceParams::HFILL:
+ case InsetSpaceParams::DOTFILL:
+ case InsetSpaceParams::HRULEFILL:
+ case InsetSpaceParams::LEFTARROWFILL:
+ case InsetSpaceParams::RIGHTARROWFILL:
+ case InsetSpaceParams::UPBRACEFILL:
+ case InsetSpaceParams::DOWNBRACEFILL:
+ // these allow line breaking
+ break;
+ }
+ return CanBreakAfter;
+}
+
+
namespace {
int const arrow_size = 8;
}
void InsetSpace::metrics(MetricsInfo & mi, Dimension & dim) const
{
if (isHfill()) {
- // The metrics for this kinds are calculated externally in
- // \c TextMetrics::computeRowMetrics. Those are dummy value:
- dim = Dimension(10, 10, 10);
+ // The width for hfills is calculated externally in
+ // TextMetrics::setRowAlignment. The value of 5 is the
+ // minimal value when the hfill is not active.
+ dim = Dimension(5, 10, 10);
return;
}
break;
case InsetSpaceParams::CUSTOM:
case InsetSpaceParams::CUSTOM_PROTECTED: {
- int const w =
- params_.length.len().inPixels(mi.base);
+ int const w = mi.base.inPixels(params_.length.len());
int const minw = (w < 0) ? 3 * arrow_size : 4;
dim.wid = max(minw, abs(w));
break;
// shut up compiler
break;
}
- // Cache the inset dimension.
- setDimCache(mi, dim);
}
}
int const w = dim.wid;
- int const h = theFontMetrics(pi.base.font).ascent('x');
+ int const h = theFontMetrics(pi.base.font).xHeight();
int xp[4], yp[4];
xp[0] = x;
if (params_.kind == InsetSpaceParams::NORMAL ||
params_.kind == InsetSpaceParams::PROTECTED ||
params_.kind == InsetSpaceParams::VISIBLE) {
- xp[1] = x; yp[1] = y;
- xp[2] = x + w; yp[2] = y;
+ xp[1] = x; yp[1] = y;
+ xp[2] = x + w - 1; yp[2] = y;
} else {
- xp[1] = x; yp[1] = y + max(h / 4, 1);
- xp[2] = x + w; yp[2] = y + max(h / 4, 1);
+ xp[1] = x; yp[1] = y + max(h / 4, 1);
+ xp[2] = x + w - 1; yp[2] = y + max(h / 4, 1);
}
- xp[3] = x + w;
+ xp[3] = x + w - 1;
yp[3] = y - max(h / 4, 1);
Color col = Color_special;
if (params_.kind == InsetSpaceParams::PROTECTED ||
params_.kind == InsetSpaceParams::ENSPACE ||
+ params_.kind == InsetSpaceParams::THIN ||
params_.kind == InsetSpaceParams::NEGTHIN ||
+ params_.kind == InsetSpaceParams::MEDIUM ||
params_.kind == InsetSpaceParams::NEGMEDIUM ||
+ params_.kind == InsetSpaceParams::THICK ||
params_.kind == InsetSpaceParams::NEGTHICK ||
params_.kind == InsetSpaceParams::CUSTOM_PROTECTED)
col = Color_latex;
void InsetSpaceParams::write(ostream & os) const
{
- string command;
switch (kind) {
case InsetSpaceParams::NORMAL:
os << "\\space{}";
kind = InsetSpaceParams::VISIBLE;
else if (command == "\\thinspace{}")
kind = InsetSpaceParams::THIN;
- else if (math && command == "\\medspace{}")
+ else if (command == "\\medspace{}")
kind = InsetSpaceParams::MEDIUM;
- else if (math && command == "\\thickspace{}")
+ else if (command == "\\thickspace{}")
kind = InsetSpaceParams::THICK;
else if (command == "\\quad{}")
kind = InsetSpaceParams::QUAD;
{
switch (params_.kind) {
case InsetSpaceParams::NORMAL:
- os << (runparams.free_spacing ? " " : "\\ ");
+ os << (runparams.free_spacing && (runparams.for_search == OutputParams::NoSearch) ? " " : "\\ ");
break;
case InsetSpaceParams::PROTECTED:
if (runparams.local_font &&
runparams.local_font->language()->lang() == "polutonikogreek")
// in babel's polutonikogreek, ~ is active
- os << (runparams.free_spacing ? " " : "\\nobreakspace{}");
+ os << (runparams.free_spacing && (runparams.for_search == OutputParams::NoSearch) ? " " : "\\nobreakspace{}");
else
- os << (runparams.free_spacing ? ' ' : '~');
+ os << (runparams.free_spacing && (runparams.for_search == OutputParams::NoSearch) ? ' ' : '~');
break;
case InsetSpaceParams::VISIBLE:
- os << (runparams.free_spacing ? " " : "\\textvisiblespace{}");
+ os << (runparams.free_spacing && (runparams.for_search == OutputParams::NoSearch) ? " " : "\\textvisiblespace{}");
break;
case InsetSpaceParams::THIN:
- os << (runparams.free_spacing ? " " : "\\,");
+ if (runparams.for_search != OutputParams::NoSearch)
+ os << "\\thinspace{}";
+ else
+ os << (runparams.free_spacing ? " " : "\\,");
break;
case InsetSpaceParams::MEDIUM:
- os << (runparams.free_spacing ? " " : "\\:");
+ if (runparams.for_search != OutputParams::NoSearch)
+ os << "\\medspace{}";
+ else if (params_.math)
+ os << (runparams.free_spacing ? " " : "\\:");
+ else
+ os << (runparams.free_spacing ? " " : "\\medspace{}");
break;
case InsetSpaceParams::THICK:
- os << (runparams.free_spacing ? " " : "\\;");
+ if (runparams.for_search != OutputParams::NoSearch)
+ os << "\\thickspace{}";
+ else if (params_.math)
+ os << (runparams.free_spacing ? " " : "\\;");
+ else
+ os << (runparams.free_spacing ? " " : "\\thickspace{}");
break;
case InsetSpaceParams::QUAD:
- os << (runparams.free_spacing ? " " : "\\quad{}");
+ os << (runparams.free_spacing && (runparams.for_search != OutputParams::NoSearch) ? " " : "\\quad{}");
break;
case InsetSpaceParams::QQUAD:
- os << (runparams.free_spacing ? " " : "\\qquad{}");
+ os << (runparams.free_spacing && (runparams.for_search != OutputParams::NoSearch) ? " " : "\\qquad{}");
break;
case InsetSpaceParams::ENSPACE:
- os << (runparams.free_spacing ? " " : "\\enspace{}");
+ os << (runparams.free_spacing && (runparams.for_search != OutputParams::NoSearch) ? " " : "\\enspace{}");
break;
case InsetSpaceParams::ENSKIP:
- os << (runparams.free_spacing ? " " : "\\enskip{}");
+ os << (runparams.free_spacing && (runparams.for_search != OutputParams::NoSearch) ? " " : "\\enskip{}");
break;
case InsetSpaceParams::NEGTHIN:
- os << (runparams.free_spacing ? " " : "\\negthinspace{}");
+ os << (runparams.free_spacing && (runparams.for_search != OutputParams::NoSearch) ? " " : "\\negthinspace{}");
break;
case InsetSpaceParams::NEGMEDIUM:
- os << (runparams.free_spacing ? " " : "\\negmedspace{}");
+ os << (runparams.free_spacing && (runparams.for_search != OutputParams::NoSearch) ? " " : "\\negmedspace{}");
break;
case InsetSpaceParams::NEGTHICK:
- os << (runparams.free_spacing ? " " : "\\negthickspace{}");
+ os << (runparams.free_spacing && (runparams.for_search != OutputParams::NoSearch) ? " " : "\\negthickspace{}");
break;
case InsetSpaceParams::HFILL:
- os << (runparams.free_spacing ? " " : "\\hfill{}");
+ os << (runparams.free_spacing && (runparams.for_search != OutputParams::NoSearch) ? " " : "\\hfill{}");
break;
case InsetSpaceParams::HFILL_PROTECTED:
- os << (runparams.free_spacing ? " " : "\\hspace*{\\fill}");
+ os << (runparams.free_spacing && (runparams.for_search != OutputParams::NoSearch) ? " " : "\\hspace*{\\fill}");
break;
case InsetSpaceParams::DOTFILL:
- os << (runparams.free_spacing ? " " : "\\dotfill{}");
+ os << (runparams.free_spacing && (runparams.for_search != OutputParams::NoSearch) ? " " : "\\dotfill{}");
break;
case InsetSpaceParams::HRULEFILL:
- os << (runparams.free_spacing ? " " : "\\hrulefill{}");
+ os << (runparams.free_spacing && (runparams.for_search != OutputParams::NoSearch) ? " " : "\\hrulefill{}");
break;
case InsetSpaceParams::LEFTARROWFILL:
- os << (runparams.free_spacing ? " " : "\\leftarrowfill{}");
+ os << (runparams.free_spacing && (runparams.for_search != OutputParams::NoSearch) ? " " : "\\leftarrowfill{}");
break;
case InsetSpaceParams::RIGHTARROWFILL:
- os << (runparams.free_spacing ? " " : "\\rightarrowfill{}");
+ os << (runparams.free_spacing && (runparams.for_search != OutputParams::NoSearch) ? " " : "\\rightarrowfill{}");
break;
case InsetSpaceParams::UPBRACEFILL:
- os << (runparams.free_spacing ? " " : "\\upbracefill{}");
+ os << (runparams.free_spacing && (runparams.for_search != OutputParams::NoSearch) ? " " : "\\upbracefill{}");
break;
case InsetSpaceParams::DOWNBRACEFILL:
- os << (runparams.free_spacing ? " " : "\\downbracefill{}");
+ os << (runparams.free_spacing && (runparams.for_search != OutputParams::NoSearch) ? " " : "\\downbracefill{}");
break;
case InsetSpaceParams::CUSTOM:
if (runparams.free_spacing)
}
-int InsetSpace::docbook(odocstream & os, OutputParams const &) const
+void InsetSpace::docbook(XMLStream & xs, OutputParams const &) const
{
switch (params_.kind) {
case InsetSpaceParams::NORMAL:
- os << " ";
+ xs << XMLStream::ESCAPE_NONE << " ";
break;
case InsetSpaceParams::QUAD:
- os << " ";
+ xs << XMLStream::ESCAPE_NONE << " "; // HTML:  
break;
case InsetSpaceParams::QQUAD:
- os << "  ";
+ xs << XMLStream::ESCAPE_NONE << "  "; // HTML:   
break;
case InsetSpaceParams::ENSKIP:
- os << " ";
+ xs << XMLStream::ESCAPE_NONE << " "; // HTML:  
break;
case InsetSpaceParams::PROTECTED:
- os << " ";
+ xs << XMLStream::ESCAPE_NONE << " "; // HTML:
break;
case InsetSpaceParams::VISIBLE:
- os << "␣";
+ xs << XMLStream::ESCAPE_NONE << "␣";
break;
- case InsetSpaceParams::ENSPACE:
- os << "⁠ ⁠";
+ case InsetSpaceParams::ENSPACE: // HTML: ⁠ ⁠ (word joiners)
+ xs << XMLStream::ESCAPE_NONE << "⁠ ⁠";
break;
case InsetSpaceParams::THIN:
- os << " ";
+ xs << XMLStream::ESCAPE_NONE << " "; // HTML: &thinspace;
break;
case InsetSpaceParams::MEDIUM:
- os << " ";
+ xs << XMLStream::ESCAPE_NONE << " "; // HTML:  
break;
case InsetSpaceParams::THICK:
- os << " ";
+ xs << XMLStream::ESCAPE_NONE << " "; // HTML:  
break;
case InsetSpaceParams::NEGTHIN:
case InsetSpaceParams::NEGMEDIUM:
case InsetSpaceParams::NEGTHICK:
- // FIXME
- os << " ";
+ xs << XMLStream::ESCAPE_NONE << " "; // HTML:
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';
+ xs << '\n';
break;
}
- return 0;
}
-docstring InsetSpace::xhtml(XHTMLStream & xs, OutputParams const &) const
+docstring InsetSpace::xhtml(XMLStream & xs, OutputParams const &) const
{
string output;
switch (params_.kind) {
break;
}
// don't escape the entities!
- xs << XHTMLStream::ESCAPE_NONE << from_ascii(output);
+ xs << XMLStream::ESCAPE_NONE << from_ascii(output);
return docstring();
}
void InsetSpace::validate(LaTeXFeatures & features) const
{
- if (params_.kind == InsetSpaceParams::NEGMEDIUM ||
- params_.kind == InsetSpaceParams::NEGTHICK)
+ if (features.isAvailable("LaTeX-2020/10/01"))
+ // As of this version, the LaTeX kernel
+ // includes all spaces.
+ return;
+
+ // In earlier versions, we require amsmath
+ // for some text and math spaces
+ if ((params_.kind == InsetSpaceParams::NEGMEDIUM
+ || params_.kind == InsetSpaceParams::NEGTHICK)
+ || (!params_.math
+ && (params_.kind == InsetSpaceParams::MEDIUM
+ || params_.kind == InsetSpaceParams::THICK)))
features.require("amsmath");
}
}
-void InsetSpace::forOutliner(docstring & os, size_t) const
+void InsetSpace::forOutliner(docstring & os, size_t const, bool const) const
{
// There's no need to be cute here.
os += " ";