GnuCashew ~ Web Application compatible with GnuCash sql data files.
GCW
Loading...
Searching...
No Matches
Core.cpp
Go to the documentation of this file.
1#line 2 "src/Glb/Core.cpp"
2
3#include <sstream>
4#include <algorithm>
5#include <dirent.h>
6#include <cmath>
7#include <fstream>
8#include <iostream>
9#include <regex>
10#include <sys/stat.h>
11#include <unistd.h>
12#include <locale.h>
13
14
15#include <Wt/WModelIndex.h>
16#include <Wt/WDate.h>
17#include <Wt/WDateTime.h>
18#include <Wt/WLocalDateTime.h>
19
20#include "../3rd/guid.hpp"
21#include "gcwglobal.h"
22#include "Core.h"
23
24static
25std::vector<std::string> &
26split( const std::string & s, char delim, std::vector<std::string> & elems )
27{
28 std::stringstream ss( s );
29 std::string item;
30 while( std::getline( ss, item, delim ) )
31 {
32 elems.push_back( item );
33 }
34 return elems;
35}
36
37
38std::vector<std::string>
40split( const std::string & s, char delim )
41{
42 std::vector<std::string> elems;
43 ::split( s, delim, elems );
44 return elems;
45}
46
47const char* GCW::Core::trim_ws = " \t\n\r\f\v";
48
49// trim from end of string (right)
50std::string &
52rtrim( std::string & s, const char* t )
53{
54 s.erase( s.find_last_not_of(t) + 1 );
55 return s;
56}
57
58// trim from beginning of string (left)
59std::string &
61ltrim( std::string & s, const char* t )
62{
63 s.erase( 0, s.find_first_not_of(t) );
64 return s;
65}
66
67// trim from both ends of string (left & right)
68std::string &
70trim( std::string & s, const char* t )
71{
72 return ltrim( rtrim(s, t), t );
73}
74
75std::string
77toupper( const std::string & s )
78{
79 std::string retVal = s;
80
81 std::transform( retVal.begin(), retVal.end(), retVal.begin(), ::toupper );
82
83 return retVal;
84}
85
86std::string
88tolower( const std::string & s )
89{
90 std::string retVal = s;
91
92 std::transform( retVal.begin(), retVal.end(), retVal.begin(), ::tolower );
93
94 return retVal;
95}
96
97/*
98** This will iterate a single a WTreeView and fill
99** a vector of every node which is the .last-expanded.
100** node of every branch.
101**
102*/
103static
104bool
106{
107#ifdef NEVER
108 /*
109 ** If this _parent node is not expanded, then we're basically done.
110 **
111 */
112 if( !view()-> isExpanded( _parent ) )
113 return false;
114
115 /*
116 ** This _parent node is expanded, so loop through all the
117 ** child nodes checking if any of them are expanded.
118 **
119 */
120 bool expanded = false;
121 for( int row=0; row< view()-> model()-> rowCount( _parent ); row++ )
122 expanded |= iterate( _jary, view()-> model()-> index( row, 0, _parent ) );
123
124 /*
125 ** None of the child nodes are expanded, so record this _parent
126 ** node as the 'last' node in the tree
127 **
128 */
129 if( !expanded )
130 {
131 /*
132 ** The true root node is not associated with an actual account,
133 ** it is simply the invisibleRoot of the tree itself, and only
134 ** contains the set of first-root nodes that actually get
135 ** displayed. So, there is no User data in this one, don't record it.
136 **
137 */
138 auto accountGuid = Wt::asString( _parent.data( Wt::ItemDataRole::User ) );
139 if( accountGuid != "" )
140 _jary.push_back( accountGuid );
141
142 } // endif( !expanded )
143
144 /*
145 ** Something is expanded. Either we are expanded, or
146 ** one of the sub-nodes are expanded, so return that 'someone' is
147 ** expanded.
148 **
149 */
150#endif
151
152 return true;
153
154} // endvoid iterate( Wt::WModelIndex _index ) const
155
158toJson( Wt::WTreeView * _view )
159{
160 Wt::Json::Object jobj;
161
162#ifdef NEVER
163 jobj["selected"] = Wt::WString( selectedAccount() );
164
165 for( int col=0; col< 7; col++ )
166 jobj[ Wt::WString("cw{1}").arg( col ).toUTF8() ] = Wt::WString( view()-> columnWidth( col ).cssText() );
167
168 Wt::Json::Array jary;
169 iterate( jary );
170 jobj["expanded"] = jary;
171
172#endif
173
174 return jobj;
175
176}
177
178auto
180hexDump( const std::string & string, int start, int end )-> std::string
181{
182 std::stringstream rv;
183
184 char buffer[100];
185 for( unsigned int i=0; i<string.length(); i += 16 )
186 {
187 std::string adrLine;
188 std::string hexLine;
189 std::string ascLine;
190
191 snprintf( buffer, sizeof(buffer), "%04x: ", i );
192 adrLine = std::string(buffer);
193
194 for( int j=0; j<16; j++ )
195 {
196 if( i+j < string.length() )
197 {
198 snprintf( buffer, sizeof(buffer), "%02x ", (string.at(i+j) & 0xff) );
199 hexLine += std::string(buffer);
200
201 if( std::isprint( string.at(i+j) ) )
202 {
203 snprintf( buffer, sizeof(buffer), "%c", string.at(i+j) );
204 ascLine += std::string(buffer);
205 }
206 else
207 {
208 ascLine += ".";
209 }
210 }
211 else
212 {
213 hexLine += "xx ";
214 ascLine += ".";
215 }
216
217 } // endfor( int j=0; j<16; j++ )
218
219 bool showline = false;
220 if( start == -1 && end == -1 )
221 showline = true;
222
223 else
224 if( (start > -1 && i >= start)
225 && (end > -1 && i <= end)
226 )
227 showline = true;
228
229 if( showline )
230 rv
231 << adrLine
232 << hexLine
233 << ascLine
234 << std::endl
235 ;
236
237 } // endfor( int i=0; i<string.length(); i += 16 )
238
239 return rv.str();
240
241} // endstd::string GCW::hexDump( const std::string & string )
242
243auto
245newGuid()-> std::string
246{
247 std::string g = xg::newGuid();
248
249 std::string retVal;
250 for( auto c : g )
251 if( c != '-' )
252 retVal.push_back( c );
253
254 return retVal;
255
256} // endnewGuid()-> std::string
257
258
259/*
260** note about this date time:
261** WLocalDateTime will produce the local-time
262** WDateTime will product a GMT time
263**
264** This was tested, and gnucash seems to want the GMT time-stamp
265** rather than the local time (makes sense really)
266**
267*/
268auto
271{
272 return
273// Wt::WLocalDateTime::currentDateTime().toString( GCW_DATE_FORMAT ).toUTF8();
275
276} // endcurrentDateTime()-> std::string
277
278auto
279dateStorageString( const Wt::WDate * _date )-> std::string
280{
281 return
282 _date-> toString( GCW_DATE_FORMAT_STORAGE ).toUTF8();
283
284}
285
286auto
288dateTimeStorageString( const Wt::WDateTime & _dateTime )-> std::string
289{
290 return
291 _dateTime.toString( GCW_DATETIME_FORMAT_STORAGE ).toUTF8();
292
293} // enddateTimeStorageString( const Wt::WDateTime & _dateTime )-> std::string
294
295/*
296**
297*/
298auto
300currentDateTimeStorageString()-> std::string
301{
302 return
304
305} // endcurrentDateTime()-> std::string
306
307auto
309dateTimeDisplayString( const Wt::WDateTime & _dateTime )-> std::string
310{
311 return
312 _dateTime.toString( GCW_DATE_FORMAT_DISPLAY ).toUTF8();
313
314} // enddateTimeDisplayString( const Wt::WDateTime & _dateTime )-> std::string
315
316/*
317**
318*/
319auto
321currentDateTimeDisplayString()-> std::string
322{
323 return
325
326} // endcurrentDateTime()-> std::string
327
328
329/*!
330** \brief Make File Name
331**
332** This will take an odrinary string and remove anything that is not
333** acceptable in a valid file-name. The intended use for this function
334** is to take something like a person's name or a company name and remove
335** and replace anything in those strings that might not produce a
336** disk-compatible file-name. This includes things like ':' colons and
337** '/' forward and back slashes and anything else that looks just
338** plain weird.
339**
340*/
341auto
343makeFileName( const std::string & value )-> std::string
344{
345 std::string retVal;
346
347 /*
348 ** each character is examined individually
349 */
350 for( auto ch : value )
351 {
352 /*!
353 ** All non-printable characters are simply discarded
354 */
355 if( isprint( ch ) )
356 {
357 /*!
358 ** The routine performs simple character-by-character
359 ** substitution. In some cases the substitution is 'nothing',
360 ** like in the case of '.' (period) and ',' (comma)
361 ** other characters are simply replaced with suitable
362 ** replacements that have similar appearance but are
363 ** not likely to mess up a file-name on disk. Odd punctuation
364 ** characters are removed since this function is a string-to-filename
365 ** conversion, therefore absolute punctuation has less meaning
366 ** in a file-name than it does in the database.
367 **
368 ** \par Examples
369 ** \code
370 ** std::cout << makeFileName("LORIMARK SOLUTIONS, LLC.") << std::endl;
371 ** std::cout << makeFileName("Bridge On The River Kwai") << std::endl;
372 ** std::cout << makeFileName("He said \"no\", She said \"yes\"") << std::endl;
373 ** std::cout << makeFileName("Chicago <south> Storage_Facility") << std::endl;
374 ** std::cout << makeFileName("Boat (float) :/: or Ship Sink") << std::endl;
375 **
376 ** result:
377 ** LORIMARK SOLUTIONS LLC
378 ** Bridge On The River Kwai
379 ** He said 'no' She said 'yes'
380 ** Chicago (south) Storage_Facility
381 ** Boat (float) -- or Ship Sink
382 ** \endcode
383 **
384 */
385 switch( ch )
386 {
387 case '.': break; /// '.' period -> nothing
388 case ',': break; /// ',' comma -> nothing
389 case '<': retVal += '('; break; /// '<' less than -> open paren
390 case '>': retVal += ')'; break; /// '>' greater than -> close paren
391 case ':': retVal += '-'; break; /// ':' colon -> dash ~ sometimes works, but is actually NTFS Alternate Data Streams
392 case '"': retVal += '\''; break; /// '"' double quote -> single quote
393 case '/': retVal += '-'; break; /// '/' forward slash -> dash
394 case '\\': retVal += '-'; break; /// '\\'backslash -> dash
395 case '|': break; /// '|' vertical bar or pipe -> nothing
396 case '?': break; /// '?' question mark -> nothing
397 case '*': break; /// '*' asterisk -> nothing
398 default: retVal += ch;
399
400 } // endswitch( ch )
401
402 } // endif( isprint( ch ) )
403
404 } // endfor( auto ch : value )
405
406 return retVal;
407
408} // endmakeFileName( const std::string & value )-> std::string
409
410
411auto
413system_command( const std::string & cmd, bool show )-> int
414{
415 int result = system( cmd.c_str() );
416
417 if( show )
418 std::cout << __FILE__ << ":" << __LINE__ << " " << cmd << std::endl;
419
420
421
422 if( result != 0 )
423 {
424 std::cout << __FILE__ << ":" << __LINE__ << " "
425 << result << " "
426 << cmd
427 << std::endl
428 ;
429 }
430
431 return result;
432
433} // endsystem_command( const std::string & cmd, bool show )-> auto
434
435/*
436** This function produces a case-insensitive sort of
437** the files and folders in a directory. The file
438** items are converted to upper-case so that case
439** becomes ignored, and then the function uses the
440** strverscmp function which causes jan-1, jan-2,
441** jan-10 to be sorted in that order, which can
442** make a little more logical sense when looking at
443** folder names.
444**
445** https://linux.die.net/man/3/scandir
446**
447*/
448static auto
449ialphasort( const struct dirent **a, const struct dirent **b )-> int
450{
451 std::string ua = (*a)-> d_name;
452 std::transform( ua.begin(), ua.end(), ua.begin(), ::toupper );
453
454 std::string ub = (*b)-> d_name;
455 std::transform( ub.begin(), ub.end(), ub.begin(), ::toupper );
456
457 return strverscmp( ua.c_str(), ub.c_str() );
458
459} // endialphasort( const struct dirent **a, const struct dirent **b )-> int
460
461
462auto
464fileList( const std::string & folder )-> std::vector<std::string>
465{
466 std::vector<std::string> retVal;
467
468 /*
469 ** pull up all the items in this folder
470 **
471 */
472 struct dirent ** namelist;
473 int n = scandir( folder.c_str(), &namelist, 0, ialphasort );
474
475 if( n > 0 )
476 {
477 /*
478 ** loop through all the items in the folder
479 **
480 */
481 for( int i=0; i< n; i++ )
482 {
483 /*
484 ** pull the folder name from the items list
485 ** and free the original source
486 **
487 */
488 std::string fileName( namelist[i]-> d_name );
489 free( namelist[i] );
490
491 /*
492 ** single '.' dot items are ignored totally
493 */
494 if( fileName == "." )
495 continue;
496
497 /*
498 ** make something that represents the full file path
499 **
500 */
501 std::string filePath( folder + "/" + fileName );
502
503 /*
504 ** the 'fileStat' value contains the following flags
505 ** and status codes. grab the filestat based on the 'stat'
506 ** function call so that the file can be parsed.
507 **
508 ** st_atime
509 ** st_ctime
510 ** st_gid
511 ** st_ino
512 ** st_mtime·
513 ** st_nlink·
514 ** st_mode·
515 ** st_size·
516 ** st_uid·
517 **
518 */
519 struct stat fileStat;
520 int result = stat( filePath.c_str(), &fileStat );
521
522 /*
523 ** there should always be a result on pulling the
524 ** file stat.
525 */
526 if( result == 0 )
527 {
528 retVal.push_back( fileName );
529 }
530
531 } // endfor( int i=0; i< n; i++ )
532
533 free( namelist );
534
535 } // endif( n > 0 )
536
537 return retVal;
538
539} // endfileList( const std::string & folder )-> std::vector<std::string>
540
541
542auto
544findFiles( const std::string & folder, const std::string & match )-> std::vector<std::string>
545{
546 std::vector<std::string> retVal;
547
548 for( auto fileName : fileList( folder ) )
549 if( fileName.find(match) != std::string::npos )
550 retVal.push_back( fileName );
551
552 return retVal;
553
554} // endfindFiles( const std::string & folder, const std::string & match )-> std::vector<std::string>
555
556
557auto
559fileExists( const std::string & fileName )-> bool
560{
561 std::ifstream f( fileName.c_str() );
562 return f.good();
563
564} // endfileExists( const std::string & fileName )-> bool
565
566
567auto
569stoi( const std::string & value )-> int
570{
571 try
572 {
573 int id = std::stoi(value);
574 return id;
575 }
576 catch(...)
577 {
578// std::cout << __FILE__ << ":" << __LINE__ << " " << __FUNCTION__ << "::value='" << value << "'" << std::endl;
579 }
580
581 return 0;
582
583} // endstoi( const std::string & value )-> int
584
585
586auto
588itos( int value )-> std::string
589{
590 return
591 Wt::WString("{1}")
592 .arg( value )
593 .toUTF8()
594 ;
595
596} // enditos( int value )-> std::string
597
598
599auto
601stof( const std::string & value )-> double
602{
603 try
604 {
605 std::string v;
606 for( auto c : value )
607 if( isdigit(c) || c == '.' || c == '-' )
608 v.push_back(c);
609
610 if( v.length() > 0 )
611 {
612 double id = std::stod(v);
613 return id;
614 }
615
616 }
617 catch(...)
618 {
619 }
620
621 return 0;
622
623} // endstof( const std::string & value )-> double
624
625
626auto
628ftos( double value, int decimals )-> std::string
629{
630 char buffer[256];
631
632 snprintf( buffer, sizeof(buffer), "%.*f", decimals, value );
633
634 return std::string(buffer);
635
636} // endftos( double value, int decimals )-> std::string
637
638
639auto
641ftos( double value, const std::string & suffix, int decimals )-> std::string
642{
643 char buffer[256];
644
645 snprintf( buffer, sizeof(buffer), "%.*f%s", decimals, value, suffix.data() );
646
647 return std::string(buffer);
648
649} // endftos( double value, const std::string & suffix, int decimals )-> std::string
650
651
652auto
654ftos( const std::string & prefix, double value, int decimals )-> std::string
655{
656 char buffer[256];
657
658 snprintf( buffer, sizeof(buffer), "%s%.*f", prefix.data(), decimals, value );
659
660 return std::string(buffer);
661
662} // endftos( const std::string & prefix, double value, int decimals )-> std::string
663
664
665auto
667ftom( double value, int decimals )-> std::string
668{
669 char buffer[256];
670
671 std::setlocale( LC_ALL, "" );
672 snprintf( buffer, sizeof(buffer), "%'.*f", decimals, value );
673
674 return std::string(buffer);
675
676} // endftom( double value, int decimals )-> std::string
677
678auto
680ftom( const std::string & prefix, double value, int decimals )-> std::string
681{
682 char buffer[256];
683
684 std::setlocale( LC_ALL, "" );
685 snprintf( buffer, sizeof(buffer), "%s%'.*f", prefix.data(), decimals, value );
686
687 return std::string(buffer);
688
689} // endftom( const std::string & prefix, double value, int decimals )-> std::string
690
691
692auto
694ends_with( const std::string & value, const std::string & ending )-> bool
695{
696 if( ending.size() > value.size() )
697 return false;
698
699 return std::equal( ending.rbegin(), ending.rend(), value.rbegin() );
700
701} // endends_with( const std::string & value, const std::string & ending )-> bool
702
703
704auto
706append( const std::string & s, const std::string & append, const std::string & separator )-> std::string
707{
708 std::string retVal = s;
709
710 /*
711 ** only put the separator on if there is already data, and...
712 */
713 if( retVal != "" )
714 {
715 /*
716 ** ...and if the end of the string doesn't already have
717 ** the separator on it
718 **
719 */
720 if( !ends_with( retVal, separator ) )
721 {
722 retVal += separator;
723 }
724
725 } // endif( retVal != "" )
726
727 retVal += append;
728
729 return retVal;
730
731} //endappend( const std::string & s, const std::string & append, const std::string & separator )-> std::string
732
733
734auto
736prepend( const std::string & s, int length, char pad )-> std::string
737{
738 std::string retVal = s;
739
740 while( retVal.length() < length )
741 retVal = pad + retVal;
742
743 return retVal;
744
745} // endprepend( const std::string & s, int length, char pad )-> std::string
746
747
748auto
750ucase( const std::string & value )-> std::string
751{
752 std::string retVal = value;
753 std::transform( retVal.begin(), retVal.end(), retVal.begin(), ::toupper );
754 return retVal;
755
756} // enducase( const std::string & value )-> std::string
757
758
759auto
761lcase( const std::string & value )-> std::string
762{
763 std::string retVal = value;
764 std::transform( retVal.begin(), retVal.end(), retVal.begin(), ::tolower );
765 return retVal;
766
767} // endlcase( const std::string & value )-> std::string
768
769
770auto
772roundUp( float value )-> int
773{
774 int v = value;
775 if( v < value )
776 v++;
777
778 return v;
779
780} // endroundUp( float value )-> int
781
782
783auto
785roundDown( float value )-> int
786{
787 return value;
788
789} // endroundDown( float value )-> int
790
791
792auto
794roundCurrency( float value )-> float
795{
796 float retVal = value * 100;
797
798 retVal = round(retVal);
799
800 retVal /= 100;
801
802 return retVal;
803
804} // endroundCurrency( float value )-> float
805
806
807auto
809replace( const std::string & string, const std::string & before, const std::string & after )-> std::string
810{
811 std::string retVal = string;
812
813 size_t start_pos = 0;
814 while( (start_pos = retVal.find( before, start_pos )) != std::string::npos )
815 {
816 retVal.replace( start_pos, before.length(), after );
817 start_pos += after.length(); // Handles case where 'to' is a substring of 'from'
818 }
819
820 return retVal;
821
822} // endreplace( const std::string & string, const std::string & before, const std::string & after )-> std::string
823
824
825enum class CSVState
826{
830};
831
832
833auto
835readCSVRow( const std::string & row )-> std::vector<std::string>
836{
838 std::vector<std::string> fields {""};
839 size_t i = 0; // index of the current field
840 for( char c : row )
841 {
842 switch( state )
843 {
845 {
846 switch( c )
847 {
848 case ',': // end of field
849 {
850 fields.push_back("");
851 i++;
852 break;
853 }
854
855 case '"':
856 {
857 state = CSVState::QuotedField;
858 break;
859 }
860
861 default:
862 {
863 fields[i].push_back(c);
864 break;
865 }
866
867 } // endswitch( c )
868
869 break;
870
871 } // endcase CSVState::UnquotedField:
872
874 {
875 switch( c )
876 {
877 case '"':
878 {
879 state = CSVState::QuotedQuote;
880 break;
881 }
882
883 default:
884 {
885 fields[i].push_back(c);
886 break;
887 }
888
889 } // endswitch( c )
890
891 break;
892
893 } // endcase CSVState::QuotedField:
894
896 {
897 switch( c )
898 {
899 case ',': // , after closing quote
900 {
901 fields.push_back("");
902 i++;
904 break;
905 }
906
907 case '"': // "" -> "
908 {
909 fields[i].push_back('"');
910 state = CSVState::QuotedField;
911 break;
912 }
913
914 default: // end of quote
915 {
917 break;
918 }
919
920 } // endswitch( c )
921
922 break;
923
924 } // endcase CSVState::QuotedQuote:
925
926 } // endswitch( state )
927
928 } // endfor( char c : row )
929
930 return fields;
931
932} // endreadCSVRow( const std::string & row )-> std::vector<std::string>
933
934
935auto
937feq( double a, double b, double epsilon, bool trace )-> bool
938{
939 bool retVal = fabs( a - b ) < epsilon;
940
941 if( trace )
942 std::cout << __FILE__ << ":" << __LINE__
943 << " retv:" << std::fixed << retVal
944 << " eps:" << std::fixed << epsilon
945 << " fabs:" << std::fixed << fabs( a - b )
946 << " a:" << std::fixed << a
947 << " b:" << std::fixed << b
948 << std::endl
949 ;
950
951 return retVal;
952
953} // endfeq( double a, double b, double epsilon, bool trace )-> bool
954
955/*
956** this will strip the leading and trailing <div> from a template html stream.
957**
958*/
959auto
961to_string( Wt::WTemplate & templt )-> std::string
962{
963 std::string retVal;
964
965 std::stringstream ss;
966 templt.htmlText( ss );
967
968 std::string junk;
969 getline( ss, junk );
970
971 while( !ss.eof() )
972 {
973 std::string line;
974 getline( ss, line );
975
976 if( !ss.eof() )
977 retVal += line;
978
979 }
980
981 return retVal;
982
983} // endWtx::to_string( Wt::WTemplate & templt )-> std::string
984
985
986auto
988to_string( Wt::WTemplate * templt )-> std::string
989{
990 return to_string( *templt );
991
992} // endto_string( Wt::WTemplate * templt )-> std::string
993
994auto
996to_htmlfile( Wt::WTemplate & templt, const std::string & folderName, const std::string & fileName )-> bool
997{
998 std::ofstream ofs( folderName + fileName, std::ofstream::out );
999 ofs << to_string( templt );
1000 return true;
1001
1002} // endto_htmlfile( Wt::WTemplate & templt, const std::string & folderName, const std::string & fileName )-> bool
1003
1004
1005auto
1007to_htmlfile( Wt::WTemplate * templt, const std::string & folderName, const std::string & fileName )-> bool
1008{
1009 to_htmlfile( *templt, folderName, fileName );
1010 return true;
1011
1012} // endto_htmlfile( Wt::WTemplate * templt, const std::string & folderName, const std::string & fileName )-> bool
1013
1014
1016{
1017// dec hex sym html utf8 pdf description
1018 { /* 0 00 */ "NUL", nullptr, nullptr, nullptr, "Null char" },
1019 { /* 1 01 */ "SOH", nullptr, nullptr, nullptr, "Start of Heading" },
1020 { /* 2 02 */ "STX", nullptr, nullptr, nullptr, "Start of Text" },
1021 { /* 3 03 */ "ETX", nullptr, nullptr, nullptr, "End of Text" },
1022 { /* 4 04 */ "EOT", nullptr, nullptr, nullptr, "End of Transmission" },
1023 { /* 5 05 */ "ENQ", nullptr, nullptr, nullptr, "Enquiry" },
1024 { /* 6 06 */ "ACK", nullptr, nullptr, nullptr, "Acknowledgment" },
1025 { /* 7 07 */ "BEL", nullptr, nullptr, nullptr, "Bell" },
1026 { /* 8 08 */ "BS", nullptr, nullptr, nullptr, "Back Space" },
1027 { /* 9 09 */ "HT", nullptr, nullptr, nullptr, "Horizontal Tab" },
1028 { /* 10 0A */ "LF", "<br />", nullptr, nullptr, "Line Feed" },
1029 { /* 11 0B */ "VT", nullptr, nullptr, nullptr, "Vertical Tab" },
1030 { /* 12 0C */ "FF", nullptr, nullptr, nullptr, "Form Feed" },
1031 { /* 13 0D */ "CR", nullptr, nullptr, nullptr, "Carriage Return" },
1032 { /* 14 0E */ "SO", nullptr, nullptr, nullptr, "Shift Out / X-On" },
1033 { /* 15 0F */ "SI", nullptr, nullptr, nullptr, "Shift In / X-Off" },
1034 { /* 16 10 */ "DLE", nullptr, nullptr, nullptr, "Data Line Escape" },
1035 { /* 17 11 */ "DC1", nullptr, nullptr, nullptr, "Device Control 1 (oft. XON)" },
1036 { /* 18 12 */ "DC2", nullptr, nullptr, nullptr, "Device Control 2" },
1037 { /* 19 13 */ "DC3", nullptr, nullptr, nullptr, "Device Control 3 (oft. XOFF)" },
1038 { /* 20 14 */ "DC4", nullptr, nullptr, nullptr, "Device Control 4" },
1039 { /* 21 15 */ "NAK", nullptr, nullptr, nullptr, "Negative Acknowledgement" },
1040 { /* 22 16 */ "SYN", nullptr, nullptr, nullptr, "Synchronous Idle" },
1041 { /* 23 17 */ "ETB", nullptr, nullptr, nullptr, "End of Transmit Block" },
1042 { /* 24 18 */ "CAN", nullptr, nullptr, nullptr, "Cancel" },
1043 { /* 25 19 */ "EM", nullptr, nullptr, nullptr, "End of Medium" },
1044 { /* 26 1A */ "SUB", nullptr, nullptr, nullptr, "Substitute" },
1045 { /* 27 1B */ "ESC", nullptr, nullptr, nullptr, "Escape" },
1046 { /* 28 1C */ "FS", nullptr, nullptr, nullptr, "File Separator" },
1047 { /* 29 1D */ "GS", nullptr, nullptr, nullptr, "Group Separator" },
1048 { /* 30 1E */ "RS", nullptr, nullptr, nullptr, "Record Separator" },
1049 { /* 31 1F */ "US", nullptr, nullptr, nullptr, "Unit Separator" },
1050 { /* 32 20 */ " ", nullptr, nullptr, nullptr, "Space" },
1051 { /* 33 21 */ "!", nullptr, nullptr, nullptr, "Exclamation mark" },
1052 { /* 34 22 */ "\"", "&quot;", nullptr, nullptr, "Double quotes (or speech marks)" },
1053 { /* 35 23 */ "#", nullptr, nullptr, nullptr, "Number" },
1054 { /* 36 24 */ "$", nullptr, nullptr, nullptr, "Dollar" },
1055 { /* 37 25 */ "%", nullptr, nullptr, nullptr, "Procenttecken" },
1056 { /* 38 26 */ "&", "&amp;", nullptr, nullptr, "Ampersand" },
1057 { /* 39 27 */ "'", nullptr, nullptr, nullptr, "Single quote" },
1058 { /* 40 28 */ "(", nullptr, nullptr, nullptr, "Open parenthesis (or open bracket)" },
1059 { /* 41 29 */ ")", nullptr, nullptr, nullptr, "Close parenthesis (or close bracket)" },
1060 { /* 42 2A */ "*", nullptr, nullptr, nullptr, "Asterisk" },
1061 { /* 43 2B */ "+", nullptr, nullptr, nullptr, "Plus" },
1062 { /* 44 2C */ ",", nullptr, nullptr, nullptr, "Comma" },
1063 { /* 45 2D */ "-", nullptr, nullptr, nullptr, "Hyphen" },
1064 { /* 46 2E */ ".", nullptr, nullptr, nullptr, "Period, dot or full stop" },
1065 { /* 47 2F */ "/", nullptr, nullptr, nullptr, "Slash or divide" },
1066 { /* 48 30 */ "0", nullptr, nullptr, nullptr, "Zero" },
1067 { /* 49 31 */ "1", nullptr, nullptr, nullptr, "One" },
1068 { /* 50 32 */ "2", nullptr, nullptr, nullptr, "Two" },
1069 { /* 51 33 */ "3", nullptr, nullptr, nullptr, "Three" },
1070 { /* 52 34 */ "4", nullptr, nullptr, nullptr, "Four" },
1071 { /* 53 35 */ "5", nullptr, nullptr, nullptr, "Five" },
1072 { /* 54 36 */ "6", nullptr, nullptr, nullptr, "Six" },
1073 { /* 55 37 */ "7", nullptr, nullptr, nullptr, "Seven" },
1074 { /* 56 38 */ "8", nullptr, nullptr, nullptr, "Eight" },
1075 { /* 57 39 */ "9", nullptr, nullptr, nullptr, "Nine" },
1076 { /* 58 3A */ ":", nullptr, nullptr, nullptr, "Colon" },
1077 { /* 59 3B */ ";", nullptr, nullptr, nullptr, "Semicolon" },
1078 { /* 60 3C */ "<", "&lt;", nullptr, nullptr, "Less than (or open angled bracket)" },
1079 { /* 61 3D */ "=", nullptr, nullptr, nullptr, "Equals" },
1080 { /* 62 3E */ ">", "&gt;", nullptr, nullptr, "Greater than (or close angled bracket)" },
1081 { /* 63 3F */ "?", nullptr, nullptr, nullptr, "Question mark" },
1082 { /* 64 40 */ "@", nullptr, nullptr, nullptr, "At symbol" },
1083 { /* 65 41 */ "A", nullptr, nullptr, nullptr, "Uppercase A" },
1084 { /* 66 42 */ "B", nullptr, nullptr, nullptr, "Uppercase B" },
1085 { /* 67 43 */ "C", nullptr, nullptr, nullptr, "Uppercase C" },
1086 { /* 68 44 */ "D", nullptr, nullptr, nullptr, "Uppercase D" },
1087 { /* 69 45 */ "E", nullptr, nullptr, nullptr, "Uppercase E" },
1088 { /* 70 46 */ "F", nullptr, nullptr, nullptr, "Uppercase F" },
1089 { /* 71 47 */ "G", nullptr, nullptr, nullptr, "Uppercase G" },
1090 { /* 72 48 */ "H", nullptr, nullptr, nullptr, "Uppercase H" },
1091 { /* 73 49 */ "I", nullptr, nullptr, nullptr, "Uppercase I" },
1092 { /* 74 4A */ "J", nullptr, nullptr, nullptr, "Uppercase J" },
1093 { /* 75 4B */ "K", nullptr, nullptr, nullptr, "Uppercase K" },
1094 { /* 76 4C */ "L", nullptr, nullptr, nullptr, "Uppercase L" },
1095 { /* 77 4D */ "M", nullptr, nullptr, nullptr, "Uppercase M" },
1096 { /* 78 4E */ "N", nullptr, nullptr, nullptr, "Uppercase N" },
1097 { /* 79 4F */ "O", nullptr, nullptr, nullptr, "Uppercase O" },
1098 { /* 80 50 */ "P", nullptr, nullptr, nullptr, "Uppercase P" },
1099 { /* 81 51 */ "Q", nullptr, nullptr, nullptr, "Uppercase Q" },
1100 { /* 82 52 */ "R", nullptr, nullptr, nullptr, "Uppercase R" },
1101 { /* 83 53 */ "S", nullptr, nullptr, nullptr, "Uppercase S" },
1102 { /* 84 54 */ "T", nullptr, nullptr, nullptr, "Uppercase T" },
1103 { /* 85 55 */ "U", nullptr, nullptr, nullptr, "Uppercase U" },
1104 { /* 86 56 */ "V", nullptr, nullptr, nullptr, "Uppercase V" },
1105 { /* 87 57 */ "W", nullptr, nullptr, nullptr, "Uppercase W" },
1106 { /* 88 58 */ "X", nullptr, nullptr, nullptr, "Uppercase X" },
1107 { /* 89 59 */ "Y", nullptr, nullptr, nullptr, "Uppercase Y" },
1108 { /* 90 5A */ "Z", nullptr, nullptr, nullptr, "Uppercase Z" },
1109 { /* 91 5B */ "[", nullptr, nullptr, nullptr, "Opening bracket" },
1110 { /* 92 5C */ "\\", nullptr, nullptr, nullptr, "Backslash" },
1111 { /* 93 5D */ "]", nullptr, nullptr, nullptr, "Closing bracket" },
1112 { /* 94 5E */ "^", nullptr, nullptr, nullptr, "Caret - circumflex" },
1113 { /* 95 5F */ "_", nullptr, nullptr, nullptr, "Underscore" },
1114 { /* 96 60 */ "`", nullptr, nullptr, nullptr, "Grave accent" },
1115 { /* 97 61 */ "a", nullptr, nullptr, nullptr, "Lowercase a" },
1116 { /* 98 62 */ "b", nullptr, nullptr, nullptr, "Lowercase b" },
1117 { /* 99 63 */ "c", nullptr, nullptr, nullptr, "Lowercase c" },
1118 { /* 100 64 */ "d", nullptr, nullptr, nullptr, "Lowercase d" },
1119 { /* 101 65 */ "e", nullptr, nullptr, nullptr, "Lowercase e" },
1120 { /* 102 66 */ "f", nullptr, nullptr, nullptr, "Lowercase f" },
1121 { /* 103 67 */ "g", nullptr, nullptr, nullptr, "Lowercase g" },
1122 { /* 104 68 */ "h", nullptr, nullptr, nullptr, "Lowercase h" },
1123 { /* 105 69 */ "i", nullptr, nullptr, nullptr, "Lowercase i" },
1124 { /* 106 6A */ "j", nullptr, nullptr, nullptr, "Lowercase j" },
1125 { /* 107 6B */ "k", nullptr, nullptr, nullptr, "Lowercase k" },
1126 { /* 108 6C */ "l", nullptr, nullptr, nullptr, "Lowercase l" },
1127 { /* 109 6D */ "m", nullptr, nullptr, nullptr, "Lowercase m" },
1128 { /* 110 6E */ "n", nullptr, nullptr, nullptr, "Lowercase n" },
1129 { /* 111 6F */ "o", nullptr, nullptr, nullptr, "Lowercase o" },
1130 { /* 112 70 */ "p", nullptr, nullptr, nullptr, "Lowercase p" },
1131 { /* 113 71 */ "q", nullptr, nullptr, nullptr, "Lowercase q" },
1132 { /* 114 72 */ "r", nullptr, nullptr, nullptr, "Lowercase r" },
1133 { /* 115 73 */ "s", nullptr, nullptr, nullptr, "Lowercase s" },
1134 { /* 116 74 */ "t", nullptr, nullptr, nullptr, "Lowercase t" },
1135 { /* 117 75 */ "u", nullptr, nullptr, nullptr, "Lowercase u" },
1136 { /* 118 76 */ "v", nullptr, nullptr, nullptr, "Lowercase v" },
1137 { /* 119 77 */ "w", nullptr, nullptr, nullptr, "Lowercase w" },
1138 { /* 120 78 */ "x", nullptr, nullptr, nullptr, "Lowercase x" },
1139 { /* 121 79 */ "y", nullptr, nullptr, nullptr, "Lowercase y" },
1140 { /* 122 7A */ "z", nullptr, nullptr, nullptr, "Lowercase z" },
1141 { /* 123 7B */ "{", nullptr, nullptr, nullptr, "Opening brace" },
1142 { /* 124 7C */ "|", nullptr, nullptr, nullptr, "Vertical bar" },
1143 { /* 125 7D */ "}", nullptr, nullptr, nullptr, "Closing brace" },
1144 { /* 126 7E */ "~", nullptr, nullptr, nullptr, "Equivalency sign - tilde" },
1145 { /* 127 7F */ "DEL", nullptr, nullptr, nullptr, "Delete" },
1146
1147// The table below is according to ISO 8859-1, also called ISO Latin-1. Codes 129-159 contain the Microsoft® Windows Latin-1 extended characters.
1148// dec hex sym html utf8 pdf description
1149 { /* 128 80 */ "€", "&euro;", nullptr, nullptr, "Euro sign" },
1150 { /* 129 81 */ nullptr, nullptr, nullptr, nullptr, nullptr },
1151 { /* 130 82 */ "‚", "&sbquo;", nullptr, nullptr, "Single low-9 quotation mark" },
1152 { /* 131 83 */ "ƒ", "&fnof;", nullptr, nullptr, "Latin small letter f with hook" },
1153 { /* 132 84 */ "„", "&bdquo;", nullptr, nullptr, "Double low-9 quotation mark" },
1154 { /* 133 85 */ "…", "&hellip;", nullptr, nullptr, "Horizontal ellipsis" },
1155 { /* 134 86 */ "†", "&dagger;", nullptr, nullptr, "Dagger" },
1156 { /* 135 87 */ "‡", "&Dagger;", nullptr, nullptr, "Double dagger" },
1157 { /* 136 88 */ "ˆ", "&circ;", nullptr, nullptr, "Modifier letter circumflex accent" },
1158 { /* 137 89 */ "‰", "&permil;", nullptr, nullptr, "Per mille sign" },
1159 { /* 138 8A */ "Š", "&Scaron;", nullptr, nullptr, "Latin capital letter S with caron" },
1160 { /* 139 8B */ "‹", "&lsaquo;", nullptr, nullptr, "Single left-pointing angle quotation" },
1161 { /* 140 8C */ "Œ", "&OElig;", nullptr, nullptr, "Latin capital ligature OE" },
1162 { /* 141 8D */ nullptr, nullptr, nullptr, nullptr, nullptr },
1163 { /* 142 8E */ "Ž", nullptr, nullptr, nullptr, "Latin captial letter Z with caron" },
1164 { /* 143 8F */ nullptr, nullptr, nullptr, nullptr, nullptr },
1165 { /* 144 90 */ nullptr, nullptr, nullptr, nullptr, nullptr },
1166 { /* 145 91 */ "‘", "&lsquo;", nullptr, "'", "Left single quotation mark" },
1167 { /* 146 92 */ "’", "&rsquo;", nullptr, "'", "Right single quotation mark" },
1168 { /* 147 93 */ "“", "&ldquo;", "\xe2\x80\x9c", "\"", "Left double quotation mark" },
1169 { /* 148 94 */ "”", "&rdquo;", "\xe2\x80\x9d", "\"", "Right double quotation mark" },
1170 { /* 149 95 */ "•", "&bull;", nullptr, nullptr, "Bullet" },
1171 { /* 150 96 */ "–", "&ndash;", nullptr, "-", "En dash" },
1172 { /* 151 97 */ "—", "&mdash;", nullptr, "-", "Em dash" },
1173 { /* 152 98 */ "˜", "&tilde;", nullptr, "~", "Small tilde" },
1174 { /* 153 99 */ "™", "&trade;", nullptr, "tm", "Trade mark sign" },
1175 { /* 154 9A */ "š", "&scaron;", nullptr, nullptr, "Latin small letter S with caron" },
1176 { /* 155 9B */ "›", "&rsaquo;", nullptr, nullptr, "Single right-pointing angle quotation mark" },
1177 { /* 156 9C */ "œ", "&oelig;", nullptr, nullptr, "Latin small ligature oe" },
1178 { /* 157 9D */ nullptr, nullptr, nullptr, nullptr, nullptr },
1179 { /* 158 9E */ "ž", nullptr, nullptr, nullptr, "Latin small letter z with caron" },
1180 { /* 159 9F */ "Ÿ", "&yuml;", nullptr, nullptr, "Latin capital letter Y with diaeresis" },
1181 { /* 160 A0 */ " ", "&nbsp;", nullptr, nullptr, "Non-breaking space" },
1182 { /* 161 A1 */ "¡", "&iexcl;", nullptr, nullptr, "Inverted exclamation mark" },
1183 { /* 162 A2 */ "¢", "&cent;", nullptr, nullptr, "Cent sign" },
1184 { /* 163 A3 */ "£", "&pound;", nullptr, "#", "Pound sign" },
1185 { /* 164 A4 */ "¤", "&curren;", nullptr, nullptr, "Currency sign" },
1186 { /* 165 A5 */ "¥", "&yen;", nullptr, nullptr, "Yen sign" },
1187 { /* 166 A6 */ "¦", "&brvbar;", nullptr, nullptr, "Pipe, Broken vertical bar" },
1188 { /* 167 A7 */ "§", "&sect;", nullptr, nullptr, "Section sign" },
1189 { /* 168 A8 */ "¨", "&uml;", nullptr, nullptr, "Spacing diaeresis - umlaut" },
1190 { /* 169 A9 */ "©", "&copy;", nullptr, nullptr, "Copyright sign" },
1191 { /* 170 AA */ "ª", "&ordf;", nullptr, nullptr, "Feminine ordinal indicator" },
1192 { /* 171 AB */ "«", "&laquo;", nullptr, nullptr, "Left double angle quotes" },
1193 { /* 172 AC */ "¬", "&not;", nullptr, nullptr, "Not sign" },
1194 { /* 173 AD */ "­", "&shy;", nullptr, nullptr, "Soft hyphen" },
1195 { /* 174 AE */ "®", "&reg;", nullptr, nullptr, "Registered trade mark sign" },
1196 { /* 175 AF */ "¯", "&macr;", nullptr, nullptr, "Spacing macron - overline" },
1197 { /* 176 B0 */ "°", "&deg;", nullptr, nullptr, "Degree sign" },
1198 { /* 177 B1 */ "±", "&plusmn;", nullptr, nullptr, "Plus-or-minus sign" },
1199 { /* 178 B2 */ "²", "&sup2;", nullptr, nullptr, "Superscript two - squared" },
1200 { /* 179 B3 */ "³", "&sup3;", nullptr, nullptr, "Superscript three - cubed" },
1201 { /* 180 B4 */ "´", "&acute;", nullptr, nullptr, "Acute accent - spacing acute" },
1202 { /* 181 B5 */ "µ", "&micro;", nullptr, nullptr, "Micro sign" },
1203 { /* 182 B6 */ "¶", "&para;", nullptr, nullptr, "Pilcrow sign - paragraph sign" },
1204 { /* 183 B7 */ "·", "&middot;", nullptr, nullptr, "Middle dot - Georgian comma" },
1205 { /* 184 B8 */ "¸", "&cedil;", nullptr, nullptr, "Spacing cedilla" },
1206 { /* 185 B9 */ "¹", "&sup1;", nullptr, nullptr, "Superscript one" },
1207 { /* 186 BA */ "º", "&ordm;", nullptr, nullptr, "Masculine ordinal indicator" },
1208 { /* 187 BB */ "»", "&raquo;", nullptr, nullptr, "Right double angle quotes" },
1209 { /* 188 BC */ "¼", "&frac14;", nullptr, nullptr, "Fraction one quarter" },
1210 { /* 189 BD */ "½", "&frac12;", nullptr, nullptr, "Fraction one half" },
1211 { /* 190 BE */ "¾", "&frac34;", nullptr, nullptr, "Fraction three quarters" },
1212 { /* 191 BF */ "¿", "&iquest;", nullptr, nullptr, "Inverted question mark" },
1213 { /* 192 C0 */ "À", "&Agrave;", nullptr, nullptr, "Latin capital letter A with grave" },
1214 { /* 193 C1 */ "Á", "&Aacute;", nullptr, nullptr, "Latin capital letter A with acute" },
1215 { /* 194 C2 */ "Â", "&Acirc;", nullptr, nullptr, "Latin capital letter A with circumflex" },
1216 { /* 195 C3 */ "Ã", "&Atilde;", nullptr, nullptr, "Latin capital letter A with tilde" },
1217 { /* 196 C4 */ "Ä", "&Auml;", nullptr, nullptr, "Latin capital letter A with diaeresis" },
1218 { /* 197 C5 */ "Å", "&Aring;", nullptr, nullptr, "Latin capital letter A with ring above" },
1219 { /* 198 C6 */ "Æ", "&AElig;", nullptr, nullptr, "Latin capital letter AE" },
1220 { /* 199 C7 */ "Ç", "&Ccedil;", nullptr, nullptr, "Latin capital letter C with cedilla" },
1221 { /* 200 C8 */ "È", "&Egrave;", nullptr, nullptr, "Latin capital letter E with grave" },
1222 { /* 201 C9 */ "É", "&Eacute;", nullptr, nullptr, "Latin capital letter E with acute" },
1223 { /* 202 CA */ "Ê", "&Ecirc;", nullptr, nullptr, "Latin capital letter E with circumflex" },
1224 { /* 203 CB */ "Ë", "&Euml;", nullptr, nullptr, "Latin capital letter E with diaeresis" },
1225 { /* 204 CC */ "Ì", "&Igrave;", nullptr, nullptr, "Latin capital letter I with grave" },
1226 { /* 205 CD */ "Í", "&Iacute;", nullptr, nullptr, "Latin capital letter I with acute" },
1227 { /* 206 CE */ "Î", "&Icirc;", nullptr, nullptr, "Latin capital letter I with circumflex" },
1228 { /* 207 CF */ "Ï", "&Iuml;", nullptr, nullptr, "Latin capital letter I with diaeresis" },
1229 { /* 208 D0 */ "Ð", "&ETH;", nullptr, nullptr, "Latin capital letter ETH" },
1230 { /* 209 D1 */ "Ñ", "&Ntilde;", nullptr, nullptr, "Latin capital letter N with tilde" },
1231 { /* 210 D2 */ "Ò", "&Ograve;", nullptr, nullptr, "Latin capital letter O with grave" },
1232 { /* 211 D3 */ "Ó", "&Oacute;", nullptr, nullptr, "Latin capital letter O with acute" },
1233 { /* 212 D4 */ "Ô", "&Ocirc;", nullptr, nullptr, "Latin capital letter O with circumflex" },
1234 { /* 213 D5 */ "Õ", "&Otilde;", nullptr, nullptr, "Latin capital letter O with tilde" },
1235 { /* 214 D6 */ "Ö", "&Ouml;", nullptr, nullptr, "Latin capital letter O with diaeresis" },
1236 { /* 215 D7 */ "×", "&times;", nullptr, nullptr, "Multiplication sign" },
1237 { /* 216 D8 */ "Ø", "&Oslash;", nullptr, nullptr, "Latin capital letter O with slash" },
1238 { /* 217 D9 */ "Ù", "&Ugrave;", nullptr, nullptr, "Latin capital letter U with grave" },
1239 { /* 218 DA */ "Ú", "&Uacute;", nullptr, nullptr, "Latin capital letter U with acute" },
1240 { /* 219 DB */ "Û", "&Ucirc;", nullptr, nullptr, "Latin capital letter U with circumflex" },
1241 { /* 220 DC */ "Ü", "&Uuml;", nullptr, nullptr, "Latin capital letter U with diaeresis" },
1242 { /* 221 DD */ "Ý", "&Yacute;", nullptr, nullptr, "Latin capital letter Y with acute" },
1243 { /* 222 DE */ "Þ", "&THORN;", nullptr, nullptr, "Latin capital letter THORN" },
1244 { /* 223 DF */ "ß", "&szlig;", nullptr, nullptr, "Latin small letter sharp s - ess-zed" },
1245 { /* 224 E0 */ "à", "&agrave;", nullptr, nullptr, "Latin small letter a with grave" },
1246 { /* 225 E1 */ "á", "&aacute;", nullptr, nullptr, "Latin small letter a with acute" },
1247 { /* 226 E2 */ "â", "&acirc;", nullptr, nullptr, "Latin small letter a with circumflex" },
1248 { /* 227 E3 */ "ã", "&atilde;", nullptr, nullptr, "Latin small letter a with tilde" },
1249 { /* 228 E4 */ "ä", "&auml;", nullptr, nullptr, "Latin small letter a with diaeresis" },
1250 { /* 229 E5 */ "å", "&aring;", nullptr, nullptr, "Latin small letter a with ring above" },
1251 { /* 230 E6 */ "æ", "&aelig;", nullptr, nullptr, "Latin small letter ae" },
1252 { /* 231 E7 */ "ç", "&ccedil;", nullptr, nullptr, "Latin small letter c with cedilla" },
1253 { /* 232 E8 */ "è", "&egrave;", nullptr, nullptr, "Latin small letter e with grave" },
1254 { /* 233 E9 */ "é", "&eacute;", nullptr, nullptr, "Latin small letter e with acute" },
1255 { /* 234 EA */ "ê", "&ecirc;", nullptr, nullptr, "Latin small letter e with circumflex" },
1256 { /* 235 EB */ "ë", "&euml;", nullptr, nullptr, "Latin small letter e with diaeresis" },
1257 { /* 236 EC */ "ì", "&igrave;", nullptr, nullptr, "Latin small letter i with grave" },
1258 { /* 237 ED */ "í", "&iacute;", nullptr, nullptr, "Latin small letter i with acute" },
1259 { /* 238 EE */ "î", "&icirc;", nullptr, nullptr, "Latin small letter i with circumflex" },
1260 { /* 239 EF */ "ï", "&iuml;", nullptr, nullptr, "Latin small letter i with diaeresis" },
1261 { /* 240 F0 */ "ð", "&eth;", nullptr, nullptr, "Latin small letter eth" },
1262 { /* 241 F1 */ "ñ", "&ntilde;", nullptr, nullptr, "Latin small letter n with tilde" },
1263 { /* 242 F2 */ "ò", "&ograve;", nullptr, nullptr, "Latin small letter o with grave" },
1264 { /* 243 F3 */ "ó", "&oacute;", nullptr, nullptr, "Latin small letter o with acute" },
1265 { /* 244 F4 */ "ô", "&ocirc;", nullptr, nullptr, "Latin small letter o with circumflex" },
1266 { /* 245 F5 */ "õ", "&otilde;", nullptr, nullptr, "Latin small letter o with tilde" },
1267 { /* 246 F6 */ "ö", "&ouml;", nullptr, nullptr, "Latin small letter o with diaeresis" },
1268 { /* 247 F7 */ "÷", "&divide;", nullptr, nullptr, "Division sign" },
1269 { /* 248 F8 */ "ø", "&oslash;", nullptr, nullptr, "Latin small letter o with slash" },
1270 { /* 249 F9 */ "ù", "&ugrave;", nullptr, nullptr, "Latin small letter u with grave" },
1271 { /* 250 FA */ "ú", "&uacute;", nullptr, nullptr, "Latin small letter u with acute" },
1272 { /* 251 FB */ "û", "&ucirc;", nullptr, nullptr, "Latin small letter u with circumflex" },
1273 { /* 252 FC */ "ü", "&uuml;", nullptr, nullptr, "Latin small letter u with diaeresis" },
1274 { /* 253 FD */ "ý", "&yacute;", nullptr, nullptr, "Latin small letter y with acute" },
1275 { /* 254 FE */ "þ", "&thorn;", nullptr, nullptr, "Latin small letter thorn" },
1276 { /* 255 FF */ "ÿ", "&yuml;", nullptr, nullptr, "Latin small letter y with diaeresis" },
1277
1278};
1279
1280
static auto ialphasort(const struct dirent **a, const struct dirent **b) -> int
Definition Core.cpp:449
static bool iterate(Wt::Json::Array &_jary, Wt::WModelIndex _parent)
Definition Core.cpp:105
static std::vector< std::string > & split(const std::string &s, char delim, std::vector< std::string > &elems)
Definition Core.cpp:26
CSVState
Definition Core.cpp:826
auto dateStorageString(const Wt::WDate *_date) -> std::string
Definition Core.cpp:279
static constexpr const int User
static WDateTime currentDateTime()
cpp17::any data(ItemDataRole role=ItemDataRole::Display) const
std::string toUTF8() const
WString & arg(const std::wstring &value)
#define GCW_DATETIME_FORMAT_STORAGE
Definition gcwglobal.h:14
#define GCW_DATE_FORMAT_DISPLAY
Definition gcwglobal.h:16
#define GCW_DATE_FORMAT_STORAGE
Definition gcwglobal.h:12
WString asString(const cpp17::any &v, const WString &formatString=WString())
const char * trim_ws
Definition Core.cpp:47
int system_command(const std::string &cmd, bool show=false)
Execute a system command.
Definition Core.cpp:413
int roundUp(float value)
Round a number up.
Definition Core.cpp:772
double stof(const std::string &value)
Convert a String to Float.
Definition Core.cpp:601
std::string toupper(const std::string &s)
Definition Core.cpp:77
std::string lcase(const std::string &value)
Lower Case a string.
Definition Core.cpp:761
auto currentDateTime() -> Wt::WDateTime
Current Date/Time.
Definition Core.cpp:270
std::string ucase(const std::string &value)
Upper Case a string.
Definition Core.cpp:750
std::string tolower(const std::string &s)
Definition Core.cpp:88
bool ends_with(const std::string &value, const std::string &ending)
Check if a string ends with another string.
Definition Core.cpp:694
int roundDown(float value)
Round a number down.
Definition Core.cpp:785
std::string ftom(double value, int decimals=2)
Definition Core.cpp:667
auto dateTimeDisplayString(const Wt::WDateTime &_dateTime) -> std::string
Definition Core.cpp:309
bool fileExists(const std::string &fileName)
Check if a File or Folder exists.
Definition Core.cpp:559
std::string append(const std::string &s, const std::string &append, const std::string &separator)
Append a string to string.
Definition Core.cpp:706
std::string ftos(double value, int decimals=2)
Convert a Float to String with decimal precision.
Definition Core.cpp:628
std::vector< std::string > split(const std::string &value, char delim)
Definition Core.cpp:40
bool feq(double a, double b, double epsilon=0.005f, bool trace=false)
Definition Core.cpp:937
float roundCurrency(float value)
Round a number for Currency.
Definition Core.cpp:794
std::string itos(int value)
Convert an Integer to a String.
Definition Core.cpp:588
std::string & trim(std::string &s, const char *t=trim_ws)
Definition Core.cpp:70
std::string & ltrim(std::string &s, const char *t=trim_ws)
Definition Core.cpp:61
std::string replace(const std::string &string, const std::string &before, const std::string &after)
Replace a String.
Definition Core.cpp:809
std::string makeFileName(const std::string &value)
Make File Name.
Definition Core.cpp:343
std::vector< std::string > findFiles(const std::string &folder, const std::string &match)
Find File.
Definition Core.cpp:544
int stoi(const std::string &value)
Convert a String to an Integer.
Definition Core.cpp:569
auto currentDateTimeDisplayString() -> std::string
Definition Core.cpp:321
std::string prepend(const std::string &s, int length=0, char pad='0')
Prepend some number of characters in front of another string.
Definition Core.cpp:736
const CharConv_t g_iso8859Conv[256]
Definition Core.cpp:1015
std::string hexDump(const std::string &data, int start=-1, int end=-1)
Definition Core.cpp:180
std::string to_string(Wt::WTemplate &templt)
Definition Core.cpp:961
std::string & rtrim(std::string &s, const char *t=trim_ws)
Definition Core.cpp:52
bool to_htmlfile(Wt::WTemplate &templt, const std::string &folderName, const std::string &fileName)
Definition Core.cpp:996
Wt::Json::Object toJson(Wt::WTreeView *_view)
Definition Core.cpp:158
std::vector< std::string > readCSVRow(const std::string &row)
Definition Core.cpp:835
auto dateTimeStorageString(const Wt::WDateTime &_dateTime) -> std::string
Definition Core.cpp:288
auto newGuid() -> std::string
Generate new GUID string value.
Definition Core.cpp:245
auto currentDateTimeStorageString() -> std::string
Definition Core.cpp:300
std::vector< std::string > fileList(const std::string &folder)
File Listing.
Definition Core.cpp:464