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 /////////////////////////////////////////////////////////////////////////////
13 // For compilers that support precompilation, includes "wx.h".
14 #include "wx/wxprec.h"
27 #if !WXWIN_COMPATIBILITY_2_4
28 static inline wxChar
* copystring(const wxChar
* s
)
29 { return wxStrcpy(new wxChar
[wxStrlen(s
) + 1], s
); }
32 long currentBlockId
= -1;
33 static TexChunk
*descriptionItemArg
= NULL
;
34 static int indentLevel
= 0;
35 static int noColumns
= 0;
36 static int currentTab
= 0;
37 static bool tableVerticalLineLeft
= false;
38 static bool tableVerticalLineRight
= false;
39 static bool inTable
= false;
40 static int citeCount
= 1;
41 wxList
hyperLinks(wxKEY_INTEGER
);
42 wxList
hyperLabels(wxKEY_STRING
);
46 extern wxHashTable TexReferences
;
49 void PadToTab(int tabPos
)
51 int currentCol
= GetCurrentColumn();
52 for (int i
= currentCol
; i
< tabPos
; i
++)
53 TexOutput(_T(" "), true);
56 static long xlpBlockId
= 0;
62 // Called on start/end of macro examination
63 void XLPOnMacro(int macroId
, int no_args
, bool start
)
70 case ltCHAPTERHEADING
:
78 if (macroId
!= ltCHAPTERSTAR
)
81 SetCurrentOutputs(Contents
, Chapters
);
82 long id1
= NewBlockId();
83 currentBlockId
= NewBlockId();
85 startedSections
= true;
86 wxFprintf(Contents
, _T("\\hy-%d{%ld}{"), hyBLOCK_SMALL_HEADING
, id1
);
87 wxFprintf(Chapters
, _T("\n\\hy-%d{%ld}{"), hyBLOCK_LARGE_VISIBLE_SECTION
, currentBlockId
);
88 wxFprintf(Index
, _T("%ld %ld\n"), id1
, currentBlockId
);
90 OutputCurrentSection(); // Repeat section header
92 wxFprintf(Contents
, _T("}\n\n"));
93 wxFprintf(Chapters
, _T("}\n\n"));
94 SetCurrentOutput(Chapters
);
95 wxChar
*topicName
= FindTopicName(GetNextChunk());
96 hyperLabels
.Append(topicName
, (wxObject
*)currentBlockId
);
102 case ltSECTIONHEADING
:
110 if (macroId
!= ltSECTIONSTAR
)
113 SetCurrentOutputs(Chapters
, Sections
);
114 long id1
= NewBlockId();
115 currentBlockId
= NewBlockId();
117 startedSections
= true;
119 if (DocumentStyle
== LATEX_ARTICLE
)
120 wxFprintf(Contents
, _T("\\hy-%d{%ld}{"), hyBLOCK_LARGE_HEADING
, id1
);
122 wxFprintf(Chapters
, _T("\\hy-%d{%ld}{"), hyBLOCK_BOLD
, id1
);
123 wxFprintf(Sections
, _T("\n\\hy-%d{%ld}{"), hyBLOCK_LARGE_VISIBLE_SECTION
, currentBlockId
);
124 wxFprintf(Index
, _T("%ld %ld\n"), id1
, currentBlockId
);
126 OutputCurrentSection(); // Repeat section header
128 if (DocumentStyle
== LATEX_ARTICLE
)
129 wxFprintf(Contents
, _T("}\n\n"));
131 wxFprintf(Chapters
, _T("}\n\n"));
132 wxFprintf(Sections
, _T("}\n\n"));
133 SetCurrentOutput(Sections
);
134 wxChar
*topicName
= FindTopicName(GetNextChunk());
135 hyperLabels
.Append(topicName
, (wxObject
*)currentBlockId
);
140 case ltSUBSECTIONSTAR
:
141 case ltMEMBERSECTION
:
142 case ltFUNCTIONSECTION
:
148 if (macroId
!= ltSUBSECTIONSTAR
)
151 SetCurrentOutputs(Sections
, Subsections
);
152 long id1
= NewBlockId();
153 currentBlockId
= NewBlockId();
154 wxFprintf(Sections
, _T("\\hy-%d{%ld}{"), hyBLOCK_BOLD
, id1
);
155 wxFprintf(Subsections
, _T("\n\\hy-%d{%ld}{"), hyBLOCK_LARGE_VISIBLE_SECTION
, currentBlockId
);
156 wxFprintf(Index
, _T("%ld %ld\n"), id1
, currentBlockId
);
158 OutputCurrentSection(); // Repeat section header
160 wxFprintf(Sections
, _T("}\n\n"));
161 wxFprintf(Subsections
, _T("}\n\n"));
162 SetCurrentOutput(Subsections
);
163 wxChar
*topicName
= FindTopicName(GetNextChunk());
164 hyperLabels
.Append(topicName
, (wxObject
*)currentBlockId
);
168 case ltSUBSUBSECTION
:
169 case ltSUBSUBSECTIONSTAR
:
173 if (macroId
!= ltSUBSUBSECTIONSTAR
)
176 SetCurrentOutputs(Subsections
, Subsubsections
);
177 long id1
= NewBlockId();
178 currentBlockId
= NewBlockId();
179 wxFprintf(Subsections
, _T("\\hy-%d{%ld}{"), hyBLOCK_BOLD
, id1
);
180 wxFprintf(Subsubsections
, _T("\n\\hy-%d{%ld}{"), hyBLOCK_LARGE_VISIBLE_SECTION
, currentBlockId
);
181 wxFprintf(Index
, _T("%ld %ld\n"), id1
, currentBlockId
);
183 OutputCurrentSection(); // Repeat section header
185 wxFprintf(Subsections
, _T("}\n\n"));
186 wxFprintf(Subsubsections
, _T("}\n\n"));
187 SetCurrentOutput(Subsubsections
);
188 wxChar
*topicName
= FindTopicName(GetNextChunk());
189 hyperLabels
.Append(topicName
, (wxObject
*)currentBlockId
);
197 SetCurrentOutput(Subsections
);
200 long id
= NewBlockId();
201 wxFprintf(Subsections
, _T("\\hy-%d{%ld}{"), hyBLOCK_BOLD
, id
);
204 wxFprintf(Subsections
, _T("}"));
209 // TexOutput(_T("void"), true);
211 case ltBACKSLASHCHAR
:
213 TexOutput(_T("\n"), true);
220 TexOutput(_T("\n"), true);
221 TexOutput(_T("\n"), true);
238 long id
= NewBlockId();
239 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_BOLD
, id
);
242 else TexOutput(_T("}"));
252 long id
= NewBlockId();
253 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_ITALIC
, id
);
256 else TexOutput(_T("}"));
265 long id
= NewBlockId();
266 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_TELETYPE
, id
);
269 else TexOutput(_T("}"));
276 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_SMALL_TEXT
, NewBlockId());
279 else TexOutput(_T("}"));
286 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_SMALL_TEXT
, NewBlockId());
289 else TexOutput(_T("}"));
296 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_NORMAL
, NewBlockId());
299 else TexOutput(_T("}"));
306 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_SMALL_HEADING
, NewBlockId());
309 else TexOutput(_T("}\n"));
316 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_LARGE_HEADING
, NewBlockId());
319 else TexOutput(_T("}\n"));
331 // if (indentLevel > 0)
332 // TexOutput(_T("\\par\\par\n"));
335 if (macroId
== ltENUMERATE
)
336 listType
= LATEX_ENUMERATE
;
337 else if (macroId
== ltITEMIZE
)
338 listType
= LATEX_ITEMIZE
;
340 listType
= LATEX_DESCRIPTION
;
341 itemizeStack
.Insert(new ItemizeStruc(listType
));
348 if (itemizeStack
.GetFirst())
350 ItemizeStruc
*struc
= (ItemizeStruc
*)itemizeStack
.GetFirst()->GetData();
352 delete itemizeStack
.GetFirst();
359 wxNode
*node
= itemizeStack
.GetFirst();
362 ItemizeStruc
*struc
= (ItemizeStruc
*)node
->GetData();
365 struc
->currentItem
+= 1;
366 wxChar indentBuf
[30];
368 switch (struc
->listType
)
370 case LATEX_ENUMERATE
:
372 wxSnprintf(indentBuf
, sizeof(indentBuf
), _T("\\hy-%d{%ld}{%d.} "),
373 hyBLOCK_BOLD
, NewBlockId(), struc
->currentItem
);
374 TexOutput(indentBuf
);
379 wxSnprintf(indentBuf
, sizeof(indentBuf
), _T("\\hy-%d{%ld}{o} "),
380 hyBLOCK_BOLD
, NewBlockId());
381 TexOutput(indentBuf
);
385 case LATEX_DESCRIPTION
:
387 if (descriptionItemArg
)
389 wxSnprintf(indentBuf
, sizeof(indentBuf
), _T("\\hy-%d{%ld}{"),
390 hyBLOCK_BOLD
, NewBlockId());
391 TexOutput(indentBuf
);
392 TraverseChildrenFromChunk(descriptionItemArg
);
394 descriptionItemArg
= NULL
;
405 if (start
&& DocumentTitle
&& DocumentAuthor
)
407 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_LARGE_HEADING
, NewBlockId());
409 TraverseChildrenFromChunk(DocumentTitle
);
410 TexOutput(_T("}\n\n"));
411 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_SMALL_HEADING
, NewBlockId());
413 TraverseChildrenFromChunk(DocumentAuthor
);
414 TexOutput(_T("}\n\n"));
417 TraverseChildrenFromChunk(DocumentDate
);
423 case ltTABLEOFCONTENTS
:
427 FILE *fd
= wxFopen(ContentsName
, _T("r"));
433 wxPutc(ch
, Chapters
);
440 TexOutput(_T("RUN TEX2RTF AGAIN FOR CONTENTS PAGE\n"));
441 OnInform(_T("Run Tex2RTF again to include contents page."));
449 TexOutput(_T("HARDY"), true);
455 TexOutput(_T("wxCLIPS"), true);
463 long id
= NewBlockId();
464 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_TELETYPE
, id
);
467 else TexOutput(_T("}"));
474 TexOutput(_T("\n------------------------------------------------------------------"), true);
482 TexOutput(_T("--------------------------------------------------------------------------------"), true);
486 case ltSPECIALAMPERSAND
:
491 int tabPos
= (80/noColumns
)*currentTab
;
501 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_TELETYPE
, NewBlockId());
508 case ltNUMBEREDBIBITEM
:
511 TexOutput(_T("\n\n"), true);
522 if (DocumentStyle
!= LATEX_ARTICLE
)
523 wxSnprintf(figBuf
, sizeof(figBuf
), _T("Figure %d.%d: "), chapterNo
, figureNo
);
525 wxSnprintf(figBuf
, sizeof(figBuf
), _T("Figure %d: "), figureNo
);
531 wxChar
*topicName
= FindTopicName(GetNextChunk());
533 AddTexRef(topicName
, NULL
, NULL
,
534 ((DocumentStyle
!= LATEX_ARTICLE
) ? chapterNo
: figureNo
),
535 ((DocumentStyle
!= LATEX_ARTICLE
) ? figureNo
: 0));
541 DefaultOnMacro(macroId
, no_args
, start
);
547 bool XLPOnArgument(int macroId
, int arg_no
, bool start
)
554 case ltCHAPTERHEADING
:
557 case ltSECTIONHEADING
:
559 case ltSUBSECTIONSTAR
:
560 case ltSUBSUBSECTION
:
561 case ltSUBSUBSECTIONSTAR
:
563 case ltMEMBERSECTION
:
564 case ltFUNCTIONSECTION
:
566 if (!start
&& (arg_no
== 1))
567 currentSection
= GetArgChunk();
572 if (!start
&& (arg_no
== 1))
573 TexOutput(_T(" "), true);
574 if (start
&& (arg_no
== 3))
575 TexOutput(_T("("), true);
576 if (!start
&& (arg_no
== 3))
577 TexOutput(_T(")"), true);
582 if (!start
&& (arg_no
== 1))
583 TexOutput(_T(" "), true);
585 if (start
&& (arg_no
== 2))
586 TexOutput(_T("(*"), true);
587 if (!start
&& (arg_no
== 2))
588 TexOutput(_T(")"), true);
590 if (start
&& (arg_no
== 3))
591 TexOutput(_T("("), true);
592 if (!start
&& (arg_no
== 3))
593 TexOutput(_T(")"), true);
598 if (!start
&& (arg_no
== 1))
599 TexOutput(_T(" "), true);
600 if (start
&& (arg_no
== 2))
602 TexOutput(_T("("), true);
603 long id
= NewBlockId();
604 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_BOLD
, id
);
607 if (!start
&& (arg_no
== 2))
611 if (!start
&& (arg_no
== 3))
612 TexOutput(_T(")"), true);
617 if (start
&& (arg_no
== 2))
619 long id
= NewBlockId();
620 wxSnprintf(buf
, sizeof(buf
), _T(" \\hy-%d{%ld}{"), hyBLOCK_BOLD
, id
);
623 if (!start
&& (arg_no
== 2))
631 if (start
&& (arg_no
== 2))
633 long id
= NewBlockId();
634 wxSnprintf(buf
, sizeof(buf
), _T(" \\hy-%d{%ld}{"), hyBLOCK_BOLD
, id
);
637 if (!start
&& (arg_no
== 2))
645 if (!start
&& (arg_no
== 1))
646 TexOutput(_T(" "), true);
659 wxChar
*refName
= GetArgData();
662 TexRef
*texRef
= FindReference(refName
);
665 sec
= texRef
->sectionNumber
;
684 currentBlockId
= NewBlockId();
685 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_RED_ITALIC
, currentBlockId
);
688 else TexOutput(_T("}"));
694 wxChar
*label
= GetArgData();
695 hyperLinks
.Append(currentBlockId
, (wxObject
*)copystring(label
));
708 else if (arg_no
== 2)
720 if (start
&& IsArgOptional())
722 descriptionItemArg
= GetArgChunk();
735 tableVerticalLineLeft
= false;
736 tableVerticalLineRight
= false;
738 wxChar
*alignString
= copystring(GetArgData());
740 // Count the number of columns
742 int len
= wxStrlen(alignString
);
745 if (alignString
[0] == '|')
746 tableVerticalLineLeft
= true;
747 if (alignString
[len
-1] == '|')
748 tableVerticalLineRight
= true;
751 for (int i
= 0; i
< len
; i
++)
752 if (isalpha(alignString
[i
]))
757 TexOutput(_T("\\brdrt\\brdrs"));
758 if (tableVerticalLineLeft)
759 TexOutput(_T("\\brdrl\\brdrs"));
760 if (tableVerticalLineRight)
761 TexOutput(_T("\\brdrr\\brdrs"));
764 // Calculate a rough size for each column
765 // int tabPos = 80/noColumns;
771 else if (arg_no
== 2 && !start
)
775 else if (arg_no
== 2 && start
)
780 case ltMARGINPAREVEN
:
787 TexOutput(_T("----------------------------------------------------------------------\n"), true);
791 TexOutput(_T("\n----------------------------------------------------------------------\n"), true);
797 if (arg_no
== 1 && start
)
799 wxChar
*citeKey
= GetArgData();
800 TexRef
*ref
= (TexRef
*)TexReferences
.Get(citeKey
);
803 if (ref
->sectionNumber
) delete[] ref
->sectionNumber
;
804 wxSnprintf(buf
, sizeof(buf
), _T("[%d]"), citeCount
);
805 ref
->sectionNumber
= copystring(buf
);
808 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{[%d]} "), hyBLOCK_BOLD
, NewBlockId(), citeCount
);
815 case ltTHEBIBLIOGRAPHY
:
817 if (start
&& (arg_no
== 1))
821 SetCurrentOutput(Chapters
);
823 SetCurrentOutputs(Contents
, Chapters
);
824 long id1
= NewBlockId();
825 long id2
= NewBlockId();
826 wxFprintf(Contents
, _T("\\hy-%d{%ld}{%s}\n"), hyBLOCK_SMALL_HEADING
, id1
, ReferencesNameString
);
827 wxFprintf(Chapters
, _T("\\hy-%d{%ld}{%s}\n\n\n"), hyBLOCK_LARGE_VISIBLE_SECTION
, id2
, ReferencesNameString
);
828 wxFprintf(Index
, _T("%ld %ld\n"), id1
, id2
);
830 SetCurrentOutput(Chapters
);
833 if (!start
&& (arg_no
== 2))
839 case ltTWOCOLITEMRULED
:
841 if (start
&& (arg_no
== 2))
842 TexOutput(_T("\n "));
844 if (!start
&& (arg_no
== 2))
856 wxChar
*val
= GetArgData();
902 wxChar
*val
= GetArgData();
954 wxChar
*val
= GetArgData();
1000 wxChar
*val
= GetArgData();
1033 case ltACCENT_UMLAUT
:
1037 wxChar
*val
= GetArgData();
1089 wxChar
*val
= GetArgData();
1107 case ltACCENT_CADILLA
:
1111 wxChar
*val
= GetArgData();
1131 return DefaultOnArgument(macroId
, arg_no
, start
);
1141 if (!InputFile
.empty() && !OutputFile
.empty())
1143 Contents
= wxFopen(TmpContentsName
, _T("w"));
1144 Chapters
= wxFopen(_T("chapters.xlp"), _T("w"));
1145 Sections
= wxFopen(_T("sections.xlp"), _T("w"));
1146 Subsections
= wxFopen(_T("subsections.xlp"), _T("w"));
1147 Subsubsections
= wxFopen(_T("subsubsections.xlp"), _T("w"));
1148 Index
= wxFopen(_T("index.xlp"), _T("w"));
1150 // Insert invisible section marker at beginning
1151 wxFprintf(Chapters
, _T("\\hy-%d{%ld}{%s}\n"),
1152 hyBLOCK_INVISIBLE_SECTION
, NewBlockId(), _T("\n"));
1154 wxFprintf(Contents
, _T("\\hy-%d{%ld}{%s}\n\n"),
1155 // hyBLOCK_LARGE_HEADING, NewBlockId(), "\n\n%s\n\n", ContentsNameString);
1156 hyBLOCK_LARGE_HEADING
, NewBlockId(), ContentsNameString
);
1158 SetCurrentOutput(Chapters
);
1160 wxFprintf(Index
, _T("\n\\hyindex{\n\"%s\"\n"),
1161 contentsString
? contentsString
: _T("WXHELPCONTENTS"));
1164 wxNode
*node
= hyperLinks
.GetFirst();
1167 long from
= node
->GetKeyInteger();
1168 wxChar
*label
= (wxChar
*)node
->GetData();
1169 wxNode
*otherNode
= hyperLabels
.Find(label
);
1172 long to
= (long)otherNode
->GetData();
1173 wxFprintf(Index
, _T("%ld %ld\n"), from
, to
);
1175 node
= node
->GetNext();
1178 wxFprintf(Index
, _T("}\n"));
1180 fclose(Contents
); Contents
= NULL
;
1181 fclose(Chapters
); Chapters
= NULL
;
1182 fclose(Sections
); Sections
= NULL
;
1183 fclose(Subsections
); Subsections
= NULL
;
1184 fclose(Subsubsections
); Subsubsections
= NULL
;
1185 fclose(Index
); Index
= NULL
;
1187 if (wxFileExists(ContentsName
)) wxRemoveFile(ContentsName
);
1189 if (!wxRenameFile(TmpContentsName
, ContentsName
))
1191 wxCopyFile(TmpContentsName
, ContentsName
);
1192 wxRemoveFile(TmpContentsName
);
1195 wxConcatFiles(_T("chapters.xlp"), _T("sections.xlp"), _T("tmp2.xlp"));
1196 wxConcatFiles(_T("tmp2.xlp"), _T("subsections.xlp"), _T("tmp1.xlp"));
1197 wxConcatFiles(_T("tmp1.xlp"), _T("subsubsections.xlp"), _T("tmp2.xlp"));
1198 wxConcatFiles(_T("tmp2.xlp"), _T("index.xlp"), OutputFile
);
1200 wxRemoveFile(_T("tmp1.xlp"));
1201 wxRemoveFile(_T("tmp2.xlp"));
1203 wxRemoveFile(_T("chapters.xlp"));
1204 wxRemoveFile(_T("sections.xlp"));
1205 wxRemoveFile(_T("subsections.xlp"));
1206 wxRemoveFile(_T("subsubsections.xlp"));
1207 wxRemoveFile(_T("index.xlp"));