27#include <fmt/format.h>
37 aOut->
Print(
"(%ls %s)", aKey.wc_str(), aValue ?
"yes" :
"no" );
42 if( aValue.has_value() )
45 aOut->
Print(
"(%ls none)", aKey.wc_str() );
57 aOut.
Print(
"(data" );
59 const wxString out = wxBase64Encode( aStream.GetBufferStart(), aStream.GetBufferSize() );
67 while( first < out.Length() )
97void Prettify( std::string& aSource,
bool aCompactSave )
100 const char quoteChar =
'"';
101 const char indentChar =
'\t';
102 const int indentSize = 1;
106 const int xySpecialCaseColumnLimit = 99;
111 const int consecutiveTokenWrapThreshold = 72;
113 std::string formatted;
114 formatted.reserve( aSource.length() );
116 auto cursor = aSource.begin();
120 char lastNonWhitespace = 0;
121 bool inQuote =
false;
122 bool hasInsertedSpace =
false;
123 bool inMultiLineList =
false;
125 bool inShortForm =
false;
126 int shortFormDepth = 0;
128 int backslashCount = 0;
130 auto isWhitespace = [](
const char aChar )
132 return ( aChar ==
' ' || aChar ==
'\t' || aChar ==
'\n' || aChar ==
'\r' );
135 auto nextNonWhitespace =
136 [&]( std::string::iterator aIt )
140 while( seek != aSource.end() && isWhitespace( *seek ) )
143 if( seek == aSource.end() )
150 [&]( std::string::iterator aIt )
154 if( ++seek == aSource.end() || *seek !=
'x' )
157 if( ++seek == aSource.end() || *seek !=
'y' )
160 if( ++seek == aSource.end() || *seek !=
' ' )
167 [&]( std::string::iterator aIt )
172 while( ++seek != aSource.end() && isalpha( *seek ) )
175 return token ==
"font" || token ==
"stroke" || token ==
"fill" || token ==
"teardrop"
176 || token ==
"offset" || token ==
"rotate" || token ==
"scale";
179 while(
cursor != aSource.end() )
183 if( isWhitespace( *
cursor ) && !inQuote )
185 if( !hasInsertedSpace
187 && lastNonWhitespace !=
'('
191 if( inXY || column < consecutiveTokenWrapThreshold )
195 formatted.push_back(
' ' );
198 else if( inShortForm )
200 formatted.push_back(
' ' );
204 formatted += fmt::format(
"\n{}",
205 std::string( listDepth * indentSize, indentChar ) );
206 column = listDepth * indentSize;
207 inMultiLineList =
true;
210 hasInsertedSpace =
true;
215 hasInsertedSpace =
false;
217 if( *
cursor ==
'(' && !inQuote )
219 bool currentIsXY = isXY(
cursor );
220 bool currentIsShortForm = aCompactSave && isShortForm(
cursor );
222 if( formatted.empty() )
224 formatted.push_back(
'(' );
227 else if( inXY && currentIsXY && column < xySpecialCaseColumnLimit )
233 else if( inShortForm )
240 formatted += fmt::format(
"\n{}(",
241 std::string( listDepth * indentSize, indentChar ) );
242 column = listDepth * indentSize + 1;
247 if( currentIsShortForm )
250 shortFormDepth = listDepth;
255 else if( *
cursor ==
')' && !inQuote )
262 formatted.push_back(
')' );
265 else if( lastNonWhitespace ==
')' || inMultiLineList )
267 formatted += fmt::format(
"\n{})",
268 std::string( listDepth * indentSize, indentChar ) );
269 column = listDepth * indentSize + 1;
270 inMultiLineList =
false;
274 formatted.push_back(
')' );
278 if( shortFormDepth == listDepth )
291 else if( *
cursor == quoteChar && ( backslashCount & 1 ) == 0 )
297 formatted.push_back( *
cursor );
301 lastNonWhitespace = *
cursor;
310 aSource = std::move( formatted );
wxString AsString() const
#define MIME_BASE64_LENGTH
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.