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
28FORCE_LINK_ME(m_pre)
29
30// replaces '\t', ' ' and '\n' with HTML markup:
31static 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
79TAG_HANDLER_BEGIN(PRE, "PRE")
80    TAG_HANDLER_CONSTR(PRE) { }
81
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
132TAG_HANDLER_END(PRE)
133
134
135
136
137
138TAGS_MODULE_BEGIN(Pre)
139
140    TAGS_MODULE_ADD(PRE)
141
142TAGS_MODULE_END(Pre)
143
144#endif
145