20#include <fmt/format.h>
31 aOut->
Print(
"(%ls %s)", aKey.wc_str(), aValue ?
"yes" :
"no" );
60void Prettify( std::string& aSource,
bool aCompactSave )
63 const char quoteChar =
'"';
64 const char indentChar =
'\t';
65 const int indentSize = 1;
69 const int xySpecialCaseColumnLimit = 99;
74 const int consecutiveTokenWrapThreshold = 72;
76 std::string formatted;
77 formatted.reserve( aSource.length() );
79 auto cursor = aSource.begin();
83 char lastNonWhitespace = 0;
85 bool hasInsertedSpace =
false;
86 bool inMultiLineList =
false;
88 bool inShortForm =
false;
89 int shortFormDepth = 0;
91 int backslashCount = 0;
93 auto isWhitespace = [](
const char aChar )
95 return ( aChar ==
' ' || aChar ==
'\t' || aChar ==
'\n' || aChar ==
'\r' );
98 auto nextNonWhitespace =
99 [&]( std::string::iterator aIt )
103 while( seek != aSource.end() && isWhitespace( *seek ) )
106 if( seek == aSource.end() )
113 [&]( std::string::iterator aIt )
117 if( ++seek == aSource.end() || *seek !=
'x' )
120 if( ++seek == aSource.end() || *seek !=
'y' )
123 if( ++seek == aSource.end() || *seek !=
' ' )
130 [&]( std::string::iterator aIt )
135 while( ++seek != aSource.end() && isalpha( *seek ) )
138 return token ==
"font" || token ==
"stroke" || token ==
"fill"
139 || token ==
"offset" || token ==
"rotate" || token ==
"scale";
142 while(
cursor != aSource.end() )
146 if( isWhitespace( *
cursor ) && !inQuote )
148 if( !hasInsertedSpace
150 && lastNonWhitespace !=
'('
154 if( inXY || column < consecutiveTokenWrapThreshold )
158 formatted.push_back(
' ' );
161 else if( inShortForm )
163 formatted.push_back(
' ' );
167 formatted += fmt::format(
"\n{}",
168 std::string( listDepth * indentSize, indentChar ) );
169 column = listDepth * indentSize;
170 inMultiLineList =
true;
173 hasInsertedSpace =
true;
178 hasInsertedSpace =
false;
180 if( *
cursor ==
'(' && !inQuote )
182 bool currentIsXY = isXY(
cursor );
183 bool currentIsShortForm = aCompactSave && isShortForm(
cursor );
185 if( formatted.empty() )
187 formatted.push_back(
'(' );
190 else if( inXY && currentIsXY && column < xySpecialCaseColumnLimit )
196 else if( inShortForm )
203 formatted += fmt::format(
"\n{}(",
204 std::string( listDepth * indentSize, indentChar ) );
205 column = listDepth * indentSize + 1;
210 if( currentIsShortForm )
213 shortFormDepth = listDepth;
218 else if( *
cursor ==
')' && !inQuote )
225 formatted.push_back(
')' );
228 else if( lastNonWhitespace ==
')' || inMultiLineList )
230 formatted += fmt::format(
"\n{})",
231 std::string( listDepth * indentSize, indentChar ) );
232 column = listDepth * indentSize + 1;
233 inMultiLineList =
false;
237 formatted.push_back(
')' );
241 if( shortFormDepth == listDepth )
254 else if( *
cursor == quoteChar && ( backslashCount & 1 ) == 0 )
260 formatted.push_back( *
cursor );
264 lastNonWhitespace = *
cursor;
273 aSource = std::move( formatted );
wxString AsString() const