Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Refactoring dump input option #3566

Open
wants to merge 12 commits into
base: develop
Choose a base branch
from
49 changes: 49 additions & 0 deletions src/coreComponents/common/format/StringUtilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,17 @@ string_view trimSpaces( string_view str )
}


std::string_view ltrimSpaces( std::string_view s )
{
std::size_t const first = s.find_first_not_of( " \f\n\r\t\v" );
if( first != std::string::npos )
{
return s.substr( first, ( s.size() - first ) );
}
return {};
}


string removeStringAndFollowingContent( string_view const str,
string_view const strToRemove )
{
Expand Down Expand Up @@ -93,6 +104,44 @@ string addCommaSeparators( T const & num )
return result;
}

std::vector< std::string > wrapTextToMaxLength( std::vector< std::string > const & lines, size_t maxLength )
{
std::vector< std::string > formattedLines;

for( const auto & line : lines )
{
size_t startPos = 0;

while( startPos < line.size())
{
// if the remaining part is shorter than maxLength
if( startPos + maxLength >= line.size())
{
formattedLines.push_back( std::string( ltrimSpaces( line.substr( startPos ))));
break;
}

// find last space occurence before maxLength
size_t endPos = startPos + maxLength;
size_t spacePos = line.rfind( ' ', endPos );
if( spacePos != std::string::npos && spacePos > startPos )
{
// cut and push at the last space found
formattedLines.push_back( std::string( ltrimSpaces( line.substr( startPos, spacePos - startPos ))));
startPos = spacePos + 1;
}
else
{
// no space found, cut in the middle of the word with maxLength
formattedLines.push_back( std::string( ltrimSpaces( line.substr( startPos, maxLength ))));
startPos += maxLength;
}
}
}

return formattedLines;
}

template string addCommaSeparators( int const & num );
template string addCommaSeparators( long int const & num );
template string addCommaSeparators( long long int const & num );
Expand Down
16 changes: 16 additions & 0 deletions src/coreComponents/common/format/StringUtilities.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,13 @@ CONTAINER< string > tokenizeBySpaces( string const & str )
string_view trim( string_view str,
string_view charsToRemove );

/**
* @brief Trim the left string
* @param[in] str the string to trim
* @return the trimmed string
*/
string_view ltrimSpaces( string_view s );

/**
* @brief Trim the string so it does not starts nor ends with any whitespaces
* @param[in] str the string to trim
Expand All @@ -236,6 +243,15 @@ string removeStringAndFollowingContent( string_view str,
template< typename T >
string addCommaSeparators( T const & num );

/**
* @brief Format all the lines by detecting spaces and by dividing each lines with maximum length specified.
* If a word has a greater size than maxLength, it will be cut in one or many parts.
* @param lines Vector containing all the lines to be formatted.
* @param maxLength The max length a line can have.
* @return A vector containing the lines wrapped.
*/
std::vector< std::string > wrapTextToMaxLength( std::vector< std::string > const & lines, size_t maxLength );

/**
* @brief Take a string, and return a array1d with the cast values
* @tparam T the type to which the string will be cast
Expand Down
62 changes: 40 additions & 22 deletions src/coreComponents/common/format/table/TableFormatter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,6 @@ void TableTextFormatter::populateHeaderCellsLayout( TableLayout & tableLayout,
cellsHeaderLayout[idxRow + 1].push_back( emptyCell );
}
}
currentCell.m_cellWidth = it->m_header.m_cellWidth;

if( it->hasParent() )
{
Expand Down Expand Up @@ -291,6 +290,16 @@ void TableTextFormatter::populateHeaderCellsLayout( TableLayout & tableLayout,
cellsHeaderLayout[currentLayer].push_back( mergingCell );
}

if( tableLayout.isMaxColumnWidthSet())
{
currentCell.m_lines = stringutilities::wrapTextToMaxLength( currentCell.m_lines,
tableLayout.getMaxWidth() );

sublineHeaderCounts[currentLayer] = std::max( sublineHeaderCounts[currentLayer],
currentCell.m_lines.size() );

}

cellsHeaderLayout[currentLayer].push_back( currentCell );
}

Expand Down Expand Up @@ -343,7 +352,13 @@ void TableTextFormatter::populateDataCellsLayout( TableLayout & tableLayout,
cell.value = m_horizontalLine;
}

cellsDataLayout[idxRow][idxColumn] = TableLayout::CellLayout( cell.type, cell.value, alignement );
TableLayout::CellLayout dataToCell( cell.type, cell.value, alignement );
if( tableLayout.isMaxColumnWidthSet() )
{
dataToCell.m_lines = stringutilities::wrapTextToMaxLength( dataToCell.m_lines,
tableLayout.getMaxWidth() );
}
cellsDataLayout[idxRow][idxColumn] = dataToCell;
maxLinesPerRow = std::max( maxLinesPerRow, cellsDataLayout[idxRow][idxColumn].m_lines.size() );
idxColumn++;
}
Expand Down Expand Up @@ -396,31 +411,35 @@ void TableTextFormatter::updateColumnMaxLength( TableLayout & tableLayout,
};

size_t const numColumns = cellsHeaderLayout[0].size();
//each idx per row
std::vector< size_t > accMaxStringColumn( cellsDataLayout.size(), 0 );

// Accumulates column lengths for each line based on "MergeNext" tag.
std::vector< size_t > linesLength( cellsDataLayout.size(), 0 );
for( size_t idxColumn = 0; idxColumn < numColumns; ++idxColumn )
{
size_t maxColumnSize = 1;

// init header column max length
for( size_t rowIdx = 0; rowIdx < cellsDataLayout.size(); ++rowIdx )
{
size_t const cellDataLength = getMaxLineLength( cellsDataLayout[rowIdx][idxColumn].m_lines );
if( idxColumn == 0 ||
(idxColumn > 0 && cellsDataLayout[rowIdx][idxColumn - 1].m_cellType != CellType::MergeNext))

{ // retrieves the maximum length of the current column
// and set each header column to maxColumnSize
for( size_t rowIdx = 0; rowIdx < cellsDataLayout.size(); ++rowIdx )
{
maxColumnSize = std::max( maxColumnSize, cellDataLength );
size_t const cellDataLength = getMaxLineLength( cellsDataLayout[rowIdx][idxColumn].m_lines );
if( idxColumn == 0 ||
(idxColumn > 0 && cellsDataLayout[rowIdx][idxColumn - 1].m_cellType != CellType::MergeNext))
{
maxColumnSize = std::max( maxColumnSize, cellDataLength );
}
}
}

for( size_t rowIdx = 0; rowIdx < cellsHeaderLayout.size(); ++rowIdx )
{
size_t const cellHeaderLength = getMaxLineLength( cellsHeaderLayout[rowIdx][idxColumn].m_lines );
maxColumnSize = std::max( {maxColumnSize, cellHeaderLength} );
cellsHeaderLayout[rowIdx][idxColumn].m_cellWidth = maxColumnSize;
for( size_t rowIdx = 0; rowIdx < cellsHeaderLayout.size(); ++rowIdx )
{
size_t const cellHeaderLength = getMaxLineLength( cellsHeaderLayout[rowIdx][idxColumn].m_lines );
maxColumnSize = std::max( {maxColumnSize, cellHeaderLength} );
cellsHeaderLayout[rowIdx][idxColumn].m_cellWidth = maxColumnSize;
}
}

// update maxColumnSize for data cell
// updates the maximum cell size for the current column
for( size_t rowIdx = 0; rowIdx < cellsDataLayout.size(); ++rowIdx )
{
TableLayout::CellLayout & dataCell = cellsDataLayout[rowIdx][idxColumn];
Expand All @@ -430,14 +449,13 @@ void TableTextFormatter::updateColumnMaxLength( TableLayout & tableLayout,

if( dataCell.m_cellType == CellType::MergeNext )
{
accMaxStringColumn[rowIdx] += cellsHeaderLayout[0][idxColumn].m_cellWidth + tableLayout.getColumnMargin();
linesLength[rowIdx] += cellsHeaderLayout[0][idxColumn].m_cellWidth + tableLayout.getColumnMargin();
}

if( idxColumn > 0 &&
previousDataCell->m_cellType == CellType::MergeNext && dataCell.m_cellType != CellType::MergeNext )
{
// root header cells know the maximum string size in the column
size_t const sumOfMergingCell = accMaxStringColumn[rowIdx] + cellsHeaderLayout[0][idxColumn].m_cellWidth;
size_t const sumOfMergingCell = linesLength[rowIdx] + cellsHeaderLayout[0][idxColumn].m_cellWidth;
if( sumOfMergingCell < dataCell.m_cellWidth )
{
maxColumnSize -= dataCell.m_cellWidth - sumOfMergingCell;
Expand All @@ -454,7 +472,7 @@ void TableTextFormatter::updateColumnMaxLength( TableLayout & tableLayout,
}
}

accMaxStringColumn[rowIdx] = 0;
linesLength[rowIdx] = 0;
}
else
{
Expand Down
10 changes: 8 additions & 2 deletions src/coreComponents/common/format/table/TableLayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ TableLayout & TableLayout::setTitle( string_view title )

TableLayout & TableLayout::enableLineBreak( bool value )
{
m_wrapLine = value;
m_lineBreakAtBegin = value;
return *this;
}

Expand All @@ -62,8 +62,14 @@ TableLayout & TableLayout::setMargin( MarginValue marginValue )
return *this;
}

TableLayout & TableLayout::setMaxColumnWidth( size_t width )
{
m_tableColumnMaxWidth = width;
return *this;
}

bool TableLayout::isLineBreakEnabled() const
{ return m_wrapLine; }
{ return m_lineBreakAtBegin; }

size_t TableLayout::getMaxDepth() const
{
Expand Down
29 changes: 27 additions & 2 deletions src/coreComponents/common/format/table/TableLayout.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,20 @@ class TableLayout
*/
TableLayout & setMargin( MarginValue marginValue );

/**
* @brief Set the maximal width for each column
* @param width The max column width
* @return The tableLayout reference
*/
TableLayout & setMaxColumnWidth( size_t width );

/**
* @brief check if a column max width has been set
* @return Truef a column max width has been set, otherwise false
*/
bool isMaxColumnWidthSet()
{ return m_tableColumnMaxWidth != noColumnMaxWidth; }

/**
* @return check if the line break at the end & beginning is activated
*/
Expand Down Expand Up @@ -485,6 +499,12 @@ class TableLayout
integer const & getMarginTitle() const
{ return m_titleMargin; }

/**
* @return The margin title
*/
size_t const & getMaxWidth() const
{ return m_tableColumnMaxWidth; }

/**
* @brief Get the Nb Rows object
* @return std::vector< integer >&
Expand Down Expand Up @@ -546,15 +566,20 @@ class TableLayout
*/
void addToColumns( TableLayout::Column const & column );

static constexpr size_t noColumnMaxWidth = std::numeric_limits< size_t >::max();

/// Contains the columns layout
std::vector< Column > m_tableColumnsData;
/// Contains the subdivision (line) counts for each line in header.
std::vector< size_t > m_sublineHeaderCounts;
/// Contains the subdivision (line) counts for each line in data.
std::vector< size_t > m_sublineDataCounts;
bool m_wrapLine = true;

// Indicate if we have a line break a the beginning of the table
bool m_lineBreakAtBegin = true;
// Contain the table tible
string m_tableTitle;
// Contain the max width for each column
size_t m_tableColumnMaxWidth = std::numeric_limits< size_t >::max();

integer m_borderMargin;
integer m_columnMargin;
Expand Down
73 changes: 58 additions & 15 deletions src/coreComponents/common/format/table/unitTests/testTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ TEST( testTable, tableColumnParamClassic )
TEST( testTable, tableHiddenColumn )
{
string const title = "Cras egestas ipsum a nisl. Vivamus variu dolor utsisicdis parturient montes, nascetur ridiculus mus. Duis";
TableLayout tableLayout( title,
TableLayout const tableLayout( title,
{
TableLayout::Column()
.setName( "Cras egestas" )
Expand Down Expand Up @@ -363,7 +363,7 @@ TEST( testTable, subColumns )
TEST( testTable, variadicTest )
{
{
TableLayout const layoutTest( "Cras egestas ipsum a nisl. Vivamus variu dolor utsisicdis parturient montes, nascetur ridiculus mus. Duis nascetur ridiculus mus",
TableLayout const layoutTest( "Cras egestas ipsum a nisl. Vivamus variu dolor utsisicdis parturient monte",
{
"Rank",
TableLayout::Column()
Expand All @@ -382,24 +382,68 @@ TEST( testTable, variadicTest )
tableData.addRow( "min(local/total)", 1, 2, 3, 4, 5, 6, 7 );
TableTextFormatter log( layoutTest );
EXPECT_EQ( log.toString( tableData ),
"\n--------------------------------------------------------------------------------------------------------------------------------------\n"
"| Cras egestas ipsum a nisl. Vivamus variu dolor utsisicdis parturient montes, nascetur ridiculus mus. Duis nascetur ridiculus mus |\n"
"--------------------------------------------------------------------------------------------------------------------------------------\n"
"| Rank | Nodes | Edge | Faces | Elems |\n"
"--------------------------------------------------------------------------------------------------------------------------------------\n"
"| | Locales | Ghost | | Locales | Ghost | Locales | Ghost |\n"
"--------------------------------------------------------------------------------------------------------------------------------------\n"
"| min(local/total) | 1 | 2 | 3 | 4 | 5 | 6 | 7 |\n"
"| min(local/total) | 1 | 2 | 3 | 4 | 5 | 6 | 7 |\n"
"--------------------------------------------------------------------------------------------------------------------------------------\n"
"\n-------------------------------------------------------------------------------------------------\n"
"| Cras egestas ipsum a nisl. Vivamus variu dolor utsisicdis parturient monte |\n"
"-------------------------------------------------------------------------------------------------\n"
"| Rank | Nodes | Edge | Faces | Elems |\n"
"-------------------------------------------------------------------------------------------------\n"
"| | Locales | Ghost | | Locales | Ghost | Locales | Ghost |\n"
"-------------------------------------------------------------------------------------------------\n"
"| min(local/total) | 1 | 2 | 3 | 4 | 5 | 6 | 7 |\n"
"| min(local/total) | 1 | 2 | 3 | 4 | 5 | 6 | 7 |\n"
"-------------------------------------------------------------------------------------------------\n"
);
}
}


TEST( testTable, maxWidth )
{
{
TableLayout const layoutTest = TableLayout( "Cras egestas ipsum a nisl. Vivamus variu dolor utsisicdis parturient monte, egestas ipsum a nisl",
{
"Rank",
TableLayout::Column()
.setName( "Nodes" )
.addSubColumns( {"Count local active\nelemnt n", "Count ghost elemnt n" } ),
"Vivamus variu dolor utsisicdis",
TableLayout::Column()
.setName( "Faces" )
.addSubColumns( {"Locales", "Ghost" } ),
TableLayout::Column()
.setName( "Elems" )
.addSubColumns( {"Locales", "egestas ipsum a nisl"} ),
} )
.setMaxColumnWidth( 16 );
TableData tableData;
tableData.addRow( "min(local/total)", 1, 2, 3, 4, 5, 6, 7 );
tableData.addRow( "min(local/total)", 1, 2, 3, 4, 5, 6, 7 );
TableTextFormatter log( layoutTest );

EXPECT_EQ( log.toString( tableData ),
"\n---------------------------------------------------------------------------------------------------------------------------------\n"
"| Cras egestas ipsum a nisl. Vivamus variu dolor utsisicdis parturient monte, egestas ipsum a nisl |\n"
"---------------------------------------------------------------------------------------------------------------------------------\n"
"| Rank | Nodes | Vivamus variu | Faces | Elems |\n"
"| | | dolor utsisicdis | | |\n"
"---------------------------------------------------------------------------------------------------------------------------------\n"
"| | Count local | Count ghost | | Locales | Ghost | Locales | egestas ipsum a |\n"
"| | active | elemnt n | | | | | nisl |\n"
"| | elemnt n | | | | | | |\n"
"---------------------------------------------------------------------------------------------------------------------------------\n"
"| min(local/total) | 1 | 2 | 3 | 4 | 5 | 6 | 7 |\n"
"| min(local/total) | 1 | 2 | 3 | 4 | 5 | 6 | 7 |\n"
"---------------------------------------------------------------------------------------------------------------------------------\n"
);
}
}

TEST( testTable, testLineBreak )
{
TableLayout tableLayout( {"Cras egestas", "CoordX", "C", "CoordZ", "Prev\nelement", "Next\nelement"} );
tableLayout.setTitle( "title" ).setMargin( TableLayout::MarginValue::tiny ).enableLineBreak( false );
TableLayout const tableLayout = TableLayout( {"Cras egestas", "CoordX", "C", "CoordZ", "Prev\nelement", "Next\nelement"} )
.setTitle( "title" )
.setMargin( TableLayout::MarginValue::tiny )
.enableLineBreak( false );

TableData tableData;
tableData.addRow( "1", "2", "3.0", 3.0129877, 2.0f, 1 );
Expand Down Expand Up @@ -459,7 +503,6 @@ TEST( testTable, testCellMerging )
tableData.addRow( "Alpha", 1001, 8, "Beta\nwater", "2002\n1.0", CellType::MergeNext );

TableTextFormatter const tableText( tableLayout );
std::cout << tableText.toString( tableData ) << std::endl;
EXPECT_EQ( tableText.toString( tableData ),
"\n-----------------------------------------------------------------------------------------------\n"
"| Cras egestas | CoordX | C | CoordZ | Prev | Next |\n"
Expand Down
Loading
Loading