From: Jean-Marc Lasgouttes Date: Mon, 22 Aug 2016 12:15:28 +0000 (+0200) Subject: Implement computation of spacing according to the TeXBook X-Git-Tag: 2.3.0alpha1~741^2~5 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=f6df4e7985a8e35e3603445f9f6ee8c569d95aba;p=lyx.git Implement computation of spacing according to the TeXBook This implements the relevant math typography rules described in the Appendix G of the TeXbook. More precisely, for each atom + the class is computed by implementing rules 5 and 6 of Appendix G + the spacing is computed according to the table p. 170 This code is not used at this point. --- diff --git a/src/mathed/MathClass.cpp b/src/mathed/MathClass.cpp index fae7654334..a46aad3794 100644 --- a/src/mathed/MathClass.cpp +++ b/src/mathed/MathClass.cpp @@ -11,10 +11,17 @@ #include #include "MathClass.h" +#include "MathSupport.h" +#include "MetricsInfo.h" +#include "FontInfo.h" + +#include "support/debug.h" #include "support/docstring.h" #include "support/lassert.h" +#include + using namespace std; namespace lyx { @@ -79,4 +86,95 @@ MathClass string_to_class(docstring const &s) } +/* + * The TeXbook presents in Appendix G a set of 22 rules (!) explaining + * how to typeset mathematic formulas. Of interest here are rules 5 + * and 6: + + * 5. If the current item is a Bin atom, and if this was the first + * atom in the list, or if the most recent previous atom was Bin, + * Op, Rel, Open, or Punct, change the current Bin to Ord [and + * continue with Rule 14. Otherwise continue with Rule 17] + * + * 6. If the current item is a Rel or Close or Punct atom, and if the + * most recent previous atom was Bin, change that previous Bin to + * Ord. [Continue with Rule 17.] + */ +void update_class(MathClass & mc, MathClass const prev, MathClass const next) +{ + if (mc == MC_BIN + && (prev == MC_BIN || prev == MC_OP || prev == MC_OPEN + || prev == MC_PUNCT || prev == MC_REL + || next == MC_CLOSE || next == MC_PUNCT || next == MC_REL)) + mc = MC_ORD; +} + + +/* + * This table of spacing between two classes can be found p. 170 of + * The TeXbook. + * + * The line is the class of the first class, and the column the second + * class. The number encodes the spacing between the two atoms, as + * follows + * + * + 0: no spacing + * + 1: thin mu skip + * + 2: med mu skip + * + 3: thick mu skip + * + 9: should never happen + * + negative value: either 0 if the atom is in script or scriptscript mode, + * or the spacing given by the absolute value. + */ +int pair_spc[MC_UNKNOWN][MC_UNKNOWN] = { +// ORD OP BIN REL OPEN CLOSE PUNCT INNER + { 0, 1, -2, -3, 0, 0, 0, -1}, // ORD + { 1, 1, 9, -3, 0, 0, 0, -1}, // OP + { -2, -2, 9, 9, -2, 9, 9, -2}, // BIN + { -3, -3, 9, 0, -3, 0, 0, -3}, // REL + { 0, 0, 9, 0, 0, 0, 0, 0}, // OPEN + { 0, 1, -2, -3, 0, 0, 0, -1}, // CLOSE + { -1, -1, 9, -1, -1, -1, -1, -1}, // PUNCT + { -1, 1, -2, -3, -1, 0, -1, -1}, // INNER +}; + + +int class_spacing(MathClass const mc1, MathClass const mc2, + MetricsBase const & mb) +{ + int spc_code = pair_spc[mc1][mc2]; + //lyxerr << class_to_string(mc1) << "+" << class_to_string(mc2) + // << "=" << spc_code << " @" << mb.style << endl; + if (spc_code < 0) { + switch (mb.style) { + case LM_ST_DISPLAY: + case LM_ST_TEXT: + spc_code = abs(spc_code); + break; + case LM_ST_SCRIPT: + case LM_ST_SCRIPTSCRIPT: + spc_code = 0; + } + } + + int spc = 0; + switch(spc_code) { + case 0: + break; + case 1: + spc = mathed_thinmuskip(mb.font); + break; + case 2: + spc = mathed_medmuskip(mb.font); + break; + case 3: + spc = mathed_thickmuskip(mb.font); + break; + default: + LYXERR0("Impossible pair of classes: (" << mc1 << ", " << mc2 << ")"); + LATTEST(false); + } + return spc; +} + } // namespace lyx diff --git a/src/mathed/MathClass.h b/src/mathed/MathClass.h index ceedd8db07..169bfdb51a 100644 --- a/src/mathed/MathClass.h +++ b/src/mathed/MathClass.h @@ -16,6 +16,7 @@ namespace lyx { +class MetricsBase; /* The TeXbook, p. 158: * @@ -58,6 +59,10 @@ MathClass string_to_class(docstring const &); docstring const class_to_string(MathClass); +void update_class(MathClass & mc, MathClass const prev, MathClass const next); + +int class_spacing(MathClass const mc1, MathClass const mc2, + MetricsBase const & mb); } // namespace lyx diff --git a/src/mathed/MathSupport.cpp b/src/mathed/MathSupport.cpp index 9d79a8abfa..3d708406d3 100644 --- a/src/mathed/MathSupport.cpp +++ b/src/mathed/MathSupport.cpp @@ -528,6 +528,9 @@ int mathed_font_em(FontInfo const & font) * punctuation, and is put around inner objects, except where these * are followed by a close or preceded by an open symbol, and except * if the other object is a large operator or a binary relation. + * + * See the file MathClass.cpp for a formal implementation of the rules + * above. */ int mathed_thinmuskip(FontInfo font)