diff --git a/src/html/bbcodeparser.cpp b/src/html/bbcodeparser.cpp
index ec39de6..254de60 100644
--- a/src/html/bbcodeparser.cpp
+++ b/src/html/bbcodeparser.cpp
@@ -463,14 +463,15 @@ bool first_tag_removed = false;
{
if( IsOpeningTagMark(lastc) )
{
- if( IsClosingTagForLastItem() )
- {
- // the last tag is skipped when using patterns with %2 or %u2
-
- PopStack(); // removing opening tag from the stack
- first_tag_removed = true;
- break;
- }
+ // FIXME
+// if( IsClosingTagForLastItem() )
+// {
+// // the last tag is skipped when using patterns with %2 or %u2
+//
+// PopStack(); // removing opening tag from the stack
+// first_tag_removed = true;
+// break;
+// }
}
else
{
diff --git a/src/html/htmlfilter.cpp b/src/html/htmlfilter.cpp
index 04888c3..9084462 100644
--- a/src/html/htmlfilter.cpp
+++ b/src/html/htmlfilter.cpp
@@ -41,7 +41,9 @@
namespace pt
{
-
+const int HTMLFilter::WHITE_MODE_ORIGIN;
+const int HTMLFilter::WHITE_MODE_SINGLE_LINE;
+const int HTMLFilter::WHITE_MODE_TREE;
@@ -197,6 +199,15 @@ void HTMLFilter::InsertTabs(size_t tabsize)
}
+int HTMLFilter::current_white_char_mode()
+{
+ if( !white_char_mode_tab.empty() )
+ return white_char_mode_tab.back();
+
+ return WHITE_MODE_ORIGIN;
+}
+
+
void HTMLFilter::CalcOrphansMaxLen(Orphans & orphans)
{
size_t i;
@@ -396,76 +407,6 @@ void HTMLFilter::SkipWhiteWithFirstNewLine()
-bool HTMLFilter::IsClosingTagForLastItem()
-{
- read_char();
- SkipWhite();
-
- if( lastc == '/' )
- {
- read_char();
- SkipWhite();
-
- ReadItemName(tmp_name);
-
- if( IsNameEqual(tmp_name, LastItem().name) )
- {
- SkipWhite();
-
- if( IsClosingTagMark(lastc) )
- {
- read_char();
- return true;
- }
- }
- }
-
-return false;
-}
-
-
-
-
-// used for such tags as: script, pre, textarea
-void HTMLFilter::PutEverythingUntilClosingTag(bool put_closing_tag_as_well)
-{
- bool was_closing_tag = false;
- tmp_text.clear();
-
- while( lastc != -1 )
- {
- if( IsOpeningTagMark(lastc) )
- {
- if( IsClosingTagForLastItem() )
- {
- was_closing_tag = true;
-
- PopStack();
- //CheckNewLine();
- break;
- }
- }
- else
- {
- tmp_text += lastc;
- read_char();
- }
- }
-
- Put(tmp_text);
-
- if( was_closing_tag && put_closing_tag_as_well )
- {
- Put('<');
- Put('/');
- Put(tmp_name);
- Put('>');
- }
-}
-
-
-
-
void HTMLFilter::SkipAndCheckClosingTag(std::wstring * remember_text)
{
bool is_quoted = false;
@@ -870,7 +811,7 @@ void HTMLFilter::PutNormalWhite(bool & was_white_char, bool & was_new_line)
else
was_white_char = true;
- if( white_mode == WHITE_MODE_ORIGIN )
+ if( current_white_char_mode() == WHITE_MODE_ORIGIN )
{
Put(lastc);
}
@@ -878,7 +819,7 @@ void HTMLFilter::PutNormalWhite(bool & was_white_char, bool & was_new_line)
read_char();
}
- if( white_mode == WHITE_MODE_SINGLE_LINE && (was_white_char || was_new_line) )
+ if( current_white_char_mode() == WHITE_MODE_SINGLE_LINE && (was_white_char || was_new_line) )
{
Put(' ');
}
@@ -950,7 +891,7 @@ bool HTMLFilter::PutOpeningTag()
return false;
}
- if( white_mode == WHITE_MODE_TREE && LastItem().new_line_before )
+ if( current_white_char_mode() == WHITE_MODE_TREE && LastItem().new_line_before )
{
Put(10);
PutTabs(LastItem().tree_index);
@@ -1089,7 +1030,7 @@ void HTMLFilter::ReadText()
bool allow_put_new_line = false;
bool allow_put_space = false;
- if( white_mode == WHITE_MODE_TREE )
+ if( current_white_char_mode() == WHITE_MODE_TREE )
{
if( LastItem().new_line || (wrap_line != 0 && LastItem().has_body_tag && line_len >= wrap_line) )
{
@@ -1124,7 +1065,7 @@ void HTMLFilter::ReadText()
PutNormalWhite(was_white_char, was_new_line);
- if( (was_white_char || was_new_line) && white_mode == WHITE_MODE_TREE )
+ if( (was_white_char || was_new_line) && current_white_char_mode() == WHITE_MODE_TREE )
{
allow_put_new_line = false;
allow_put_space = false;
@@ -1270,7 +1211,7 @@ void HTMLFilter::ReadItemSpecial()
if( !skip_tags )
{
- if( white_mode == WHITE_MODE_TREE && LastItem().new_line_before )
+ if( current_white_char_mode() == WHITE_MODE_TREE && LastItem().new_line_before )
{
Put(10);
PutTabs(LastItem().tree_index);
@@ -1303,7 +1244,7 @@ void HTMLFilter::ReadItemSpecial()
Put(tmp_text);
Put('>');
- if( is_first_item && white_mode == WHITE_MODE_TREE && is_equal_nc(LastItem().name.c_str(), L"!doctype") )
+ if( is_first_item && current_white_char_mode() == WHITE_MODE_TREE && is_equal_nc(LastItem().name.c_str(), L"!doctype") )
{
Put(10);
Put(10);
@@ -1383,6 +1324,7 @@ bool HTMLFilter::ReadItem()
ReadItemOpening();
}
+ // IMPROVE ME later CheckSingleItemExceptions() can change opening to single type
ItemFound();
return true;
@@ -1491,7 +1433,7 @@ bool HTMLFilter::IsLastTag(const std::wstring & name)
// checking exceptions for opening tags
-void HTMLFilter::CheckExceptions()
+void HTMLFilter::CheckSingleItemExceptions()
{
if( IsLastTag(L"meta") ||
IsLastTag(L"input") ||
@@ -1508,21 +1450,47 @@ void HTMLFilter::CheckExceptions()
return;
}
- // in safe_mode the script tag is ignored
- if( !safe_mode && IsLastTag(L"script") )
- PutEverythingUntilClosingTag(!skip_tags);
-
- if( IsLastTag(L"pre") || IsLastTag(L"textarea") )
- PutEverythingUntilClosingTag(!skip_tags);
-
- if( IsLastTag(no_filter_tag) )
- PutEverythingUntilClosingTag(false);
-
+ // move me to a better place
if( IsLastTag(L"body") )
LastItem().has_body_tag = true;
}
+void HTMLFilter::CheckWhiteCharsExceptions(Item & item)
+{
+ bool change_white_mode = false;
+
+ // in safe_mode the script tag is ignored
+ if( !safe_mode && IsNameEqual(item.name, L"script") )
+ {
+ change_white_mode = true;
+ }
+
+ if( IsNameEqual(item.name, L"pre") || IsNameEqual(item.name, L"textarea") )
+ {
+ change_white_mode = true;
+ }
+
+ if( IsNameEqual(item.name, no_filter_tag) )
+ {
+ change_white_mode = true;
+ }
+
+ if( change_white_mode )
+ {
+ if( item.type == Item::opening )
+ {
+ white_char_mode_tab.push_back(WHITE_MODE_ORIGIN);
+ }
+ else
+ {
+ if( !white_char_mode_tab.empty() )
+ white_char_mode_tab.pop_back();
+ }
+ }
+}
+
+
void HTMLFilter::AddForgottenTags()
@@ -1549,9 +1517,11 @@ int i;
for(int z=(int)stack_len-2 ; z>=i ; --z)
{
+ CheckWhiteCharsExceptions(pstack[z]);
+
if( !skip_tags && pstack[z].new_line )
{
- if( white_mode == WHITE_MODE_TREE )
+ if( current_white_char_mode() == WHITE_MODE_TREE )
{
Put(10);
PutTabs(pstack[z].tree_index);
@@ -1575,7 +1545,7 @@ void HTMLFilter::CheckStackPrintRest()
{
if( stack_len==0 || pstack[stack_len-1].new_line )
{
- if( white_mode == WHITE_MODE_TREE )
+ if( current_white_char_mode() == WHITE_MODE_TREE )
{
Put(10);
PutTabs(pstack[stack_len-1].tree_index);
@@ -1610,10 +1580,12 @@ void HTMLFilter::CheckClosingTags()
// there are more than one tag
if( (pstack[stack_len-1].is_commentary && pstack[stack_len-2].is_commentary) || IsNameEqual(pstack[stack_len-1].name, pstack[stack_len-2].name) )
{
+ CheckWhiteCharsExceptions(pstack[stack_len-1]);
+
// last closing tag is from the previous one
if( !skip_tags && pstack[stack_len-2].new_line )
{
- if( white_mode == WHITE_MODE_TREE )
+ if( current_white_char_mode() == WHITE_MODE_TREE )
{
Put(10);
PutTabs(pstack[stack_len-2].tree_index);
@@ -1668,7 +1640,8 @@ void HTMLFilter::ReadLoop()
{
if( LastItem().type == Item::opening )
{
- CheckExceptions();
+ CheckSingleItemExceptions();
+ CheckWhiteCharsExceptions(LastItem());
}
else
if( LastItem().type == Item::special )
@@ -1703,7 +1676,10 @@ void HTMLFilter::Read()
read_char(); // put first character to lastc
is_first_item = true;
- if( white_mode != WHITE_MODE_ORIGIN )
+ white_char_mode_tab.clear();
+ white_char_mode_tab.push_back(white_mode);
+
+ if( current_white_char_mode() != WHITE_MODE_ORIGIN )
SkipWhiteLines();
// it can be some text or white lines before the first html tag (we print it)
diff --git a/src/html/htmlfilter.h b/src/html/htmlfilter.h
index 4b20ef4..b24e925 100644
--- a/src/html/htmlfilter.h
+++ b/src/html/htmlfilter.h
@@ -251,7 +251,9 @@ protected:
virtual bool IsValidCharForName(int c);
virtual bool IsValidCharForAttrName(int c);
virtual bool IsValidCharForEntityName(int c);
- virtual void CheckExceptions();
+
+ virtual void CheckSingleItemExceptions();
+ virtual void CheckWhiteCharsExceptions(Item & item);
virtual void Put(wchar_t c);
virtual void Put(const wchar_t * str, const wchar_t * end);
@@ -300,7 +302,9 @@ protected:
void SkipWhite();
void SkipWhiteLines();
void SkipWhiteWithFirstNewLine();
- bool IsClosingTagForLastItem();
+
+ int current_white_char_mode();
+
void SkipAndCheckClosingTag(std::wstring * remember_text = nullptr);
void PopStack();
@@ -331,7 +335,7 @@ protected:
void PutNormalNonWhite(std::wstring & str, bool allow_put_new_line, bool allow_put_space);
void PutNormalWhite(bool & was_white_char, bool & was_new_line);
- void PutEverythingUntilClosingTag(bool put_closing_tag_as_well);
+
void PutTabs(size_t len);
void PutNonBreakingSpace();
void CalcOrphansMaxLen(Orphans & orphans);
@@ -341,6 +345,9 @@ protected:
size_t stack_len; // length of the stack
wchar_t * buffer; // buffer used when printing
std::wstring * out_string;
+
+ std::vector white_char_mode_tab;
+
//bool last_new_line;
bool new_item_has_new_line_before;
int white_mode;