X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FVSpace.cpp;h=aad2a6e79a5df4b4a0621407151c8d84694f96db;hb=3d4076b598deb18660e50ec9c327efc3b15f15d0;hp=d720589eef6b6a136177c5c2122d2ad0025d354c;hpb=8c622e4ff04765c786cbe9ccc9824f4429aee4e7;p=lyx.git diff --git a/src/VSpace.cpp b/src/VSpace.cpp index d720589eef..aad2a6e79a 100644 --- a/src/VSpace.cpp +++ b/src/VSpace.cpp @@ -11,330 +11,25 @@ #include #include "VSpace.h" + #include "Buffer.h" #include "BufferParams.h" #include "BufferView.h" -#include "gettext.h" -#include "lengthcommon.h" -#include "LyXText.h" +#include "support/gettext.h" +#include "Length.h" +#include "Text.h" +#include "TextMetrics.h" // for defaultRowHeight() #include "support/convert.h" #include "support/lstrings.h" +#include "support/lassert.h" -namespace lyx { - -using support::compare; -using support::isStrDbl; -using support::ltrim; -using support::prefixIs; -using support::rtrim; - -using std::string; - - -namespace { - -/// used to return numeric values in parsing vspace -double number[4] = { 0, 0, 0, 0 }; -/// used to return unit types in parsing vspace -Length::UNIT unit[4] = { Length::UNIT_NONE, - Length::UNIT_NONE, - Length::UNIT_NONE, - Length::UNIT_NONE }; +using namespace std; +using namespace lyx::support; -/// the current position in the number array -int number_index; -/// the current position in the unit array -int unit_index; - -/// skip n characters of input -inline -void lyx_advance(string & data, string::size_type n) -{ - data.erase(0, n); -} - - -/// return true when the input is at the end -inline -bool isEndOfData(string const & data) -{ - return ltrim(data).empty(); -} - - -/** - * nextToken - return the next token in the input - * @param data input string - * @return a char representing the type of token returned - * - * The possible return values are : - * + stretch indicator for glue length - * - shrink indicator for glue length - * n a numeric value (stored in number array) - * u a unit type (stored in unit array) - * E parse error - */ -char nextToken(string & data) -{ - data = ltrim(data); - - if (data.empty()) - return '\0'; - - if (data[0] == '+') { - lyx_advance(data, 1); - return '+'; - } - - if (prefixIs(data, "plus")) { - lyx_advance(data, 4); - return '+'; - } - - if (data[0] == '-') { - lyx_advance(data, 1); - return '-'; - } - - if (prefixIs(data, "minus")) { - lyx_advance(data, 5); - return '-'; - } - - string::size_type i = data.find_first_not_of("0123456789."); - - if (i != 0) { - if (number_index > 3) - return 'E'; - - string buffer; - - // we have found some number - if (i == string::npos) { - buffer = data; - i = data.size() + 1; - } else - buffer = data.substr(0, i); - - lyx_advance(data, i); - - if (isStrDbl(buffer)) { - number[number_index] = convert(buffer); - ++number_index; - return 'n'; - } - return 'E'; - } - - i = data.find_first_not_of("abcdefghijklmnopqrstuvwxyz%"); - if (i != 0) { - if (unit_index > 3) - return 'E'; - - string buffer; - - // we have found some alphabetical string - if (i == string::npos) { - buffer = data; - i = data.size() + 1; - } else - buffer = data.substr(0, i); - - // possibly we have "mmplus" string or similar - if (buffer.size() > 5 && - (buffer.substr(2, 4) == string("plus") || - buffer.substr(2, 5) == string("minus"))) - { - lyx_advance(data, 2); - unit[unit_index] = unitFromString(buffer.substr(0, 2)); - } else { - lyx_advance(data, i); - unit[unit_index] = unitFromString(buffer); - } - - if (unit[unit_index] != Length::UNIT_NONE) { - ++unit_index; - return 'u'; - } - return 'E'; // Error - } - return 'E'; // Error -} - - -/// latex representation of a vspace -struct LaTeXLength { - char const * pattern; - int plus_val_index; - int minus_val_index; - int plus_uni_index; - int minus_uni_index; -}; - - -/// the possible formats for a vspace string -LaTeXLength table[] = { - { "nu", 0, 0, 0, 0 }, - { "nu+nu", 2, 0, 2, 0 }, - { "nu+nu-nu", 2, 3, 2, 3 }, - { "nu+-nu", 2, 2, 2, 2 }, - { "nu-nu", 0, 2, 0, 2 }, - { "nu-nu+nu", 3, 2, 3, 2 }, - { "nu-+nu", 2, 2, 2, 2 }, - { "n+nu", 2, 0, 1, 0 }, - { "n+n-nu", 2, 3, 1, 1 }, - { "n+-nu", 2, 2, 1, 1 }, - { "n-nu", 0, 2, 0, 1 }, - { "n-n+nu", 3, 2, 1, 1 }, - { "n-+nu", 2, 2, 1, 1 }, - { "", 0, 0, 0, 0 } // sentinel, must be empty -}; - - -} // namespace anon - -const char * stringFromUnit(int unit) -{ - if (unit < 0 || unit > num_units) - return 0; - return unit_name[unit]; -} - - -bool isValidGlueLength(string const & data, GlueLength * result) -{ - // This parser is table-driven. First, it constructs a "pattern" - // that describes the sequence of tokens in "data". For example, - // "n-nu" means: number, minus sign, number, unit. As we go along, - // numbers and units are stored into static arrays. Then, "pattern" - // is searched in the "table". If it is found, the associated - // table entries tell us which number and unit should go where - // in the Length structure. Example: if "data" has the "pattern" - // "nu+nu-nu", the associated table entries are "2, 3, 2, 3". - // That means, "plus_val" is the second number that was seen - // in the input, "minus_val" is the third number, and "plus_uni" - // and "minus_uni" are the second and third units, respectively. - // ("val" and "uni" are always the first items seen in "data".) - // This is the most elegant solution I could find -- a straight- - // forward approach leads to very long, tedious code that would be - // much harder to understand and maintain. (AS) - - if (data.empty()) - return true; - string buffer = ltrim(data); - - // To make isValidGlueLength recognize negative values as - // the first number this little hack is needed: - int val_sign = 1; // positive as default - switch (buffer[0]) { - case '-': - lyx_advance(buffer, 1); - val_sign = -1; - break; - case '+': - lyx_advance(buffer, 1); - break; - default: - break; - } - // end of hack - - int pattern_index = 0; - int table_index = 0; - char pattern[20]; - - number_index = 1; - unit_index = 1; // entries at index 0 are sentinels - - // construct "pattern" from "data" - while (!isEndOfData (buffer)) { - if (pattern_index > 20) return false; - pattern[pattern_index] = nextToken (buffer); - if (pattern[pattern_index] == 'E') return false; - ++pattern_index; - } - pattern[pattern_index] = '\0'; - - // search "pattern" in "table" - table_index = 0; - while (compare(pattern, table[table_index].pattern)) { - ++table_index; - if (!*table[table_index].pattern) - return false; - } - - // Get the values from the appropriate places. If an index - // is zero, the corresponding array value is zero or UNIT_NONE, - // so we needn't check this. - if (result) { - result->len_.value (number[1] * val_sign); - result->len_.unit (unit[1]); - result->plus_.value (number[table[table_index].plus_val_index]); - result->plus_.unit (unit [table[table_index].plus_uni_index]); - result->minus_.value(number[table[table_index].minus_val_index]); - result->minus_.unit (unit [table[table_index].minus_uni_index]); - } - return true; -} - - -bool isValidLength(string const & data, Length * result) -{ - // This is a trimmed down version of isValidGlueLength. - // The parser may seem overkill for lengths without - // glue, but since we already have it, using it is - // easier than writing something from scratch. - if (data.empty()) - return true; - - string buffer = data; - int pattern_index = 0; - char pattern[3]; - - // To make isValidLength recognize negative values - // this little hack is needed: - int val_sign = 1; // positive as default - switch (buffer[0]) { - case '-': - lyx_advance(buffer, 1); - val_sign = -1; - break; - case '+': - lyx_advance(buffer, 1); - // fall through - default: - // no action - break; - } - // end of hack - - number_index = unit_index = 1; // entries at index 0 are sentinels - - // construct "pattern" from "data" - while (!isEndOfData(buffer)) { - if (pattern_index > 2) - return false; - pattern[pattern_index] = nextToken(buffer); - if (pattern[pattern_index] == 'E') - return false; - ++pattern_index; - } - pattern[pattern_index] = '\0'; - - // only the most basic pattern is accepted here - if (compare(pattern, "nu") != 0) return false; - - // It _was_ a correct length string. - // Store away the values we found. - if (result) { - result->val_ = number[1] * val_sign; - result->unit_ = unit[1]; - } - return true; -} +namespace lyx { // // VSpace class @@ -345,7 +40,7 @@ VSpace::VSpace() {} -VSpace::VSpace(vspace_kind k) +VSpace::VSpace(VSpaceKind k) : kind_(k), len_(), keep_(false) {} @@ -368,7 +63,7 @@ VSpace::VSpace(string const & data) string input = rtrim(data); - string::size_type const length = input.length(); + size_t const length = input.length(); if (length > 1 && input[length - 1] == '*') { keep_ = true; @@ -397,30 +92,6 @@ VSpace::VSpace(string const & data) } -VSpace::vspace_kind VSpace::kind() const -{ - return kind_; -} - - -GlueLength const & VSpace::length() const -{ - return len_; -} - - -bool VSpace::keep() const -{ - return keep_; -} - - -void VSpace::setKeep(bool val) -{ - keep_ = val; -} - - bool VSpace::operator==(VSpace const & other) const { if (kind_ != other.kind_) @@ -476,9 +147,10 @@ string const VSpace::asLatexCommand(BufferParams const & params) const : "\\vspace{" + len_.asLatexString() + '}'; default: - BOOST_ASSERT(false); - return string(); + LATTEST(false); + // fall through in release mode } + return string(); } @@ -511,6 +183,25 @@ docstring const VSpace::asGUIName() const } +string VSpace::asHTMLLength() const +{ + string result; + switch (kind_) { + case DEFSKIP: result = "2ex"; break; + case SMALLSKIP: result = "1ex"; break; + case MEDSKIP: result = "3ex"; break; + case BIGSKIP: result = "5ex"; break; + case LENGTH: { + Length tmp = len_.len(); + if (tmp.value() > 0) + result = tmp.asHTMLString(); + } + case VFILL: break; + } + return result; +} + + int VSpace::inPixels(BufferView const & bv) const { // Height of a normal line in pixels (zoom factor considered) @@ -519,7 +210,7 @@ int VSpace::inPixels(BufferView const & bv) const switch (kind_) { case DEFSKIP: - return bv.buffer()->params().getDefSkip().inPixels(bv); + return bv.buffer().params().getDefSkip().inPixels(bv); // This is how the skips are normally defined by LateX. // But there should be some way to change this per document. @@ -540,9 +231,10 @@ int VSpace::inPixels(BufferView const & bv) const return len_.len().inPixels(bv.workWidth()); default: - BOOST_ASSERT(false); - return 0; + LATTEST(false); + // fall through in release mode } + return 0; }