]> git.lyx.org Git - features.git/blobdiff - src/support/lstrings.cpp
Handle multiple spaces at row break
[features.git] / src / support / lstrings.cpp
index 4a12c34b4daec5fb2767ccec63a4ae4626859305..d5b6dea588f10e40d378576f0be08270d444f29e 100644 (file)
@@ -146,7 +146,7 @@ bool isSpace(char_type c)
 {
        if (!is_utf16(c)) {
                // assume that no non-utf16 character is a space
-               // c outside the UCS4 range is catched as well
+               // c outside the UCS4 range is caught as well
                return false;
        }
        QChar const qc = ucs4_to_qchar(c);
@@ -158,17 +158,44 @@ bool isNumber(char_type c)
 {
        if (!is_utf16(c))
                // assume that no non-utf16 character is a numeral
-               // c outside the UCS4 range is catched as well
+               // c outside the UCS4 range is caught as well
                return false;
        return ucs4_to_qchar(c).isNumber();
 }
 
 
+bool isCommonNumberSeparator(char_type c)
+{
+       if (!is_utf16(c))
+               // assume that no non-utf16 character is a numeral
+               // c outside the UCS4 range is caught as well
+               return false;
+       return ucs4_to_qchar(c).direction() == QChar::DirCS;
+}
+
+
+bool isEuropeanNumberTerminator(char_type c)
+{
+       if (!is_utf16(c))
+               // assume that no non-utf16 character is a numeral
+               // c outside the UCS4 range is caught as well
+               return false;
+       return ucs4_to_qchar(c).direction() == QChar::DirET;
+}
+
+
 bool isDigitASCII(char_type c)
 {
        return '0' <= c && c <= '9';
 }
 
+bool isNumberChar(char_type c)
+{
+       if (c > ucs4_max)
+               // outside the UCS4 range
+               return false;
+       return ucs4_to_qchar(c).isNumber();
+}
 
 bool isAlnumASCII(char_type c)
 {
@@ -186,7 +213,7 @@ bool isOpenPunctuation(char_type c)
 {
        if (!is_utf16(c)) {
                // assume that no non-utf16 character is an op
-               // c outside the UCS4 range is catched as well
+               // c outside the UCS4 range is caught as well
                return false;
        }
        QChar const qc = ucs4_to_qchar(c);
@@ -386,13 +413,13 @@ bool isHexChar(char_type c)
 
 bool isHex(docstring const & str)
 {
-       int index = 0;
+       size_t index = 0;
 
        if (str.length() > 2 && str[0] == '0' &&
            (str[1] == 'x' || str[1] == 'X'))
                index = 2;
 
-       int const len = str.length();
+       size_t const len = str.length();
 
        for (; index < len; ++index) {
                if (!isHexChar(str[index]))
@@ -402,10 +429,10 @@ bool isHex(docstring const & str)
 }
 
 
-int hexToInt(docstring const & str)
+unsigned int hexToInt(docstring const & str)
 {
        string s = to_ascii(str);
-       int h;
+       unsigned int h;
        sscanf(s.c_str(), "%x", &h);
        return h;
 }
@@ -413,8 +440,8 @@ int hexToInt(docstring const & str)
 
 bool isAscii(docstring const & str)
 {
-       int const len = str.length();
-       for (int i = 0; i < len; ++i)
+       size_t const len = str.length();
+       for (size_t i = 0; i < len; ++i)
                if (str[i] >= 0x80)
                        return false;
        return true;
@@ -423,8 +450,8 @@ bool isAscii(docstring const & str)
 
 bool isAscii(string const & str)
 {
-       int const len = str.length();
-       for (int i = 0; i < len; ++i)
+       size_t const len = str.length();
+       for (size_t i = 0; i < len; ++i)
                if (static_cast<unsigned char>(str[i]) >= 0x80)
                        return false;
        return true;
@@ -523,6 +550,14 @@ docstring const uppercase(docstring const & a)
 }
 
 
+docstring capitalize(docstring const & s) {
+       docstring ret = s;
+       char_type t = uppercase(ret[0]);
+       ret[0] = t;
+       return ret;
+}
+
+
 string const ascii_lowercase(string const & a)
 {
        string tmp(a);
@@ -870,7 +905,7 @@ String const subst_string(String const & a,
        size_t const olen = oldstr.length();
        while ((i = lstr.find(oldstr, i)) != string::npos) {
                lstr.replace(i, olen, newstr);
-               i += newstr.length(); // We need to be sure that we dont
+               i += newstr.length(); // We need to be sure that we don't
                // use the same i over and over again.
        }
        return lstr;
@@ -886,7 +921,7 @@ docstring const subst_string(docstring const & a,
        size_t const olen = oldstr.length();
        while ((i = lstr.find(oldstr, i)) != string::npos) {
                lstr.replace(i, olen, newstr);
-               i += newstr.length(); // We need to be sure that we dont
+               i += newstr.length(); // We need to be sure that we don't
                // use the same i over and over again.
        }
        return lstr;
@@ -947,6 +982,21 @@ int count_char(docstring const & str, docstring::value_type chr)
 }
 
 
+int wordCount(docstring const & d)
+{
+       docstring dt = trim(d);
+       if (dt.empty())
+               return 0;
+       int words = 1;
+       for (auto const & c : dt) {
+               if (isSpace(c))
+                       words++;
+       }
+       return words;
+}
+
+
+
 int count_bin_chars(string const & str)
 {
        QString const qstr = toqstr(str).simplified();
@@ -1177,8 +1227,7 @@ docstring const escape(docstring const & lab)
        char_type hexdigit[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
                                   '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
        docstring enc;
-       for (size_t i = 0; i < lab.length(); ++i) {
-               char_type c = lab[i];
+       for (char_type const c : lab) {
                if (c >= 128 || c == '=' || c == '%' || c == '#' || c == '$'
                    || c == '}' || c == '{' || c == ']' || c == '[' || c == '&'
                    || c == '\\') {
@@ -1213,13 +1262,21 @@ docstring const protectArgument(docstring & arg, char const l,
 }
 
 
-bool truncateWithEllipsis(docstring & str, size_t const len)
+bool truncateWithEllipsis(docstring & str, size_t const len, bool const mid)
 {
        if (str.size() <= len)
                return false;
-       str.resize(len);
-       if (len > 0)
-               str[len - 1] = 0x2026;// HORIZONTAL ELLIPSIS
+       if (mid && len > 0) {
+               size_t const hlen = len / 2;
+               docstring suffix = str.substr(str.size() - hlen);
+               str.resize(hlen);
+               str[hlen - 1] = 0x2026;// HORIZONTAL ELLIPSIS
+               str += suffix;
+       } else {
+               str.resize(len);
+               if (len > 0)
+                       str[len - 1] = 0x2026;// HORIZONTAL ELLIPSIS
+       }
        return true;
 }
 
@@ -1419,8 +1476,8 @@ std::string formatFPNumber(double x)
        os << std::fixed;
        // Prevent outputs of 23.4200000000000017 but output small numbers
        // with at least 6 significant digits.
-       double const logarithm = log10(fabs(x));
-       os << std::setprecision(max(6 - iround(logarithm), 0)) << x;
+       int const precision = (x == 0.0) ? 0 : max(6 - iround(log10(fabs(x))), 0);
+       os << std::setprecision(precision) << x;
        string result = os.str();
        if (result.find('.') != string::npos) {
                result = rtrim(result, "0");
@@ -1433,9 +1490,29 @@ std::string formatFPNumber(double x)
 
 docstring to_percent_encoding(docstring const & in, docstring const & ex)
 {
-       QByteArray input = toqstr(in).toUtf8();
-       QByteArray excludes = toqstr(ex).toUtf8();
-       return qstring_to_ucs4(QString(input.toPercentEncoding(excludes)));
+       QByteArray input = to_utf8(in).c_str();
+       QByteArray excludes = to_utf8(ex).c_str();
+       return from_utf8(string(input.toPercentEncoding(excludes).data()));
+}
+
+
+string from_percent_encoding(string const & in)
+{
+       return QByteArray::fromPercentEncoding(in.c_str()).data();
+}
+
+
+int countExpanders(docstring const & str)
+{
+       // Numbers of characters that are expanded by inter-word spacing.  These
+       // characters are spaces, except for characters 09-0D which are treated
+       // specially.  (From a combination of testing with the notepad found in qt's
+       // examples, and reading the source code.)
+       int nexp = 0;
+       for (char_type c : str)
+               if (c > 0x0d && isSpace(c))
+                       ++nexp;
+       return nexp;
 }
 
 
@@ -1455,7 +1532,7 @@ docstring bformat(docstring const & fmt, long arg1)
 }
 
 
-#ifdef LYX_USE_LONG_LONG
+#ifdef HAVE_LONG_LONG_INT
 docstring bformat(docstring const & fmt, long long arg1)
 {
        LATTEST(contains(fmt, from_ascii("%1$d")));
@@ -1511,11 +1588,7 @@ docstring bformat(docstring const & fmt, docstring const & arg1, int arg2)
 
 docstring bformat(docstring const & fmt, char const * arg1, docstring const & arg2)
 {
-       LATTEST(contains(fmt, from_ascii("%1$s")));
-       LATTEST(contains(fmt, from_ascii("%2$s")));
-       docstring str = subst(fmt, from_ascii("%1$s"), from_ascii(arg1));
-       str = subst(str, from_ascii("%2$s"), arg2);
-       return subst(str, from_ascii("%%"), from_ascii("%"));
+       return bformat(fmt, from_ascii(arg1), arg2);
 }
 
 
@@ -1555,5 +1628,22 @@ docstring bformat(docstring const & fmt,
        return subst(str, from_ascii("%%"), from_ascii("%"));
 }
 
+docstring bformat(docstring const & fmt, docstring const & arg1,
+                                 docstring const & arg2, docstring const & arg3,
+                                 docstring const & arg4, docstring const & arg5)
+{
+       LATTEST(contains(fmt, from_ascii("%1$s")));
+       LATTEST(contains(fmt, from_ascii("%2$s")));
+       LATTEST(contains(fmt, from_ascii("%3$s")));
+       LATTEST(contains(fmt, from_ascii("%4$s")));
+       LATTEST(contains(fmt, from_ascii("%5$s")));
+       docstring str = subst(fmt, from_ascii("%1$s"), arg1);
+       str = subst(str, from_ascii("%2$s"), arg2);
+       str = subst(str, from_ascii("%3$s"), arg3);
+       str = subst(str, from_ascii("%4$s"), arg4);
+       str = subst(str, from_ascii("%5$s"), arg5);
+       return subst(str, from_ascii("%%"), from_ascii("%"));
+}
+
 } // namespace support
 } // namespace lyx