milesj / decoda Goto Github PK
View Code? Open in Web Editor NEWA lightweight lexical string parser for BBCode styled markup.
License: MIT License
A lightweight lexical string parser for BBCode styled markup.
License: MIT License
Following BBCode
[image]/some/url.png[/image]
should be parsed as
<img src="/some/url.png alt="">
but it parsed to instead
<img src="/some/url.png" alt="">/some/url.png</img>
At the same time [img]
tag works as supposed.
this syntax should work
[quote=bob
]
test
[/quote]
like this
[quote=bob]
test
[/quote]
Hi!
I use your library for a while with Symfony2 via FMBbCodeBundle for a while. And it works nice =)
But after recent upgrade I started receiving wrong results.
And here is the story.
I have texts provided by the users.
Of cource it can contain XSS and such, so I escape the text manually.
Texts can contain my own wiki-like tags. So I process them manually too - this operation creates hyperlinks from those tags.
Then inside my Twig template I apply BBCode filter from FMBbCodeBundle.
And I see that all of my lovely hyperlinks are escaped =(
I found that
Decoda::parse()
now has this string
$this->_string = str_replace(array('<', '>'), array('<', '>'), $this->_string);
For now I switched to version 3.1.
Could this thing be fixed?
Thanks for a nice lib =)
It would be nice to have a setter function nl2br, it would allow us to apply multiple filters to a string
https://github.com/milesj/Decoda/blob/master/src/Decoda/Decoda.php#L559
https://github.com/milesj/Decoda/blob/master/src/Decoda/Decoda.php#L837
https://github.com/milesj/Decoda/blob/master/src/Decoda/Decoda.php#L1454
https://github.com/milesj/Decoda/blob/master/src/Decoda/Decoda.php#L1484
Hey,
For instance, if you center this text "Hello :)" in a wysiwyg editor, the text will eventually look like this when passed to Decoda: "[center]Hello :)[/center]"
The smiley will not get passed because it is right next to the /center tag..
I'm not so sure that this is a bug, or more of a feature request.
I have a phpBB Forum, which when you use bbcode, will insert extra code within the tag so that it knows where that tag ends for example:
[b:fd3fds]2 more[/b:fd3fds]
When this gets passed through parse() it doesn't recognise this. Is it possible at all to do this with Decoda?
I'd like to create my own Filter which is placed somewhere in my symfony2 structure while decoda is imported via the deps file.
So I tried to simply extend DecodaFilter, placed the filter in my bundle and called addFilter, which then doesn't work because Decoda is extracting the classname and later for some reason tries to require_once this file. This of course fails because my Custom Filter is located outside the decoda directory structure.
It there a way to work around this issue which I'm currently missing?
Hi Miles,
I've got one question. In the newest version of decoda. I miss the possibility to alias a attribute. Is there a specific reason why it is removed?
Kind regards
Sean
Thanks for this, it's very handy.
My one issue so far is that it returns all newlines in the text with BR tags, where I'd prefer it to wrap the string in P tags at each break, so instead of this:
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
<br>
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
<br>
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
I'd like this:
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
<p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. </p>
Suggestions welcome!
Hello, is there a reason why reset() method is not cleaning errors from previous parse?
Fixed it by extending decoda and just adding php $this->_errors = array();
into reset() method. And I don't see a reason why it would be needed to check errors after all parses as there is no indication which parse contained the errors so reseting it and checking errors after each parse individually makes more sense imo.
<?php
$string = '[code]<?php echo 123;) ?>[/code]';
$code = new Decoda($string);
$code->defaults();
echo $code->parse(); ?>
// <pre class="decoda-code "><?php echo 123<img alt="" src="/decoda/decoda/emoticons/wink.png"> ?></pre>
When I use this syntax:
[size=25][center]test[/center][/size]
outputs
<span style="font-size: 25px">test</span>
And when I use this syntax:
[center][size=25]test[/size][/center]
outputs
<div class="align-center"><span style="font-size: 25px">test</span></div>
It does not work, since parser/filter translates all new lines to < br />, and of course on output there is no new lines in line.
To fix that, probably, new lines should be cleaned before parsing bbcode.
<?php
$string = "<script>alert('I can use xss');</script>";
$code = new Decoda($string);
$code->defaults();
echo $code->parse();
Just tried to execute an example:
$string = 'Hello, my name is [b]Miles Johnson[/b], you may visit my website at [url]http://milesj.me/[/url].';
// Load the text and parse
$code = new Decoda($string);
echo $code->parse();
and got an error Call to a member function tag() on a non-object in ... Decoda.php on line 864
When I started discovering a reason, I found a problem with namespaces.
on line 864 there is a call to $this->getFilter('Empty')->tag('root')
but $this->getFilter('Empty') returns nothing, because instead of 'Empty' key in $_filters array there is a key 'mjohnson\decoda\filters\Empty' (with full namespace).
If I change in Decoda::addFilter()
$class = str_replace(array('Filter', __NAMESPACE__.'\\filters\\'), '', basename(get_class($filter)));
instead of
$class = str_replace('Filter', '', basename(get_class($filter)));
then everything seems to be fine. Is it only my problem?
Could you add [right], [left] and [justify] BBCode in your library ?
I currently have an issue with block elements getting these extra
.
For example:
[b]Bold[/b]
[qoute]test[/quote]
gets converted to <b>Bold</b><br><blockquote>
However, since blockquote and (some other tags) are block elements shouldn't this
at the end be removed?
Is there any way setting to prevent a filter from doing this?
Well I had to spent about 2 hours debugging code to find out that for initial bbcode decoding I need to add Decoda\Filter\DefaultFilter filter to decoder object.
Example on your site:
$code = new Decoda\Decoda('Hello, my name is [b]Miles Johnson[/b], you may visit my website at [url]http://milesj.me[/url].');
echo $code->parse();
In reality it does not work.
Currently & is added if a word is censored this should be &
Wouldn't it be ok to allow the use of # and ? after .jpg, .jpeg, .png, .gif, .bmp.
const IMAGE_PATTERN = '/^(?:https?:/)?(?:.){0,2}/(.?).(?:jpg|jpeg|png|gif|bmp)(?:?([^#]))?(?:#(.*))?$/is';
For me this regular expression is working. I don't know if the added stuff is completely safe though.
Hello,
Could you add the support of this type of code :
[olist]
[li]Présentation de l'Alpe d'Huez[/li]
[li]Historique rapide de l'installation[/li]
[li]Présentation et situation du télésiège de l'Éclose[/li]
[li]L'appareil en photos[/li]
[list]
[li]Gare aval[/li]
[li]Ligne[/li]
[li]Gare amont[/li]
[li]Sièges et pinces[/li]
[li]Depuis les abords directs de l'appareil[/li]
[/list]
[li]Conclusion[/li]
[li]Goodies et sources[/li]
[/olist]
With sublists ?
Thanks a lot,
remontees
The following results in an XSS attack in IE7:
[div style="width: expression(alert('XSS'));"]woot?[/div]
Outputted by Decoda:
<div style="width: expression(alert('XSS'));">woot?</div>
You might want to check out http://ha.ckers.org/xss.html for more to test.
I'm working with Invision Power Board tags and am having issue with some of their tags not working in Decoda.
Specifically, they don't end self-closing tags with a slash.
So I have a tag that looks like this:
[attachment=90210:file1.png]
But Decoda won't pick up on it unless I add a trailing slash before the closing bracket.
Is there any way to make this parse?
Here is what my filter looks like so far:
class IPBAttachmentFilter extends AbstractFilter
{
/**
* Supported tags.
*
* @type array
*/
protected $_tags = array(
'attachment' => array(
'htmlTag' => 'test',
'displayType' => Decoda::TYPE_INLINE,
'allowedTypes' => Decoda::TYPE_INLINE,
'attributes' => array(
'default' => true
),
'mapAttributes' => array(
'default' => 'href'
),
'autoClose' => true
)
);
It'd be great if there is a way to parse back from html to bbcode (eg. when editing a post).
Will that be easy to do?
I'm installing decoda using composer into my symfony2 project with this: "mjohnson/decoda": "6.0.1"
. However, when I try to load the Decoda class, I'm getting: ERROR: CLASS 'DECODA\DECODA' NOT FOUND IN /WWW/[...].PHP LINE 29
.
A short analysis gives a hint at the issue: Composer's autoload_namespaces.php
file lists Decoda as follows:
'Decoda' => $vendorDir . '/mjohnson/decoda/src',
However, the decoda src
folder actually gets installed here:
vendor/mjohnson/decoda/mjohnson/decoda/src
Looks like there's something wrong with the metadata there.
Best regards,
Mike
I'm trying to get the Forum plugin working, and I'm having issues with the Decoda editor from the Utility plugin. Specifically, the submenus are popping under the other buttons on the toolbar. The submenus from the buttons in the bottom row work flawlessly, but the menus from the top row lose focus as soon as you try to mouse down to select a value, and pass over a button in the lower row. This is happening in Chrome (27.0.1.1453.166 m) and Firefox (21.0 & 22.0)
Hello,
I'm getting a strange error parsing the following:
[quote]
[code="clike"]
Route::filter('ajax', function()
{
if (!Request::ajax())
{
return Redirect::to('error')->
with(array('custom_message' => 'Sorry, you are not authorised to access this page.'));
}
});[/code]
[/quote]
[code="clike"]
URL::asset('js/jquery.file.js')
[/code]
The first block is parsed fine but the second [code] content comes out as:
77u/Cu+7v1VSTDo6YXNzZXQoJ2pzL2pxdWVyeS5maWxlLmpzJyk=
This is using the following filters:
public static function getDecoda()
{
$decoda = new Decoda\Decoda();
$decoda->addFilter(new Decoda\Filter\DefaultFilter());
$decoda->addFilter(new Decoda\Filter\BlockFilter());
$decoda->addFilter(new Decoda\Filter\TextFilter());
$decoda->addFilter(new Decoda\Filter\EmailFilter());
$decoda->addFilter(new Decoda\Filter\UrlFilter());
$decoda->addHook(new \Decoda\Hook\ClickableHook());
$decoda->addFilter(new Decoda\Filter\ImageFilter());
$decoda->addFilter(new Decoda\Filter\VideoFilter());
$decoda->addFilter(new Decoda\Filter\CodeFilter());
$decoda->addFilter(new Decoda\Filter\QuoteFilter());
$decoda->setStrict(false);
return $decoda;
}
I've tried capturing the errors using getErrors() but it's returning an empty array. Any ideas?
[spoiler][COLOR="DarkSlateBlue"][CENTER][SIZE="4"][B]TEXT HERE[/B][/SIZE][/COLOR][/CENTER][/spoiler]
If we take a loot above, [/CENTER] close tag is not in order, so the parser removes [spoiler], and spoiler does not show.
Note :
Sorry bout my english
Hello,
Why you don't respect the official syntax of BBCode List ? Source : http://forums.phpbb-fr.com/faq.php?mode=bbcode#f3r0
remontees
We have a code like this:
[img]http://выбрать-прическу.рф/files/jessica007.jpg[/img]
This is proper russian cyrillic domain name. On the parse: Invalid img
I am using Decoda with symfony2.1 which uses composer, and it is very difficult to change the messages, add filters, etc.
It could be good if you could have another aproach for this.
Hello,
It could be good to add the BBCode [abbr] for acronyms to the library.
remontees
It's seem the URL filter break when parsing a string like this :
Some text with [url=https://github.com/milesj/Decoda/]a link[/url] and some other text.
If I remove le last "/" in the url, the text is parsed correctly.
Fatal Error
Error: Class 'Decoda\Filter\EmptyFilter' not found
File: /var/www/user44819/data/www/magazin.v-bologoe.ru/app/Vendor/decoda/Decoda/Decoda.php
Line: 707
I don't undestend - why?
Thanks
I'd like to see a blacklist option to supplement the current whitelist option.
There are times when its easier to set what tags are not allowed vs which ones are allowed.
Please, make your autoload class public and static.
I'm using Yii Framework and I need register external autoloading methods, but I can't because you make your autoloading method private.
// make this
public function __construct($string = '') {
spl_autoload_register(array(__CLASS__, 'loadFile'));
$this->_messages = json_decode(file_get_contents(DECODA_CONFIG .'messages.json'), true);
$this->reset($string, true);
}
public static function loadFile($class) {
if (strpos($class, 'Filter') !== false) {
include_once DECODA_FILTERS . $class .'.php';
} else if (strpos($class, 'Hook') !== false) {
include_once DECODA_HOOKS . $class .'.php';
}
}
//so i can use this
Yii::registerAutoloader(array('Decoda', 'loadFile'));
When I use emoticon hook and I want to convert this string ':) :) :)'
Parser convert only the first ":)"
But if I add spaces between smileys, it works
Hi all,
what would be the best way to allow the usage of "https"-urls (e.g. https://www.youtube.com/...) ?
Kind regards
Raphael
Hello,
Could you add this type of BBCode :
[url=Toto]http://toto.fr[/url]
=> Toto
Thanks a lot,
remontees
There are a few self contained tags such as [br] and [hr] common in BBC.
I don't see an option for flagging a tag that does not need a closing option ...
so to get a horizontal rule one needs to do [hr[[/hr] instead of the common [hr]
Can we get a way to strip all the tags so that:
test [b]some [i]text[/i] here[/b] with a [url]http://google.com[/url] tag
could become the following if we include content:
test some text here with a http://google.com tag
or if we exclude the content:
test tag
I am not sure how you call it whether you would do something like $code->parse(array('strip_tags'=>true, 'exclude_content'=>true))
or $code->stripTags(array('exclude_content'=>true))
I was also wondering instead of that last options to add another param in the FilterAbstract for 'stripContent' => false
and then when running $code->stripTags()
it would default to including the text within the tag but removing the tag itself. Then by setting 'stripContent' => true
it would also strip out everything within the tag which would be useful for [code]blah blah[/code]
.
This functionality would allow us to get back to the original content for further parsing. For example, building search functionality against our content would not index the tags or the content within the tags that are not useful for our parsing.
Absolute and relative urls (without domain part) [url="/path/to/some-page.html"]Some page[/url] or [url="../another-page.html"]Another page[/url] not supported.
Hi Miles,
Within one of your last updates the function isParseable was integrated.
protected function _isParseable($string) {
return (
mb_strpos($string, $this->config('open')) !== false &&
mb_strpos($string, $this->config('close')) !== false &&
!$this->config('disabled')
);
}
This function checks if the config key disabled is true and if so it returns that the string is not parseable. This was not the case in earlier versions so that when the disabled flag was set the string was parsed but all tags were stripped out (which I think is the desired behavior).
Would it be possible that you added the last part of the if condition mistakenly? :-)
Regards!
Sebastian
Can you please add your project to http://packagist.org so we can use it with composer for easy including.
This is possible situation, when self-closing tag has attributes. As example - soundcloud service share code:
[soundcloud url="http://api.soundcloud.com/tracks/71043648" params="" width=" 100%" height="166" iframe="true" /]
To correctly handle such situation we need to change one method only:
protected function _buildTag($string) {
....
// Self closing tag
} else if (substr($string, -2) === '/]') {
$tag['tag'] = trim(substr($string, 1, strlen($string) - 3));
$tag['type'] = self::TAG_SELF_CLOSE;
change to:
// Self closing tag
} else if (substr($string, -2) === '/]') {
$whitespacePos = strpos($string, " ");
$tag['tag'] = trim(substr($string, 1, $whitespacePos ? $whitespacePos - 1 : strlen($string) - 3));
$tag['type'] = self::TAG_SELF_CLOSE;
If you use my code or make your own fix - I will be very grateful. Thanks for your work and great product!
Code:
$code = new Decoda\Decoda('[quote=milesj]Hello, my name is [b]Miles Johnson[/b] :)[/quote] [b]Hello[/b] ;)');
$code->defaults();
$code->addHook(new \Decoda\Hook\EmoticonHook());
echo $code->parse();
Output:
<blockquote class="decoda-quote">
<div class="decoda-quote-body">
Hello, my name is <b>Miles Johnson</b> :)
</div>
</blockquote>
<b>Hello</b> <img src="/images/wink.png" alt="">
As you can see the :) inside the quote is rendered as text instead of an image,
which seems to have to do with persistContent being false in QuoteFilter.
Hi,
The documentation at http://milesj.me/code/php/decoda#configuration mentions setLineBreaks() to toggle newline to line break (nl2br) conversion, however, I cannot find this method in the code.
Is there another way now to enable/disable nl2br?
require 'vendor/autoload.php';
$decoda = new Decoda\Decoda('[div]some[hr /]text[/div]');
$decoda->defaults();
echo $decoda->parse();
outputs
<hr><div>some<hr>text</div>
Same for [br /]
tag.
I think tags with TAG_SELF_CLOSE
should be handled differently in Decoda::_extractNodes()
, but I'm not sure to provide PR.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.