56#include <wx/datetime.h>
57#include <wx/tokenzr.h>
59#include <wx/wxcrtvararg.h>
60#include <wx/convauto.h>
85 m_pString = String ?
new wxString(String) :
new wxString;
90 m_pString = String ?
new wxString(String) :
new wxString;
95 m_pString =
new wxString(Character, nRepeat);
100 m_pString =
new wxString(Character, nRepeat);
106 m_pString = String ?
new wxString(*String) :
new wxString;
191 if( i >= 0 && i < (
int)
Length() )
196 return(
SG_T(
'\0') );
206 return(
SG_T(
'\0') );
216 return(
SG_T(
'\0') );
275 wxString _Format(
Format); _Format.Replace(
"%s",
"%ls");
276 va_list argptr; va_start(argptr, _Format);
279 va_list argptr; va_start(argptr,
Format);
294 wxString _Format(
Format); _Format.Replace(
"%s",
"%ls");
295 va_list argptr; va_start(argptr, _Format);
298 va_list argptr; va_start(argptr,
Format);
311 wxString _Format(
Format); _Format.Replace(
"%s",
"%ls");
312 va_list argptr; va_start(argptr, _Format);
313 int Result =
m_pString->PrintfV(_Format, argptr);
315 va_list argptr; va_start(argptr,
Format);
328 wxString _Format(
Format); _Format.Replace(
"%s",
"%ls");
329 va_list argptr; va_start(argptr, _Format);
330 int Result =
m_pString->PrintfV(_Format, argptr);
332 va_list argptr; va_start(argptr,
Format);
534 return(
m_pString->IsSameAs(Character, bCase) );
539 return(
m_pString->IsSameAs(Character, bCase) );
573 for(
size_t i=0; i<
Length(); i++)
575 if( (n == 0 || bReplaceAll)
599 for(
size_t i=0; i<
Length(); i++)
643 return( (
int)(n -
m_pString->Length()) );
654 return( (
int)(n -
m_pString->Length()) );
665 return(
m_pString->Find(Character, fromEnd) );
670 return(
m_pString->Find(Character, fromEnd) );
771 int Value;
return(
asInt(Value) ? Value : 0 );
776 const wxChar *start =
m_pString->c_str(); wxChar *end;
778 int value = wxStrtol(start, &end, 10);
809 double Value;
return(
asDouble(Value) ? Value : 0. );
814 const wxChar *start =
m_pString->c_str(); wxChar *end;
816 double value = wxStrtod(start, &end);
881 const wxScopedCharBuffer Buffer =
m_pString->utf8_str();
883 String.
Set_Data(Buffer.data(), Buffer.length() + 1);
923 wxScopedCharBuffer Buffer;
934 default : Buffer =
m_pString->mb_str(wxConvAuto ());
break;
937 String.
Set_Data(Buffer.data(), Buffer.length() + 1);
977 #if wxCHECK_VERSION(3, 1, 0)
980 const wxScopedCharBuffer Buffer =
m_pString->ToAscii();
983 String.
Set_Data(Buffer.data(), Buffer.length() + 1);
1037 return(
Add(Strings) );
1043 for(
int i=0; i<nStrings; i++)
1071 for(
size_t i=0; i<Strings.
Get_Size(); i++)
1099 return(
Add(String) );
1104 for(
size_t i=
Get_Size()-1; i>Index; i--)
1127 for(
size_t i=Index+1; i<
Get_Size(); i++)
1140 while(
Del(Count) ) {}
1142 for(
size_t i=
Get_Size(); i<Count; i++)
1156 CSG_Index_Compare_Strings(
CSG_String **Values,
bool Ascending) : m_Values(Values), m_Ascending(Ascending) {}
1158 virtual int Compare (
const sLong _a,
const sLong _b)
1160 sLong a = m_Ascending ? _a : _b;
1161 sLong b = m_Ascending ? _b : _a;
1163 return( m_Values[a]->Cmp(*m_Values[b]) );
1233 CSG_String s; wxDateTime t; t.SetToCurrent();
1237 s += t.FormatISODate().wc_str(); s +=
"/";
1240 s += t.FormatISOTime().wc_str();
1255 int deg, min;
double sec;
char sig = Value < 0. ?
'-' :
'+';
1262 Value = fmod(Value, 360.);
1264 Value = 60. * (Value - deg);
1266 Value = 60. * (Value - min);
1275 double sig = 1., deg = 0., min = 0., sec = 0.;
1281 sig = -1.; deg = -deg;
1292 return( sig * (deg + min / 60. + sec / 3600.) );
1307 Value = fabs(Value);
1309 for(decimals=0; decimals<maxDecimals; decimals++)
1311 double Remainder = Value - floor(Value);
1313 if( Remainder == 0. )
1321 return( maxDecimals );
1334 for(
size_t i=0; i<String.
Length(); i++)
1371 if ( Precision == -99 )
1375 else if( Precision == -98 )
1379 else if( Precision == -97 )
1383 else if( Precision == 0 )
1385 s.
Printf(
"%d", (
int)Value);
1387 else if( Precision > 0 )
1389 s.
Printf(
"%.*f", Precision, Value);
1397 s.
Printf(
"%d", (
int)Value);
1399 else if( Decimals > Precision )
1405 s.
Printf(
"%.*f", Decimals, Value);
1450 m_pTokenizer =
new wxStringTokenizer();
1456 m_pTokenizer =
new wxStringTokenizer();
1464 delete(m_pTokenizer);
1470 return( m_pTokenizer->CountTokens() );
1476 return( m_pTokenizer->GetLastDelimiter() );
1482 wxString s(m_pTokenizer->GetNextToken());
1490 return( m_pTokenizer->GetPosition() );
1496 wxString s(m_pTokenizer->GetString());
1504 return( m_pTokenizer->HasMoreTokens() );
1510 wxStringTokenizerMode _Mode;
1514 default : _Mode = wxTOKEN_DEFAULT ;
break;
1522 m_pTokenizer->SetString(String.
c_str(), Delimiters.
c_str(), _Mode);
1562 {
"table",
"\n============\n",
"============\n" },
1563 {
"tr" ,
"" ,
"\n" },
1564 {
"th" ,
"" ,
"\t" },
1565 {
"td" ,
"" ,
"\t" },
1567 {
"b" ,
"[" ,
"]" },
1568 {
"i" ,
"'" ,
"'" },
1569 {
"code" ,
"`" ,
"`" },
1570 {
"br" ,
"\n" ,
"" },
1571 {
"p" ,
"" ,
"\n" },
1572 {
"hr" ,
"\n____________\n",
"\n" },
1573 {
"h1" ,
"\n############\n",
"\n" },
1574 {
"h2" ,
"\n============\n",
"\n" },
1575 {
"h3" ,
"\n------------\n",
"\n" },
1576 {
"h4" ,
"\n" ,
"\n" },
1577 {
"ol" ,
"\n" ,
"\n" },
1578 {
"ul" ,
"\n" ,
"\n" },
1579 {
"li" ,
"- " ,
"\n" },
1585 for(
int i=0, n; !Tags[i][0].
is_Empty(); i++)
1587 _Text.
Replace(
"<" + Tags[i][0] +
">", Tags[i][1]);
1589 while( (n = _Text.
Find(
"<" + Tags[i][0])) >= 0 )
1593 if( Tags[i][0].Cmp(
"a") == 0 && (n = Right.
BeforeFirst(
'>').
Find(
"href=\"")) >= 0 )
1597 if( !href.
is_Empty() && (n = Right.
Find(
"</a>")) >= 0 )
1603 _Text = Left +
"[" + text +
"](" + href +
")" + Right.
Right(Right.
Length() - n);
1610 _Text = Left + Tags[i][1] + Right.
AfterFirst(
'>');
1613 _Text.
Replace(
"</" + Tags[i][0] +
">", Tags[i][2]);
1629 return( _Html_to_Markdown(_Text) );
1635 CSG_String Markdown, Head, Tail(Text), Tag, Attributes, Content;
1637 while( !Tail.is_Empty() )
1639 if( _Html_Tag_Find(Head, Tail, Tag, Attributes, Content) )
1643 _Html_Tag_to_Markdown(Tag, Attributes, Content);
1645 Markdown += _Html_to_Markdown(Content);
1649 Markdown += Tail; Tail.
Clear();
1659 if( Tail.
Find(
"<") >= 0 )
1663 int n = Tail.
Find(
"</" + Tag +
">");
1683 if ( !Tag.
CmpNoCase(
"br") ) { Content =
"\n"; }
1684 else if( !Tag.
CmpNoCase(
"hr") ) { Content =
"\n---\n"; }
1685 else if( !Tag.
CmpNoCase(
"p" ) ) { Content =
"\n" + Content +
"\n"; }
1687 else if( !Tag.
CmpNoCase(
"h1") ) { Content =
"\n# " + Content +
"\n"; }
1688 else if( !Tag.
CmpNoCase(
"h2") ) { Content =
"\n## " + Content +
"\n"; }
1689 else if( !Tag.
CmpNoCase(
"h3") ) { Content =
"\n### " + Content +
"\n"; }
1690 else if( !Tag.
CmpNoCase(
"h4") ) { Content =
"\n#### " + Content +
"\n"; }
1692 else if( !Tag.
CmpNoCase(
"b" ) ) { Content =
"**" + Content +
"**"; }
1693 else if( !Tag.
CmpNoCase(
"i" ) ) { Content =
"*" + Content +
"*" ; }
1706 int n = Attributes.
Find(
"href=\"");
1712 Content =
"[" + Content +
"](" + href +
")";
1718 CSG_String head, tail(Content), tag, attributes, content;
1720 if( _Html_Tag_Find(head, tail, tag, attributes, content) && !tag.
CmpNoCase(
"tr") )
1722 content = _Html_to_Markdown(content);
1726 for(
int i=0; i<fields.
Get_Count() - 1; i++) { content +=
"| - "; }
1728 Content = content +
"\n" + tail;
1732 else if( !Tag.
CmpNoCase(
"tr") ) { Content +=
"\n"; }
1733 else if( !Tag.
CmpNoCase(
"th") ) { Content =
"| " + Content +
" "; }
1734 else if( !Tag.
CmpNoCase(
"td") ) { Content =
"| " + Content +
" "; }
1752 CSG_String Head, Tail(Text);
int n, m, nFigs = 0;
1754 while( (n = Tail.
Find(
"<img ")) >= 0 && (m = Tail.
Find(
"/>")) > n )
1758 if( (n = Content.
Find(
"src")) >= 0 )
1762 if( bAltAsText && (m = Content.
Find(
"alt")) >= 0 )
1767 Head +=
"<img " + Content.
Left(n); Content = Content.
Right(Content.
Length() - n);
1773 if( Text[Text.
Length() - 1] !=
'.' )
1807 Lines[i].Replace(
"*",
"*");
1824 if ( i < Lines.
Get_Count() - 1 && Lines[i + 1].Find(
"| -") == 0 )
1828 else if( Lines[i].Find(
"- ") == 0 )
1832 else if( Lines[i].Find(
"1. ") == 0 )
1839 _Markdown_to_Html(Lines[i], Mode);
1841 Html += Lines[i] +
"\n";
1848bool CSG_Text_Format_Converter::_Markdown_to_Html(
CSG_String &Line,
int Mode)
1852 if( Trimmed.Find(
"# " ) == 0 ) { Line =
"<h1>" + Trimmed.
AfterFirst(
' ') +
"</h1>";
return(
true ); }
1853 if( Trimmed.Find(
"## " ) == 0 ) { Line =
"<h2>" + Trimmed.
AfterFirst(
' ') +
"</h2>";
return(
true ); }
1854 if( Trimmed.Find(
"### " ) == 0 ) { Line =
"<h3>" + Trimmed.
AfterFirst(
' ') +
"</h3>";
return(
true ); }
1855 if( Trimmed.Find(
"#### ") == 0 ) { Line =
"<h4>" + Trimmed.
AfterFirst(
' ') +
"</h4>";
return(
true ); }
1857 if( Trimmed.Find(
"---" ) == 0 ) { Line =
"<hr>";
return(
true ); }
1860 _Markdown_to_Html(Line,
"***",
"bi"); Line.
Replace(
"<bi>",
"<b><i>"); Line.
Replace(
"</bi>",
"</i></b>");
1861 _Markdown_to_Html(Line,
"**",
"b");
1862 _Markdown_to_Html(Line,
"*",
"i");
1864 _Markdown_to_Html_Links(Line);
1869 Line = Line.
AfterFirst(
' '); Line.
Trim(); Line =
"<li>" + Line +
"</li>";
return(
true );
1880 if( i > 0 || fields[i].is_Empty() ==
false )
1882 Line +=
"<td>" + fields[i] +
"</td>";
1897 for(
int i; (i = Line.
Find(MD)) >= 0; )
1904 Line.
Replace(MD,
"<" + Tag +
">",
false);
1905 Line.
Replace(MD,
"</" + Tag +
">",
false);
1914bool CSG_Text_Format_Converter::_Markdown_to_Html_Links(
CSG_String &Line)
1916 int n = 0; CSG_String head, text, link, tail;
1918 while( _Markdown_Split_Link(Line, head, text, link, tail) )
1920 if( head.
Length() > 0 && head[head.
Length() - 1] ==
'!' )
1922 Line = head.
Left(head.
Length() - 1) +
"<img alt=\"" + text +
"\" src=\"" + link +
"\"/>" + tail;
1926 Line = head +
"<a href=\"" + link +
"\">" + text +
"</a>" + tail;
1936 int n = MD.
Find(
"[");
1942 if( (n = Tail.
Find(
"]")) >= 0 && Tail.
Length() > (
size_t)n + 2 && Tail[n + 1] ==
'(' )
1944 Text = Tail.
Left(n); Tail = Tail.
Right(Tail.
Length() - ((
size_t)n + 2));
1946 if( (n = Tail.
Find(
")")) >= 0 )
1948 Link = Tail.
Left(n); Tail = Tail.
Right(Tail.
Length() - ((
size_t)n + 1));
SAGA_API_DLL_EXPORT CSG_String SG_File_Get_Path_Absolute(const CSG_String &full_Path, const CSG_String &CWD="")
SAGA_API_DLL_EXPORT void * SG_Malloc(size_t size)
TSG_String_Tokenizer_Mode
SAGA_API_DLL_EXPORT CSG_Strings SG_String_Tokenize(const CSG_String &String, const CSG_String &Delimiters=SG_DEFAULT_DELIMITERS, TSG_String_Tokenizer_Mode Mode=SG_TOKEN_DEFAULT)
@ SG_FILE_ENCODING_UTF16LE
@ SG_FILE_ENCODING_UTF16BE
@ SG_FILE_ENCODING_UTF32BE
@ SG_FILE_ENCODING_UTF32LE
CSG_String operator+(const char *A, const CSG_String &B)
CSG_String SG_Get_CurrentTimeStr(bool bWithDate)
double SG_Degree_To_Double(const CSG_String &String)
bool SG_is_Character_Numeric(int Character)
CSG_Strings SG_String_Tokenize(const CSG_String &String, const CSG_String &Delimiters, TSG_String_Tokenizer_Mode Mode)
int SG_Get_Significant_Decimals(double Value, int maxDecimals)
void SG_Flip_Decimal_Separators(CSG_String &String)
CSG_String SG_Double_To_Degree(double Value)
CSG_String SG_Get_String(double Value, int Precision)
CSG_String SG_HTML_Tag_Replacer(const CSG_String &Text)
size_t Get_Size(void) const
bool Set_Data(const char *Data, size_t Size, bool bShrink=true)
char * Get_Data(int Offset=0) const
size_t Get_Position(void) const
SG_Char Get_Last_Delimiter(void) const
size_t Get_Tokens_Count(void) const
CSG_String Get_Next_Token(void)
bool Has_More_Tokens(void) const
void Set_String(const CSG_String &String, const CSG_String &Delimiters=SG_DEFAULT_DELIMITERS, TSG_String_Tokenizer_Mode Mode=SG_TOKEN_DEFAULT)
~CSG_String_Tokenizer(void)
CSG_String Get_String(void) const
CSG_String_Tokenizer(void)
size_t Length(void) const
CSG_String AfterFirst(char Character) const
const char * b_str(void) const
CSG_String & Remove(size_t pos)
int CmpNoCase(const CSG_String &String) const
CSG_String AfterLast(char Character) const
int Cmp(const CSG_String &String) const
size_t Replace_Single_Char(const SG_Char Old, const CSG_String &New, bool bReplaceAll=true)
CSG_String & operator=(const CSG_String &String)
CSG_String BeforeFirst(char Character) const
void operator+=(const CSG_String &String)
virtual ~CSG_String(void)
void Set_Char(size_t i, char Character)
size_t Replace(const CSG_String &Old, const CSG_String &New, bool bReplaceAll=true)
std::string to_StdString(void) const
CSG_String operator+(const CSG_String &String) const
CSG_String BeforeLast(char Character) const
static CSG_String Format(const char *Format,...)
int Trim(bool fromRight=false)
CSG_String & Append(const CSG_String &String)
int Find(char Character, bool fromEnd=false) const
size_t to_MBChar(char **pString, int Encoding) const
bool is_Same_As(const CSG_String &String, bool bCase=true) const
SG_Char Get_Char(size_t i) const
SG_Char operator[](int i) const
CSG_String Right(size_t count) const
const SG_Char * c_str(void) const
bool to_ASCII(char **pString, char Replace='_') const
CSG_String & Make_Lower(void)
class wxString * m_pString
int Printf(const char *Format,...)
bool is_Empty(void) const
CSG_String Mid(size_t first, size_t count=0) const
bool Contains(const CSG_String &String) const
CSG_String Left(size_t count) const
static CSG_String from_UTF8(const char *String, size_t Length=0)
CSG_Buffer to_UTF8(void) const
bool is_Number(void) const
std::wstring to_StdWstring(void) const
CSG_String & Make_Upper(void)
double asDouble(void) const
bool Create(const class wxString *pString)
const wchar_t * w_str(void) const
CSG_String & Prepend(const CSG_String &String)
sLong asLongLong(void) const
bool Add(const CSG_Strings &Strings)
CSG_Array_Pointer m_Strings
bool Sort(bool Ascending=true)
bool Set_Count(int Count)
bool Create(const CSG_Strings &Strings)
size_t Get_Size(void) const
int Get_Count(void) const
virtual ~CSG_Strings(void)
bool Ins(const CSG_String &String, int Index)
static CSG_String Html_Absolute_Image_Paths(const CSG_String &Text, const CSG_String &Path, bool bAltAsText=false)
static CSG_String Markdown_to_Html(const CSG_String &Text, bool bSimple=true)
static CSG_String Html_to_Markdown(const CSG_String &Text)
static CSG_String Html_to_SimpleText(const CSG_String &Text)