1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Converts Latex to obsolete XLP format
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"
31 #if !WXWIN_COMPATIBILITY_2_4
32 static inline wxChar
* copystring(const wxChar
* s
)
33 { return wxStrcpy(new wxChar
[wxStrlen(s
) + 1], s
); }
36 long currentBlockId
= -1;
37 static TexChunk
*descriptionItemArg
= NULL
;
38 static int indentLevel
= 0;
39 static int noColumns
= 0;
40 static int currentTab
= 0;
41 static bool tableVerticalLineLeft
= false;
42 static bool tableVerticalLineRight
= false;
43 static bool inTable
= false;
44 static int citeCount
= 1;
45 wxList
hyperLinks(wxKEY_INTEGER
);
46 wxList
hyperLabels(wxKEY_STRING
);
50 extern wxHashTable TexReferences
;
53 void PadToTab(int tabPos
)
55 int currentCol
= GetCurrentColumn();
56 for (int i
= currentCol
; i
< tabPos
; i
++)
57 TexOutput(_T(" "), true);
60 static long xlpBlockId
= 0;
66 // Called on start/end of macro examination
67 void XLPOnMacro(int macroId
, int no_args
, bool start
)
74 case ltCHAPTERHEADING
:
82 if (macroId
!= ltCHAPTERSTAR
)
85 SetCurrentOutputs(Contents
, Chapters
);
86 long id1
= NewBlockId();
87 currentBlockId
= NewBlockId();
89 startedSections
= true;
90 wxFprintf(Contents
, _T("\\hy-%d{%ld}{"), hyBLOCK_SMALL_HEADING
, id1
);
91 wxFprintf(Chapters
, _T("\n\\hy-%d{%ld}{"), hyBLOCK_LARGE_VISIBLE_SECTION
, currentBlockId
);
92 wxFprintf(Index
, _T("%ld %ld\n"), id1
, currentBlockId
);
94 OutputCurrentSection(); // Repeat section header
96 wxFprintf(Contents
, _T("}\n\n"));
97 wxFprintf(Chapters
, _T("}\n\n"));
98 SetCurrentOutput(Chapters
);
99 wxChar
*topicName
= FindTopicName(GetNextChunk());
100 hyperLabels
.Append(topicName
, (wxObject
*)currentBlockId
);
106 case ltSECTIONHEADING
:
114 if (macroId
!= ltSECTIONSTAR
)
117 SetCurrentOutputs(Chapters
, Sections
);
118 long id1
= NewBlockId();
119 currentBlockId
= NewBlockId();
121 startedSections
= true;
123 if (DocumentStyle
== LATEX_ARTICLE
)
124 wxFprintf(Contents
, _T("\\hy-%d{%ld}{"), hyBLOCK_LARGE_HEADING
, id1
);
126 wxFprintf(Chapters
, _T("\\hy-%d{%ld}{"), hyBLOCK_BOLD
, id1
);
127 wxFprintf(Sections
, _T("\n\\hy-%d{%ld}{"), hyBLOCK_LARGE_VISIBLE_SECTION
, currentBlockId
);
128 wxFprintf(Index
, _T("%ld %ld\n"), id1
, currentBlockId
);
130 OutputCurrentSection(); // Repeat section header
132 if (DocumentStyle
== LATEX_ARTICLE
)
133 wxFprintf(Contents
, _T("}\n\n"));
135 wxFprintf(Chapters
, _T("}\n\n"));
136 wxFprintf(Sections
, _T("}\n\n"));
137 SetCurrentOutput(Sections
);
138 wxChar
*topicName
= FindTopicName(GetNextChunk());
139 hyperLabels
.Append(topicName
, (wxObject
*)currentBlockId
);
144 case ltSUBSECTIONSTAR
:
145 case ltMEMBERSECTION
:
146 case ltFUNCTIONSECTION
:
152 if (macroId
!= ltSUBSECTIONSTAR
)
155 SetCurrentOutputs(Sections
, Subsections
);
156 long id1
= NewBlockId();
157 currentBlockId
= NewBlockId();
158 wxFprintf(Sections
, _T("\\hy-%d{%ld}{"), hyBLOCK_BOLD
, id1
);
159 wxFprintf(Subsections
, _T("\n\\hy-%d{%ld}{"), hyBLOCK_LARGE_VISIBLE_SECTION
, currentBlockId
);
160 wxFprintf(Index
, _T("%ld %ld\n"), id1
, currentBlockId
);
162 OutputCurrentSection(); // Repeat section header
164 wxFprintf(Sections
, _T("}\n\n"));
165 wxFprintf(Subsections
, _T("}\n\n"));
166 SetCurrentOutput(Subsections
);
167 wxChar
*topicName
= FindTopicName(GetNextChunk());
168 hyperLabels
.Append(topicName
, (wxObject
*)currentBlockId
);
172 case ltSUBSUBSECTION
:
173 case ltSUBSUBSECTIONSTAR
:
177 if (macroId
!= ltSUBSUBSECTIONSTAR
)
180 SetCurrentOutputs(Subsections
, Subsubsections
);
181 long id1
= NewBlockId();
182 currentBlockId
= NewBlockId();
183 wxFprintf(Subsections
, _T("\\hy-%d{%ld}{"), hyBLOCK_BOLD
, id1
);
184 wxFprintf(Subsubsections
, _T("\n\\hy-%d{%ld}{"), hyBLOCK_LARGE_VISIBLE_SECTION
, currentBlockId
);
185 wxFprintf(Index
, _T("%ld %ld\n"), id1
, currentBlockId
);
187 OutputCurrentSection(); // Repeat section header
189 wxFprintf(Subsections
, _T("}\n\n"));
190 wxFprintf(Subsubsections
, _T("}\n\n"));
191 SetCurrentOutput(Subsubsections
);
192 wxChar
*topicName
= FindTopicName(GetNextChunk());
193 hyperLabels
.Append(topicName
, (wxObject
*)currentBlockId
);
201 SetCurrentOutput(Subsections
);
204 long id
= NewBlockId();
205 wxFprintf(Subsections
, _T("\\hy-%d{%ld}{"), hyBLOCK_BOLD
, id
);
208 wxFprintf(Subsections
, _T("}"));
213 // TexOutput(_T("void"), true);
215 case ltBACKSLASHCHAR
:
217 TexOutput(_T("\n"), true);
224 TexOutput(_T("\n"), true);
225 TexOutput(_T("\n"), true);
242 long id
= NewBlockId();
243 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_BOLD
, id
);
246 else TexOutput(_T("}"));
256 long id
= NewBlockId();
257 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_ITALIC
, id
);
260 else TexOutput(_T("}"));
269 long id
= NewBlockId();
270 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_TELETYPE
, id
);
273 else TexOutput(_T("}"));
280 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_SMALL_TEXT
, NewBlockId());
283 else TexOutput(_T("}"));
290 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_SMALL_TEXT
, NewBlockId());
293 else TexOutput(_T("}"));
300 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_NORMAL
, NewBlockId());
303 else TexOutput(_T("}"));
310 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_SMALL_HEADING
, NewBlockId());
313 else TexOutput(_T("}\n"));
320 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_LARGE_HEADING
, NewBlockId());
323 else TexOutput(_T("}\n"));
335 // if (indentLevel > 0)
336 // TexOutput(_T("\\par\\par\n"));
339 if (macroId
== ltENUMERATE
)
340 listType
= LATEX_ENUMERATE
;
341 else if (macroId
== ltITEMIZE
)
342 listType
= LATEX_ITEMIZE
;
344 listType
= LATEX_DESCRIPTION
;
345 itemizeStack
.Insert(new ItemizeStruc(listType
));
352 if (itemizeStack
.GetFirst())
354 ItemizeStruc
*struc
= (ItemizeStruc
*)itemizeStack
.GetFirst()->GetData();
356 delete itemizeStack
.GetFirst();
363 wxNode
*node
= itemizeStack
.GetFirst();
366 ItemizeStruc
*struc
= (ItemizeStruc
*)node
->GetData();
369 struc
->currentItem
+= 1;
370 wxChar indentBuf
[30];
372 switch (struc
->listType
)
374 case LATEX_ENUMERATE
:
376 wxSnprintf(indentBuf
, sizeof(indentBuf
), _T("\\hy-%d{%ld}{%d.} "),
377 hyBLOCK_BOLD
, NewBlockId(), struc
->currentItem
);
378 TexOutput(indentBuf
);
383 wxSnprintf(indentBuf
, sizeof(indentBuf
), _T("\\hy-%d{%ld}{o} "),
384 hyBLOCK_BOLD
, NewBlockId());
385 TexOutput(indentBuf
);
389 case LATEX_DESCRIPTION
:
391 if (descriptionItemArg
)
393 wxSnprintf(indentBuf
, sizeof(indentBuf
), _T("\\hy-%d{%ld}{"),
394 hyBLOCK_BOLD
, NewBlockId());
395 TexOutput(indentBuf
);
396 TraverseChildrenFromChunk(descriptionItemArg
);
398 descriptionItemArg
= NULL
;
409 if (start
&& DocumentTitle
&& DocumentAuthor
)
411 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_LARGE_HEADING
, NewBlockId());
413 TraverseChildrenFromChunk(DocumentTitle
);
414 TexOutput(_T("}\n\n"));
415 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_SMALL_HEADING
, NewBlockId());
417 TraverseChildrenFromChunk(DocumentAuthor
);
418 TexOutput(_T("}\n\n"));
421 TraverseChildrenFromChunk(DocumentDate
);
427 case ltTABLEOFCONTENTS
:
431 FILE *fd
= wxFopen(ContentsName
, _T("r"));
437 wxPutc(ch
, Chapters
);
444 TexOutput(_T("RUN TEX2RTF AGAIN FOR CONTENTS PAGE\n"));
445 OnInform(_T("Run Tex2RTF again to include contents page."));
453 TexOutput(_T("HARDY"), true);
459 TexOutput(_T("wxCLIPS"), true);
467 long id
= NewBlockId();
468 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_TELETYPE
, id
);
471 else TexOutput(_T("}"));
478 TexOutput(_T("\n------------------------------------------------------------------"), true);
486 TexOutput(_T("--------------------------------------------------------------------------------"), true);
490 case ltSPECIALAMPERSAND
:
495 int tabPos
= (80/noColumns
)*currentTab
;
505 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_TELETYPE
, NewBlockId());
512 case ltNUMBEREDBIBITEM
:
515 TexOutput(_T("\n\n"), true);
526 if (DocumentStyle
!= LATEX_ARTICLE
)
527 wxSnprintf(figBuf
, sizeof(figBuf
), _T("Figure %d.%d: "), chapterNo
, figureNo
);
529 wxSnprintf(figBuf
, sizeof(figBuf
), _T("Figure %d: "), figureNo
);
535 wxChar
*topicName
= FindTopicName(GetNextChunk());
537 AddTexRef(topicName
, NULL
, NULL
,
538 ((DocumentStyle
!= LATEX_ARTICLE
) ? chapterNo
: figureNo
),
539 ((DocumentStyle
!= LATEX_ARTICLE
) ? figureNo
: 0));
545 DefaultOnMacro(macroId
, no_args
, start
);
551 bool XLPOnArgument(int macroId
, int arg_no
, bool start
)
558 case ltCHAPTERHEADING
:
561 case ltSECTIONHEADING
:
563 case ltSUBSECTIONSTAR
:
564 case ltSUBSUBSECTION
:
565 case ltSUBSUBSECTIONSTAR
:
567 case ltMEMBERSECTION
:
568 case ltFUNCTIONSECTION
:
570 if (!start
&& (arg_no
== 1))
571 currentSection
= GetArgChunk();
576 if (!start
&& (arg_no
== 1))
577 TexOutput(_T(" "), true);
578 if (start
&& (arg_no
== 3))
579 TexOutput(_T("("), true);
580 if (!start
&& (arg_no
== 3))
581 TexOutput(_T(")"), true);
586 if (!start
&& (arg_no
== 1))
587 TexOutput(_T(" "), true);
589 if (start
&& (arg_no
== 2))
590 TexOutput(_T("(*"), true);
591 if (!start
&& (arg_no
== 2))
592 TexOutput(_T(")"), true);
594 if (start
&& (arg_no
== 3))
595 TexOutput(_T("("), true);
596 if (!start
&& (arg_no
== 3))
597 TexOutput(_T(")"), true);
602 if (!start
&& (arg_no
== 1))
603 TexOutput(_T(" "), true);
604 if (start
&& (arg_no
== 2))
606 TexOutput(_T("("), true);
607 long id
= NewBlockId();
608 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_BOLD
, id
);
611 if (!start
&& (arg_no
== 2))
615 if (!start
&& (arg_no
== 3))
616 TexOutput(_T(")"), true);
621 if (start
&& (arg_no
== 2))
623 long id
= NewBlockId();
624 wxSnprintf(buf
, sizeof(buf
), _T(" \\hy-%d{%ld}{"), hyBLOCK_BOLD
, id
);
627 if (!start
&& (arg_no
== 2))
635 if (start
&& (arg_no
== 2))
637 long id
= NewBlockId();
638 wxSnprintf(buf
, sizeof(buf
), _T(" \\hy-%d{%ld}{"), hyBLOCK_BOLD
, id
);
641 if (!start
&& (arg_no
== 2))
649 if (!start
&& (arg_no
== 1))
650 TexOutput(_T(" "), true);
663 wxChar
*refName
= GetArgData();
666 TexRef
*texRef
= FindReference(refName
);
669 sec
= texRef
->sectionNumber
;
688 currentBlockId
= NewBlockId();
689 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_RED_ITALIC
, currentBlockId
);
692 else TexOutput(_T("}"));
698 wxChar
*label
= GetArgData();
699 hyperLinks
.Append(currentBlockId
, (wxObject
*)copystring(label
));
712 else if (arg_no
== 2)
724 if (start
&& IsArgOptional())
726 descriptionItemArg
= GetArgChunk();
739 tableVerticalLineLeft
= false;
740 tableVerticalLineRight
= false;
742 wxChar
*alignString
= copystring(GetArgData());
744 // Count the number of columns
746 int len
= wxStrlen(alignString
);
749 if (alignString
[0] == '|')
750 tableVerticalLineLeft
= true;
751 if (alignString
[len
-1] == '|')
752 tableVerticalLineRight
= true;
755 for (int i
= 0; i
< len
; i
++)
756 if (isalpha(alignString
[i
]))
761 TexOutput(_T("\\brdrt\\brdrs"));
762 if (tableVerticalLineLeft)
763 TexOutput(_T("\\brdrl\\brdrs"));
764 if (tableVerticalLineRight)
765 TexOutput(_T("\\brdrr\\brdrs"));
768 // Calculate a rough size for each column
769 // int tabPos = 80/noColumns;
775 else if (arg_no
== 2 && !start
)
779 else if (arg_no
== 2 && start
)
784 case ltMARGINPAREVEN
:
791 TexOutput(_T("----------------------------------------------------------------------\n"), true);
795 TexOutput(_T("\n----------------------------------------------------------------------\n"), true);
801 if (arg_no
== 1 && start
)
803 wxChar
*citeKey
= GetArgData();
804 TexRef
*ref
= (TexRef
*)TexReferences
.Get(citeKey
);
807 if (ref
->sectionNumber
) delete[] ref
->sectionNumber
;
808 wxSnprintf(buf
, sizeof(buf
), _T("[%d]"), citeCount
);
809 ref
->sectionNumber
= copystring(buf
);
812 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{[%d]} "), hyBLOCK_BOLD
, NewBlockId(), citeCount
);
819 case ltTHEBIBLIOGRAPHY
:
821 if (start
&& (arg_no
== 1))
825 SetCurrentOutput(Chapters
);
827 SetCurrentOutputs(Contents
, Chapters
);
828 long id1
= NewBlockId();
829 long id2
= NewBlockId();
830 wxFprintf(Contents
, _T("\\hy-%d{%ld}{%s}\n"), hyBLOCK_SMALL_HEADING
, id1
, ReferencesNameString
);
831 wxFprintf(Chapters
, _T("\\hy-%d{%ld}{%s}\n\n\n"), hyBLOCK_LARGE_VISIBLE_SECTION
, id2
, ReferencesNameString
);
832 wxFprintf(Index
, _T("%ld %ld\n"), id1
, id2
);
834 SetCurrentOutput(Chapters
);
837 if (!start
&& (arg_no
== 2))
843 case ltTWOCOLITEMRULED
:
845 if (start
&& (arg_no
== 2))
846 TexOutput(_T("\n "));
848 if (!start
&& (arg_no
== 2))
860 wxChar
*val
= GetArgData();
906 wxChar
*val
= GetArgData();
958 wxChar
*val
= GetArgData();
1000 case ltACCENT_TILDE
:
1004 wxChar
*val
= GetArgData();
1037 case ltACCENT_UMLAUT
:
1041 wxChar
*val
= GetArgData();
1093 wxChar
*val
= GetArgData();
1111 case ltACCENT_CADILLA
:
1115 wxChar
*val
= GetArgData();
1135 return DefaultOnArgument(macroId
, arg_no
, start
);
1145 if (InputFile
&& OutputFile
)
1147 Contents
= wxFopen(TmpContentsName
, _T("w"));
1148 Chapters
= wxFopen(_T("chapters.xlp"), _T("w"));
1149 Sections
= wxFopen(_T("sections.xlp"), _T("w"));
1150 Subsections
= wxFopen(_T("subsections.xlp"), _T("w"));
1151 Subsubsections
= wxFopen(_T("subsubsections.xlp"), _T("w"));
1152 Index
= wxFopen(_T("index.xlp"), _T("w"));
1154 // Insert invisible section marker at beginning
1155 wxFprintf(Chapters
, _T("\\hy-%d{%ld}{%s}\n"),
1156 hyBLOCK_INVISIBLE_SECTION
, NewBlockId(), _T("\n"));
1158 wxFprintf(Contents
, _T("\\hy-%d{%ld}{%s}\n\n"),
1159 // hyBLOCK_LARGE_HEADING, NewBlockId(), "\n\n%s\n\n", ContentsNameString);
1160 hyBLOCK_LARGE_HEADING
, NewBlockId(), ContentsNameString
);
1162 SetCurrentOutput(Chapters
);
1164 wxFprintf(Index
, _T("\n\\hyindex{\n\"%s\"\n"),
1165 contentsString
? contentsString
: _T("WXHELPCONTENTS"));
1168 wxNode
*node
= hyperLinks
.GetFirst();
1171 long from
= node
->GetKeyInteger();
1172 wxChar
*label
= (wxChar
*)node
->GetData();
1173 wxNode
*otherNode
= hyperLabels
.Find(label
);
1176 long to
= (long)otherNode
->GetData();
1177 wxFprintf(Index
, _T("%ld %ld\n"), from
, to
);
1179 node
= node
->GetNext();
1182 wxFprintf(Index
, _T("}\n"));
1184 fclose(Contents
); Contents
= NULL
;
1185 fclose(Chapters
); Chapters
= NULL
;
1186 fclose(Sections
); Sections
= NULL
;
1187 fclose(Subsections
); Subsections
= NULL
;
1188 fclose(Subsubsections
); Subsubsections
= NULL
;
1189 fclose(Index
); Index
= NULL
;
1191 if (wxFileExists(ContentsName
)) wxRemoveFile(ContentsName
);
1193 if (!wxRenameFile(TmpContentsName
, ContentsName
))
1195 wxCopyFile(TmpContentsName
, ContentsName
);
1196 wxRemoveFile(TmpContentsName
);
1199 wxConcatFiles(_T("chapters.xlp"), _T("sections.xlp"), _T("tmp2.xlp"));
1200 wxConcatFiles(_T("tmp2.xlp"), _T("subsections.xlp"), _T("tmp1.xlp"));
1201 wxConcatFiles(_T("tmp1.xlp"), _T("subsubsections.xlp"), _T("tmp2.xlp"));
1202 wxConcatFiles(_T("tmp2.xlp"), _T("index.xlp"), OutputFile
);
1204 wxRemoveFile(_T("tmp1.xlp"));
1205 wxRemoveFile(_T("tmp2.xlp"));
1207 wxRemoveFile(_T("chapters.xlp"));
1208 wxRemoveFile(_T("sections.xlp"));
1209 wxRemoveFile(_T("subsections.xlp"));
1210 wxRemoveFile(_T("subsubsections.xlp"));
1211 wxRemoveFile(_T("index.xlp"));