Skip to content
Permalink
Browse files

Improved title case conversion, add tests

  • Loading branch information
nyalldawson committed May 15, 2018
1 parent 825a697 commit 3949802d581919a9bad5201d6a8016abd732c22f
Showing with 45 additions and 7 deletions.
  1. +16 −7 src/core/qgsstringutils.cpp
  2. +29 −0 tests/src/core/testqgsstringutils.cpp
@@ -18,6 +18,7 @@
#include <QRegExp>
#include <QStringList>
#include <QTextBoundaryFinder>
#include <QRegularExpression>

QString QgsStringUtils::capitalize( const QString &string, QgsStringUtils::Capitalization capitalization )
{
@@ -61,29 +62,37 @@ QString QgsStringUtils::capitalize( const QString &string, QgsStringUtils::Capit
// yes, this is MASSIVELY simplifying the problem!!

static QStringList smallWords;
static QStringList newPhraseSeparators;
static QRegularExpression splitWords;
if ( smallWords.empty() )
{
smallWords = QObject::tr( "a|an|and|as|at|but|by|en|for|if|in|nor|of|on|or|per|the|to|vs.|vs|via" ).split( '|' );
smallWords = QObject::tr( "a|an|and|as|at|but|by|en|for|if|in|nor|of|on|or|per|s|the|to|vs.|vs|via" ).split( '|' );

This comment has been minimized.

Copy link
@DelazJ

DelazJ Aug 16, 2018

Contributor

@nyalldawson is this worth putting to translation? I guess English title case rules are different from other languages and those may not be concerned by the small words rules eg. And that translators do apply their rules manually.
(unless I misunderstood what is supposed to be done here and would then need some guidance to know how handle this as a translator). Thanks.

newPhraseSeparators = QObject::tr( ".|:" ).split( '|' );
splitWords = QRegularExpression( QStringLiteral( "\\b" ) );
}

const QStringList parts = string.split( ' ' );
const QStringList parts = string.split( splitWords, QString::SkipEmptyParts );
QString result;
bool firstWord = true;
int i = 0;
int lastWord = parts.count() - 1;
for ( const QString &word : qgis::as_const( parts ) )
{
if ( word.isEmpty() )
if ( newPhraseSeparators.contains( word.trimmed() ) )
{
result += ' ';
firstWord = true;
result += word;
}
else if ( firstWord || !smallWords.contains( word ) )
else if ( firstWord || ( i == lastWord ) || !smallWords.contains( word ) )
{
result += ' ' + word.at( 0 ).toUpper() + word.mid( 1 );
result += word.at( 0 ).toUpper() + word.mid( 1 );
firstWord = false;
}
else
{
result += ' ' + word;
result += word;
}
i++;
}
return result;
}
@@ -34,6 +34,8 @@ class TestQgsStringUtils : public QObject
void hammingDistance();
void soundex();
void insertLinks();
void titleCase_data();
void titleCase();

};

@@ -154,6 +156,33 @@ void TestQgsStringUtils::insertLinks()
QVERIFY( !found );
}

void TestQgsStringUtils::titleCase_data()
{
QTest::addColumn<QString>( "input" );
QTest::addColumn<QString>( "expected" );

// invalid strings
QTest::newRow( "empty string" ) << "" << "";
QTest::newRow( "single character" ) << "a" << "A";
QTest::newRow( "string 1" ) << "follow step-by-step instructions" << "Follow Step-by-Step Instructions";
QTest::newRow( "string 2" ) << "this sub-phrase is nice" << "This Sub-Phrase Is Nice";
QTest::newRow( "" ) << "catchy title: a subtitle" << "Catchy Title: A Subtitle";
QTest::newRow( "string 3" ) << "all words capitalized" << "All Words Capitalized";
QTest::newRow( "string 4" ) << "small words are for by and of lowercase" << "Small Words Are for by and of Lowercase";
QTest::newRow( "string 5" ) << "a small word starts" << "A Small Word Starts";
QTest::newRow( "last word" ) << "a small word it ends on" << "A Small Word It Ends On";
QTest::newRow( "last word2" ) << "Ends with small word of" << "Ends With Small Word Of";
QTest::newRow( "string 6" ) << "Merge VRT(s)" << "Merge VRT(s)";
QTest::newRow( "string 6" ) << "multiple sentences. more than one." << "Multiple Sentences. More Than One.";
}

void TestQgsStringUtils::titleCase()
{
QFETCH( QString, input );
QFETCH( QString, expected );
QCOMPARE( QgsStringUtils::capitalize( input, QgsStringUtils::TitleCase ), expected );
}


QGSTEST_MAIN( TestQgsStringUtils )
#include "testqgsstringutils.moc"

0 comments on commit 3949802

Please sign in to comment.
You can’t perform that action at this time.