1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        src/html/m_pre.cpp
3 // Purpose:     wxHtml module for <PRE> ... </PRE> tag (code citation)
4 // Author:      Vaclav Slavik
5 // RCS-ID:      $Id: m_pre.cpp 56547 2008-10-28 10:06:32Z VS $
6 // Copyright:   (c) 1999 Vaclav Slavik
7 // Licence:     wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9 
10 #include "wx/wxprec.h"
11 
12 #ifdef __BORLANDC__
13     #pragma hdrstop
14 #endif
15 
16 #if wxUSE_HTML && wxUSE_STREAMS
17 
18 #ifndef WXPRECOMP
19 #endif
20 
21 #include "wx/html/forcelnk.h"
22 #include "wx/html/m_templ.h"
23 
24 #include "wx/html/htmlcell.h"
25 #include "wx/tokenzr.h"
26 #include "wx/encconv.h"
27 
FORCE_LINK_ME(m_pre)28 FORCE_LINK_ME(m_pre)
29 
30 // replaces '\t', ' ' and '\n' with HTML markup:
31 static wxString LINKAGEMODE HtmlizeLinebreaks(const wxString& str)
32 {
33     wxString out;
34     out.reserve(str.length()); // we'll certainly need at least that
35 
36     size_t len = str.Len();
37 
38     for (size_t i = 0; i < len; i++)
39     {
40         switch (str[i])
41         {
42             case wxT('<'):
43                 while (i < len && str[i] != wxT('>'))
44                 {
45                     out << str[i++];
46                 }
47                 out << wxT('>');
48                 break;
49 
50             // We need to translate any line break into exactly one <br>.
51             // Quoting HTML spec: "A line break is defined to be a carriage
52             // return (&#x000D;), a line feed (&#x000A;), or a carriage
53             // return/line feed pair."
54             case wxT('\r'):
55                 {
56                     size_t j = i + 1;
57                     if ( j < len && str[j] == wxT('\n') )
58                         i = j;
59                 }
60                 // fall through
61             case wxT('\n'):
62                 out << wxT("<br>");
63                 break;
64 
65             default:
66                 out << str[i];
67                 break;
68         }
69     }
70     return out;
71 }
72 
73 
74 //-----------------------------------------------------------------------------
75 // The list handler:
76 //-----------------------------------------------------------------------------
77 
78 
79 TAG_HANDLER_BEGIN(PRE, "PRE")
TAG_HANDLER_CONSTR(PRE)80     TAG_HANDLER_CONSTR(PRE) { }
81 
TAG_HANDLER_PROC(tag)82     TAG_HANDLER_PROC(tag)
83     {
84         wxHtmlContainerCell *c;
85 
86         const int fixed = m_WParser->GetFontFixed();
87         const int italic = m_WParser->GetFontItalic();
88         const int underlined = m_WParser->GetFontUnderlined();
89         const int bold = m_WParser->GetFontBold();
90         const int fsize = m_WParser->GetFontSize();
91         const wxHtmlWinParser::WhitespaceMode whitespace =
92             m_WParser->GetWhitespaceMode();
93 
94         c = m_WParser->GetContainer();
95         m_WParser->SetWhitespaceMode(wxHtmlWinParser::Whitespace_Pre);
96         m_WParser->SetFontUnderlined(false);
97         m_WParser->SetFontBold(false);
98         m_WParser->SetFontItalic(false);
99         m_WParser->SetFontFixed(true);
100         m_WParser->SetFontSize(3);
101         c->InsertCell(new wxHtmlFontCell(m_WParser->CreateCurrentFont()));
102 
103         m_WParser->CloseContainer();
104         c = m_WParser->OpenContainer();
105         c->SetWidthFloat(tag);
106         c = m_WParser->OpenContainer();
107         c->SetAlignHor(wxHTML_ALIGN_LEFT);
108         c->SetIndent(m_WParser->GetCharHeight(), wxHTML_INDENT_TOP);
109 
110         wxString srcMid = m_WParser->GetInnerSource(tag);
111 
112         // setting Whitespace_Pre mode takes care of spaces and TABs, but
113         // not linebreaks, so we have to translate them into <br> by
114         // calling HtmlizeLinebreaks() here
115         ParseInnerSource(HtmlizeLinebreaks(srcMid));
116 
117         m_WParser->CloseContainer();
118         m_WParser->CloseContainer();
119         c = m_WParser->OpenContainer();
120 
121         m_WParser->SetWhitespaceMode(whitespace);
122         m_WParser->SetFontUnderlined(underlined);
123         m_WParser->SetFontBold(bold);
124         m_WParser->SetFontItalic(italic);
125         m_WParser->SetFontFixed(fixed);
126         m_WParser->SetFontSize(fsize);
127         c->InsertCell(new wxHtmlFontCell(m_WParser->CreateCurrentFont()));
128 
129         return true;
130     }
131 
132 TAG_HANDLER_END(PRE)
133 
134 
135 
136 
137 
138 TAGS_MODULE_BEGIN(Pre)
139 
140     TAGS_MODULE_ADD(PRE)
141 
142 TAGS_MODULE_END(Pre)
143 
144 #endif
145