forked from Alepha/Alepha
Word wrapping implementation.
This was in my scratch notes. I have to get it building again.
This commit is contained in:
66
word_wrap.cpp
Normal file
66
word_wrap.cpp
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
static_assert( __cplusplus > 2020 );
|
||||||
|
|
||||||
|
#include "word_wrap.h"
|
||||||
|
|
||||||
|
namespace Alepha::Cavorite ::detail:: word_wrap
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// Returns the number of chars in the line just written to.
|
||||||
|
std::size_t
|
||||||
|
applyWordToLine( const std::size_t maximumWidth, const std::size_t nextLineOffset, const std::size_t currentLineWidth, std::string &&word, std::string &result )
|
||||||
|
{
|
||||||
|
if( word.empty() ) return currentLineWidth;
|
||||||
|
|
||||||
|
const auto lineWidth= evaluate <=[&]
|
||||||
|
{
|
||||||
|
if( currentLineWidth + word.size() > maximumWidth )
|
||||||
|
{
|
||||||
|
result+= '\n';
|
||||||
|
std::fill_n( back_inserter( result ), ' ', nextLineOffset );
|
||||||
|
return nextLineOffset;
|
||||||
|
}
|
||||||
|
else return currentLineWidth;
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto rv= lineWidth + word.size();
|
||||||
|
result+= std::move( word );
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
exports::wordWrap( const std::string &text, const std::size_t width, const std::size_t nextLineOffset )
|
||||||
|
{
|
||||||
|
auto putWord= [[nodiscard]] [width, nextLineOffset]( std::string &&word, std::string &line, const std::size_t lineLength )
|
||||||
|
{
|
||||||
|
return applyWordToLine( width, nextLineOffset, line.size(), std::move( word ), line );
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string result;
|
||||||
|
std::string word;
|
||||||
|
std::size_t lineLength= 0;
|
||||||
|
for( const char ch: text )
|
||||||
|
{
|
||||||
|
if( ch == '\n' )
|
||||||
|
{
|
||||||
|
std::ignore= putWord( std::move( word ), result, lineLength );
|
||||||
|
word.clear();
|
||||||
|
lineLength= 0;
|
||||||
|
}
|
||||||
|
else if( ch == ' ' )
|
||||||
|
{
|
||||||
|
lineLength= putWord( std::move( word ), result, lineLength );
|
||||||
|
word.clear();
|
||||||
|
if( lineLength < width )
|
||||||
|
{
|
||||||
|
line+= ' ';
|
||||||
|
lineLength++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else word+= ch;
|
||||||
|
}
|
||||||
|
if( not word.empty() ) std::ignore= putWord( std::move( word ), result, lineLength );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
13
word_wrap.h
Normal file
13
word_wrap.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
static_assert( __cplusplus > 2020'00 );
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
namespace Alepha::inline Cavorite ::detail:: word_wrap
|
||||||
|
{
|
||||||
|
inline namespace exports
|
||||||
|
{
|
||||||
|
std::string wordWrap( const std::string &text, std::size_t width, std::size_t nextLineOffset= 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user