added: bbcode
files: core/bbcodeparser.h core/bbcodeparser.cpp git-svn-id: svn://ttmath.org/publicrep/winix/trunk@615 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
parent
759135fd7d
commit
16bb238518
|
@ -183,7 +183,7 @@ return lastc;
|
|||
|
||||
bool ConfParser::IsWhite(int c)
|
||||
{
|
||||
if( c==' ' || c=='\t' || c==13 )
|
||||
if( c==' ' || c=='\t' || c==13 || c==160 )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# DO NOT DELETE
|
||||
|
||||
acceptbaseparser.o: acceptbaseparser.h
|
||||
bbcodeparser.o: bbcodeparser.h htmlfilter.h
|
||||
compress.o: compress.h log.h
|
||||
config.o: config.h ../confparser/confparser.h log.h data.h dirs.h item.h
|
||||
config.o: dircontainer.h users.h user.h ugcontainer.h groups.h group.h
|
||||
|
|
|
@ -1 +1 @@
|
|||
o = acceptbaseparser.o compress.o config.o data.o db.o db_itemcolumns.o dircontainer.o dirs.o function.o functioncodeparser.o functionparser.o functions.o groups.o htmlfilter.o httpsimpleparser.o lastcontainer.o loadavg.o locale.o log.o misc.o mount.o mountparser.o mounts.o notify.o plugin.o plugindata.o postmultiparser.o rebus.o request.o requestcontroller.o session.o sessioncontainer.o sessionmanager.o sessionparser.o users.o
|
||||
o = acceptbaseparser.o bbcodeparser.o compress.o config.o data.o db.o db_itemcolumns.o dircontainer.o dirs.o function.o functioncodeparser.o functionparser.o functions.o groups.o htmlfilter.o httpsimpleparser.o lastcontainer.o loadavg.o locale.o log.o misc.o mount.o mountparser.o mounts.o notify.o plugin.o plugindata.o postmultiparser.o rebus.o request.o requestcontroller.o session.o sessioncontainer.o sessionmanager.o sessionparser.o users.o
|
||||
|
|
|
@ -0,0 +1,566 @@
|
|||
/*
|
||||
* This file is a part of Winix
|
||||
* and is not publicly distributed
|
||||
*
|
||||
* Copyright (c) 2008-2010, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "bbcodeparser.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool BBCODEParser::IsValidCharForName(int c)
|
||||
{
|
||||
if( (c>='a' && c<='z') ||
|
||||
(c>='A' && c<='Z') ||
|
||||
c=='*' || c=='_')
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool BBCODEParser::IsOpeningTagMark()
|
||||
{
|
||||
return (*pchar == '[');
|
||||
}
|
||||
|
||||
|
||||
// there are no commentaries in bbcode
|
||||
bool BBCODEParser::IsOpeningCommentaryTagMark()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool BBCODEParser::SkipCommentaryTagIfExists()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool BBCODEParser::IsClosingTagMark()
|
||||
{
|
||||
return (*pchar == ']');
|
||||
}
|
||||
|
||||
|
||||
bool BBCODEParser::IsClosingXmlSimpleTagMark()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// one enter will generate one <br>
|
||||
// two enters or more will generate only two br (<br><br>)
|
||||
void BBCODEParser::PutNormalText(const char * str, const char * end)
|
||||
{
|
||||
int br_len;
|
||||
|
||||
if( *pchar == 0 )
|
||||
{
|
||||
// trimming last white characters at end of the user text
|
||||
while( str<end && (IsWhite(*(end-1)) || *(end-1)==10) )
|
||||
--end;
|
||||
}
|
||||
|
||||
|
||||
while( str < end )
|
||||
{
|
||||
if( *str == 10 )
|
||||
{
|
||||
++str;
|
||||
br_len = 1;
|
||||
|
||||
// skipping white characters without a new line character
|
||||
while( str < end && IsWhite(*str) )
|
||||
++str;
|
||||
|
||||
if( str < end && *str == 10 )
|
||||
{
|
||||
br_len = 2;
|
||||
|
||||
// skipping white characters with new line characters
|
||||
while( str < end && (IsWhite(*str) || *str==10) )
|
||||
++str;
|
||||
}
|
||||
|
||||
if( !has_open_ol_tag && !has_open_ul_tag && !has_open_li_tag )
|
||||
{
|
||||
for(int i=0 ; i < br_len ; ++i)
|
||||
(*out_string) += "<br>\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintEscape(*str);
|
||||
++str;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BBCODEParser::PutNormalTextTrim(const char * str, const char * end)
|
||||
{
|
||||
// we don't use trimming in bbcode parser
|
||||
PutNormalText(str, end);
|
||||
}
|
||||
|
||||
|
||||
void BBCODEParser::ReadNormalTextSkipWhite(const char * & start, const char * & last_non_white)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void BBCODEParser::CheckExceptions()
|
||||
{
|
||||
if( stack_len >= 2 )
|
||||
{
|
||||
if( pstack[stack_len-1].type == Item::opening &&
|
||||
pstack[stack_len-2].type == Item::opening &&
|
||||
IsNameEqual("*", pstack[stack_len-1].name) &&
|
||||
IsNameEqual("*", pstack[stack_len-2].name) )
|
||||
{
|
||||
// removing the last [*] from the stack
|
||||
// </li> was put automatically
|
||||
PopStack();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
bbcode format:
|
||||
[bbcodetag=value]some text[/bbcodetag]
|
||||
the value can be quoted, e.g.
|
||||
[bbcodetag="value"]some text[/bbcodetag], or
|
||||
[bbcodetag='value']some text[/bbcodetag]
|
||||
|
||||
the third string below (in tags table) is 'html_argument' from Tags,
|
||||
it can contain a special character % followed by a string which means:
|
||||
%1 - "value" escaped as for html
|
||||
%2 - "some text" escaped as for html
|
||||
%u1 - "value" trimmed and escaped as for url-es
|
||||
%u2 - "some text" trimmed and escaped as for url-es
|
||||
%% - one %
|
||||
|
||||
if you are using %2 or %u2 then "some text" is not treated as bbcode, e.g.
|
||||
[bbcodetag=value]some [b]text[/b][/bbcodetag] will produce:
|
||||
<htmltag arg="value">some [b]text[/b]</htmltag> (the inner tags [b][/b] were not parsed)
|
||||
|
||||
also when using %2 or %u2 the closing bbcode tag is skipped
|
||||
(if you want this tag then you can put it in 'html_argument')
|
||||
|
||||
and when using u (%u1 or %u2) the argument is trimmed from whitespaces and new lines
|
||||
at the beginning and at the end
|
||||
(because otherwise a space would be changed to %20 and this were probably not what you really wanted)
|
||||
*/
|
||||
const BBCODEParser::Tags * BBCODEParser::FindTag(const char * tag)
|
||||
{
|
||||
static Tags tags[] = {
|
||||
{"*", "li", ">", false},
|
||||
{"b", "em", ">", true},
|
||||
{"i", "span", " class=\"bbitalic\">", true},
|
||||
{"u", "span", " class=\"bbunderline\">", true},
|
||||
{"s", "span", " class=\"bbstrike\">", true},
|
||||
{"code", "code", " class=\"bbcode\">", false},
|
||||
{"list", "ul", " class=\"bblist\">", false},
|
||||
{"color", "span", " class=\"bbcol%1\">", true},
|
||||
{"url", "a", " href=\"%u1\">", true},
|
||||
{"img", "img", " alt=\"%1\" src=\"%u2\">", true},
|
||||
{"quote", "div", " class=\"bbquote\">\n<span class=\"bbquotewho\">%1</span><br>\n", false},
|
||||
};
|
||||
|
||||
size_t i;
|
||||
size_t len = sizeof(tags) / sizeof(Tags);
|
||||
|
||||
for(i=0 ; i<len ; ++i)
|
||||
{
|
||||
if( strcmp(tag, tags[i].bbcode) == 0 )
|
||||
return &tags[i];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void BBCODEParser::PrintArgumentCheckQuotes(const char * & start, const char * & end)
|
||||
{
|
||||
// skipping white characters from the argument
|
||||
while( start<end && IsWhite(*start) )
|
||||
++start;
|
||||
|
||||
// skipping first '=' character if exists
|
||||
if( start<end && *start == '=' )
|
||||
++start;
|
||||
|
||||
// skipping white characters from the argument
|
||||
// at the beginning
|
||||
while( start<end && IsWhite(*start) )
|
||||
++start;
|
||||
|
||||
// and at the end
|
||||
while( start<end && IsWhite(*(end-1)) )
|
||||
--end;
|
||||
|
||||
|
||||
if( start<end && (*start=='\'' || *start=='\"') )
|
||||
{
|
||||
++start;
|
||||
|
||||
if( start<end && *(start-1) == *(end-1) )
|
||||
--end;
|
||||
|
||||
// skipping white characters after a first quote char [url = " ww...."]
|
||||
while( start<end && IsWhite(*start) )
|
||||
++start;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void BBCODEParser::PrintEncode(int c)
|
||||
{
|
||||
if( c == '&' )
|
||||
{
|
||||
(*out_string) += "&";
|
||||
}
|
||||
else
|
||||
if( (c>='a' && c<='z') ||
|
||||
(c>='A' && c<='Z') ||
|
||||
(c>='0' && c<='9') ||
|
||||
(c=='_' || c=='?' || c=='.' || c==',' || c=='/' || c=='-' ||
|
||||
c=='+' || c=='*' || c=='(' || c==')' || c=='=' || c==':')
|
||||
)
|
||||
{
|
||||
(*out_string) += c;
|
||||
}
|
||||
else
|
||||
{
|
||||
char buffer[20];
|
||||
sprintf(buffer, "%02X", c);
|
||||
|
||||
(*out_string) += '%';
|
||||
(*out_string) += buffer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BBCODEParser::PrintEscape(int c, bool change_quote)
|
||||
{
|
||||
if( c == '<' )
|
||||
{
|
||||
(*out_string) += "<";
|
||||
}
|
||||
else
|
||||
if( c == '>' )
|
||||
{
|
||||
(*out_string) += ">";
|
||||
}
|
||||
else
|
||||
if( c == '&' )
|
||||
{
|
||||
(*out_string) += "&";
|
||||
}
|
||||
else
|
||||
if( c == '\"' && change_quote )
|
||||
{
|
||||
(*out_string) += """;
|
||||
}
|
||||
else
|
||||
{
|
||||
(*out_string) += c;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BBCODEParser::PrintArgumentEncode(const char * start, const char * end)
|
||||
{
|
||||
PrintArgumentCheckQuotes(start, end);
|
||||
TrimWhiteWithNewLines(start, end);
|
||||
|
||||
for( ; start<end ; ++start )
|
||||
PrintEncode(*start);
|
||||
}
|
||||
|
||||
|
||||
void BBCODEParser::PrintArgumentEscape(const char * start, const char * end)
|
||||
{
|
||||
PrintArgumentCheckQuotes(start, end);
|
||||
|
||||
for( ; start<end ; ++start )
|
||||
PrintEscape(*start, true); // quotes are escaped as well here
|
||||
}
|
||||
|
||||
|
||||
void BBCODEParser::CheckOpeningTag(const Tags * tag, const char * tag_name, bool & condition)
|
||||
{
|
||||
if( strcmp(tag->html_tag, tag_name) == 0 )
|
||||
{
|
||||
if( condition )
|
||||
{
|
||||
PutClosingTag(tag);
|
||||
(*out_string) += '\n';
|
||||
}
|
||||
|
||||
condition = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BBCODEParser::CheckOpeningTag(const Tags * tag)
|
||||
{
|
||||
bool has_list_tag = has_open_ul_tag || has_open_ol_tag;
|
||||
|
||||
CheckOpeningTag(tag, "li", has_open_li_tag);
|
||||
CheckOpeningTag(tag, "ul", has_open_ul_tag);
|
||||
CheckOpeningTag(tag, "ol", has_open_ol_tag);
|
||||
|
||||
if( has_open_li_tag && !has_list_tag )
|
||||
{
|
||||
(*out_string) += "<ul>\n";
|
||||
has_open_ul_tag = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BBCODEParser::PrintEscape(const char * start, const char * end, bool change_quote)
|
||||
{
|
||||
for( ; start < end ; ++start)
|
||||
PrintEscape(*start, change_quote);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void BBCODEParser::PrintEncode(const char * start, const char * end)
|
||||
{
|
||||
for( ; start < end ; ++start)
|
||||
PrintEncode(*start);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void BBCODEParser::PutOpeningTagFromEzc(const char * start, const char * end)
|
||||
{
|
||||
// this can be a tag from Ezc templates system
|
||||
(*out_string) += '[';
|
||||
(*out_string) += LastItem().name;
|
||||
|
||||
if( start != end )
|
||||
{
|
||||
(*out_string) += ' ';
|
||||
PrintEscape(start, end);
|
||||
}
|
||||
|
||||
(*out_string) += ']';
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BBCODEParser::PutHtmlArgument1(const char * arg_start, const char * arg_end, bool has_u)
|
||||
{
|
||||
if( has_u )
|
||||
PrintArgumentEncode(arg_start, arg_end);
|
||||
else
|
||||
PrintArgumentEscape(arg_start, arg_end);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void BBCODEParser::TrimWhiteWithNewLines(const char * & start, const char * & end)
|
||||
{
|
||||
while( start < end && (IsWhite(*start) || *start==10) )
|
||||
++start;
|
||||
|
||||
while( start < end && (IsWhite(*(end-1)) || *(end-1)==10) )
|
||||
--end;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void BBCODEParser::PutHtmlArgument2(const Tags * tag, bool has_u)
|
||||
{
|
||||
const char * start = pchar;
|
||||
const char * end = pchar;
|
||||
bool first_tag_removed = false;
|
||||
|
||||
while( *pchar != 0 )
|
||||
{
|
||||
if( IsOpeningTagMark() )
|
||||
{
|
||||
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
|
||||
{
|
||||
pchar += 1;
|
||||
end = pchar;
|
||||
}
|
||||
}
|
||||
|
||||
if( !first_tag_removed )
|
||||
PopStack(); // user has forgotten to close the tag
|
||||
|
||||
if( has_u )
|
||||
{
|
||||
TrimWhiteWithNewLines(start, end);
|
||||
PrintEncode(start, end);
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintEscape(start, end);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void BBCODEParser::PutHtmlArgument(const Tags * tag, const char * arg_start, const char * arg_end)
|
||||
{
|
||||
const char * pattern = tag->html_argument;
|
||||
bool has_u;
|
||||
|
||||
while( *pattern )
|
||||
{
|
||||
if( *pattern == '%' )
|
||||
{
|
||||
++pattern;
|
||||
has_u = false;
|
||||
|
||||
if( *pattern == 'u' )
|
||||
{
|
||||
++pattern;
|
||||
has_u = true;
|
||||
}
|
||||
|
||||
if( *pattern == '1' )
|
||||
{
|
||||
++pattern;
|
||||
PutHtmlArgument1(arg_start, arg_end, has_u);
|
||||
}
|
||||
else
|
||||
if( *pattern == '2' )
|
||||
{
|
||||
++pattern;
|
||||
PutHtmlArgument2(tag, has_u);
|
||||
}
|
||||
else
|
||||
if( *pattern == '%' )
|
||||
{
|
||||
(*out_string) += '%';
|
||||
++pattern;
|
||||
}
|
||||
// else unrecognized, will be printed next time as a normal character
|
||||
}
|
||||
else
|
||||
{
|
||||
(*out_string) += *pattern;
|
||||
++pattern;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BBCODEParser::PutOpeningTagFromBBCode(const Tags * tag, const char * start, const char * end)
|
||||
{
|
||||
CheckOpeningTag(tag);
|
||||
PutOpeningTagMark();
|
||||
(*out_string) += tag->html_tag;
|
||||
PutHtmlArgument(tag, start, end);
|
||||
|
||||
if( !tag->inline_tag )
|
||||
{
|
||||
(*out_string) += "\n";
|
||||
SkipWhiteLines();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BBCODEParser::PutOpeningTag(const char * start, const char * end)
|
||||
{
|
||||
const Tags * tag = FindTag(LastItem().name);
|
||||
|
||||
if( !tag )
|
||||
{
|
||||
PutOpeningTagFromEzc(start, end);
|
||||
}
|
||||
else
|
||||
{
|
||||
PutOpeningTagFromBBCode(tag, start, end);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BBCODEParser::PutClosingTag(const Tags * tag)
|
||||
{
|
||||
if( !tag )
|
||||
return; // skipping the tag
|
||||
|
||||
PutOpeningTagMark();
|
||||
(*out_string) += '/';
|
||||
(*out_string) += tag->html_tag;
|
||||
PutClosingTagMark();
|
||||
|
||||
if( !tag->inline_tag )
|
||||
{
|
||||
(*out_string) += "\n";
|
||||
SkipWhiteLines();
|
||||
}
|
||||
|
||||
if( strcmp(tag->html_tag, "li") == 0 )
|
||||
has_open_li_tag = false;
|
||||
|
||||
if( strcmp(tag->html_tag, "ol") == 0 )
|
||||
has_open_ol_tag = false;
|
||||
|
||||
if( strcmp(tag->html_tag, "ul") == 0 )
|
||||
has_open_ul_tag = false;
|
||||
}
|
||||
|
||||
|
||||
void BBCODEParser::PutClosingTag(const char * tag_name)
|
||||
{
|
||||
const Tags * tag = FindTag(tag_name);
|
||||
PutClosingTag(tag);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void BBCODEParser::Init()
|
||||
{
|
||||
has_open_li_tag = false;
|
||||
has_open_ol_tag = false;
|
||||
has_open_ul_tag = false;
|
||||
|
||||
SkipWhiteLines();
|
||||
}
|
||||
|
||||
|
||||
void BBCODEParser::Deinit()
|
||||
{
|
||||
if( has_open_li_tag )
|
||||
(*out_string) += "</li>\n";
|
||||
|
||||
if( has_open_ol_tag )
|
||||
(*out_string) += "</ol>\n";
|
||||
|
||||
if( has_open_ul_tag )
|
||||
(*out_string) += "</ul>\n";
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* This file is a part of Winix
|
||||
* and is not publicly distributed
|
||||
*
|
||||
* Copyright (c) 2008-2010, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef headerfilecmslucorebbcodeparser
|
||||
#define headerfilecmslucorebbcodeparser
|
||||
|
||||
#include "htmlfilter.h"
|
||||
|
||||
|
||||
class BBCODEParser : public HTMLFilter
|
||||
{
|
||||
|
||||
//using HTMLFilter::pchar;
|
||||
|
||||
|
||||
struct Tags
|
||||
{
|
||||
/*
|
||||
const char * bbcode;
|
||||
const char * html_tag;
|
||||
const char * html_arg_prefix;
|
||||
const char * html_arg_postfix;
|
||||
const char * additional_html_tag_prefix;
|
||||
const char * additional_html_tag_postfix;
|
||||
bool inline_tag;
|
||||
*/
|
||||
const char * bbcode;
|
||||
const char * html_tag;
|
||||
const char * html_argument; // with closing '>'
|
||||
bool inline_tag;
|
||||
};
|
||||
|
||||
virtual bool IsValidCharForName(int c);
|
||||
|
||||
virtual bool IsOpeningTagMark();
|
||||
virtual bool IsOpeningCommentaryTagMark();
|
||||
virtual bool SkipCommentaryTagIfExists();
|
||||
virtual bool IsClosingTagMark();
|
||||
virtual bool IsClosingXmlSimpleTagMark();
|
||||
|
||||
|
||||
void PutHtmlArgument1(const char * arg_start, const char * arg_end, bool has_u);
|
||||
void PutHtmlArgument2(const Tags * tag, bool has_u);
|
||||
void PutHtmlArgument(const Tags * tag, const char * arg_start, const char * arg_end);
|
||||
|
||||
void PutOpeningTagFromEzc(const char * start, const char * end);
|
||||
void PutOpeningTagFromBBCode(const Tags * tag, const char * start, const char * end);
|
||||
|
||||
virtual void PutOpeningTag(const char * start, const char * end);
|
||||
virtual void PutClosingTag(const char * tag);
|
||||
|
||||
const Tags * FindTag(const char * tag);
|
||||
void PrintArgumentCheckQuotes(const char * & start, const char * & end);
|
||||
|
||||
|
||||
void PrintEscape(int c, bool change_quote = false);
|
||||
void PrintEncode(int c);
|
||||
|
||||
void PrintEscape(const char * start, const char * end, bool change_quote = false);
|
||||
void PrintEncode(const char * start, const char * end);
|
||||
|
||||
void PrintArgumentEncode(const char * start, const char * end);
|
||||
void PrintArgumentEscape(const char * start, const char * end);
|
||||
|
||||
virtual void ReadNormalTextSkipWhite(const char * & start, const char * & last_non_white);
|
||||
virtual void PutNormalText(const char * str, const char * end);
|
||||
virtual void PutNormalTextTrim(const char * str, const char * end);
|
||||
|
||||
virtual void CheckExceptions();
|
||||
|
||||
virtual void Init();
|
||||
virtual void Deinit();
|
||||
|
||||
void PutClosingTag(const Tags * tag);
|
||||
|
||||
|
||||
void CheckOpeningTag(const Tags * tag, const char * tag_name, bool & condition);
|
||||
void CheckOpeningTag(const Tags * tag);
|
||||
|
||||
void TrimWhiteWithNewLines(const char * & start, const char * & end);
|
||||
|
||||
bool has_open_ol_tag; // has open html <ol> tag
|
||||
bool has_open_ul_tag; // has open html <ul> tag
|
||||
bool has_open_li_tag; // has open html <li> tag
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -70,6 +70,7 @@ HTMLFilter::HTMLFilter()
|
|||
break_after = 0;
|
||||
lang = lang_none;
|
||||
orphan_mode = orphan_nbsp;
|
||||
safe_mode = false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -130,6 +131,12 @@ void HTMLFilter::CheckOrphans(HTMLFilter::Lang lang_, HTMLFilter::OrphanMode mod
|
|||
}
|
||||
|
||||
|
||||
void HTMLFilter::SafeMode(bool safe_mode_)
|
||||
{
|
||||
safe_mode = safe_mode_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
HTMLFilter::Item & HTMLFilter::GetItem(size_t i)
|
||||
{
|
||||
|
@ -182,7 +189,7 @@ bool HTMLFilter::IsWhite(int c)
|
|||
{
|
||||
// dont use c==10 here
|
||||
|
||||
if( c==' ' || c=='\t' || c==13 )
|
||||
if( c==' ' || c=='\t' || c==13 || c==160 )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -645,10 +652,38 @@ void HTMLFilter::PutTagName(const char * name)
|
|||
}
|
||||
|
||||
|
||||
bool HTMLFilter::IsTagSafe(const char * tag)
|
||||
{
|
||||
if( !safe_mode )
|
||||
return true;
|
||||
|
||||
static const char * unsafe_tags[] = {
|
||||
"script", "iframe", "frame", "frameset",
|
||||
"applet", "head", "meta", "html", "link", "body"
|
||||
};
|
||||
|
||||
size_t len = sizeof(unsafe_tags) / sizeof(const char*);
|
||||
size_t i;
|
||||
|
||||
for(i=0 ; i<len ; ++i)
|
||||
{
|
||||
if( IsNameEqual(tag, unsafe_tags[i]) )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// start, end - arguments
|
||||
void HTMLFilter::PutOpeningTag(const char * start, const char * end)
|
||||
{
|
||||
if( !IsTagSafe(LastItem().name) )
|
||||
return;
|
||||
|
||||
PutOpeningTagMark();
|
||||
PutTagName(LastItem().name);
|
||||
|
||||
|
@ -665,6 +700,9 @@ void HTMLFilter::PutOpeningTag(const char * start, const char * end)
|
|||
|
||||
void HTMLFilter::PutClosingTag(const char * tag)
|
||||
{
|
||||
if( !IsTagSafe(tag) )
|
||||
return;
|
||||
|
||||
PutOpeningTagMark();
|
||||
(*out_string) += '/';
|
||||
PutTagName(tag);
|
||||
|
@ -875,10 +913,6 @@ const char * last_non_white = pchar;
|
|||
|
||||
// start, end - parameters to a tag
|
||||
void HTMLFilter::PrintItem(const char * start, const char * end)
|
||||
{
|
||||
// closing tags will be printed later
|
||||
// (when we check the stack)
|
||||
if( LastItem().type != Item::closing )
|
||||
{
|
||||
if( last_new_line )
|
||||
{
|
||||
|
@ -890,7 +924,6 @@ void HTMLFilter::PrintItem(const char * start, const char * end)
|
|||
|
||||
PutOpeningTag(start, end);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -902,12 +935,13 @@ const char * start = pchar;
|
|||
if( *pchar == 0 )
|
||||
return false;
|
||||
|
||||
if( !PushStack() )
|
||||
return false;
|
||||
|
||||
// we have '<'
|
||||
pchar += 1;
|
||||
SkipWhite();
|
||||
|
||||
if( PushStack() )
|
||||
{
|
||||
if( *pchar == '/' ) // we have a closing tag
|
||||
{
|
||||
pchar += 1;
|
||||
|
@ -923,17 +957,16 @@ const char * start = pchar;
|
|||
LastItem().type = (LastItem().name[0] == '!') ? Item::special : Item::opening;
|
||||
|
||||
const char * end = SkipItemCheckXmlSimple();
|
||||
|
||||
if( LastItem().type != Item::closing )
|
||||
PrintItem(start, end);
|
||||
|
||||
CheckNewLine();
|
||||
LastItem().new_line = last_new_line;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
pchar = start;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int HTMLFilter::ToLower(int c)
|
||||
|
@ -998,8 +1031,11 @@ void HTMLFilter::CheckExceptions()
|
|||
return;
|
||||
}
|
||||
|
||||
// in safe_mode the script tag is ignored
|
||||
if( !safe_mode && IsLastTag("script") )
|
||||
PutLastTagWithClosingTag();
|
||||
|
||||
if( IsLastTag("script") || IsLastTag("pre") || IsLastTag("textarea") )
|
||||
if( IsLastTag("pre") || IsLastTag("textarea") )
|
||||
PutLastTagWithClosingTag();
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ class HTMLFilter
|
|||
{
|
||||
public:
|
||||
|
||||
|
||||
// for checking orphans
|
||||
enum Lang
|
||||
{
|
||||
|
@ -59,27 +60,29 @@ public:
|
|||
|
||||
enum OrphanMode
|
||||
{
|
||||
orphan_nbsp,
|
||||
orphan_nbspace
|
||||
orphan_nbsp, // putting " " string
|
||||
orphan_160space // putting 160 ascii code
|
||||
};
|
||||
|
||||
|
||||
|
||||
HTMLFilter();
|
||||
HTMLFilter(const HTMLFilter & f);
|
||||
HTMLFilter & operator=(const HTMLFilter & f);
|
||||
~HTMLFilter();
|
||||
|
||||
|
||||
// main methods used for filtering
|
||||
void Filter(const char * in, std::string & out);
|
||||
void Filter(const std::string & in, std::string & out);
|
||||
|
||||
|
||||
// insert a white space into long lines
|
||||
// only between html tags
|
||||
// skipped in such tags: script, pre, textarea
|
||||
// break_after - after how many characters insert a space (0 - off)
|
||||
void BreakLines(size_t break_after_);
|
||||
|
||||
|
||||
// trimming white characters (with new lines)
|
||||
// at the beginning, at the end and in the middle of a string
|
||||
// only between html tags
|
||||
|
@ -88,17 +91,24 @@ public:
|
|||
// false by default
|
||||
void TrimWhite(bool trim);
|
||||
|
||||
|
||||
// first tabs in a tree
|
||||
// default: 2 (spaces)
|
||||
// set 0 to turn off
|
||||
void InsertTabs(size_t tabsize);
|
||||
|
||||
|
||||
// check 'orphans' for the specicic language
|
||||
// if an orphans is detected then the non-break space ( ) will be put
|
||||
// default disable: lang_none
|
||||
// if an orphan is detected then the non-break space (" " or ascii 160 code) will be put
|
||||
// default disable (lang_none)
|
||||
void CheckOrphans(Lang lang_, OrphanMode mode = orphan_nbsp);
|
||||
|
||||
|
||||
// skipping some unsafe tags
|
||||
// (script, iframe, frame, frameset, applet, head, meta, html, link, body, ...)
|
||||
void SafeMode(bool safe_mode_);
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -126,7 +136,7 @@ protected:
|
|||
|
||||
// only this method have direct access to the output string
|
||||
// you can easily change the output from a std::string to something else
|
||||
void Put(const char * str, const char * end);
|
||||
virtual void Put(const char * str, const char * end);
|
||||
|
||||
|
||||
Item & GetItem(size_t i);
|
||||
|
@ -136,8 +146,7 @@ protected:
|
|||
bool IsNameEqual(const char * name1, const char * name2);
|
||||
bool IsNameEqual(const char * name1, const char * name2, size_t len);
|
||||
bool IsLastTag(const char * name);
|
||||
|
||||
public: // !!
|
||||
bool IsTagSafe(const char * tag);
|
||||
|
||||
int CheckOrphan(const char * str, const char * end, const char * orphan);
|
||||
bool CheckOrphanTable(const char * str, const char * end, const char ** table, size_t o1, size_t o2);
|
||||
|
@ -162,11 +171,11 @@ public: // !!
|
|||
bool PushStack();
|
||||
virtual bool IsValidCharForName(int c);
|
||||
void CheckNewLine();
|
||||
void CheckExceptions();
|
||||
virtual void CheckExceptions();
|
||||
void CheckStackPrintRest();
|
||||
void AddForgottenTags();
|
||||
void CheckClosingTags();
|
||||
void ReadNormalTextSkipWhite(const char * & start, const char * & last_non_white);
|
||||
virtual void ReadNormalTextSkipWhite(const char * & start, const char * & last_non_white);
|
||||
void ReadNormalText();
|
||||
bool PrintRest();
|
||||
void PrintItem(const char * start, const char * end);
|
||||
|
@ -178,8 +187,8 @@ public: // !!
|
|||
|
||||
size_t PutNormalTextTrimFillBuffer(const char * & str, const char * & end);
|
||||
size_t PutNormalTextFillBuffer(const char * & str, const char * & end);
|
||||
void PutNormalText(const char * str, const char * end);
|
||||
void PutNormalTextTrim(const char * str, const char * end);
|
||||
virtual void PutNormalText(const char * str, const char * end);
|
||||
virtual void PutNormalTextTrim(const char * str, const char * end);
|
||||
void PutLastTagWithClosingTag();
|
||||
virtual void PutOpeningTagMark();
|
||||
virtual void PutClosingTagMark();
|
||||
|
@ -203,6 +212,7 @@ public: // !!
|
|||
size_t tab_size;
|
||||
Lang lang; // current language for checking orphans
|
||||
OrphanMode orphan_mode;
|
||||
bool safe_mode; // skipping some unsafe tags
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -389,7 +389,7 @@ return buffer;
|
|||
|
||||
bool IsWhite(int s)
|
||||
{
|
||||
if( s==' ' || s=='\t' || s==13 )
|
||||
if( s==' ' || s=='\t' || s==13 || s==160 )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
bool MountParser::IsWhite(int c)
|
||||
{
|
||||
if( c==' ' || c=='\t' || c==13 )
|
||||
if( c==' ' || c=='\t' || c==13 || c==160 )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
|
@ -485,7 +485,7 @@ void Request::SendPage(bool compressing, const std::string & source_ref)
|
|||
html_filter.TrimWhite(true);
|
||||
html_filter.BreakLines(60);
|
||||
html_filter.InsertTabs(2);
|
||||
html_filter.CheckOrphans(HTMLFilter::lang_pl, HTMLFilter::orphan_nbspace);
|
||||
html_filter.CheckOrphans(HTMLFilter::lang_pl, HTMLFilter::orphan_160space);
|
||||
|
||||
html_filter.Filter(*source, clean_html);
|
||||
source = &clean_html;
|
||||
|
@ -926,7 +926,8 @@ bool Request::CanUseHtml(long user_id)
|
|||
|
||||
bool Request::CanUseBBCode(long user_id)
|
||||
{
|
||||
return CanUse(user_id, "allow_bbcode");
|
||||
// logged users can use bbcode
|
||||
return (user_id != -1);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "ticket.h"
|
||||
|
||||
|
||||
|
||||
struct Request
|
||||
{
|
||||
// request id
|
||||
|
|
|
@ -678,3 +678,74 @@ img.catimage {
|
|||
max-width: 600px;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
from bbcode
|
||||
*/
|
||||
|
||||
span.bbitalic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
|
||||
span.bbunderline {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
|
||||
span.bbstrike {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
|
||||
div.bbquote {
|
||||
display: block;
|
||||
padding: 0.5em;
|
||||
margin: 0.5em 0 1em 0;
|
||||
border: 1px solid #C3C3C3;
|
||||
background: #F0F0F0;
|
||||
}
|
||||
|
||||
div.bbquote span.bbquotewho {
|
||||
font-size: 0.8em;
|
||||
color: #BABABA;
|
||||
}
|
||||
|
||||
code.bbcode {
|
||||
|
||||
}
|
||||
|
||||
|
||||
ul.bblist {
|
||||
margin-left: 2em;
|
||||
}
|
||||
|
||||
|
||||
ul.bblist li {
|
||||
list-style-type: disc;
|
||||
}
|
||||
|
||||
span.bbcolyellow {
|
||||
color: yellow;
|
||||
}
|
||||
|
||||
span.bbcolred {
|
||||
color: red;
|
||||
}
|
||||
|
||||
span.bbcolgreen {
|
||||
color: green;
|
||||
}
|
||||
|
||||
span.bbcolblue {
|
||||
color: blue;
|
||||
}
|
||||
|
||||
span.bbcolbrown {
|
||||
color: brown;
|
||||
}
|
||||
|
||||
span.bbcolblack {
|
||||
color: black;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ item.o: ../core/request.h ../core/requesttypes.h ../core/session.h
|
|||
item.o: ../core/plugindata.h ../core/thread.h ../core/compress.h
|
||||
item.o: ../core/acceptencodingparser.h ../core/acceptbaseparser.h
|
||||
item.o: ../core/htmlfilter.h ../core/postmultiparser.h ../core/ticket.h
|
||||
item.o: ../core/misc.h
|
||||
item.o: ../core/misc.h ../core/bbcodeparser.h
|
||||
last.o: templates.h patterncacher.h ../core/item.h misc.h localefilter.h
|
||||
last.o: ../core/locale.h ../confparser/confparser.h ckeditorgetparser.h
|
||||
last.o: ../core/httpsimpleparser.h ../core/log.h indexpatterns.h
|
||||
|
|
|
@ -12,12 +12,15 @@
|
|||
#include "../core/data.h"
|
||||
#include "../core/request.h"
|
||||
#include "../core/misc.h"
|
||||
#include "../core/bbcodeparser.h"
|
||||
|
||||
|
||||
|
||||
|
||||
namespace TemplatesFunctions
|
||||
{
|
||||
static BBCODEParser bbcode_parser;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -114,20 +117,19 @@ void item_print_content(std::ostringstream & out, const std::string & content, I
|
|||
HtmlEscapeFormTxt(out, content);
|
||||
}
|
||||
else
|
||||
if( content_type == Item::ct_html )
|
||||
if( content_type == Item::ct_html || content_type == Item::ct_raw )
|
||||
{
|
||||
out << content;
|
||||
}
|
||||
else
|
||||
if( content_type == Item::ct_bbcode )
|
||||
{
|
||||
//out << content; // !! tutaj bedzie parsowanie bbcodu i tworzenie odpowiadajacego mu html-a
|
||||
out << "bbcode is not implemented yet";
|
||||
}
|
||||
else
|
||||
if( content_type == Item::ct_raw )
|
||||
{
|
||||
out << content;
|
||||
static std::string out_temp;
|
||||
out_temp.clear();
|
||||
out_temp.reserve(content.size()*2);
|
||||
|
||||
bbcode_parser.Filter(content.c_str(), out_temp);
|
||||
out << out_temp;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -523,8 +525,6 @@ void item_tab_date_creation_nice(Info & i)
|
|||
{
|
||||
tm * ptm = &request.item_table[item_index].date_creation;
|
||||
TemplatesMisc::print_date_nice(i, ptm);
|
||||
|
||||
i.out << "<!-- creation hour: " << ptm->tm_hour << " -->";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -536,8 +536,6 @@ void item_tab_date_modification_nice(Info & i)
|
|||
{
|
||||
tm * ptm = &request.item_table[item_index].date_modification;
|
||||
TemplatesMisc::print_date_nice(i, ptm);
|
||||
|
||||
i.out << "<!-- modification hour: " << ptm->tm_hour << " -->";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ Locale locale;
|
|||
LocaleFilter locale_filter;
|
||||
CKEditorGetParser ckeditor_getparser;
|
||||
|
||||
|
||||
const std::string empty; // used by GenerateRunRaw()
|
||||
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
|
||||
|
||||
|
||||
namespace TemplatesFunctions
|
||||
{
|
||||
using Ezc::Info;
|
||||
|
|
Loading…
Reference in New Issue