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 static inline wxChar
* copystring(const wxChar
* s
)
28 { return wxStrcpy(new wxChar
[wxStrlen(s
) + 1], s
); }
30 long currentBlockId
= -1;
31 static TexChunk
*descriptionItemArg
= NULL
;
32 static int indentLevel
= 0;
33 static int noColumns
= 0;
34 static int currentTab
= 0;
35 static bool tableVerticalLineLeft
= false;
36 static bool tableVerticalLineRight
= false;
37 static bool inTable
= false;
38 static int citeCount
= 1;
39 wxList
hyperLinks(wxKEY_INTEGER
);
40 wxList
hyperLabels(wxKEY_STRING
);
44 extern wxHashTable TexReferences
;
47 void PadToTab(int tabPos
)
49 int currentCol
= GetCurrentColumn();
50 for (int i
= currentCol
; i
< tabPos
; i
++)
51 TexOutput(_T(" "), true);
54 static long xlpBlockId
= 0;
60 // Called on start/end of macro examination
61 void XLPOnMacro(int macroId
, int no_args
, bool start
)
68 case ltCHAPTERHEADING
:
76 if (macroId
!= ltCHAPTERSTAR
)
79 SetCurrentOutputs(Contents
, Chapters
);
80 long id1
= NewBlockId();
81 currentBlockId
= NewBlockId();
83 startedSections
= true;
84 wxFprintf(Contents
, _T("\\hy-%d{%ld}{"), hyBLOCK_SMALL_HEADING
, id1
);
85 wxFprintf(Chapters
, _T("\n\\hy-%d{%ld}{"), hyBLOCK_LARGE_VISIBLE_SECTION
, currentBlockId
);
86 wxFprintf(Index
, _T("%ld %ld\n"), id1
, currentBlockId
);
88 OutputCurrentSection(); // Repeat section header
90 wxFprintf(Contents
, _T("}\n\n"));
91 wxFprintf(Chapters
, _T("}\n\n"));
92 SetCurrentOutput(Chapters
);
93 wxChar
*topicName
= FindTopicName(GetNextChunk());
94 hyperLabels
.Append(topicName
, (wxObject
*)currentBlockId
);
100 case ltSECTIONHEADING
:
108 if (macroId
!= ltSECTIONSTAR
)
111 SetCurrentOutputs(Chapters
, Sections
);
112 long id1
= NewBlockId();
113 currentBlockId
= NewBlockId();
115 startedSections
= true;
117 if (DocumentStyle
== LATEX_ARTICLE
)
118 wxFprintf(Contents
, _T("\\hy-%d{%ld}{"), hyBLOCK_LARGE_HEADING
, id1
);
120 wxFprintf(Chapters
, _T("\\hy-%d{%ld}{"), hyBLOCK_BOLD
, id1
);
121 wxFprintf(Sections
, _T("\n\\hy-%d{%ld}{"), hyBLOCK_LARGE_VISIBLE_SECTION
, currentBlockId
);
122 wxFprintf(Index
, _T("%ld %ld\n"), id1
, currentBlockId
);
124 OutputCurrentSection(); // Repeat section header
126 if (DocumentStyle
== LATEX_ARTICLE
)
127 wxFprintf(Contents
, _T("}\n\n"));
129 wxFprintf(Chapters
, _T("}\n\n"));
130 wxFprintf(Sections
, _T("}\n\n"));
131 SetCurrentOutput(Sections
);
132 wxChar
*topicName
= FindTopicName(GetNextChunk());
133 hyperLabels
.Append(topicName
, (wxObject
*)currentBlockId
);
138 case ltSUBSECTIONSTAR
:
139 case ltMEMBERSECTION
:
140 case ltFUNCTIONSECTION
:
146 if (macroId
!= ltSUBSECTIONSTAR
)
149 SetCurrentOutputs(Sections
, Subsections
);
150 long id1
= NewBlockId();
151 currentBlockId
= NewBlockId();
152 wxFprintf(Sections
, _T("\\hy-%d{%ld}{"), hyBLOCK_BOLD
, id1
);
153 wxFprintf(Subsections
, _T("\n\\hy-%d{%ld}{"), hyBLOCK_LARGE_VISIBLE_SECTION
, currentBlockId
);
154 wxFprintf(Index
, _T("%ld %ld\n"), id1
, currentBlockId
);
156 OutputCurrentSection(); // Repeat section header
158 wxFprintf(Sections
, _T("}\n\n"));
159 wxFprintf(Subsections
, _T("}\n\n"));
160 SetCurrentOutput(Subsections
);
161 wxChar
*topicName
= FindTopicName(GetNextChunk());
162 hyperLabels
.Append(topicName
, (wxObject
*)currentBlockId
);
166 case ltSUBSUBSECTION
:
167 case ltSUBSUBSECTIONSTAR
:
171 if (macroId
!= ltSUBSUBSECTIONSTAR
)
174 SetCurrentOutputs(Subsections
, Subsubsections
);
175 long id1
= NewBlockId();
176 currentBlockId
= NewBlockId();
177 wxFprintf(Subsections
, _T("\\hy-%d{%ld}{"), hyBLOCK_BOLD
, id1
);
178 wxFprintf(Subsubsections
, _T("\n\\hy-%d{%ld}{"), hyBLOCK_LARGE_VISIBLE_SECTION
, currentBlockId
);
179 wxFprintf(Index
, _T("%ld %ld\n"), id1
, currentBlockId
);
181 OutputCurrentSection(); // Repeat section header
183 wxFprintf(Subsections
, _T("}\n\n"));
184 wxFprintf(Subsubsections
, _T("}\n\n"));
185 SetCurrentOutput(Subsubsections
);
186 wxChar
*topicName
= FindTopicName(GetNextChunk());
187 hyperLabels
.Append(topicName
, (wxObject
*)currentBlockId
);
195 SetCurrentOutput(Subsections
);
198 long id
= NewBlockId();
199 wxFprintf(Subsections
, _T("\\hy-%d{%ld}{"), hyBLOCK_BOLD
, id
);
202 wxFprintf(Subsections
, _T("}"));
207 // TexOutput(_T("void"), true);
209 case ltBACKSLASHCHAR
:
211 TexOutput(_T("\n"), true);
218 TexOutput(_T("\n"), true);
219 TexOutput(_T("\n"), true);
236 long id
= NewBlockId();
237 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_BOLD
, id
);
240 else TexOutput(_T("}"));
250 long id
= NewBlockId();
251 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_ITALIC
, id
);
254 else TexOutput(_T("}"));
263 long id
= NewBlockId();
264 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_TELETYPE
, id
);
267 else TexOutput(_T("}"));
274 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_SMALL_TEXT
, NewBlockId());
277 else TexOutput(_T("}"));
284 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_SMALL_TEXT
, NewBlockId());
287 else TexOutput(_T("}"));
294 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_NORMAL
, NewBlockId());
297 else TexOutput(_T("}"));
304 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_SMALL_HEADING
, NewBlockId());
307 else TexOutput(_T("}\n"));
314 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_LARGE_HEADING
, NewBlockId());
317 else TexOutput(_T("}\n"));
329 // if (indentLevel > 0)
330 // TexOutput(_T("\\par\\par\n"));
333 if (macroId
== ltENUMERATE
)
334 listType
= LATEX_ENUMERATE
;
335 else if (macroId
== ltITEMIZE
)
336 listType
= LATEX_ITEMIZE
;
338 listType
= LATEX_DESCRIPTION
;
339 itemizeStack
.Insert(new ItemizeStruc(listType
));
346 if (itemizeStack
.GetFirst())
348 ItemizeStruc
*struc
= (ItemizeStruc
*)itemizeStack
.GetFirst()->GetData();
350 delete itemizeStack
.GetFirst();
357 wxNode
*node
= itemizeStack
.GetFirst();
360 ItemizeStruc
*struc
= (ItemizeStruc
*)node
->GetData();
363 struc
->currentItem
+= 1;
364 wxChar indentBuf
[30];
366 switch (struc
->listType
)
368 case LATEX_ENUMERATE
:
370 wxSnprintf(indentBuf
, sizeof(indentBuf
), _T("\\hy-%d{%ld}{%d.} "),
371 hyBLOCK_BOLD
, NewBlockId(), struc
->currentItem
);
372 TexOutput(indentBuf
);
377 wxSnprintf(indentBuf
, sizeof(indentBuf
), _T("\\hy-%d{%ld}{o} "),
378 hyBLOCK_BOLD
, NewBlockId());
379 TexOutput(indentBuf
);
383 case LATEX_DESCRIPTION
:
385 if (descriptionItemArg
)
387 wxSnprintf(indentBuf
, sizeof(indentBuf
), _T("\\hy-%d{%ld}{"),
388 hyBLOCK_BOLD
, NewBlockId());
389 TexOutput(indentBuf
);
390 TraverseChildrenFromChunk(descriptionItemArg
);
392 descriptionItemArg
= NULL
;
403 if (start
&& DocumentTitle
&& DocumentAuthor
)
405 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_LARGE_HEADING
, NewBlockId());
407 TraverseChildrenFromChunk(DocumentTitle
);
408 TexOutput(_T("}\n\n"));
409 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_SMALL_HEADING
, NewBlockId());
411 TraverseChildrenFromChunk(DocumentAuthor
);
412 TexOutput(_T("}\n\n"));
415 TraverseChildrenFromChunk(DocumentDate
);
421 case ltTABLEOFCONTENTS
:
425 FILE *fd
= wxFopen(ContentsName
, _T("r"));
431 wxPutc(ch
, Chapters
);
438 TexOutput(_T("RUN TEX2RTF AGAIN FOR CONTENTS PAGE\n"));
439 OnInform(_T("Run Tex2RTF again to include contents page."));
447 TexOutput(_T("HARDY"), true);
453 TexOutput(_T("wxCLIPS"), true);
461 long id
= NewBlockId();
462 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_TELETYPE
, id
);
465 else TexOutput(_T("}"));
472 TexOutput(_T("\n------------------------------------------------------------------"), true);
480 TexOutput(_T("--------------------------------------------------------------------------------"), true);
484 case ltSPECIALAMPERSAND
:
489 int tabPos
= (80/noColumns
)*currentTab
;
499 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_TELETYPE
, NewBlockId());
506 case ltNUMBEREDBIBITEM
:
509 TexOutput(_T("\n\n"), true);
520 if (DocumentStyle
!= LATEX_ARTICLE
)
521 wxSnprintf(figBuf
, sizeof(figBuf
), _T("Figure %d.%d: "), chapterNo
, figureNo
);
523 wxSnprintf(figBuf
, sizeof(figBuf
), _T("Figure %d: "), figureNo
);
529 wxChar
*topicName
= FindTopicName(GetNextChunk());
531 AddTexRef(topicName
, NULL
, NULL
,
532 ((DocumentStyle
!= LATEX_ARTICLE
) ? chapterNo
: figureNo
),
533 ((DocumentStyle
!= LATEX_ARTICLE
) ? figureNo
: 0));
539 DefaultOnMacro(macroId
, no_args
, start
);
545 bool XLPOnArgument(int macroId
, int arg_no
, bool start
)
552 case ltCHAPTERHEADING
:
555 case ltSECTIONHEADING
:
557 case ltSUBSECTIONSTAR
:
558 case ltSUBSUBSECTION
:
559 case ltSUBSUBSECTIONSTAR
:
561 case ltMEMBERSECTION
:
562 case ltFUNCTIONSECTION
:
564 if (!start
&& (arg_no
== 1))
565 currentSection
= GetArgChunk();
570 if (!start
&& (arg_no
== 1))
571 TexOutput(_T(" "), true);
572 if (start
&& (arg_no
== 3))
573 TexOutput(_T("("), true);
574 if (!start
&& (arg_no
== 3))
575 TexOutput(_T(")"), true);
580 if (!start
&& (arg_no
== 1))
581 TexOutput(_T(" "), true);
583 if (start
&& (arg_no
== 2))
584 TexOutput(_T("(*"), true);
585 if (!start
&& (arg_no
== 2))
586 TexOutput(_T(")"), true);
588 if (start
&& (arg_no
== 3))
589 TexOutput(_T("("), true);
590 if (!start
&& (arg_no
== 3))
591 TexOutput(_T(")"), true);
596 if (!start
&& (arg_no
== 1))
597 TexOutput(_T(" "), true);
598 if (start
&& (arg_no
== 2))
600 TexOutput(_T("("), true);
601 long id
= NewBlockId();
602 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_BOLD
, id
);
605 if (!start
&& (arg_no
== 2))
609 if (!start
&& (arg_no
== 3))
610 TexOutput(_T(")"), true);
615 if (start
&& (arg_no
== 2))
617 long id
= NewBlockId();
618 wxSnprintf(buf
, sizeof(buf
), _T(" \\hy-%d{%ld}{"), hyBLOCK_BOLD
, id
);
621 if (!start
&& (arg_no
== 2))
629 if (start
&& (arg_no
== 2))
631 long id
= NewBlockId();
632 wxSnprintf(buf
, sizeof(buf
), _T(" \\hy-%d{%ld}{"), hyBLOCK_BOLD
, id
);
635 if (!start
&& (arg_no
== 2))
643 if (!start
&& (arg_no
== 1))
644 TexOutput(_T(" "), true);
657 wxChar
*refName
= GetArgData();
660 TexRef
*texRef
= FindReference(refName
);
663 sec
= texRef
->sectionNumber
;
682 currentBlockId
= NewBlockId();
683 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{"), hyBLOCK_RED_ITALIC
, currentBlockId
);
686 else TexOutput(_T("}"));
692 wxChar
*label
= GetArgData();
693 hyperLinks
.Append(currentBlockId
, (wxObject
*)copystring(label
));
706 else if (arg_no
== 2)
718 if (start
&& IsArgOptional())
720 descriptionItemArg
= GetArgChunk();
733 tableVerticalLineLeft
= false;
734 tableVerticalLineRight
= false;
736 wxChar
*alignString
= copystring(GetArgData());
738 // Count the number of columns
740 int len
= wxStrlen(alignString
);
743 if (alignString
[0] == '|')
744 tableVerticalLineLeft
= true;
745 if (alignString
[len
-1] == '|')
746 tableVerticalLineRight
= true;
749 for (int i
= 0; i
< len
; i
++)
750 if (isalpha(alignString
[i
]))
755 TexOutput(_T("\\brdrt\\brdrs"));
756 if (tableVerticalLineLeft)
757 TexOutput(_T("\\brdrl\\brdrs"));
758 if (tableVerticalLineRight)
759 TexOutput(_T("\\brdrr\\brdrs"));
762 // Calculate a rough size for each column
763 // int tabPos = 80/noColumns;
769 else if (arg_no
== 2 && !start
)
773 else if (arg_no
== 2 && start
)
778 case ltMARGINPAREVEN
:
785 TexOutput(_T("----------------------------------------------------------------------\n"), true);
789 TexOutput(_T("\n----------------------------------------------------------------------\n"), true);
795 if (arg_no
== 1 && start
)
797 wxChar
*citeKey
= GetArgData();
798 TexRef
*ref
= (TexRef
*)TexReferences
.Get(citeKey
);
801 if (ref
->sectionNumber
) delete[] ref
->sectionNumber
;
802 wxSnprintf(buf
, sizeof(buf
), _T("[%d]"), citeCount
);
803 ref
->sectionNumber
= copystring(buf
);
806 wxSnprintf(buf
, sizeof(buf
), _T("\\hy-%d{%ld}{[%d]} "), hyBLOCK_BOLD
, NewBlockId(), citeCount
);
813 case ltTHEBIBLIOGRAPHY
:
815 if (start
&& (arg_no
== 1))
819 SetCurrentOutput(Chapters
);
821 SetCurrentOutputs(Contents
, Chapters
);
822 long id1
= NewBlockId();
823 long id2
= NewBlockId();
824 wxFprintf(Contents
, _T("\\hy-%d{%ld}{%s}\n"), hyBLOCK_SMALL_HEADING
, id1
, ReferencesNameString
);
825 wxFprintf(Chapters
, _T("\\hy-%d{%ld}{%s}\n\n\n"), hyBLOCK_LARGE_VISIBLE_SECTION
, id2
, ReferencesNameString
);
826 wxFprintf(Index
, _T("%ld %ld\n"), id1
, id2
);
828 SetCurrentOutput(Chapters
);
831 if (!start
&& (arg_no
== 2))
837 case ltTWOCOLITEMRULED
:
839 if (start
&& (arg_no
== 2))
840 TexOutput(_T("\n "));
842 if (!start
&& (arg_no
== 2))
854 wxChar
*val
= GetArgData();
900 wxChar
*val
= GetArgData();
952 wxChar
*val
= GetArgData();
998 wxChar
*val
= GetArgData();
1031 case ltACCENT_UMLAUT
:
1035 wxChar
*val
= GetArgData();
1087 wxChar
*val
= GetArgData();
1105 case ltACCENT_CADILLA
:
1109 wxChar
*val
= GetArgData();
1129 return DefaultOnArgument(macroId
, arg_no
, start
);
1139 if (!InputFile
.empty() && !OutputFile
.empty())
1141 Contents
= wxFopen(TmpContentsName
, _T("w"));
1142 Chapters
= wxFopen(_T("chapters.xlp"), _T("w"));
1143 Sections
= wxFopen(_T("sections.xlp"), _T("w"));
1144 Subsections
= wxFopen(_T("subsections.xlp"), _T("w"));
1145 Subsubsections
= wxFopen(_T("subsubsections.xlp"), _T("w"));
1146 Index
= wxFopen(_T("index.xlp"), _T("w"));
1148 // Insert invisible section marker at beginning
1149 wxFprintf(Chapters
, _T("\\hy-%d{%ld}{%s}\n"),
1150 hyBLOCK_INVISIBLE_SECTION
, NewBlockId(), _T("\n"));
1152 wxFprintf(Contents
, _T("\\hy-%d{%ld}{%s}\n\n"),
1153 // hyBLOCK_LARGE_HEADING, NewBlockId(), "\n\n%s\n\n", ContentsNameString);
1154 hyBLOCK_LARGE_HEADING
, NewBlockId(), ContentsNameString
);
1156 SetCurrentOutput(Chapters
);
1158 wxFprintf(Index
, _T("\n\\hyindex{\n\"%s\"\n"),
1159 contentsString
? contentsString
: _T("WXHELPCONTENTS"));
1162 wxNode
*node
= hyperLinks
.GetFirst();
1165 long from
= node
->GetKeyInteger();
1166 wxChar
*label
= (wxChar
*)node
->GetData();
1167 wxNode
*otherNode
= hyperLabels
.Find(label
);
1170 long to
= (long)otherNode
->GetData();
1171 wxFprintf(Index
, _T("%ld %ld\n"), from
, to
);
1173 node
= node
->GetNext();
1176 wxFprintf(Index
, _T("}\n"));
1178 fclose(Contents
); Contents
= NULL
;
1179 fclose(Chapters
); Chapters
= NULL
;
1180 fclose(Sections
); Sections
= NULL
;
1181 fclose(Subsections
); Subsections
= NULL
;
1182 fclose(Subsubsections
); Subsubsections
= NULL
;
1183 fclose(Index
); Index
= NULL
;
1185 if (wxFileExists(ContentsName
)) wxRemoveFile(ContentsName
);
1187 if (!wxRenameFile(TmpContentsName
, ContentsName
))
1189 wxCopyFile(TmpContentsName
, ContentsName
);
1190 wxRemoveFile(TmpContentsName
);
1193 wxConcatFiles(_T("chapters.xlp"), _T("sections.xlp"), _T("tmp2.xlp"));
1194 wxConcatFiles(_T("tmp2.xlp"), _T("subsections.xlp"), _T("tmp1.xlp"));
1195 wxConcatFiles(_T("tmp1.xlp"), _T("subsubsections.xlp"), _T("tmp2.xlp"));
1196 wxConcatFiles(_T("tmp2.xlp"), _T("index.xlp"), OutputFile
);
1198 wxRemoveFile(_T("tmp1.xlp"));
1199 wxRemoveFile(_T("tmp2.xlp"));
1201 wxRemoveFile(_T("chapters.xlp"));
1202 wxRemoveFile(_T("sections.xlp"));
1203 wxRemoveFile(_T("subsections.xlp"));
1204 wxRemoveFile(_T("subsubsections.xlp"));
1205 wxRemoveFile(_T("index.xlp"));