implemented (more) correct <pre> handling
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@9870 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
3da2715fb8
commit
1309ba6c7e
@ -37,41 +37,42 @@ class WXDLLEXPORT wxHtmlParser : public wxObject
|
||||
DECLARE_ABSTRACT_CLASS(wxHtmlParser)
|
||||
|
||||
public:
|
||||
wxHtmlParser() : wxObject(), m_HandlersHash(wxKEY_STRING) {m_FS = NULL; m_Cache = NULL; m_HandlersStack = NULL;}
|
||||
wxHtmlParser() : wxObject(), m_HandlersHash(wxKEY_STRING)
|
||||
{ m_FS = NULL; m_Cache = NULL; m_HandlersStack = NULL; }
|
||||
virtual ~wxHtmlParser();
|
||||
|
||||
void SetFS(wxFileSystem *fs) {m_FS = fs;}
|
||||
// Sets the class which will be used for opening files
|
||||
void SetFS(wxFileSystem *fs) { m_FS = fs; }
|
||||
|
||||
wxFileSystem* GetFS() const { return m_FS; }
|
||||
|
||||
wxObject* Parse(const wxString& source);
|
||||
// You can simply call this method when you need parsed output.
|
||||
// This method does these things:
|
||||
// 1. call InitParser(source);
|
||||
// 2. call DoParsing();
|
||||
// 3. call GetProduct(); (it's return value is then returned)
|
||||
// 4. call DoneParser();
|
||||
wxObject* Parse(const wxString& source);
|
||||
|
||||
virtual void InitParser(const wxString& source);
|
||||
// Sets the source. This must be called before running Parse() method.
|
||||
virtual void DoneParser();
|
||||
virtual void InitParser(const wxString& source);
|
||||
// This must be called after Parse().
|
||||
virtual void DoneParser();
|
||||
|
||||
void DoParsing(int begin_pos, int end_pos);
|
||||
inline void DoParsing() {DoParsing(0, m_Source.Length());};
|
||||
// Parses the m_Source from begin_pos to end_pos-1.
|
||||
// (in noparams version it parses whole m_Source)
|
||||
void DoParsing(int begin_pos, int end_pos);
|
||||
inline void DoParsing() {DoParsing(0, m_Source.Length());};
|
||||
|
||||
virtual wxObject* GetProduct() = 0;
|
||||
// Returns product of parsing
|
||||
// Returned value is result of parsing of the part. The type of this result
|
||||
// depends on internal representation in derived parser
|
||||
// (see wxHtmlWinParser for details).
|
||||
virtual wxObject* GetProduct() = 0;
|
||||
|
||||
virtual void AddTagHandler(wxHtmlTagHandler *handler);
|
||||
// adds handler to the list & hash table of handlers.
|
||||
virtual void AddTagHandler(wxHtmlTagHandler *handler);
|
||||
|
||||
void PushTagHandler(wxHtmlTagHandler *handler, wxString tags);
|
||||
// Forces the handler to handle additional tags (not returned by GetSupportedTags).
|
||||
// The handler should already be in use by this parser.
|
||||
// Example: you want to parse following pseudo-html structure:
|
||||
@ -83,36 +84,37 @@ class WXDLLEXPORT wxHtmlParser : public wxObject
|
||||
// handler can handle only 'myitems' (e.g. it's GetSupportedTags returns "MYITEMS")
|
||||
// you can call PushTagHandler(handler, "IT") when you find <myitems>
|
||||
// and call PopTagHandler() when you find </myitems>
|
||||
void PushTagHandler(wxHtmlTagHandler *handler, wxString tags);
|
||||
|
||||
void PopTagHandler();
|
||||
// Restores state before last call to PushTagHandler
|
||||
void PopTagHandler();
|
||||
|
||||
wxString* GetSource() {return &m_Source;}
|
||||
void SetSource(const wxString& src);
|
||||
|
||||
protected:
|
||||
|
||||
virtual void AddText(const char* txt) = 0;
|
||||
// Adds text to the output.
|
||||
// This is called from Parse() and must be overriden in derived classes.
|
||||
// txt is not guaranteed to be only one word. It is largest continuous part of text
|
||||
// (= not broken by tags)
|
||||
// NOTE : using char* because of speed improvements
|
||||
virtual void AddText(const char* txt) = 0;
|
||||
|
||||
virtual void AddTag(const wxHtmlTag& tag);
|
||||
// Adds tag and proceeds it. Parse() may (and usually is) called from this method.
|
||||
// This is called from Parse() and may be overriden.
|
||||
// Default behavior is that it looks for proper handler in m_Handlers. The tag is
|
||||
// ignored if no hander is found.
|
||||
// Derived class is *responsible* for filling in m_Handlers table.
|
||||
|
||||
virtual void AddTag(const wxHtmlTag& tag);
|
||||
|
||||
protected:
|
||||
wxString m_Source;
|
||||
// source being parsed
|
||||
wxHtmlTagsCache *m_Cache;
|
||||
wxString m_Source;
|
||||
|
||||
// tags cache, used during parsing.
|
||||
wxHtmlTagsCache *m_Cache;
|
||||
wxHashTable m_HandlersHash;
|
||||
wxList m_HandlersList;
|
||||
|
||||
// handlers that handle particular tags. The table is accessed by
|
||||
// key = tag's name.
|
||||
// This attribute MUST be filled by derived class otherwise it would
|
||||
@ -122,11 +124,12 @@ class WXDLLEXPORT wxHtmlParser : public wxObject
|
||||
// it may (and often does) contain more references to one object
|
||||
// m_HandlersList is list of all handlers and it is guaranteed to contain
|
||||
// only one reference to each handler instance.
|
||||
wxFileSystem *m_FS;
|
||||
// class for opening files (file system)
|
||||
wxList *m_HandlersStack;
|
||||
// handlers stack used by PushTagHandler and PopTagHandler
|
||||
wxList m_HandlersList;
|
||||
|
||||
// class for opening files (file system)
|
||||
wxFileSystem *m_FS;
|
||||
// handlers stack used by PushTagHandler and PopTagHandler
|
||||
wxList *m_HandlersStack;
|
||||
};
|
||||
|
||||
|
||||
@ -149,34 +152,35 @@ class WXDLLEXPORT wxHtmlTagHandler : public wxObject
|
||||
{
|
||||
DECLARE_ABSTRACT_CLASS(wxHtmlTagHandler)
|
||||
|
||||
protected:
|
||||
wxHtmlParser *m_Parser;
|
||||
|
||||
public:
|
||||
wxHtmlTagHandler() : wxObject () {m_Parser = NULL;};
|
||||
wxHtmlTagHandler() : wxObject () { m_Parser = NULL; }
|
||||
|
||||
virtual void SetParser(wxHtmlParser *parser) {m_Parser = parser;}
|
||||
// Sets the parser.
|
||||
// NOTE : each _instance_ of handler is guaranteed to be called
|
||||
// only by one parser. This means you don't have to care about
|
||||
// reentrancy.
|
||||
virtual void SetParser(wxHtmlParser *parser)
|
||||
{ m_Parser = parser; }
|
||||
|
||||
virtual wxString GetSupportedTags() = 0;
|
||||
// Returns list of supported tags. The list is in uppercase and
|
||||
// tags are delimited by ','.
|
||||
// Example : "I,B,FONT,P"
|
||||
// is capable of handling italic, bold, font and paragraph tags
|
||||
virtual wxString GetSupportedTags() = 0;
|
||||
|
||||
virtual bool HandleTag(const wxHtmlTag& tag) = 0;
|
||||
// This is hadling core method. It does all the Steps 1-3.
|
||||
// To process step 2, you can call ParseInner()
|
||||
// returned value : TRUE if it called ParseInner(),
|
||||
// FALSE etherwise
|
||||
virtual bool HandleTag(const wxHtmlTag& tag) = 0;
|
||||
|
||||
protected:
|
||||
void ParseInner(const wxHtmlTag& tag) {m_Parser->DoParsing(tag.GetBeginPos(), tag.GetEndPos1());}
|
||||
// parses input between beginning and ending tag.
|
||||
// m_Parser must be set.
|
||||
void ParseInner(const wxHtmlTag& tag)
|
||||
{ m_Parser->DoParsing(tag.GetBeginPos(), tag.GetEndPos1()); }
|
||||
|
||||
wxHtmlParser *m_Parser;
|
||||
};
|
||||
|
||||
|
||||
|
@ -51,24 +51,23 @@ wxObject* wxHtmlParser::Parse(const wxString& source)
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void wxHtmlParser::InitParser(const wxString& source)
|
||||
{
|
||||
m_Source = source;
|
||||
m_Cache = new wxHtmlTagsCache(m_Source);
|
||||
SetSource(source);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void wxHtmlParser::DoneParser()
|
||||
{
|
||||
delete m_Cache;
|
||||
m_Cache = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void wxHtmlParser::SetSource(const wxString& src)
|
||||
{
|
||||
m_Source = src;
|
||||
delete m_Cache;
|
||||
m_Cache = new wxHtmlTagsCache(m_Source);
|
||||
}
|
||||
|
||||
void wxHtmlParser::DoParsing(int begin_pos, int end_pos)
|
||||
{
|
||||
@ -117,8 +116,6 @@ void wxHtmlParser::DoParsing(int begin_pos, int end_pos)
|
||||
delete[] temp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void wxHtmlParser::AddTag(const wxHtmlTag& tag)
|
||||
{
|
||||
wxHtmlTagHandler *h;
|
||||
@ -134,8 +131,6 @@ void wxHtmlParser::AddTag(const wxHtmlTag& tag)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void wxHtmlParser::AddTagHandler(wxHtmlTagHandler *handler)
|
||||
{
|
||||
wxString s(handler->GetSupportedTags());
|
||||
@ -150,8 +145,6 @@ void wxHtmlParser::AddTagHandler(wxHtmlTagHandler *handler)
|
||||
handler->SetParser(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void wxHtmlParser::PushTagHandler(wxHtmlTagHandler *handler, wxString tags)
|
||||
{
|
||||
wxStringTokenizer tokenizer(tags, ", ");
|
||||
@ -173,8 +166,6 @@ void wxHtmlParser::PushTagHandler(wxHtmlTagHandler *handler, wxString tags)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void wxHtmlParser::PopTagHandler()
|
||||
{
|
||||
wxNode *first;
|
||||
@ -189,8 +180,6 @@ void wxHtmlParser::PopTagHandler()
|
||||
m_HandlersStack->DeleteNode(first);
|
||||
}
|
||||
|
||||
|
||||
|
||||
wxHtmlParser::~wxHtmlParser()
|
||||
{
|
||||
if (m_HandlersStack) delete m_HandlersStack;
|
||||
@ -199,8 +188,6 @@ wxHtmlParser::~wxHtmlParser()
|
||||
m_HandlersList.Clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// wxHtmlTagHandler
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -33,82 +33,6 @@
|
||||
|
||||
FORCE_LINK_ME(m_pre)
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// wxHtmlCodeCell
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class wxHtmlPRECell : public wxHtmlCell
|
||||
{
|
||||
private:
|
||||
wxString** m_Text;
|
||||
// list of wxString objects.
|
||||
int m_LinesCnt;
|
||||
// number of lines
|
||||
int m_LineHeight;
|
||||
// height of single line of text
|
||||
|
||||
public:
|
||||
wxHtmlPRECell(const wxString& s, wxDC& dc);
|
||||
~wxHtmlPRECell();
|
||||
void Draw(wxDC& dc, int x, int y, int view_y1, int view_y2);
|
||||
};
|
||||
|
||||
|
||||
wxHtmlPRECell::wxHtmlPRECell(const wxString& s, wxDC& dc) : wxHtmlCell()
|
||||
{
|
||||
wxStringTokenizer tokenizer(s, "\n");
|
||||
wxString tmp;
|
||||
long int x, z;
|
||||
int i;
|
||||
|
||||
m_LineHeight = dc.GetCharHeight();
|
||||
m_LinesCnt = 0;
|
||||
m_Text = NULL;
|
||||
m_Width = m_Height = 0;
|
||||
|
||||
i = 0;
|
||||
while (tokenizer.HasMoreTokens())
|
||||
{
|
||||
if (i % 10 == 0) m_Text = (wxString**) realloc(m_Text, sizeof(wxString*) * (i + 10));
|
||||
tmp = tokenizer.NextToken();
|
||||
tmp.Replace(wxT("©"), wxT("(c)"), TRUE);
|
||||
tmp.Replace(wxT(" "), wxT(" "), TRUE);
|
||||
tmp.Replace(wxT("""), wxT("\""), TRUE);
|
||||
tmp.Replace(wxT("<"), wxT("<"), TRUE);
|
||||
tmp.Replace(wxT(">"), wxT(">"), TRUE);
|
||||
tmp.Replace(wxT("&"), wxT("&"), TRUE);
|
||||
tmp.Replace(wxT("\t"), wxT(" "), TRUE);
|
||||
tmp.Replace(wxT("\r"), wxT(""), TRUE);
|
||||
m_Text[i++] = new wxString(tmp);
|
||||
|
||||
dc.GetTextExtent(tmp, &x, &z, &z);
|
||||
if (x > m_Width) m_Width = x;
|
||||
m_Height += m_LineHeight;
|
||||
m_LinesCnt++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
wxHtmlPRECell::~wxHtmlPRECell()
|
||||
{
|
||||
for (int i = 0; i < m_LinesCnt; i++) delete m_Text[i];
|
||||
free(m_Text);
|
||||
}
|
||||
|
||||
|
||||
void wxHtmlPRECell::Draw(wxDC& dc, int x, int y, int view_y1, int view_y2)
|
||||
{
|
||||
for (int i = 0; i < m_LinesCnt; i++)
|
||||
dc.DrawText(*(m_Text[i]), x + m_PosX, y + m_PosY + m_LineHeight * i);
|
||||
|
||||
wxHtmlCell::Draw(dc, x, y, view_y1, view_y2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// The list handler:
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -126,11 +50,7 @@ TAG_HANDLER_BEGIN(PRE, "PRE")
|
||||
bold = m_WParser->GetFontBold(),
|
||||
fsize = m_WParser->GetFontSize();
|
||||
|
||||
m_WParser->CloseContainer();
|
||||
c = m_WParser->OpenContainer();
|
||||
c->SetAlignHor(wxHTML_ALIGN_LEFT);
|
||||
c->SetIndent(m_WParser->GetCharHeight(), wxHTML_INDENT_VERTICAL);
|
||||
|
||||
c = m_WParser->GetContainer();
|
||||
m_WParser->SetFontUnderlined(FALSE);
|
||||
m_WParser->SetFontBold(FALSE);
|
||||
m_WParser->SetFontItalic(FALSE);
|
||||
@ -138,18 +58,27 @@ TAG_HANDLER_BEGIN(PRE, "PRE")
|
||||
m_WParser->SetFontSize(3);
|
||||
c->InsertCell(new wxHtmlFontCell(m_WParser->CreateCurrentFont()));
|
||||
|
||||
{
|
||||
wxString cit;
|
||||
wxEncodingConverter *encconv = m_WParser->GetEncodingConverter();
|
||||
cit = m_WParser->GetSource()->Mid(tag.GetBeginPos(),
|
||||
m_WParser->CloseContainer();
|
||||
c = m_WParser->OpenContainer();
|
||||
c->SetAlignHor(wxHTML_ALIGN_LEFT);
|
||||
|
||||
wxString src, srcMid;
|
||||
|
||||
src = *m_WParser->GetSource();
|
||||
srcMid = src.Mid(tag.GetBeginPos(),
|
||||
tag.GetEndPos1() - tag.GetBeginPos());
|
||||
if (encconv)
|
||||
c->InsertCell(new wxHtmlPRECell(encconv->Convert(cit),
|
||||
*(m_WParser->GetDC())));
|
||||
else
|
||||
c->InsertCell(new wxHtmlPRECell(cit,
|
||||
*(m_WParser->GetDC())));
|
||||
}
|
||||
srcMid.Replace(wxT("\t"), wxT(" "));
|
||||
srcMid.Replace(wxT(" "), wxT(" "));
|
||||
srcMid.Replace(wxT("\n"), wxT("<br>"));
|
||||
|
||||
// It is safe to temporarily change the source being parsed,
|
||||
// provided we restore the state back after parsing
|
||||
m_Parser->SetSource(srcMid);
|
||||
m_Parser->DoParsing();
|
||||
m_Parser->SetSource(src);
|
||||
|
||||
m_WParser->CloseContainer();
|
||||
c = m_WParser->OpenContainer();
|
||||
|
||||
m_WParser->SetFontUnderlined(underlined);
|
||||
m_WParser->SetFontBold(bold);
|
||||
@ -158,8 +87,6 @@ TAG_HANDLER_BEGIN(PRE, "PRE")
|
||||
m_WParser->SetFontSize(fsize);
|
||||
c->InsertCell(new wxHtmlFontCell(m_WParser->CreateCurrentFont()));
|
||||
|
||||
m_WParser->CloseContainer();
|
||||
m_WParser->OpenContainer();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user