1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     Miscellaneous utilities 
   4 // Author:      Julian Smart 
   5 // Modified by: Wlodzimiez ABX Skiba 2003/2004 Unicode support 
   9 // Copyright:   (c) Julian Smart 
  10 // Licence:     wxWindows licence 
  11 ///////////////////////////////////////////////////////////////////////////// 
  14 #pragma implementation 
  17 // For compilers that support precompilation, includes "wx.h". 
  18 #include "wx/wxprec.h" 
  47 #if !WXWIN_COMPATIBILITY_2_4 
  48 static inline wxChar
* copystring(const wxChar
* s
) 
  49     { return wxStrcpy(new wxChar
[wxStrlen(s
) + 1], s
); } 
  52 wxHashTable 
TexReferences(wxKEY_STRING
); 
  53 wxList 
BibList(wxKEY_STRING
); 
  54 wxStringList CitationList
; 
  55 wxList 
ColourTable(wxKEY_STRING
); 
  56 wxHashTable 
BibStringTable(wxKEY_STRING
); 
  57 wxList 
CustomMacroList(wxKEY_STRING
); 
  58 TexChunk 
*currentSection 
= NULL
; 
  59 wxChar 
*fakeCurrentSection 
= NULL
; 
  61 static long BibLine 
= 1; 
  63 void OutputCurrentSection(void) 
  65   if (fakeCurrentSection
) 
  66     TexOutput(fakeCurrentSection
); 
  67   else if (currentSection
) 
  68     TraverseChildrenFromChunk(currentSection
); 
  71 // Nasty but the way things are done now, necessary, 
  72 // in order to output a chunk properly to a string (macros and all). 
  73 void OutputCurrentSectionToString(wxChar 
*buf
) 
  75     if (fakeCurrentSection
) 
  76         wxStrcpy(buf
, fakeCurrentSection
); 
  78         OutputChunkToString(currentSection
, buf
); 
  81 void OutputChunkToString(TexChunk 
*chunk
, wxChar 
*buf
) 
  83   FILE *tempfd 
= wxFopen(_T("tmp.tmp"), _T("w")); 
  87   FILE *old1 
= CurrentOutput1
; 
  88   FILE *old2 
= CurrentOutput2
; 
  90   CurrentOutput1 
= tempfd
; 
  91   CurrentOutput2 
= NULL
; 
  93   TraverseChildrenFromChunk(chunk
); 
  95   CurrentOutput1 
= old1
; 
  96   CurrentOutput2 
= old2
; 
 100   // Read from file into string 
 101   tempfd 
= wxFopen(_T("tmp.tmp"), _T("r")); 
 120   wxRemoveFile(_T("tmp.tmp")); 
 123 // Called by Tex2Any to simulate a section 
 124 void FakeCurrentSection(wxChar 
*fakeSection
, bool addToContents
) 
 126   currentSection 
= NULL
; 
 127   if (fakeCurrentSection
) delete[] fakeCurrentSection
; 
 128   fakeCurrentSection 
= copystring(fakeSection
); 
 130   if (DocumentStyle 
== LATEX_ARTICLE
) 
 132     int mac 
= ltSECTIONHEADING
; 
 134       mac 
= ltSECTIONHEADINGSTAR
; 
 135     OnMacro(mac
, 0, true); 
 136     OnMacro(mac
, 0, false); 
 140     int mac 
= ltCHAPTERHEADING
; 
 142       mac 
= ltCHAPTERHEADINGSTAR
; 
 143     OnMacro(mac
, 0, true); 
 144     OnMacro(mac
, 0, false); 
 146   if (fakeCurrentSection
) delete[] fakeCurrentSection
; 
 147   fakeCurrentSection 
= NULL
; 
 150 // Look for \label macro, use this ref name if found or 
 151 // make up a topic name otherwise. 
 152 static long topicCounter 
= 0; 
 154 void ResetTopicCounter(void) 
 159 static wxChar 
*forceTopicName 
= NULL
; 
 161 void ForceTopicName(const wxChar 
*name
) 
 164     delete[] forceTopicName
; 
 166     forceTopicName 
= copystring(name
); 
 168     forceTopicName 
= NULL
; 
 171 wxChar 
*FindTopicName(TexChunk 
*chunk
) 
 174     return forceTopicName
; 
 176   wxChar 
*topicName 
= NULL
; 
 177   static wxChar topicBuf
[100]; 
 179   if (chunk 
&& (chunk
->type 
== CHUNK_TYPE_MACRO
) && 
 180       (chunk
->macroId 
== ltLABEL
)) 
 182     wxNode 
*node 
= chunk
->children
.GetFirst(); 
 185       TexChunk 
*child 
= (TexChunk 
*)node
->GetData(); 
 186       if (child
->type 
== CHUNK_TYPE_ARG
) 
 188         wxNode 
*snode 
= child
->children
.GetFirst(); 
 191           TexChunk 
*schunk 
= (TexChunk 
*)snode
->GetData(); 
 192           if (schunk
->type 
== CHUNK_TYPE_STRING
) 
 193             topicName 
= schunk
->value
; 
 202     wxSnprintf(topicBuf
, sizeof(topicBuf
), _T("topic%ld"), topicCounter
); 
 209  * Simulate argument data, so we can 'drive' clients which implement 
 210  * certain basic formatting behaviour. 
 211  * Snag is that some save a TexChunk, so don't use yet... 
 215 void StartSimulateArgument(wxChar 
*data
) 
 217   wxStrcpy(currentArgData
, data
); 
 221 void EndSimulateArgument(void) 
 227  * Parse and convert unit arguments to points 
 231 int ParseUnitArgument(wxChar 
*unitArg
) 
 233   float conversionFactor 
= 1.0; 
 234   float unitValue 
= 0.0; 
 235   int len 
= wxStrlen(unitArg
); 
 236   // Get rid of any accidentally embedded commands 
 237   for (int i 
= 0; i 
< len
; i
++) 
 238     if (unitArg
[i
] == '\\') 
 240   len 
= wxStrlen(unitArg
); 
 242   if (unitArg 
&& (len 
> 0) && (isdigit(unitArg
[0]) || unitArg
[0] == '-')) 
 244     wxSscanf(unitArg
, _T("%f"), &unitValue
); 
 248       units
[0] = unitArg
[len
-2]; 
 249       units
[1] = unitArg
[len
-1]; 
 251       if (wxStrcmp(units
, _T("in")) == 0) 
 252         conversionFactor 
= 72.0; 
 253       else if (wxStrcmp(units
, _T("cm")) == 0) 
 254         conversionFactor 
= (float)72.0/(float)2.51; 
 255       else if (wxStrcmp(units
, _T("mm")) == 0) 
 256         conversionFactor 
= (float)72.0/(float)25.1; 
 257       else if (wxStrcmp(units
, _T("pt")) == 0) 
 258         conversionFactor 
= 1; 
 260     return (int)(unitValue
*conversionFactor
); 
 266  * Strip off any extension (dot something) from end of file, 
 267  * IF one exists. Inserts zero into buffer. 
 271 void StripExtension(wxChar 
*buffer
) 
 273   int len 
= wxStrlen(buffer
); 
 277     if (buffer
[i
] == '.') 
 291 void SetFontSizes(int pointSize
) 
 343 void AddTexRef(wxChar 
*name
, wxChar 
*file
, wxChar 
*sectionName
, 
 344                int chapter
, int section
, int subsection
, int subsubsection
) 
 346   TexRef 
*texRef 
= (TexRef 
*)TexReferences
.Get(name
); 
 347   if (texRef
) TexReferences
.Delete(name
); 
 354     wxStrcat(buf, sectionName); 
 361     wxSnprintf(buf2
, sizeof(buf2
), _T("%d"), chapter
); 
 368       wxStrcat(buf
, _T(".")); 
 370     wxSnprintf(buf2
, sizeof(buf2
), _T("%d"), section
); 
 376     wxStrcat(buf
, _T(".")); 
 377     wxSnprintf(buf2
, sizeof(buf2
), _T("%d"), subsection
); 
 383     wxStrcat(buf
, _T(".")); 
 384     wxSnprintf(buf2
, sizeof(buf2
), _T("%d"), subsubsection
); 
 387   wxChar 
*tmp 
= ((wxStrlen(buf
) > 0) ? buf 
: (wxChar 
*)NULL
); 
 388   TexReferences
.Put(name
, new TexRef(name
, file
, tmp
, sectionName
)); 
 391 void WriteTexReferences(wxChar 
*filename
) 
 394   wxString name 
= filename
; 
 395   wxSTD ofstream 
ostr((char const *)name
.fn_str()); 
 396   if (ostr
.bad()) return; 
 398   TexReferences
.BeginFind(); 
 399   wxHashTable::Node 
*node 
= TexReferences
.Next(); 
 403     TexRef 
*ref 
= (TexRef 
*)node
->GetData(); 
 404     converter 
= ref
->refLabel
; 
 405     ostr 
<< converter
.mb_str(); 
 407     converter 
= (ref
->refFile 
? ref
->refFile 
: _T("??")); 
 408     ostr 
<< converter
.mb_str(); 
 410     converter 
= (ref
->sectionName 
? ref
->sectionName 
: _T("??")) ; 
 411     ostr 
<< converter
.mb_str(); 
 413     converter 
= (ref
->sectionNumber 
? ref
->sectionNumber 
: _T("??")) ; 
 414     ostr 
<< converter
.mb_str(); 
 416     if (!ref
->sectionNumber 
|| (wxStrcmp(ref
->sectionNumber
, _T("??")) == 0 && wxStrcmp(ref
->sectionName
, _T("??")) == 0)) 
 419       wxSnprintf(buf
, sizeof(buf
), _T("Warning: reference %s not resolved."), ref
->refLabel
); 
 422     node 
= TexReferences
.Next(); 
 426 void ReadTexReferences(wxChar 
*filename
) 
 428   if (!wxFileExists(filename
)) 
 431   wxString name 
= filename
; 
 432   wxSTD ifstream 
istr((char const *)name
.fn_str(), wxSTD 
ios::in
); 
 434   if (istr
.bad()) return; 
 439   char sectionName
[100]; 
 449       istr
.get(ch
); // Read past space 
 452       while (ch 
!= '\n' && !istr
.eof()) 
 460       wxString label_string       
= wxString::FromAscii(label
); 
 461       wxString file_string        
= wxString::FromAscii(file
); 
 462       wxString sectionName_string 
= wxString::FromAscii(sectionName
); 
 463       wxString section_string     
= wxString::FromAscii(section
); 
 465       // gt - needed to trick the hash table "TexReferences" into deleting the key 
 466       // strings it creates in the Put() function, but not the item that is 
 467       // created here, as that is destroyed elsewhere.  Without doing this, there 
 468       // were massive memory leaks 
 469       TexReferences
.DeleteContents(true); 
 471         label_string
.c_str(), 
 473               label_string
.c_str(), 
 475               section_string
.c_str(), 
 476               sectionName_string
.c_str() 
 479       TexReferences
.DeleteContents(false); 
 486  * Bibliography-handling code 
 490 void BibEatWhiteSpace(wxSTD istream
& str
) 
 492   char ch 
= (char)str
.peek(); 
 494   while (!str
.eof() && (ch 
== ' ' || ch 
== '\t' || ch 
== 13 || ch 
== 10 || ch 
== (char)EOF
)) 
 499     if ((ch 
== (char)EOF
) || str
.eof()) return; 
 500     ch 
= (char)str
.peek(); 
 503   // Ignore end-of-line comments 
 504   if (ch 
== '%' || ch 
== ';' || ch 
== '#') 
 507     ch 
= (char)str
.peek(); 
 508     while (ch 
!= 10 && ch 
!= 13 && !str
.eof()) 
 511       ch 
= (char)str
.peek(); 
 513     BibEatWhiteSpace(str
); 
 517 // Read word up to { or , or space 
 518 void BibReadWord(wxSTD istream
& istr
, wxChar 
*buffer
) 
 522   char ch 
= (char)istr
.peek(); 
 523   while (!istr
.eof() && ch 
!= ' ' && ch 
!= '{' && ch 
!= '(' && ch 
!= 13 && ch 
!= 10 && ch 
!= '\t' && 
 524          ch 
!= ',' && ch 
!= '=') 
 529     ch 
= (char)istr
.peek(); 
 534 // Read string (double-quoted or not) to end quote or EOL 
 535 void BibReadToEOL(wxSTD istream
& istr
, wxChar 
*buffer
) 
 539   char ch 
= (char)istr
.peek(); 
 540   bool inQuotes 
= false; 
 544     ch 
= (char)istr
.peek(); 
 547   // If in quotes, read white space too. If not, 
 548   // stop at white space or comment. 
 549   while (!istr
.eof() && ch 
!= 13 && ch 
!= 10 && ch 
!= _T('"') && 
 550          (inQuotes 
|| ((ch 
!= _T(' ')) && (ch 
!= 9) && 
 551                         (ch 
!= _T(';')) && (ch 
!= _T('%')) && (ch 
!= _T('#'))))) 
 556     ch 
= (char)istr
.peek(); 
 563 // Read }-terminated value, taking nested braces into account. 
 564 void BibReadValue(wxSTD istream
& istr
, wxChar 
*buffer
, bool ignoreBraces 
= true, 
 565                   bool quotesMayTerminate 
= true) 
 570   char ch 
= (char)istr
.peek(); 
 571   bool stopping 
= false; 
 572   while (!istr
.eof() && !stopping
) 
 578       wxSnprintf(buf
, sizeof(buf
), _T("Sorry, value > 4000 chars in bib file at line %ld."), BibLine
); 
 579       wxLogError(buf
, "Tex2RTF Fatal Error"); 
 596     else if (quotesMayTerminate 
&& ch 
== '"') 
 603       if (!ignoreBraces 
|| (ch 
!= '{' && ch 
!= '}')) 
 613   wxUnusedVar(stopping
); 
 616 bool ReadBib(wxChar 
*filename
) 
 618   if (!wxFileExists(filename
)) 
 621   wxString name 
= filename
; 
 623   wxSTD ifstream 
istr((char const *)name
.fn_str(), wxSTD 
ios::in
); 
 624   if (istr
.bad()) return false; 
 628   OnInform(_T("Reading .bib file...")); 
 631   wxChar fieldValue
[4000]; 
 632   wxChar recordType
[100]; 
 633   wxChar recordKey
[100]; 
 634   wxChar recordField
[100]; 
 639     BibEatWhiteSpace(istr
); 
 643       wxSnprintf(buf
, sizeof(buf
), _T("Expected @: malformed bib file at line %ld (%s)"), BibLine
, filename
); 
 647     BibReadWord(istr
, recordType
); 
 648     BibEatWhiteSpace(istr
); 
 650     if (ch 
!= '{' && ch 
!= '(') 
 652       wxSnprintf(buf
, sizeof(buf
), _T("Expected { or ( after record type: malformed .bib file at line %ld (%s)"), BibLine
, filename
); 
 656     BibEatWhiteSpace(istr
); 
 657     if (StringMatch(recordType
, _T("string"), false, true)) 
 659       BibReadWord(istr
, recordType
); 
 660       BibEatWhiteSpace(istr
); 
 664         wxSnprintf(buf
, sizeof(buf
), _T("Expected = after string key: malformed .bib file at line %ld (%s)"), BibLine
, filename
); 
 668       BibEatWhiteSpace(istr
); 
 670       if (ch 
!= '"' && ch 
!= '{') 
 672         wxSnprintf(buf
, sizeof(buf
), _T("Expected = after string key: malformed .bib file at line %ld (%s)"), BibLine
, filename
); 
 676       BibReadValue(istr
, fieldValue
); 
 678       // Now put in hash table if necesary 
 679       if (!BibStringTable
.Get(recordType
)) 
 680         BibStringTable
.Put(recordType
, (wxObject 
*)copystring(fieldValue
)); 
 682       // Read closing ) or } 
 683       BibEatWhiteSpace(istr
); 
 685       BibEatWhiteSpace(istr
); 
 689       BibReadWord(istr
, recordKey
); 
 691       BibEntry 
*bibEntry 
= new BibEntry
; 
 692       bibEntry
->key 
= copystring(recordKey
); 
 693       bibEntry
->type 
= copystring(recordType
); 
 695       bool moreRecords 
= true; 
 696       while (moreRecords 
&& !istr
.eof()) 
 698         BibEatWhiteSpace(istr
); 
 700         if (ch 
== '}' || ch 
== ')') 
 706           BibEatWhiteSpace(istr
); 
 707           BibReadWord(istr
, recordField
); 
 708           BibEatWhiteSpace(istr
); 
 712             wxSnprintf(buf
, sizeof(buf
), _T("Expected = after field type: malformed .bib file at line %ld (%s)"), BibLine
, filename
); 
 716           BibEatWhiteSpace(istr
); 
 718           if (ch 
!= '{' && ch 
!= '"') 
 721             BibReadWord(istr
, fieldValue
+1); 
 723             // If in the table of strings, replace with string from table. 
 724             wxChar 
*s 
= (wxChar 
*)BibStringTable
.Get(fieldValue
); 
 727               wxStrcpy(fieldValue
, s
); 
 731             BibReadValue(istr
, fieldValue
, true, (ch 
== _T('"') ? true : false)); 
 733           // Now we can add a field 
 734           if (StringMatch(recordField
, _T("author"), false, true)) 
 735             bibEntry
->author 
= copystring(fieldValue
); 
 736           else if (StringMatch(recordField
, _T("key"), false, true)) 
 738           else if (StringMatch(recordField
, _T("annotate"), false, true)) 
 740           else if (StringMatch(recordField
, _T("abstract"), false, true)) 
 742           else if (StringMatch(recordField
, _T("edition"), false, true)) 
 744           else if (StringMatch(recordField
, _T("howpublished"), false, true)) 
 746           else if (StringMatch(recordField
, _T("note"), false, true) || StringMatch(recordField
, _T("notes"), false, true)) 
 748           else if (StringMatch(recordField
, _T("series"), false, true)) 
 750           else if (StringMatch(recordField
, _T("type"), false, true)) 
 752           else if (StringMatch(recordField
, _T("keywords"), false, true)) 
 754           else if (StringMatch(recordField
, _T("editor"), false, true) || StringMatch(recordField
, _T("editors"), false, true)) 
 755             bibEntry
->editor
= copystring(fieldValue
); 
 756           else if (StringMatch(recordField
, _T("title"), false, true)) 
 757             bibEntry
->title
= copystring(fieldValue
); 
 758           else if (StringMatch(recordField
, _T("booktitle"), false, true)) 
 759             bibEntry
->booktitle
= copystring(fieldValue
); 
 760           else if (StringMatch(recordField
, _T("journal"), false, true)) 
 761             bibEntry
->journal
= copystring(fieldValue
); 
 762           else if (StringMatch(recordField
, _T("volume"), false, true)) 
 763             bibEntry
->volume
= copystring(fieldValue
); 
 764           else if (StringMatch(recordField
, _T("number"), false, true)) 
 765             bibEntry
->number
= copystring(fieldValue
); 
 766           else if (StringMatch(recordField
, _T("year"), false, true)) 
 767             bibEntry
->year
= copystring(fieldValue
); 
 768           else if (StringMatch(recordField
, _T("month"), false, true)) 
 769             bibEntry
->month
= copystring(fieldValue
); 
 770           else if (StringMatch(recordField
, _T("pages"), false, true)) 
 771             bibEntry
->pages
= copystring(fieldValue
); 
 772           else if (StringMatch(recordField
, _T("publisher"), false, true)) 
 773             bibEntry
->publisher
= copystring(fieldValue
); 
 774           else if (StringMatch(recordField
, _T("address"), false, true)) 
 775             bibEntry
->address
= copystring(fieldValue
); 
 776           else if (StringMatch(recordField
, _T("institution"), false, true) || StringMatch(recordField
, _T("school"), false, true)) 
 777             bibEntry
->institution
= copystring(fieldValue
); 
 778           else if (StringMatch(recordField
, _T("organization"), false, true) || StringMatch(recordField
, _T("organisation"), false, true)) 
 779             bibEntry
->organization
= copystring(fieldValue
); 
 780           else if (StringMatch(recordField
, _T("comment"), false, true) || StringMatch(recordField
, _T("comments"), false, true)) 
 781             bibEntry
->comment
= copystring(fieldValue
); 
 782           else if (StringMatch(recordField
, _T("annote"), false, true)) 
 783             bibEntry
->comment
= copystring(fieldValue
); 
 784           else if (StringMatch(recordField
, _T("chapter"), false, true)) 
 785             bibEntry
->chapter
= copystring(fieldValue
); 
 788             wxSnprintf(buf
, sizeof(buf
), _T("Unrecognised bib field type %s at line %ld (%s)"), recordField
, BibLine
, filename
); 
 793       BibList
.Append(recordKey
, bibEntry
); 
 794       BibEatWhiteSpace(istr
); 
 800 void OutputBibItem(TexRef 
*ref
, BibEntry 
*bib
) 
 804   OnMacro(ltNUMBEREDBIBITEM
, 2, true); 
 805   OnArgument(ltNUMBEREDBIBITEM
, 1, true); 
 806   TexOutput(ref
->sectionNumber
); 
 807   OnArgument(ltNUMBEREDBIBITEM
, 1, false); 
 808   OnArgument(ltNUMBEREDBIBITEM
, 2, true); 
 811   OnMacro(ltBF
, 1, true); 
 812   OnArgument(ltBF
, 1, true); 
 814     TexOutput(bib
->author
); 
 815   OnArgument(ltBF
, 1, false); 
 816   OnMacro(ltBF
, 1, false); 
 817   if (bib
->author 
&& (wxStrlen(bib
->author
) > 0) && (bib
->author
[wxStrlen(bib
->author
) - 1] != '.')) 
 824     TexOutput(bib
->year
); 
 829     TexOutput(bib
->month
); 
 832   if (bib
->year 
|| bib
->month
) 
 835   if (StringMatch(bib
->type
, _T("article"), false, true)) 
 839       TexOutput(bib
->title
); 
 844       OnMacro(ltIT
, 1, true); 
 845       OnArgument(ltIT
, 1, true); 
 846       TexOutput(bib
->journal
); 
 847       OnArgument(ltIT
, 1, false); 
 848       OnMacro(ltIT
, 1, false); 
 853       OnMacro(ltBF
, 1, true); 
 854       OnArgument(ltBF
, 1, true); 
 855       TexOutput(bib
->volume
); 
 856       OnArgument(ltBF
, 1, false); 
 857       OnMacro(ltBF
, 1, false); 
 862       TexOutput(bib
->number
); 
 867       TexOutput(_T(", pages ")); 
 868       TexOutput(bib
->pages
); 
 872   else if (StringMatch(bib
->type
, _T("book"), false, true) || 
 873            StringMatch(bib
->type
, _T("unpublished"), false, true) || 
 874            StringMatch(bib
->type
, _T("manual"), false, true) || 
 875            StringMatch(bib
->type
, _T("phdthesis"), false, true) || 
 876            StringMatch(bib
->type
, _T("mastersthesis"), false, true) || 
 877            StringMatch(bib
->type
, _T("misc"), false, true) || 
 878            StringMatch(bib
->type
, _T("techreport"), false, true) || 
 879            StringMatch(bib
->type
, _T("booklet"), false, true)) 
 881     if (bib
->title 
|| bib
->booktitle
) 
 883       OnMacro(ltIT
, 1, true); 
 884       OnArgument(ltIT
, 1, true); 
 885       TexOutput(bib
->title 
? bib
->title 
: bib
->booktitle
); 
 887       OnArgument(ltIT
, 1, false); 
 888       OnMacro(ltIT
, 1, false); 
 890     if (StringMatch(bib
->type
, _T("phdthesis"), false, true)) 
 891       TexOutput(_T("PhD thesis. ")); 
 892     if (StringMatch(bib
->type
, _T("techreport"), false, true)) 
 893       TexOutput(_T("Technical report. ")); 
 896       TexOutput(_T("Ed. ")); 
 897       TexOutput(bib
->editor
); 
 900     if (bib
->institution
) 
 902       TexOutput(bib
->institution
); 
 905     if (bib
->organization
) 
 907       TexOutput(bib
->organization
); 
 912       TexOutput(bib
->publisher
); 
 917       TexOutput(bib
->address
); 
 921   else if (StringMatch(bib
->type
, _T("inbook"), false, true) || 
 922            StringMatch(bib
->type
, _T("inproceedings"), false, true) || 
 923            StringMatch(bib
->type
, _T("incollection"), false, true) || 
 924            StringMatch(bib
->type
, _T("conference"), false, true)) 
 928       TexOutput(bib
->title
); 
 932       TexOutput(_T(", from ")); 
 933       OnMacro(ltIT
, 1, true); 
 934       OnArgument(ltIT
, 1, true); 
 935       TexOutput(bib
->booktitle
); 
 937       OnArgument(ltIT
, 1, false); 
 938       OnMacro(ltIT
, 1, false); 
 942       TexOutput(_T(", ed. ")); 
 943       TexOutput(bib
->editor
); 
 948       TexOutput(bib
->publisher
); 
 952       if (bib
->publisher
) TexOutput(_T(", ")); 
 953       else TexOutput(_T(" ")); 
 954       TexOutput(bib
->address
); 
 956     if (bib
->publisher 
|| bib
->address
) 
 962       OnMacro(ltBF
, 1, true); 
 963       OnArgument(ltBF
, 1, true); 
 964       TexOutput(bib
->volume
); 
 965       OnArgument(ltBF
, 1, false); 
 966       OnMacro(ltBF
, 1, false); 
 973         TexOutput(bib
->number
); 
 978         TexOutput(_T(" Number ")); 
 979         TexOutput(bib
->number
); 
 985       TexOutput(_T(" Chap. ")); 
 986       TexOutput(bib
->chapter
); 
 990       if (bib
->chapter
) TexOutput(_T(", pages ")); 
 991       else TexOutput(_T(" Pages ")); 
 992       TexOutput(bib
->pages
); 
 996   OnArgument(ltNUMBEREDBIBITEM
, 2, false); 
 997   OnMacro(ltNUMBEREDBIBITEM
, 2, false); 
1000 void OutputBib(void) 
1002   // Write the heading 
1003   ForceTopicName(_T("bibliography")); 
1004   FakeCurrentSection(ReferencesNameString
); 
1005   ForceTopicName(NULL
); 
1007   OnMacro(ltPAR
, 0, true); 
1008   OnMacro(ltPAR
, 0, false); 
1010   if ((convertMode 
== TEX_RTF
) && !winHelp
) 
1012     OnMacro(ltPAR
, 0, true); 
1013     OnMacro(ltPAR
, 0, false); 
1016   wxStringListNode 
*node 
= CitationList
.GetFirst(); 
1019     wxChar 
*citeKey 
= (wxChar 
*)node
->GetData(); 
1020 //    wxNode *texNode = TexReferences.Find(citeKey); 
1021     TexRef 
*ref 
= (TexRef 
*)TexReferences
.Get(citeKey
); 
1022     wxNode 
*bibNode 
= BibList
.Find(citeKey
); 
1025       BibEntry 
*entry 
= (BibEntry 
*)bibNode
->GetData(); 
1026       OutputBibItem(ref
, entry
); 
1028     node 
= node
->GetNext(); 
1032 static int citeCount 
= 1; 
1034 void ResolveBibReferences(void) 
1036   if (CitationList
.GetCount() > 0) 
1037     OnInform(_T("Resolving bibliographic references...")); 
1041   wxStringListNode 
*node 
= CitationList
.GetFirst(); 
1045     wxChar 
*citeKey 
= (wxChar 
*)node
->GetData(); 
1046 //    wxNode *texNode = TexReferences.Find(citeKey); 
1047     TexRef 
*ref 
= (TexRef 
*)TexReferences
.Get(citeKey
); 
1048     wxNode 
*bibNode 
= BibList
.Find(citeKey
); 
1052       //BibEntry *entry = (BibEntry *)bibNode->GetData(); 
1053       if (ref
->sectionNumber
) delete[] ref
->sectionNumber
; 
1054       wxSnprintf(buf
, sizeof(buf
), _T("[%d]"), citeCount
); 
1055       ref
->sectionNumber 
= copystring(buf
); 
1060       wxSnprintf(buf
, sizeof(buf
), _T("Warning: bib ref %s not resolved."), citeKey
); 
1063     node 
= node
->GetNext(); 
1067 // Remember we need to resolve this citation 
1068 void AddCitation(wxChar 
*citeKey
) 
1070   if (!CitationList
.Member(citeKey
)) 
1071     CitationList
.Add(citeKey
); 
1073   if (!TexReferences
.Get(citeKey
)) 
1075     TexReferences
.Put(citeKey
, new TexRef(citeKey
, _T("??"), NULL
)); 
1079 TexRef 
*FindReference(wxChar 
*key
) 
1081   return (TexRef 
*)TexReferences
.Get(key
); 
1085  * Custom macro stuff 
1089 bool StringTobool(wxChar 
*val
) 
1091   if (wxStrncmp(val
, _T("yes"), 3) == 0 || wxStrncmp(val
, _T("YES"), 3) == 0 || 
1092       wxStrncmp(val
, _T("on"), 2) == 0 || wxStrncmp(val
, _T("ON"), 2) == 0 || 
1093       wxStrncmp(val
, _T("true"), 4) == 0 || wxStrncmp(val
, _T("true"), 4) == 0 || 
1094       wxStrncmp(val
, _T("ok"), 2) == 0 || wxStrncmp(val
, _T("OK"), 2) == 0 || 
1095       wxStrncmp(val
, _T("1"), 1) == 0) 
1101 void RegisterIntSetting (const wxString
& s
, int *number
) 
1111 // Define a variable value from the .ini file 
1112 wxChar 
*RegisterSetting(wxChar 
*settingName
, wxChar 
*settingValue
, bool interactive
) 
1114     wxString 
settingValueStr( settingValue 
); 
1116     static wxChar errorCode
[100]; 
1117     wxStrcpy(errorCode
, _T("OK")); 
1118     if (StringMatch(settingName
, _T("chapterName"), false, true)) 
1120         delete[] ChapterNameString
; 
1121         ChapterNameString 
= copystring(settingValue
); 
1123     else if (StringMatch(settingName
, _T("sectionName"), false, true)) 
1125         delete[] SectionNameString
; 
1126         SectionNameString 
= copystring(settingValue
); 
1128     else if (StringMatch(settingName
, _T("subsectionName"), false, true)) 
1130         delete[] SubsectionNameString
; 
1131         SubsectionNameString 
= copystring(settingValue
); 
1133     else if (StringMatch(settingName
, _T("subsubsectionName"), false, true)) 
1135         delete[] SubsubsectionNameString
; 
1136         SubsubsectionNameString 
= copystring(settingValue
); 
1138     else if (StringMatch(settingName
, _T("indexName"), false, true)) 
1140         delete[] IndexNameString
; 
1141         IndexNameString 
= copystring(settingValue
); 
1143     else if (StringMatch(settingName
, _T("contentsName"), false, true)) 
1145         delete[] ContentsNameString
; 
1146         ContentsNameString 
= copystring(settingValue
); 
1148     else if (StringMatch(settingName
, _T("glossaryName"), false, true)) 
1150         delete[] GlossaryNameString
; 
1151         GlossaryNameString 
= copystring(settingValue
); 
1153     else if (StringMatch(settingName
, _T("referencesName"), false, true)) 
1155         delete[] ReferencesNameString
; 
1156         ReferencesNameString 
= copystring(settingValue
); 
1158     else if (StringMatch(settingName
, _T("tablesName"), false, true)) 
1160         delete[] TablesNameString
; 
1161         TablesNameString 
= copystring(settingValue
); 
1163     else if (StringMatch(settingName
, _T("figuresName"), false, true)) 
1165         delete[] FiguresNameString
; 
1166         FiguresNameString 
= copystring(settingValue
); 
1168     else if (StringMatch(settingName
, _T("tableName"), false, true)) 
1170         delete[] TableNameString
; 
1171         TableNameString 
= copystring(settingValue
); 
1173     else if (StringMatch(settingName
, _T("figureName"), false, true)) 
1175         delete[] FigureNameString
; 
1176         FigureNameString 
= copystring(settingValue
); 
1178     else if (StringMatch(settingName
, _T("abstractName"), false, true)) 
1180         delete[] AbstractNameString
; 
1181         AbstractNameString 
= copystring(settingValue
); 
1183     else if (StringMatch(settingName
, _T("chapterFontSize"), false, true)) 
1184         RegisterIntSetting(settingValueStr
, &chapterFont
); 
1185     else if (StringMatch(settingName
, _T("sectionFontSize"), false, true)) 
1186         RegisterIntSetting(settingValueStr
, §ionFont
); 
1187     else if (StringMatch(settingName
, _T("subsectionFontSize"), false, true)) 
1188         RegisterIntSetting(settingValueStr
, &subsectionFont
); 
1189     else if (StringMatch(settingName
, _T("titleFontSize"), false, true)) 
1190         RegisterIntSetting(settingValueStr
, &titleFont
); 
1191     else if (StringMatch(settingName
, _T("authorFontSize"), false, true)) 
1192         RegisterIntSetting(settingValueStr
, &authorFont
); 
1193     else if (StringMatch(settingName
, _T("ignoreInput"), false, true)) 
1194         IgnorableInputFiles
.Add(wxFileNameFromPath(settingValue
)); 
1195     else if (StringMatch(settingName
, _T("mirrorMargins"), false, true)) 
1196         mirrorMargins 
= StringTobool(settingValue
); 
1197     else if (StringMatch(settingName
, _T("runTwice"), false, true)) 
1198         runTwice 
= StringTobool(settingValue
); 
1199     else if (StringMatch(settingName
, _T("isInteractive"), false, true)) 
1200         isInteractive 
= StringTobool(settingValue
); 
1201     else if (StringMatch(settingName
, _T("headerRule"), false, true)) 
1202         headerRule 
= StringTobool(settingValue
); 
1203     else if (StringMatch(settingName
, _T("footerRule"), false, true)) 
1204         footerRule 
= StringTobool(settingValue
); 
1205     else if (StringMatch(settingName
, _T("combineSubSections"), false, true)) 
1206         combineSubSections 
= StringTobool(settingValue
); 
1207     else if (StringMatch(settingName
, _T("listLabelIndent"), false, true)) 
1208         RegisterIntSetting(settingValueStr
, &labelIndentTab
); 
1209     else if (StringMatch(settingName
, _T("listItemIndent"), false, true)) 
1210         RegisterIntSetting(settingValueStr
, &itemIndentTab
); 
1211     else if (StringMatch(settingName
, _T("useUpButton"), false, true)) 
1212         useUpButton 
= StringTobool(settingValue
); 
1213     else if (StringMatch(settingName
, _T("useHeadingStyles"), false, true)) 
1214         useHeadingStyles 
= StringTobool(settingValue
); 
1215     else if (StringMatch(settingName
, _T("useWord"), false, true)) 
1216         useWord 
= StringTobool(settingValue
); 
1217     else if (StringMatch(settingName
, _T("contentsDepth"), false, true)) 
1218         RegisterIntSetting(settingValueStr
, &contentsDepth
); 
1219     else if (StringMatch(settingName
, _T("generateHPJ"), false, true)) 
1220         generateHPJ 
= StringTobool(settingValue
); 
1221     else if (StringMatch(settingName
, _T("truncateFilenames"), false, true)) 
1222         truncateFilenames 
= StringTobool(settingValue
); 
1223     else if (StringMatch(settingName
, _T("winHelpVersion"), false, true)) 
1224         RegisterIntSetting(settingValueStr
, &winHelpVersion
); 
1225     else if (StringMatch(settingName
, _T("winHelpContents"), false, true)) 
1226         winHelpContents 
= StringTobool(settingValue
); 
1227     else if (StringMatch(settingName
, _T("htmlIndex"), false, true)) 
1228         htmlIndex 
= StringTobool(settingValue
); 
1229     else if (StringMatch(settingName
, _T("htmlWorkshopFiles"), false, true)) 
1230         htmlWorkshopFiles 
= StringTobool(settingValue
); 
1231     else if (StringMatch(settingName
, _T("htmlFrameContents"), false, true)) 
1232         htmlFrameContents 
= StringTobool(settingValue
); 
1233     else if (StringMatch(settingName
, _T("htmlStylesheet"), false, true)) 
1236             delete[] htmlStylesheet
; 
1237         htmlStylesheet 
= copystring(settingValue
); 
1239     else if (StringMatch(settingName
, _T("upperCaseNames"), false, true)) 
1240         upperCaseNames 
= StringTobool(settingValue
); 
1241     else if (StringMatch(settingName
, _T("ignoreBadRefs"), false, true)) 
1242         ignoreBadRefs 
= StringTobool(settingValue
); 
1243     else if (StringMatch(settingName
, _T("htmlFaceName"), false, true)) 
1245         delete[] htmlFaceName
; 
1246         htmlFaceName 
= copystring(settingValue
); 
1248     else if (StringMatch(settingName
, _T("winHelpTitle"), false, true)) 
1251             delete[] winHelpTitle
; 
1252         winHelpTitle 
= copystring(settingValue
); 
1254     else if (StringMatch(settingName
, _T("indexSubsections"), false, true)) 
1255         indexSubsections 
= StringTobool(settingValue
); 
1256     else if (StringMatch(settingName
, _T("compatibility"), false, true)) 
1257         compatibilityMode 
= StringTobool(settingValue
); 
1258     else if (StringMatch(settingName
, _T("defaultColumnWidth"), false, true)) 
1260         RegisterIntSetting(settingValueStr
, &defaultTableColumnWidth
); 
1261         defaultTableColumnWidth 
= 20*defaultTableColumnWidth
; 
1263     else if (StringMatch(settingName
, _T("bitmapMethod"), false, true)) 
1265         if ((wxStrcmp(settingValue
, _T("includepicture")) != 0) && (wxStrcmp(settingValue
, _T("hex")) != 0) && 
1266             (wxStrcmp(settingValue
, _T("import")) != 0)) 
1269                 OnError(_T("Unknown bitmapMethod")); 
1270             wxStrcpy(errorCode
, _T("Unknown bitmapMethod")); 
1274             delete[] bitmapMethod
; 
1275             bitmapMethod 
= copystring(settingValue
); 
1278     else if (StringMatch(settingName
, _T("htmlBrowseButtons"), false, true)) 
1280         if (wxStrcmp(settingValue
, _T("none")) == 0) 
1281             htmlBrowseButtons 
= HTML_BUTTONS_NONE
; 
1282         else if (wxStrcmp(settingValue
, _T("bitmap")) == 0) 
1283             htmlBrowseButtons 
= HTML_BUTTONS_BITMAP
; 
1284         else if (wxStrcmp(settingValue
, _T("text")) == 0) 
1285             htmlBrowseButtons 
= HTML_BUTTONS_TEXT
; 
1289                 OnInform(_T("Initialisation file error: htmlBrowseButtons must be one of none, bitmap, or text.")); 
1290             wxStrcpy(errorCode
, _T("Initialisation file error: htmlBrowseButtons must be one of none, bitmap, or text.")); 
1293     else if (StringMatch(settingName
, _T("backgroundImage"), false, true)) 
1295         backgroundImageString 
= copystring(settingValue
); 
1297     else if (StringMatch(settingName
, _T("backgroundColour"), false, true)) 
1299         delete[] backgroundColourString
; 
1300         backgroundColourString 
= copystring(settingValue
); 
1302     else if (StringMatch(settingName
, _T("textColour"), false, true)) 
1304         textColourString 
= copystring(settingValue
); 
1306     else if (StringMatch(settingName
, _T("linkColour"), false, true)) 
1308         linkColourString 
= copystring(settingValue
); 
1310     else if (StringMatch(settingName
, _T("followedLinkColour"), false, true)) 
1312         followedLinkColourString 
= copystring(settingValue
); 
1314     else if (StringMatch(settingName
, _T("conversionMode"), false, true)) 
1316         if (StringMatch(settingValue
, _T("RTF"), false, true)) 
1318             winHelp 
= false; convertMode 
= TEX_RTF
; 
1320         else if (StringMatch(settingValue
, _T("WinHelp"), false, true)) 
1322             winHelp 
= true; convertMode 
= TEX_RTF
; 
1324         else if (StringMatch(settingValue
, _T("XLP"), false, true) || 
1325                  StringMatch(settingValue
, _T("wxHelp"), false, true)) 
1327             convertMode 
= TEX_XLP
; 
1329         else if (StringMatch(settingValue
, _T("HTML"), false, true)) 
1331             convertMode 
= TEX_HTML
; 
1336                 OnInform(_T("Initialisation file error: conversionMode must be one of\nRTF, WinHelp, XLP (or wxHelp), HTML.")); 
1337             wxStrcpy(errorCode
, _T("Initialisation file error: conversionMode must be one of\nRTF, WinHelp, XLP (or wxHelp), HTML.")); 
1340     else if (StringMatch(settingName
, _T("documentFontSize"), false, true)) 
1343         RegisterIntSetting(settingValueStr
, &n
); 
1344         if (n 
== 10 || n 
== 11 || n 
== 12) 
1349             wxSnprintf(buf
, sizeof(buf
), _T("Initialisation file error: nonstandard document font size %d."), n
); 
1352             wxStrcpy(errorCode
, buf
); 
1358         wxSnprintf(buf
, sizeof(buf
), _T("Initialisation file error: unrecognised setting %s."), settingName
); 
1361         wxStrcpy(errorCode
, buf
); 
1366 bool ReadCustomMacros(wxChar 
*filename
) 
1368   if (!wxFileExists(filename
)) 
1371   wxString name 
= filename
; 
1372   wxSTD ifstream 
istr((char const *)name
.fn_str(), wxSTD 
ios::in
); 
1374   if (istr
.bad()) return false; 
1376   CustomMacroList
.Clear(); 
1378   wxChar macroName
[100]; 
1379   wxChar macroBody
[1000]; 
1384     BibEatWhiteSpace(istr
); 
1389     if (ch 
!= '\\') // Not a macro definition, so must be NAME=VALUE 
1391       wxChar settingName
[100]; 
1392       settingName
[0] = ch
; 
1393       BibReadWord(istr
, (settingName
+1)); 
1394       BibEatWhiteSpace(istr
); 
1398         OnError(_T("Expected = following name: malformed tex2rtf.ini file.")); 
1403         wxChar settingValue
[200]; 
1404         BibEatWhiteSpace(istr
); 
1405         BibReadToEOL(istr
, settingValue
); 
1406         RegisterSetting(settingName
, settingValue
); 
1411       BibReadWord(istr
, macroName
); 
1412       BibEatWhiteSpace(istr
); 
1416         OnError(_T("Expected [ followed by number of arguments: malformed tex2rtf.ini file.")); 
1423         OnError(_T("Expected ] following number of arguments: malformed tex2rtf.ini file.")); 
1426       BibEatWhiteSpace(istr
); 
1430         OnError(_T("Expected { followed by macro body: malformed tex2rtf.ini file.")); 
1433       CustomMacro 
*macro 
= new CustomMacro(macroName
, noArgs
, NULL
); 
1434       BibReadValue(istr
, macroBody
, false, false); // Don't ignore extra braces 
1435       if (wxStrlen(macroBody
) > 0) 
1436         macro
->macroBody 
= copystring(macroBody
); 
1438       BibEatWhiteSpace(istr
); 
1439       CustomMacroList
.Append(macroName
, macro
); 
1440       AddMacroDef(ltCUSTOM_MACRO
, macroName
, noArgs
); 
1444   wxSnprintf(mbuf
, sizeof(mbuf
), _T("Read initialization file %s."), filename
); 
1449 CustomMacro 
*FindCustomMacro(wxChar 
*name
) 
1451   wxNode 
*node 
= CustomMacroList
.Find(name
); 
1454     CustomMacro 
*macro 
= (CustomMacro 
*)node
->GetData(); 
1460 // Display custom macros 
1461 void ShowCustomMacros(void) 
1463   wxNode 
*node 
= CustomMacroList
.GetFirst(); 
1466     OnInform(_T("No custom macros loaded.\n")); 
1473     CustomMacro 
*macro 
= (CustomMacro 
*)node
->GetData(); 
1474     wxSnprintf(buf
, sizeof(buf
), _T("\\%s[%d]\n    {%s}"), macro
->macroName
, macro
->noArgs
, 
1475      macro
->macroBody 
? macro
->macroBody 
: _T("")); 
1477     node 
= node
->GetNext(); 
1481 // Parse a string into several comma-separated fields 
1482 wxChar 
*ParseMultifieldString(wxChar 
*allFields
, int *pos
) 
1484   static wxChar buffer
[300]; 
1486   int fieldIndex 
= *pos
; 
1487   int len 
= wxStrlen(allFields
); 
1489   bool keepGoing 
= true; 
1490   while ((fieldIndex 
<= len
) && keepGoing
) 
1492     if (allFields
[fieldIndex
] == _T(' ')) 
1497     else if (allFields
[fieldIndex
] == _T(',')) 
1499       *pos 
= fieldIndex 
+ 1; 
1502     else if (allFields
[fieldIndex
] == 0) 
1504       *pos 
= fieldIndex 
+ 1; 
1509       buffer
[i
] = allFields
[fieldIndex
]; 
1515   if (oldPos 
== (*pos
)) 
1529 ColourTableEntry::ColourTableEntry(const wxChar 
*theName
, unsigned int r
,  unsigned int g
,  unsigned int b
) 
1531   name 
= copystring(theName
); 
1537 ColourTableEntry::~ColourTableEntry(void) 
1542 void AddColour(const wxChar 
*theName
, unsigned int r
,  unsigned int g
,  unsigned int b
) 
1544   wxNode 
*node 
= ColourTable
.Find(theName
); 
1547     ColourTableEntry 
*entry 
= (ColourTableEntry 
*)node
->GetData(); 
1548     if (entry
->red 
== r 
|| entry
->green 
== g 
|| entry
->blue 
== b
) 
1556   ColourTableEntry 
*entry 
= new ColourTableEntry(theName
, r
, g
, b
); 
1557   ColourTable
.Append(theName
, entry
); 
1560 int FindColourPosition(wxChar 
*theName
) 
1563   wxNode 
*node 
= ColourTable
.GetFirst(); 
1566     ColourTableEntry 
*entry 
= (ColourTableEntry 
*)node
->GetData(); 
1567     if (wxStrcmp(theName
, entry
->name
) == 0) 
1570     node 
= node
->GetNext(); 
1575 // Converts e.g. "red" -> "#FF0000" 
1576 extern void DecToHex(int, wxChar 
*); 
1577 bool FindColourHTMLString(wxChar 
*theName
, wxChar 
*buf
) 
1579   wxNode 
*node 
= ColourTable
.GetFirst(); 
1582     ColourTableEntry 
*entry 
= (ColourTableEntry 
*)node
->GetData(); 
1583     if (wxStrcmp(theName
, entry
->name
) == 0) 
1585         wxStrcpy(buf
, _T("#")); 
1588         DecToHex(entry
->red
, buf2
); 
1589         wxStrcat(buf
, buf2
); 
1590         DecToHex(entry
->green
, buf2
); 
1591         wxStrcat(buf
, buf2
); 
1592         DecToHex(entry
->blue
, buf2
); 
1593         wxStrcat(buf
, buf2
); 
1597     node 
= node
->GetNext(); 
1603 void InitialiseColourTable(void) 
1605   // \\red0\\green0\\blue0; 
1606   AddColour(_T("black"), 0,0,0); 
1608   // \\red0\\green0\\blue255;\\red0\\green255\\blue255;\n"); 
1609   AddColour(_T("cyan"), 0,255,255); 
1611   // \\red0\\green255\\blue0; 
1612   AddColour(_T("green"), 0,255,0); 
1614   // \\red255\\green0\\blue255; 
1615   AddColour(_T("magenta"), 255,0,255); 
1617   // \\red255\\green0\\blue0; 
1618   AddColour(_T("red"), 255,0,0); 
1620   // \\red255\\green255\\blue0; 
1621   AddColour(_T("yellow"), 255,255,0); 
1623   // \\red255\\green255\\blue255;}"); 
1624   AddColour(_T("white"), 255,255,255); 
1628  * The purpose of this is to reduce the number of times wxYield is 
1629  * called, since under Windows this can slow things down. 
1632 void Tex2RTFYield(bool force
) 
1635     static int yieldCount 
= 0; 
1642     if (yieldCount 
== 0) 
1652 // In both RTF generation and HTML generation for wxHelp version 2, 
1653 // we need to associate \indexed keywords with the current filename/topics. 
1655 // Hash table for lists of keywords for topics (WinHelp). 
1656 wxHashTable 
TopicTable(wxKEY_STRING
); 
1657 void AddKeyWordForTopic(wxChar 
*topic
, wxChar 
*entry
, wxChar 
*filename
) 
1659   TexTopic 
*texTopic 
= (TexTopic 
*)TopicTable
.Get(topic
); 
1662     texTopic 
= new TexTopic(filename
); 
1663     texTopic
->keywords 
= new wxStringList
; 
1664     TopicTable
.Put(topic
, texTopic
); 
1667   if (!texTopic
->keywords
->Member(entry
)) 
1668     texTopic
->keywords
->Add(entry
); 
1671 void ClearKeyWordTable(void) 
1673   TopicTable
.BeginFind(); 
1674   wxHashTable::Node 
*node 
= TopicTable
.Next(); 
1677     TexTopic 
*texTopic 
= (TexTopic 
*)node
->GetData(); 
1679     node 
= TopicTable
.Next(); 
1686  * TexTopic structure 
1689 TexTopic::TexTopic(wxChar 
*f
) 
1692     filename 
= copystring(f
); 
1695   hasChildren 
= false; 
1699 TexTopic::~TexTopic(void) 
1707 // Convert case, according to upperCaseNames setting. 
1708 wxChar 
*ConvertCase(wxChar 
*s
) 
1710   static wxChar buf
[256]; 
1711   int len 
= wxStrlen(s
); 
1714     for (i 
= 0; i 
< len
; i 
++) 
1715       buf
[i
] = (wxChar
)wxToupper(s
[i
]); 
1717     for (i 
= 0; i 
< len
; i 
++) 
1718       buf
[i
] = (wxChar
)wxTolower(s
[i
]); 
1723 #if !WXWIN_COMPATIBILITY_2 
1724 // if substring is true, search for str1 in str2 
1725 bool StringMatch(const wxChar 
*str1
, const wxChar 
*str2
, bool subString
, 
1730       wxString 
Sstr1(str1
); 
1731       wxString 
Sstr2(str2
); 
1737       return Sstr2
.Index(Sstr1
) != (size_t)wxNOT_FOUND
; 
1740       return exact 
? wxString(str2
).Cmp(str1
) == 0 : 
1741                      wxString(str2
).CmpNoCase(str1
) == 0;