]> git.saurik.com Git - wxWidgets.git/blobdiff - src/html/m_pre.cpp
State fix
[wxWidgets.git] / src / html / m_pre.cpp
index acf9998d213f1000c60eab208c05637c3e40add3..1a0ef36813be6f8df7a8f25c64c5aa332cc04cb9 100644 (file)
@@ -15,7 +15,7 @@
 
 #if wxUSE_HTML && wxUSE_STREAMS
 
-#ifndef WXPRECOMP
+#ifndef WX_PRECOMP
 #endif
 
 #include "wx/html/forcelnk.h"
 FORCE_LINK_ME(m_pre)
 
 // replaces '\t', ' ' and '\n' with HTML markup:
-static wxString LINKAGEMODE HtmlizeWhitespaces(const wxString& str)
+static wxString LINKAGEMODE HtmlizeLinebreaks(const wxString& str)
 {
     wxString out;
-    size_t len = str.Len();
-    size_t linepos = 0;
-    for (size_t i = 0; i < len; i++)
+    out.reserve(str.length()); // we'll certainly need at least that
+
+    const wxString::const_iterator end = str.end();
+    for ( wxString::const_iterator i = str.begin(); i != end; ++i )
     {
-        switch ( str[i].GetValue() )
+        switch ( (*i).GetValue() )
         {
-            case wxT('<'):
-                while (i < len && str[i] != wxT('>'))
+            case '<':
+                while ( i != end && *i != '>' )
                 {
-                    out << str[i++];
-                    linepos++;
+                    out << *i++;
                 }
-                out << wxT('>');
-                linepos++;
-                break;
-            case wxT(' '):
-                out << wxT("&nbsp;");
-                linepos++;
+                out << '>';
+                if ( i == end )
+                    return out;
                 break;
-            case wxT('\n'):
-                out << wxT("<br>");
-                linepos = 0;
-                break;
-            case wxT('\t'):
+
+            // We need to translate any line break into exactly one <br>.
+            // Quoting HTML spec: "A line break is defined to be a carriage
+            // return (&#x000D;), a line feed (&#x000A;), or a carriage
+            // return/line feed pair."
+            case '\r':
                 {
-                    for (size_t j = 8 - linepos % 8; j > 0; j--)
-                        out << wxT("&nbsp;");
-                    linepos += 8 - linepos % 8;
+                    wxString::const_iterator j(i + 1);
+                    if ( j != end && *j == '\n' )
+                        i = j;
                 }
+                // fall through
+            case '\n':
+                out << "<br>";
                 break;
+
             default:
-                out << str[i];
-                linepos++;
+                out << *i;
                 break;
         }
     }
+
     return out;
 }
 
@@ -83,13 +85,16 @@ TAG_HANDLER_BEGIN(PRE, "PRE")
     {
         wxHtmlContainerCell *c;
 
-        int fixed = m_WParser->GetFontFixed(),
-            italic = m_WParser->GetFontItalic(),
-            underlined = m_WParser->GetFontUnderlined(),
-            bold = m_WParser->GetFontBold(),
-            fsize = m_WParser->GetFontSize();
+        const int fixed = m_WParser->GetFontFixed();
+        const int italic = m_WParser->GetFontItalic();
+        const int underlined = m_WParser->GetFontUnderlined();
+        const int bold = m_WParser->GetFontBold();
+        const int fsize = m_WParser->GetFontSize();
+        const wxHtmlWinParser::WhitespaceMode whitespace =
+            m_WParser->GetWhitespaceMode();
 
         c = m_WParser->GetContainer();
+        m_WParser->SetWhitespaceMode(wxHtmlWinParser::Whitespace_Pre);
         m_WParser->SetFontUnderlined(false);
         m_WParser->SetFontBold(false);
         m_WParser->SetFontItalic(false);
@@ -105,12 +110,17 @@ TAG_HANDLER_BEGIN(PRE, "PRE")
         c->SetIndent(m_WParser->GetCharHeight(), wxHTML_INDENT_TOP);
 
         wxString srcMid = m_WParser->GetInnerSource(tag);
-        ParseInnerSource(HtmlizeWhitespaces(srcMid));
+
+        // setting Whitespace_Pre mode takes care of spaces and TABs, but
+        // not linebreaks, so we have to translate them into <br> by
+        // calling HtmlizeLinebreaks() here
+        ParseInnerSource(HtmlizeLinebreaks(srcMid));
 
         m_WParser->CloseContainer();
         m_WParser->CloseContainer();
         c = m_WParser->OpenContainer();
 
+        m_WParser->SetWhitespaceMode(whitespace);
         m_WParser->SetFontUnderlined(underlined);
         m_WParser->SetFontBold(bold);
         m_WParser->SetFontItalic(italic);