diff --git a/JBBCode/CodeDefinition.php b/JBBCode/CodeDefinition.php
index 2594e42..b2e46c4 100644
--- a/JBBCode/CodeDefinition.php
+++ b/JBBCode/CodeDefinition.php
@@ -14,6 +14,9 @@ class CodeDefinition
/** @var string NOTE: THIS PROPERTY SHOULD ALWAYS BE LOWERCASE; USE setTagName() TO ENSURE THIS */
protected $tagName;
+ /** @var string The original defined tag name. Needed for uppercased tags */
+ protected $originalTagName;
+
/** @var boolean Whether or not this CodeDefinition uses an option parameter. */
protected $useOption;
@@ -188,6 +191,16 @@ public function getTagName()
return $this->tagName;
}
+ /**
+ * Returns the original and not normalized tag name of this code definition
+ *
+ * @return string this definition's associated original tag name
+ */
+ public function getOriginalTagName()
+ {
+ return $this->originalTagName;
+ }
+
/**
* Returns the replacement text of this code definition. This usually has little, if any meaning if the
* CodeDefinition class was extended. For default, html replacement CodeDefinitions this returns the html
@@ -243,6 +256,7 @@ public function getNestLimit()
*/
public function setTagName($tagName)
{
+ $this->originalTagName = $tagName;
$this->tagName = strtolower($tagName);
}
diff --git a/JBBCode/ElementNode.php b/JBBCode/ElementNode.php
index 4eb6b8a..e915861 100644
--- a/JBBCode/ElementNode.php
+++ b/JBBCode/ElementNode.php
@@ -16,6 +16,13 @@ class ElementNode extends Node
/** @var string The tagname of this element, for i.e. "b" in [b]bold[/b] */
protected $tagName;
+ /**
+ * The original defined tag name of this element, for i.e. "b" in [b]bold[/b]
+ * or [B]bold[/B]
+ * @var string
+ */
+ protected $originalTagName;
+
/** @var string[] The attributes, if any, of this element node */
protected $attribute;
@@ -61,6 +68,7 @@ public function setCodeDefinition(CodeDefinition $codeDef)
{
$this->codeDefinition = $codeDef;
$this->setTagName($codeDef->getTagName());
+ $this->originalTagName = $codeDef->getOriginalTagName();
}
/**
@@ -83,6 +91,16 @@ public function getAttribute()
return $this->attribute;
}
+ /**
+ * Returns if element has any children.
+ *
+ * @return bool
+ */
+ public function hasChildren()
+ {
+ return (bool) $this->children;
+ }
+
/**
* Returns all the children of this element.
*
@@ -123,17 +141,19 @@ public function getAsText()
*/
public function getAsBBCode()
{
- $str = "[".$this->tagName;
+ $str = "[".$this->originalTagName;
if (!empty($this->attribute)) {
- if(isset($this->attribute[$this->tagName])) {
- $str .= "=".$this->attribute[$this->tagName];
+ if (isset($this->attribute[$this->originalTagName])) {
+ // avoid to generate something like [FOO= bar=baz]...[/FOO]
+ if (!empty($this->attribute[$this->originalTagName]) || !$this->hasChildren()) {
+ $str .= "=".$this->attribute[$this->originalTagName];
+ }
}
- foreach($this->attribute as $key => $value){
- if($key == $this->tagName){
+ foreach ($this->attribute as $key => $value) {
+ if (strcasecmp($key, $this->originalTagName) === 0) {
continue;
- }
- else{
+ } else{
$str .= " ".$key."=" . $value;
}
}
@@ -142,7 +162,7 @@ public function getAsBBCode()
foreach ($this->getChildren() as $child) {
$str .= $child->getAsBBCode();
}
- $str .= "[/".$this->tagName."]";
+ $str .= "[/".$this->originalTagName."]";
return $str;
}
diff --git a/JBBCode/UppercasedCodeDefinitionSet.php b/JBBCode/UppercasedCodeDefinitionSet.php
new file mode 100644
index 0000000..3a106c9
--- /dev/null
+++ b/JBBCode/UppercasedCodeDefinitionSet.php
@@ -0,0 +1,76 @@
+{param}');
+ $this->definitions[] = $builder->build();
+
+ /* [I] italics tag */
+ $builder = new CodeDefinitionBuilder('I', '{param}');
+ $this->definitions[] = $builder->build();
+
+ /* [U] underline tag */
+ $builder = new CodeDefinitionBuilder('U', '{param}');
+ $this->definitions[] = $builder->build();
+
+ $urlValidator = new \JBBCode\validators\UrlValidator();
+
+ /* [URL] link tag */
+ $builder = new CodeDefinitionBuilder('URL', '{param}');
+ $builder->setParseContent(false)->setBodyValidator($urlValidator);
+ $this->definitions[] = $builder->build();
+
+ /* [URL=http://example.com] link tag */
+ $builder = new CodeDefinitionBuilder('URL', '{param}');
+ $builder->setUseOption(true)->setParseContent(true)->setOptionValidator($urlValidator);
+ $this->definitions[] = $builder->build();
+
+ /* [IMG] image tag */
+ $builder = new CodeDefinitionBuilder('IMG', '
');
+ $builder->setUseOption(false)->setParseContent(false)->setBodyValidator($urlValidator);
+ $this->definitions[] = $builder->build();
+
+ /* [IMG=alt text] image tag */
+ $builder = new CodeDefinitionBuilder('IMG', '
');
+ $builder->setUseOption(true)->setParseContent(false)->setBodyValidator($urlValidator);
+ $this->definitions[] = $builder->build();
+
+ /* [COLOR] color tag */
+ $builder = new CodeDefinitionBuilder('COLOR', '{param}');
+ $builder->setUseOption(true)->setOptionValidator(new \JBBCode\validators\CssColorValidator());
+ $this->definitions[] = $builder->build();
+ }
+
+ /**
+ * Returns an array of the default code definitions.
+ *
+ * @return CodeDefinition[]
+ */
+ public function getCodeDefinitions()
+ {
+ return $this->definitions;
+ }
+}
diff --git a/JBBCode/tests/ElementNodeTest.php b/JBBCode/tests/ElementNodeTest.php
index 0230cbc..d97617b 100644
--- a/JBBCode/tests/ElementNodeTest.php
+++ b/JBBCode/tests/ElementNodeTest.php
@@ -76,4 +76,22 @@ public function testGetAsBBCode()
));
$this->assertEquals('[foo=bar bar=baz][/foo]', $this->_elementNode->getAsBBCode());
}
+
+ public function testGetAsBBCodeUppercased()
+ {
+ $builder = new JBBCode\CodeDefinitionBuilder('FOO', 'bar');
+ $codeDefinition = $builder->build();
+ $this->_elementNode->setCodeDefinition($codeDefinition);
+ $this->assertEquals('[FOO][/FOO]', $this->_elementNode->getAsBBCode());
+
+ $this->_elementNode->setAttribute(array('bar' => 'baz'));
+ $this->assertEquals('[FOO bar=baz][/FOO]', $this->_elementNode->getAsBBCode());
+
+ /** @ticket 55 */
+ $this->_elementNode->setAttribute(array(
+ 'bar' => 'baz',
+ 'FOO' => 'bar'
+ ));
+ $this->assertEquals('[FOO=bar bar=baz][/FOO]', $this->_elementNode->getAsBBCode());
+ }
}
diff --git a/JBBCode/tests/ParsingUpperCaseTest.php b/JBBCode/tests/ParsingUpperCaseTest.php
new file mode 100644
index 0000000..976a583
--- /dev/null
+++ b/JBBCode/tests/ParsingUpperCaseTest.php
@@ -0,0 +1,113 @@
+_parser = new JBBCode\Parser();
+ $this->_parser->addCodeDefinitionSet(new JBBCode\UppercasedCodeDefinitionSet());
+ }
+
+ /**
+ * @param string $code
+ * @param string[] $expected
+ * @dataProvider textCodeProvider
+ */
+ public function testParse($code, $expected)
+ {
+ $parser = $this->_parser->parse($code);
+ $this->assertEquals($expected['text'], $parser->getAsText());
+ $this->assertEquals($expected['html'], $parser->getAsHTML());
+ $this->assertEquals($expected['bbcode'], $parser->getAsBBCode());
+ }
+
+ public function textCodeProvider()
+ {
+ return array(
+ array(
+ 'foo',
+ array(
+ 'text' => 'foo',
+ 'html' => 'foo',
+ 'bbcode' => 'foo',
+ )
+ ),
+ array(
+ '[B]this is bold[/B]',
+ array(
+ 'text' => 'this is bold',
+ 'html' => 'this is bold',
+ 'bbcode' => '[B]this is bold[/B]',
+ )
+ ),
+ array(
+ '[B]this is bold',
+ array(
+ 'text' => 'this is bold',
+ 'html' => 'this is bold',
+ 'bbcode' => '[B]this is bold[/B]',
+ )
+ ),
+ array(
+ 'buffer text [B]this is bold[/B] buffer text',
+ array(
+ 'text' => 'buffer text this is bold buffer text',
+ 'html' => 'buffer text this is bold buffer text',
+ 'bbcode' => 'buffer text [B]this is bold[/B] buffer text',
+ )
+ ),
+ array(
+ 'this is some text with [B]bold tags[/B] and [I]italics[/I] and things like [U]that[/U].',
+ array(
+ 'text' => 'this is some text with bold tags and italics and things like that.',
+ 'html' => 'this is some text with bold tags and italics and things like that.',
+ 'bbcode' => 'this is some text with [B]bold tags[/B] and [I]italics[/I] and things like [U]that[/U].',
+ )
+ ),
+ array(
+ 'This contains a [URL=http://jbbcode.com]url[/URL] which uses an option.',
+ array(
+ 'text' => 'This contains a url which uses an option.',
+ 'html' => 'This contains a url which uses an option.',
+ 'bbcode' => 'This contains a [URL=http://jbbcode.com]url[/URL] which uses an option.',
+ )
+ ),
+ array(
+ 'This doesn\'t use the url option [URL]http://jbbcode.com[/URL].',
+ array(
+ 'text' => 'This doesn\'t use the url option http://jbbcode.com.',
+ 'html' => 'This doesn\'t use the url option http://jbbcode.com.',
+ 'bbcode' => 'This doesn\'t use the url option [URL]http://jbbcode.com[/URL].',
+ )
+ ),
+ );
+ }
+
+ /**
+ * @param string $code
+ *
+ * @dataProvider textCodeProviderWithInvalidCode
+ */
+ public function testParseInvalidCode($code)
+ {
+ $parser = $this->_parser->parse($code);
+ $this->assertEquals($code, $parser->getAsText());
+ $this->assertEquals($code, $parser->getAsHTML());
+ $this->assertEquals($code, $parser->getAsBBCode());
+ }
+
+ public function textCodeProviderWithInvalidCode()
+ {
+ return array(
+ array('This is some text with an [URL]I N V A L I D[/URL] URL tag.'),
+ array('This is some text with an [URL foo=bar]INVALID[/URL] URL tag.'),
+ array('This is some text with an invalid [URL=INVALID]URL[/URL] tag.')
+ );
+ }
+}
diff --git a/JBBCode/tests/bootstrap.php b/JBBCode/tests/bootstrap.php
index 797237a..542cb0d 100644
--- a/JBBCode/tests/bootstrap.php
+++ b/JBBCode/tests/bootstrap.php
@@ -1,2 +1,3 @@