📄 texutils.cpp
字号:
/////////////////////////////////////////////////////////////////////////////
// Name: texutils.cpp
// Purpose: Miscellaneous utilities
// Author: Julian Smart
// Modified by: Wlodzimiez ABX Skiba 2003/2004 Unicode support
// Ron Lee
// Created: 7.9.93
// RCS-ID: $Id: texutils.cpp,v 1.36 2006/06/13 10:33:24 ABX Exp $
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/log.h"
#endif
#include "wx/app.h"
#include "wx/hash.h"
#include "wx/textfile.h"
#ifdef new
#undef new
#endif
#if wxUSE_IOSTREAMH
#include <iostream.h>
#include <fstream.h>
#else
#include <iostream>
#include <fstream>
using namespace std;
#endif
#include <ctype.h>
#include "tex2any.h"
#if !WXWIN_COMPATIBILITY_2_4
static inline wxChar* copystring(const wxChar* s)
{ return wxStrcpy(new wxChar[wxStrlen(s) + 1], s); }
#endif
wxHashTable TexReferences(wxKEY_STRING);
wxList BibList(wxKEY_STRING);
wxStringList CitationList;
wxList ColourTable(wxKEY_STRING);
wxHashTable BibStringTable(wxKEY_STRING);
wxList CustomMacroList(wxKEY_STRING);
TexChunk *currentSection = NULL;
wxChar *fakeCurrentSection = NULL;
static long BibLine = 1;
void OutputCurrentSection(void)
{
if (fakeCurrentSection)
TexOutput(fakeCurrentSection);
else if (currentSection)
TraverseChildrenFromChunk(currentSection);
}
// Nasty but the way things are done now, necessary,
// in order to output a chunk properly to a string (macros and all).
void OutputCurrentSectionToString(wxChar *buf)
{
if (fakeCurrentSection)
wxStrcpy(buf, fakeCurrentSection);
else
OutputChunkToString(currentSection, buf);
}
void OutputChunkToString(TexChunk *chunk, wxChar *buf)
{
FILE *tempfd = wxFopen(_T("tmp.tmp"), _T("w"));
if (!tempfd)
return;
FILE *old1 = CurrentOutput1;
FILE *old2 = CurrentOutput2;
CurrentOutput1 = tempfd;
CurrentOutput2 = NULL;
TraverseChildrenFromChunk(chunk);
CurrentOutput1 = old1;
CurrentOutput2 = old2;
fclose(tempfd);
// Read from file into string
tempfd = wxFopen(_T("tmp.tmp"), _T("r"));
if (!tempfd)
return;
buf[0] = 0;
int ch = -2;
int i = 0;
while (ch != EOF)
{
ch = getc(tempfd);
if (ch == EOF)
buf[i] = 0;
else
{
buf[i] = (wxChar)ch;
i ++;
}
}
fclose(tempfd);
wxRemoveFile(_T("tmp.tmp"));
}
// Called by Tex2Any to simulate a section
void FakeCurrentSection(wxChar *fakeSection, bool addToContents)
{
currentSection = NULL;
if (fakeCurrentSection) delete[] fakeCurrentSection;
fakeCurrentSection = copystring(fakeSection);
if (DocumentStyle == LATEX_ARTICLE)
{
int mac = ltSECTIONHEADING;
if (!addToContents)
mac = ltSECTIONHEADINGSTAR;
OnMacro(mac, 0, true);
OnMacro(mac, 0, false);
}
else
{
int mac = ltCHAPTERHEADING;
if (!addToContents)
mac = ltCHAPTERHEADINGSTAR;
OnMacro(mac, 0, true);
OnMacro(mac, 0, false);
}
if (fakeCurrentSection) delete[] fakeCurrentSection;
fakeCurrentSection = NULL;
}
// Look for \label macro, use this ref name if found or
// make up a topic name otherwise.
static long topicCounter = 0;
void ResetTopicCounter(void)
{
topicCounter = 0;
}
static wxChar *forceTopicName = NULL;
void ForceTopicName(const wxChar *name)
{
if (forceTopicName)
delete[] forceTopicName;
if (name)
forceTopicName = copystring(name);
else
forceTopicName = NULL;
}
wxChar *FindTopicName(TexChunk *chunk)
{
if (forceTopicName)
return forceTopicName;
wxChar *topicName = NULL;
static wxChar topicBuf[100];
if (chunk && (chunk->type == CHUNK_TYPE_MACRO) &&
(chunk->macroId == ltLABEL))
{
wxNode *node = chunk->children.GetFirst();
if (node)
{
TexChunk *child = (TexChunk *)node->GetData();
if (child->type == CHUNK_TYPE_ARG)
{
wxNode *snode = child->children.GetFirst();
if (snode)
{
TexChunk *schunk = (TexChunk *)snode->GetData();
if (schunk->type == CHUNK_TYPE_STRING)
topicName = schunk->value;
}
}
}
}
if (topicName)
return topicName;
else
{
wxSnprintf(topicBuf, sizeof(topicBuf), _T("topic%ld"), topicCounter);
topicCounter ++;
return topicBuf;
}
}
/*
* Simulate argument data, so we can 'drive' clients which implement
* certain basic formatting behaviour.
* Snag is that some save a TexChunk, so don't use yet...
*
*/
void StartSimulateArgument(wxChar *data)
{
wxStrcpy(currentArgData, data);
haveArgData = true;
}
void EndSimulateArgument(void)
{
haveArgData = false;
}
/*
* Parse and convert unit arguments to points
*
*/
int ParseUnitArgument(wxChar *unitArg)
{
float conversionFactor = 1.0;
float unitValue = 0.0;
int len = wxStrlen(unitArg);
// Get rid of any accidentally embedded commands
for (int i = 0; i < len; i++)
if (unitArg[i] == '\\')
unitArg[i] = 0;
len = wxStrlen(unitArg);
if (unitArg && (len > 0) && (isdigit(unitArg[0]) || unitArg[0] == '-'))
{
wxSscanf(unitArg, _T("%f"), &unitValue);
if (len > 1)
{
wxChar units[3];
units[0] = unitArg[len-2];
units[1] = unitArg[len-1];
units[2] = 0;
if (wxStrcmp(units, _T("in")) == 0)
conversionFactor = 72.0;
else if (wxStrcmp(units, _T("cm")) == 0)
conversionFactor = (float)72.0/(float)2.51;
else if (wxStrcmp(units, _T("mm")) == 0)
conversionFactor = (float)72.0/(float)25.1;
else if (wxStrcmp(units, _T("pt")) == 0)
conversionFactor = 1;
}
return (int)(unitValue*conversionFactor);
}
else return 0;
}
/*
* Strip off any extension (dot something) from end of file,
* IF one exists. Inserts zero into buffer.
*
*/
void StripExtension(wxChar *buffer)
{
int len = wxStrlen(buffer);
int i = len-1;
while (i > 0)
{
if (buffer[i] == '.')
{
buffer[i] = 0;
break;
}
i --;
}
}
/*
* Latex font setting
*
*/
void SetFontSizes(int pointSize)
{
switch (pointSize)
{
case 12:
{
normalFont = 12;
smallFont = 10;
tinyFont = 8;
largeFont1 = 14;
LargeFont2 = 16;
LARGEFont3 = 20;
hugeFont1 = 24;
HugeFont2 = 28;
HUGEFont3 = 32;
break;
}
case 11:
{
normalFont = 11;
smallFont = 9;
tinyFont = 7;
largeFont1 = 13;
LargeFont2 = 16;
LARGEFont3 = 19;
hugeFont1 = 22;
HugeFont2 = 26;
HUGEFont3 = 30;
break;
}
case 10:
{
normalFont = 10;
smallFont = 8;
tinyFont = 6;
largeFont1 = 12;
LargeFont2 = 14;
LARGEFont3 = 18;
hugeFont1 = 20;
HugeFont2 = 24;
HUGEFont3 = 28;
break;
}
}
}
/*
* Latex references
*
*/
void AddTexRef(wxChar *name, wxChar *file, wxChar *sectionName,
int chapter, int section, int subsection, int subsubsection)
{
TexRef *texRef = (TexRef *)TexReferences.Get(name);
if (texRef) TexReferences.Delete(name);
wxChar buf[100];
buf[0] = 0;
/*
if (sectionName)
{
wxStrcat(buf, sectionName);
wxStrcat(buf, " ");
}
*/
if (chapter)
{
wxChar buf2[10];
wxSnprintf(buf2, sizeof(buf2), _T("%d"), chapter);
wxStrcat(buf, buf2);
}
if (section)
{
wxChar buf2[10];
if (chapter)
wxStrcat(buf, _T("."));
wxSnprintf(buf2, sizeof(buf2), _T("%d"), section);
wxStrcat(buf, buf2);
}
if (subsection)
{
wxChar buf2[10];
wxStrcat(buf, _T("."));
wxSnprintf(buf2, sizeof(buf2), _T("%d"), subsection);
wxStrcat(buf, buf2);
}
if (subsubsection)
{
wxChar buf2[10];
wxStrcat(buf, _T("."));
wxSnprintf(buf2, sizeof(buf2), _T("%d"), subsubsection);
wxStrcat(buf, buf2);
}
wxChar *tmp = ((wxStrlen(buf) > 0) ? buf : (wxChar *)NULL);
TexReferences.Put(name, new TexRef(name, file, tmp, sectionName));
}
void WriteTexReferences(wxChar *filename)
{
wxString name = filename;
wxTextFile file;
if (!(wxFileExists(name)?file.Open(name):file.Create(name)))
return;
file.Clear();
TexReferences.BeginFind();
wxHashTable::Node *node = TexReferences.Next();
while (node)
{
Tex2RTFYield();
TexRef *ref = (TexRef *)node->GetData();
wxString converter = ref->refLabel;
converter << wxT(" ");
converter << (ref->refFile ? ref->refFile : _T("??"));
converter << wxT(" ");
converter << (ref->sectionName ? ref->sectionName : _T("??")) ;
converter << wxT(" ");
converter << (ref->sectionNumber ? ref->sectionNumber : _T("??")) ;
file.AddLine(converter);
if (!ref->sectionNumber || (wxStrcmp(ref->sectionNumber, _T("??")) == 0 && wxStrcmp(ref->sectionName, _T("??")) == 0))
{
wxChar buf[200];
wxSnprintf(buf, sizeof(buf), _T("Warning: reference %s not resolved."), ref->refLabel);
OnInform(buf);
}
node = TexReferences.Next();
}
file.Write();
file.Close();
}
void ReadTexReferences(wxChar *filename)
{
wxString name = filename;
if (!wxFileExists(name))
return;
wxTextFile file;
if (!file.Open(name))
return;
wxString line;
for ( line = file.GetFirstLine(); !file.Eof(); line = file.GetNextLine() )
{
wxString labelStr = line.BeforeFirst(wxT(' '));
line = line.AfterFirst(wxT(' '));
wxString fileStr = line.BeforeFirst(wxT(' '));
line = line.AfterFirst(wxT(' '));
wxString sectionNameStr = line.BeforeFirst(wxT(' '));
wxString sectionStr = line.AfterFirst(wxT(' '));
// gt - needed to trick the hash table "TexReferences" into deleting the key
// strings it creates in the Put() function, but not the item that is
// created here, as that is destroyed elsewhere. Without doing this, there
// were massive memory leaks
TexReferences.DeleteContents(true);
TexReferences.Put(
labelStr.c_str(),
new TexRef(
labelStr.c_str(),
fileStr.c_str(),
sectionStr.c_str(),
sectionNameStr.c_str()
)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -