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